示例#1
0
        internal jvmtiError AddGlobalReference(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jobject obj)
        {
            long       tag;
            jvmtiError error = environment.GetTag(obj, out tag);

            if (error != jvmtiError.None)
            {
                return(error);
            }

            if (tag == 0)
            {
                return(jvmtiError.IllegalArgument);
            }

            _globalReferences.AddOrUpdate(tag,
                                          t =>
            {
                return(Tuple.Create(nativeEnvironment.NewGlobalReference(obj), 1));
            },
                                          (t, v) =>
            {
                if (v.Item2 == 0)
                {
                    return(Tuple.Create(nativeEnvironment.NewGlobalReference(obj), 1));
                }
                else
                {
                    return(Tuple.Create(v.Item1, v.Item2 + 1));
                }
            });

            return(jvmtiError.None);
        }
示例#2
0
        internal jvmtiError RemoveGlobalReference(JvmtiEnvironment environment, JniEnvironment nativeEnvironment, jobject obj)
        {
            long       tag;
            jvmtiError error = environment.GetTag(obj, out tag);

            if (error != jvmtiError.None)
            {
                return(error);
            }

            if (tag == 0)
            {
                return(jvmtiError.IllegalArgument);
            }

            var result = _globalReferences.AddOrUpdate(tag,
                                                       t =>
            {
                return(Tuple.Create(jobject.Null, 0));
            },
                                                       (t, v) =>
            {
                if (v.Item2 == 0)
                {
                    return(Tuple.Create(jobject.Null, 0));
                }
                else if (v.Item2 == 1)
                {
                    nativeEnvironment.DeleteGlobalReference(v.Item1);
                    return(Tuple.Create(jobject.Null, 0));
                }
                else
                {
                    return(Tuple.Create(v.Item1, v.Item2 - 1));
                }
            });

            return(jvmtiError.None);
        }
示例#3
0
        internal TaggedObjectId TrackLocalObjectReference(jobject @object, JvmtiEnvironment environment, JniEnvironment nativeEnvironment, bool freeLocalReference)
        {
            if (@object == jobject.Null)
            {
                return(new TaggedObjectId(Tag.Object, new ObjectId(0), default(TaggedReferenceTypeId)));
            }

            long tag;

            JvmtiErrorHandler.ThrowOnFailure(environment.GetTag(@object, out tag));

            TaggedReferenceTypeId type = default(TaggedReferenceTypeId);
            Tag objectKind;

            if (tag == 0)
            {
                long uniqueTag = Interlocked.Increment(ref _nextTag);

                /* first figure out what type of object we're dealing with. could be:
                 *  - String
                 *  - Thread
                 *  - ThreadGroup
                 *  - ClassLoader
                 *  - ClassObject
                 *  - Array
                 *  - Object
                 */

                // check for array
                jclass objectClass = nativeEnvironment.GetObjectClass(@object);
                try
                {
                    type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, false);

                    bool isArray = type.TypeTag == TypeTag.Array;
                    if (isArray)
                    {
                        objectKind = Tag.Array;
                    }
                    else
                    {
                        if (_stringClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _stringClass))
                        {
                            objectKind = Tag.String;
                        }
                        else if (_threadClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadClass))
                        {
                            objectKind = Tag.Thread;
                        }
                        else if (_threadGroupClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _threadGroupClass))
                        {
                            objectKind = Tag.ThreadGroup;
                        }
                        else if (_classClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classClass))
                        {
                            objectKind = Tag.ClassObject;
                        }
                        else if (_classLoaderClass != jclass.Null && nativeEnvironment.IsInstanceOf(@object, _classLoaderClass))
                        {
                            objectKind = Tag.ClassLoader;
                        }
                        else
                        {
                            objectKind = Tag.Object;
                        }
                    }
                }
                finally
                {
                    nativeEnvironment.DeleteLocalReference(objectClass);
                }

                tag = (uniqueTag << 8) | (uint)objectKind;
                JvmtiErrorHandler.ThrowOnFailure(environment.SetTag(@object, tag));

                lock (_objects)
                {
                    _objects.Add(new ObjectId(tag), nativeEnvironment.NewWeakGlobalReference(@object));
                }
            }
            else
            {
                jclass objectClass = nativeEnvironment.GetObjectClass(@object);
                type = TrackLocalClassReference(objectClass, environment, nativeEnvironment, true);
            }

            if (freeLocalReference)
            {
                nativeEnvironment.DeleteLocalReference(@object);
            }

            objectKind = (Tag)(tag & 0xFF);
            return(new TaggedObjectId(objectKind, new ObjectId(tag), type));
        }