harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ge...@apache.org
Subject svn commit: r471216 - in /incubator/harmony/enhanced/drlvm/trunk/vm: include/ vmcore/src/jvmti/
Date Sat, 04 Nov 2006 15:24:29 GMT
Author: geirm
Date: Sat Nov  4 07:24:28 2006
New Revision: 471216

URL: http://svn.apache.org/viewvc?view=rev&rev=471216
Log:
HARMONY-1635

Additional files from patch that I forgot to commit.

This is in addition to commit r470903


Added:
    incubator/harmony/enhanced/drlvm/trunk/vm/include/jvmti_support.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/include/slot.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_enumerate.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.cpp   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.h   (with props)
    incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/ulist.h   (with props)

Added: incubator/harmony/enhanced/drlvm/trunk/vm/include/jvmti_support.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/include/jvmti_support.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/include/jvmti_support.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/include/jvmti_support.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,62 @@
+/*
+ *  Copyright 2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+#ifndef _JVMTI_SUPPORT_H_
+#define _JVMTI_SUPPORT_H_
+
+#include <open/types.h>
+#include <jvmti_types.h>
+
+/**
+ * @file
+ * This file describes inter-component interfaces needed to support
+ * JVMTI in the VM.
+ * 
+ * For now, the functions for interpreter and jitted code
+ * execution support are specified directly. This may be
+ * reconsidered later to be a table function.
+ */
+
+/**
+ * Enumerates one stack root to the VM.
+ */
+VMEXPORT void vm_ti_enumerate_stack_root(jvmtiEnv* env,
+        void* root, 
+        Managed_Object_Handle obj,
+        jvmtiHeapRootKind root_kind,
+        int depth,
+        jmethodID method,
+        int slot);
+
+/**
+ * Enumerates one heap root to the VM.
+ */
+VMEXPORT void vm_ti_enumerate_heap_root(jvmtiEnv* env,
+        void* root,
+        Managed_Object_Handle obj,
+        jvmtiHeapRootKind root_kind);
+
+/**
+ * Requests interpreter to enumerate one thread for TI.
+ */
+void interpreter_ti_enumerate_thread(jvmtiEnv *env, class VM_thread *thread);
+
+/**
+ * Requests JIT support to enumerate one thread for TI.
+ */
+void jitted_ti_enumerate_thread(jvmtiEnv *env, class VM_thread *thread);
+
+
+#endif // _JVMTI_SUPPORT_H_

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/include/jvmti_support.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/include/slot.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/include/slot.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/include/slot.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/include/slot.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,122 @@
+/*
+ *  Copyright 2005-2006 The Apache Software Foundation or its licensors, as applicable.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+/** 
+ * @author Intel, Salikh Zakirov
+ * @version $Revision$
+ */  
+#ifndef _SLOT_H_
+#define _SLOT_H_
+
+/**
+ * @file
+ * Define the Slot structure to read the object fields of reference type.
+ *
+ * This data layout is statically shared between all VM components.
+ */
+
+#include "open/gc.h"        // for the declaration of gc_heap_base_address()
+#include "open/vm_util.h"   // VM_Global_State
+#include "environment.h"    // Global_Env
+
+// (this file is based on gc_v4/src/compressed_references.h)
+//
+// The Slot data structure represents a pointer to a heap location that contains
+// a reference field.  It is packaged this way because the heap location may
+// contain either a raw pointer or a compressed pointer, depending on command line
+// options.
+//
+// Code originally of the form:
+//     ManagedObject **p_slot = foo ;
+//     ... *p_slot ...
+// can be expressed as:
+//     Slot p_slot(foo);
+//     ... p_slot.dereference() ...
+
+class Slot {
+private:
+    union {
+        void **raw;
+        uint32 *compressed;
+        void *value;
+    } content;
+
+    static void* heap_base;
+    static void* heap_ceiling;
+
+public:
+    Slot(void *v) {
+        set_address(v);
+    }
+
+    static void init(void* base, void* ceiling)
+    {
+        heap_base = base;
+        heap_ceiling = ceiling;
+    }
+
+    // Sets the raw value of the slot.
+    void *set_address(void *v) {
+        content.value = v;
+        return v;
+    }
+
+    // Returns the raw pointer value.
+    void *get_address() { return content.value; }
+
+    // Dereferences the slot and converts it to a raw object pointer.
+    void *dereference() {
+        if (VM_Global_State::loader_env->compress_references) {
+            assert(content.compressed != NULL);
+            return (void*)((UDATA)*content.compressed + (UDATA)heap_base);
+        } else {
+            assert(content.raw != NULL);
+            return *content.raw;
+        }
+    }
+
+    // Writes a new object reference into the slot.
+    void write(void *obj) {
+        if (VM_Global_State::loader_env->compress_references) {
+            if (obj != NULL) {
+                *content.compressed = (uint32) ((UDATA)obj - (UDATA)heap_base);
+            } else {
+                *content.compressed = 0;
+            }
+        } else {
+            *content.raw = obj;
+        }
+    }
+
+    // Returns true if the slot points to a null reference.
+    bool is_null() {
+        if (VM_Global_State::loader_env->compress_references) {
+            assert(content.compressed != NULL);
+            return (*content.compressed == 0);
+        } else {
+            assert(content.raw != NULL);
+            return (*content.raw == NULL);
+        }
+    }
+
+    // Returns the raw value of a managed null, which may be different
+    // depending on whether compressed references are used.
+    static void *managed_null() {
+        return (VM_Global_State::loader_env->compress_references ? heap_base : NULL);
+    }
+
+};
+
+#endif // _SLOT_H_

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/include/slot.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_enumerate.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_enumerate.cpp?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_enumerate.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_enumerate.cpp Sat Nov  4 07:24:28 2006
@@ -0,0 +1,51 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/**
+ * @file
+ * This file implements enumeration
+ * of global references controlled by the TI
+ */
+
+#define LOG_DOMAIN "ti.enum"
+#include "cxxlog.h"
+
+#include "jvmti.h"
+#include "jvmti_internal.h"
+#include "jvmti_utils.h"
+#include "jvmti_tags.h"
+
+
+// enumerates tags for one TI environment
+static void enumerate_env(TIEnv* env)
+{
+    if (env->tags != NULL) {
+        env->tags->enumerate();
+    }
+}
+
+
+// traverses the list of TI environments
+// and enumerates the global refs for each 
+void DebugUtilsTI::enumerate()
+{
+    TIEnv* env = p_TIenvs;
+    while (env != NULL) {
+        enumerate_env(env);
+        env = env->next;
+    }
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_enumerate.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,134 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _JVMTI_HEAP_H_
+#define _JVMTI_HEAP_H_
+
+#include <stack>
+
+// DRLVM exported headers
+#include <open/types.h>
+#include <open/vm.h>
+#include <jvmti_types.h>
+
+// DRLVM internal headers
+#include "jvmti_direct.h"
+#include "vm_arrays.h"
+
+// private module headers
+#include "jvmti_tags.h"
+
+/**
+ * @file
+ * Internal header file for heap iteration functions.
+ */
+
+struct TIIterationState {
+
+    // iterate over heap
+    jvmtiHeapObjectCallback heap_object_callback;
+    jvmtiHeapObjectFilter object_filter;
+
+    // iterate over instance of class
+    Class* class_filter;
+
+    // iterate over reachable objects
+    jvmtiHeapRootCallback heap_root_callback;
+    jvmtiStackReferenceCallback stack_ref_callback;
+    jvmtiObjectReferenceCallback object_ref_callback;
+
+    // true means that user requested to terminate iteration,
+    // by returning JVMTI_ITERATION_ABORT,  thus no subsequent
+    // data is passed to user callbacks
+    bool abort;
+    // non-zero value means the error occured during heap iteration
+    int error;
+
+    // used to trace the heap
+    unsigned char *markbits;
+    unsigned markbits_size;
+    std::stack<ManagedObject*> *markstack;
+
+    // some data is set up in enclosing scope and saved here,
+    // the actual callback function uses them
+    // deeper in the stack to pass to user callback
+    jvmtiHeapRootKind root_kind;    
+    jlong thread_tag;
+    jint depth;
+    jmethodID method;
+    void* frame_base; // used in calculation of slot index
+    void* user_data;
+
+    // debug data
+    int objects;
+    int bytes;
+};
+
+extern TIEnv* ti_env; // FIXME: store it in TLS
+
+/**
+ * returns object tag.
+ */
+inline jlong ti_get_object_tag(TIEnv *ti_env, Managed_Object_Handle obj)
+{
+    return ti_env->tags->get(obj);
+}
+
+/**
+ * returns tag of object class.
+ */
+inline jlong ti_get_object_class_tag(TIEnv *ti_env, Managed_Object_Handle obj)
+{
+    Class* clss = ((ManagedObject*)obj)->vt()->clss;
+    return ti_env->tags->get(*clss->class_handle);
+}
+
+/**
+ * returns object size.
+ */
+inline jint ti_get_object_size(TIEnv *ti_env, Managed_Object_Handle obj)
+{
+    Class* clss = ((ManagedObject*)obj)->vt()->clss;
+    if (class_is_array(clss)) {
+        return vm_vector_size(clss, get_vector_length(obj));
+    } else {
+        return class_get_boxed_data_size(clss);
+    }
+}
+
+/**
+ * returns true if the object pointer looks like a valid object.
+ */
+inline bool is_object_valid(Managed_Object_Handle obj)
+{
+    return ((obj != NULL) && (obj > Class::heap_base)
+            && (obj < Class::heap_end));
+}
+
+/**
+ * returns true if the jobject looks like a valid object.
+ */
+inline bool is_jobject_valid(jobject jobj)
+{
+    if (jobj == NULL) return false;
+    hythread_suspend_disable();
+    bool r = is_object_valid(jobj->object);
+    hythread_suspend_enable();
+    return r;
+}
+
+#endif // _JVMTI_HEAP_H_

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_heap.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.cpp?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.cpp Sat Nov  4 07:24:28 2006
@@ -0,0 +1,393 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/*
+ * JVMTI heap API
+ */
+
+#define LOG_DOMAIN "ti.roots"
+#include "cxxlog.h"
+
+// global headers
+#include <open/gc.h>
+#include <open/vm_gc.h>
+#include <open/jthread.h>
+#include <open/hythread_ext.h>
+#include <jvmti_support.h>
+
+// VM headers
+#include "Class.h"
+#include "classloader.h"
+#include "finalize.h"
+#include "interpreter.h"
+#include "jit_intf_cpp.h"
+#include "m2n.h"
+#include "object_handles.h"
+#include "object_layout.h"
+#include "root_set_enum_internal.h"
+#include "stack_iterator.h"
+#include "suspend_checker.h"
+#include "thread_manager.h"
+#include "vm_arrays.h"
+
+// JVMTI headers
+#include "jvmti_direct.h"
+#include "jvmti_utils.h"
+
+// private headers
+#include "jvmti_heap.h"
+#include "jvmti_tags.h"
+#include "jvmti_trace.h"
+
+/**
+ * calls stack root object callback.
+ *
+ * @param root is location of the root pointer (or interior pointer, or heap
+ * offset).
+ * @param obj is value of the root (differs from *root in case of interior
+ * pointers).
+ */
+void vm_ti_enumerate_stack_root(
+        jvmtiEnv* env,
+        void* root, Managed_Object_Handle obj,
+        jvmtiHeapRootKind root_kind,
+        int depth,
+        jmethodID method,
+        int slot)
+{
+    // JVMTI does not care about NULL roots
+    if (NULL == obj) return;
+
+    TIEnv* ti_env = (TIEnv*)env;
+    TIIterationState *state = ti_env->iteration_state;
+    assert(state);
+    if (state->abort) {
+        // user requested iteration abort, so ignore root
+        return;
+    }
+
+    tag_pair **tp = ti_get_object_tptr(obj);
+    jlong tag = (*tp != NULL ? (*tp)->tag : 0);
+    jlong class_tag = ti_get_object_class_tag(ti_env, obj);
+    jlong size = ti_get_object_size(ti_env, obj);
+
+    void* user_data = state->user_data;
+
+    jvmtiIterationControl r;
+
+    jlong thread_tag = state->thread_tag;
+
+    r = state->stack_ref_callback(root_kind, class_tag, size, &tag,
+            thread_tag, depth, method, slot, user_data);
+
+    ti_env->tags->update(obj, tag, tp);
+
+    if (JVMTI_ITERATION_ABORT == r) {
+        state->abort = true;
+    } else if (JVMTI_ITERATION_CONTINUE == r) {
+        // push the reference to the mark stack for later tracing
+        assert(state->markstack);
+        if (ti_mark_object(obj, state)) {
+            state->markstack->push((ManagedObject*)obj);
+        }
+    }
+}
+
+/**
+ * calls heap root object callback.
+ *
+ * @param root is location of the root pointer (or interior pointer, or heap offset).
+ * @param obj is value of the root (differs from *root in case of interior pointers).
+ */
+void vm_ti_enumerate_heap_root(
+        jvmtiEnv* env,
+        void* root,
+        Managed_Object_Handle obj,
+        jvmtiHeapRootKind root_kind)
+{
+    // JVMTI does not care about NULL roots
+    if (NULL == obj) return;
+
+    TIEnv* ti_env = (TIEnv*)env;
+    TIIterationState *state = ti_env->iteration_state;
+    assert(state);
+    if (state->abort) {
+        // user requested iteration abort, so ignore root
+        return;
+    }
+
+    tag_pair** tp = ti_get_object_tptr(obj);
+    jlong tag = ((*tp) != NULL ? (*tp)->tag : 0);
+
+    jlong class_tag = ti_get_object_class_tag(ti_env, obj);
+    jlong size = ti_get_object_size(ti_env, obj);
+
+    void* user_data = state->user_data;
+
+    jvmtiIterationControl r;
+
+    r = state->heap_root_callback(root_kind, class_tag, size, &tag, user_data);
+
+    ti_env->tags->update(obj, tag, tp);
+
+    if (JVMTI_ITERATION_ABORT == r) {
+        state->abort = true;
+    } else if (JVMTI_ITERATION_CONTINUE == r) {
+        // push the reference to the mark stack for later tracing
+        assert(state->markstack);
+        if (ti_mark_object(obj, state)) {
+            state->markstack->push((ManagedObject*)obj);
+        }
+    }
+}
+
+/**
+ * calls root object callback, taking some information
+ * from TIIterationState.
+ *
+ * @param root is location of the root pointer (or interior pointer, or heap offset).
+ * @param obj is value of the root (differs from *root in case of interior pointers).
+ */
+static void ti_enumerate_root(void* root, Managed_Object_Handle obj)
+{
+    TIEnv* ti_env = ::ti_env; // FIXME: load ti_env from TLS
+    TIIterationState *state = ti_env->iteration_state;
+    assert(state);
+    if (JVMTI_HEAP_ROOT_STACK_LOCAL == state->root_kind
+            || JVMTI_HEAP_ROOT_JNI_LOCAL == state->root_kind) {
+        jint depth = state->depth;
+        jmethodID method = state->method;
+        jint slot = ((UDATA)state->frame_base - (UDATA)root)/sizeof(void*);
+
+        vm_ti_enumerate_stack_root((jvmtiEnv*)ti_env, 
+                root, obj, state->root_kind, 
+                depth, method, slot);
+    } else {
+        vm_ti_enumerate_heap_root((jvmtiEnv*)ti_env, 
+                root, obj, 
+                state->root_kind);
+    }
+}
+
+////////////////////////////////////////
+// hijacked enumeration functions
+//
+
+static void ti_add_root_set_entry(
+        Managed_Object_Handle *root, 
+        Boolean UNREF pinned)
+{
+    TRACE2("ti.root", "ti root " << root << " -> " << *root);
+    ti_enumerate_root(root, *root);
+}
+
+static void ti_add_weak_root_set_entry(
+        Managed_Object_Handle *root,
+        Boolean UNREF pinned,
+        Boolean UNREF short_weak)
+{
+    TRACE2("ti.root", "ti root " << root << " -> " << *root);
+    // XXX: should weak roots be enumerated?
+    ti_enumerate_root(root, *root);
+}
+
+static void ti_add_root_set_entry_interior_pointer(
+        void **slot, 
+        int offset, 
+        Boolean UNREF pinned)
+{
+    Managed_Object_Handle obj = (Managed_Object_Handle)
+        ((UDATA)*slot - offset);
+    ti_enumerate_root(slot, obj);
+}
+
+static void ti_add_compressed_root_set_entry(
+        uint32 *ref, 
+        Boolean UNREF pinned)
+{
+    Managed_Object_Handle obj = (Managed_Object_Handle)
+        uncompress_compressed_reference(*ref);
+    ti_enumerate_root(ref, obj);
+}
+
+//
+// hijacked enumeration functions
+////////////////////////////////////////
+
+static void ti_enumerate_globals(TIEnv* ti_env)
+{
+    // this function reimplements the function
+    // vm_enumerate_root_set_global_refs()
+
+    TIIterationState *state = ti_env->iteration_state;
+    state->root_kind = JVMTI_HEAP_ROOT_OTHER;
+
+    // Static fields of all classes
+    vm_enumerate_static_fields();
+    vm_enumerate_objects_to_be_finalized();
+    vm_enumerate_references_to_enqueue();
+
+    state->root_kind = JVMTI_HEAP_ROOT_JNI_GLOBAL;
+    oh_enumerate_global_handles();
+
+
+    state->root_kind = JVMTI_HEAP_ROOT_OTHER;
+    vm_enumerate_interned_strings();
+
+
+    state->root_kind = JVMTI_HEAP_ROOT_MONITOR;
+    extern void vm_enumerate_root_set_mon_arrays();
+    vm_enumerate_root_set_mon_arrays();
+
+    state->root_kind = JVMTI_HEAP_ROOT_SYSTEM_CLASS;
+    ClassLoader::gc_enumerate();
+}
+
+static void ti_enumerate_thread_not_on_stack(TIEnv* ti_env, VM_thread* thread)
+{
+    TIIterationState *state = ti_env->iteration_state;
+    state->root_kind = JVMTI_HEAP_ROOT_THREAD;
+
+    assert(thread);
+    if (thread->thread_exception.exc_object != NULL) {
+        vm_enumerate_root_reference((void **)&(thread->thread_exception.exc_object), FALSE);
+    }
+    if (thread->thread_exception.exc_cause != NULL) {
+        vm_enumerate_root_reference((void **)&(thread->thread_exception.exc_cause), FALSE);
+    }
+    if (thread->p_exception_object_ti != NULL) {
+        vm_enumerate_root_reference((void **)&(thread->p_exception_object_ti), FALSE);
+    }
+
+    if (thread->native_handles)
+        thread->native_handles->enumerate();
+    if (thread->gc_frames) {
+        thread->gc_frames->enumerate();
+    }
+}
+
+
+
+static void ti_enumerate_thread_stack(TIEnv* ti_env, StackIterator* si)
+{
+    ASSERT_NO_INTERPRETER
+
+    TIIterationState *state = ti_env->iteration_state;
+    state->depth = 0;
+
+    while (!si_is_past_end(si)) {
+
+        CodeChunkInfo* cci = si_get_code_chunk_info(si);
+        if (cci) {
+            state->method = (jmethodID)cci->get_method();
+            state->root_kind = JVMTI_HEAP_ROOT_STACK_LOCAL;
+            // FIXME: set up frame base (platform dependent!)
+            cci->get_jit()->get_root_set_from_stack_frame(cci->get_method(), 0, si_get_jit_context(si));
+        } else {
+            state->method = (jmethodID)m2n_get_method(si_get_m2n(si));
+            state->root_kind = JVMTI_HEAP_ROOT_JNI_LOCAL;
+            oh_enumerate_handles(m2n_get_local_handles(si_get_m2n(si)));
+        }
+        state->depth += 1;
+        si_goto_previous(si);
+    }
+    si_free(si);
+}
+
+void jitted_ti_enumerate_thread(jvmtiEnv *env, VM_thread *thread)
+{
+    StackIterator* si;
+    si = si_create_from_native(thread);
+    ti_enumerate_thread_stack(ti_env, si);    
+
+    // Enumerate references associated with a thread that are not stored on the thread's stack.
+    ti_enumerate_thread_not_on_stack(ti_env, thread);
+}
+
+static void ti_enumerate_thread(TIEnv *ti_env, VM_thread* thread)
+{
+    TIIterationState *state = ti_env->iteration_state;
+    state->root_kind = JVMTI_HEAP_ROOT_THREAD;
+    state->thread_tag = ti_env->tags->get(
+            (Managed_Object_Handle)
+            jthread_get_java_thread(hythread_self())->object);
+
+    if (interpreter_enabled()) {
+        interpreter.interpreter_ti_enumerate_thread((jvmtiEnv*)ti_env, thread);
+    } else {
+        jitted_ti_enumerate_thread((jvmtiEnv*)ti_env, thread);
+    }
+}
+
+void ti_enumerate_roots(TIEnv *ti_env, hythread_iterator_t iterator)
+{
+    TRACE2("ti.trace", "enumerating roots");
+
+    // FIXME: weird function table manipulations
+    void (*save_gc_add_root_set_entry)
+        (Managed_Object_Handle *ref, Boolean pinned);
+    void (*save_gc_add_weak_root_set_entry)
+        (Managed_Object_Handle *ref1, Boolean pinned, Boolean short_weak);
+    void (*save_gc_add_root_set_entry_interior_pointer)
+        (void **slot, int offset, Boolean pinned);
+    void (*save_gc_add_compressed_root_set_entry)
+        (uint32 *ref, Boolean pinned);
+
+    // save away old values
+    save_gc_add_root_set_entry =
+        gc_add_root_set_entry;
+    save_gc_add_weak_root_set_entry =
+        gc_add_weak_root_set_entry;
+    save_gc_add_root_set_entry_interior_pointer =
+        gc_add_root_set_entry_interior_pointer;
+    save_gc_add_compressed_root_set_entry =
+        gc_add_compressed_root_set_entry;
+
+    // hijack ti enumeration functions
+    gc_add_root_set_entry =
+        ti_add_root_set_entry;
+    gc_add_weak_root_set_entry =
+        ti_add_weak_root_set_entry;
+    gc_add_root_set_entry_interior_pointer =
+        ti_add_root_set_entry_interior_pointer;
+    gc_add_compressed_root_set_entry =
+        ti_add_compressed_root_set_entry;
+
+    // Run through list of active threads and enumerate each one of them.
+    hythread_t tm_thread = hythread_iterator_next(&iterator);
+    while (tm_thread && !ti_env->iteration_state->abort) {
+        VM_thread *thread = get_vm_thread(tm_thread);
+        if (thread)
+            ti_enumerate_thread(ti_env, thread);
+        tm_thread = hythread_iterator_next(&iterator);
+    }
+
+    // finally, process all the global refs
+    ti_enumerate_globals(ti_env);
+
+    // restore original enumeration functions
+    gc_add_root_set_entry =
+        save_gc_add_root_set_entry;
+    gc_add_weak_root_set_entry =
+        save_gc_add_weak_root_set_entry;
+    gc_add_root_set_entry_interior_pointer =
+        save_gc_add_root_set_entry_interior_pointer;
+    gc_add_compressed_root_set_entry =
+        save_gc_add_compressed_root_set_entry;
+
+    TRACE2("ti.trace", "completed root enumeration");
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,25 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _JVMTI_ROOTS_H
+#define _JVMTI_ROOTS_H
+
+#include "jvmti_direct.h"
+
+void ti_enumerate_roots(TIEnv* ti_env, hythread_iterator_t);
+
+#endif // _JVMTI_ROOTS_H

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_roots.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.cpp?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.cpp Sat Nov  4 07:24:28 2006
@@ -0,0 +1,186 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#include <algorithm>
+
+// global
+#include "open/gc.h"
+#include "open/vm_gc.h"
+#include "cxxlog.h"
+
+// VM-internal
+#include "environment.h"    // Global_Env
+#include "open/vm_util.h"   // VM_Global_State
+#include "jvmti_direct.h"   // TIEnv
+#include "vm_arrays.h"      // vm_array_size
+
+// private
+#include "jvmti_tags.h"
+
+jlong TITags::get(Managed_Object_Handle obj) {
+    tag_pair **tp = ti_get_object_tptr(obj);
+    if (*tp != NULL) {
+        return (*tp)->tag;
+    } else {
+        return 0;
+    }
+}
+
+void TITags::update(Managed_Object_Handle obj, jlong tag, tag_pair** tp)
+{
+    assert((*tp) == NULL ||
+            ((*tp)->obj == obj && tp == ti_get_object_tptr(obj)));
+    if (tag != 0) {
+        if ((*tp) != NULL) {
+            // update tag if we already had a pair
+            (*tp)->tag = tag;
+        } else {
+            // add new tag pair
+            tag_pair pair;
+            pair.obj = obj;
+            pair.tag = tag;
+            tags.push_back(pair);
+            *tp = &(tags.back());
+        }
+    } else {
+        // remove tag if we had any
+        if ((*tp) != NULL) {
+            tags.erase(tags.find(*tp));
+            *tp = NULL;
+        }
+    }
+}
+
+void TITags::set(Managed_Object_Handle obj, jlong tag) {
+    tag_pair **tp = ti_get_object_tptr(obj);
+    if (!*tp) {
+        // the object was not tagged before
+        if (tag != 0) {
+            // only need to store non-zero tags
+            tag_pair pair;
+            pair.obj = obj;
+            pair.tag = tag;
+            tags.push_back(pair);
+            *tp = &(tags.back());
+        }
+    } else {
+        // the object was tagged before
+        if (tag != 0) {
+            // update the tag value
+            (*tp)->tag = tag;
+        } else {
+            if (*tp) {
+                // remove the tag
+                tags.erase(tags.find(*tp));
+                *tp = NULL;
+            }
+        }
+    }
+}
+
+void TITags::enumerate() {
+    tag_pair_list::iterator i;
+    for (i = tags.begin(); i != tags.end(); i++) {
+        // (2) false = not pinned,
+        // (3) true = "long" weak root = reset after finalization
+        gc_add_weak_root_set_entry(&i->obj, false, true);
+    }
+}
+
+void TITags::get_objects_with_tags(
+        std::set<jlong> & tagset,
+        std::list<tag_pair> & objects)
+{
+    assert(objects.empty());
+    tag_pair_list::iterator i;
+    for (i = tags.begin(); i != tags.end(); i++) {
+        if (tagset.find(i->tag) != tagset.end()) {
+            objects.push_back(*i);
+        }
+    }
+}
+
+void TITags::iterate ()
+{
+    tag_pair_list::iterator i;
+    for (i = tags.begin(); i != tags.end(); i++) {
+        assert(i->obj);
+        bool r = vm_iterate_object(i->obj);
+        // terminate iteration if vm_iterate_object
+        // returns false
+        if (false == r) return;
+    }
+}
+
+void jvmti_send_object_free_event(TIEnv* ti_env, jlong tag)
+{
+    jvmtiEventObjectFree func =
+        (jvmtiEventObjectFree)
+        ti_env->get_event_callback(JVMTI_EVENT_OBJECT_FREE);
+
+    if (NULL != func) {
+        // user call backs are supposed to be
+        // called in suspend-enabled mode.
+        // switching is safe because we are in stop-the-world phase
+        tmn_suspend_enable(); // ----vv
+        TRACE2("jvmti.event.of", "Callback JVMTI_EVENT_OBJECT_FREE called");
+        func((jvmtiEnv*)ti_env, tag);
+        TRACE2("jvmti.event.of", "Callback JVMTI_EVENT_OBJECT_FREE finished");
+        tmn_suspend_disable(); // ----^^
+    }
+}
+
+void TITags::clean_reclaimed_object_tags(bool send_event, TIEnv* ti_env)
+{
+    tag_pair_list::iterator i;
+    for (i = tags.begin(); i != tags.end(); i++) {
+        if (i->obj == NULL) {
+            TRACE2("jvmti.tags", "object tagged by " << i->tag << " reclaimed"
+                    << (send_event ? ", event sent" : ""));
+            if (send_event) {
+                jvmti_send_object_free_event(ti_env, i->tag);
+            }
+            tags.erase(i--);
+        }
+    }
+}
+
+void jvmti_clean_reclaimed_object_tags()
+{
+    Global_Env *env = VM_Global_State::loader_env;
+    // this event is sent from stop-the-world setting
+    assert(!hythread_is_suspend_enabled());
+
+    DebugUtilsTI *ti = env->TI;
+    if (!ti->isEnabled())
+        return;
+
+    TIEnv *ti_env = ti->getEnvironments();
+    TIEnv *next_env;
+    while (NULL != ti_env)
+    {
+        next_env = ti_env->next;
+        bool send_event = ti_env->global_events[JVMTI_EVENT_OBJECT_FREE - JVMTI_MIN_EVENT_TYPE_VAL];
+
+        TITags* tags = ti_env->tags;
+        if (tags != NULL) {
+            tags->clean_reclaimed_object_tags(send_event, ti_env);
+        }
+
+        ti_env = next_env;
+    }
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,103 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _JVMTI_TAGS_H_
+#define _JVMTI_TAGS_H_
+/*
+ * JVMTI tags datatypes
+ */
+
+#include <list>
+#include <set>
+
+#include "jvmti_types.h"
+#include "open/types.h"
+
+#include "ulist.h"
+
+struct tag_pair {
+    Managed_Object_Handle obj;
+    jlong tag;
+
+    bool operator==(tag_pair p) {
+        return (obj == p.obj);
+    }
+};
+
+typedef ulist<tag_pair> tag_pair_list;
+
+struct TITags {
+    private:
+    tag_pair_list tags;
+
+    public:
+    TITags() : tags(128) {}
+
+    /// gets tag.
+    /// @return tag value or 0 if no tag exist
+    jlong get(Managed_Object_Handle obj);
+
+    /// sets tag.
+    /// Tag value of 0 means remove tag.
+    void set(Managed_Object_Handle obj, jlong tag);
+
+    /// updates the tag list by either
+    /// updating tag value, inserting new entry
+    /// or removing entry
+    void update(Managed_Object_Handle obj, jlong tag, tag_pair** tptr);
+
+    /// constructs a list of tagged objects filtered by tag values.
+    /// @param[in] tagset - the set of tag values to search
+    /// @param[out] objects - the set of found tag-object pairs
+    void get_objects_with_tags(std::set<jlong> & tagset, std::list<tag_pair> & objects);
+ 
+    /// enumerates all tagged objects as weak roots
+    void enumerate();
+    
+    /// calls vm_iterate_object for each tagged object
+    void iterate();
+
+    /// removes reclaimed objects from tag list,
+    /// @param send_event - true means that jvmti_send_object_free_event() 
+    ///   will be called for each reclaimed object tag.
+    /// @param ti_env - the pass-through parameter 
+    ///   to jvmti_send_object_free_event()
+    void clean_reclaimed_object_tags(bool send_event, TIEnv* ti_env);
+};
+
+/**
+ * returns location of object tag pointer ("tptr").
+ */
+inline tag_pair** ti_get_object_tptr(Managed_Object_Handle obj)
+{
+    ManagedObject *o = (ManagedObject*)obj;
+    if (class_is_array(o->vt()->clss)) {
+        return (tag_pair**)((VM_Vector*)obj)->get_tag_pointer_address();
+    } else {
+        return (tag_pair**)((ManagedObject*)obj)->get_tag_pointer_address();
+    }
+}
+
+// update tag pointer in objects when the tag pair has been moved
+// ("magically" called by ulist<tag_pair>::erase())
+inline void element_moved(tag_pair* from, tag_pair* to) {
+    tag_pair** tptr = ti_get_object_tptr(from->obj);
+    *tptr = to;
+}
+
+
+#endif // _JVMTI_TAGS_H_

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_tags.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.cpp
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.cpp?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.cpp (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.cpp Sat Nov  4 07:24:28 2006
@@ -0,0 +1,142 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+/*
+ * Trace the java heap
+ */
+
+#include "cxxlog.h"
+
+#include "open/gc.h"
+#include "slot.h"
+
+// VM internal headers
+#include "vm_arrays.h"
+
+// private module headers
+#include "jvmti_heap.h"
+#include "jvmti_roots.h"
+#include "jvmti_tags.h"
+#include "jvmti_trace.h"
+
+static void ti_trace_reference(TIEnv *ti_env,
+        ManagedObject* referrer,
+        ManagedObject* obj,
+        jvmtiObjectReferenceKind reference_kind,
+        jint referrer_index)
+{
+    TIIterationState *state = ti_env->iteration_state;
+
+    // do nothing if the user requested abort termination
+    if (state->abort) return;
+
+    jlong class_tag = ti_get_object_class_tag(ti_env, obj);
+    jlong size = ti_get_object_size(ti_env, obj);
+
+    tag_pair** tp = ti_get_object_tptr(obj);
+    jlong tag = (*tp != NULL ? (*tp)->tag : 0);
+
+    jlong referrer_tag = ti_get_object_tag(ti_env, referrer);
+
+    void *user_data = state->user_data;
+
+    jvmtiIterationControl r;
+    r = state->object_ref_callback(reference_kind,
+            class_tag, size, &tag, referrer_tag,
+            referrer_index, user_data);
+
+    ti_env->tags->update(obj, tag, tp);
+    
+    if (JVMTI_ITERATION_ABORT == r) {
+        state->abort = true;
+    }
+    if (r != JVMTI_ITERATION_CONTINUE) return;
+
+    if (ti_mark_object(obj, state)) {
+        TRACE2("ti.trace", "marked " << (void*)obj
+                << " from " << (void*)referrer);
+        state->markstack->push(obj);
+    }
+}
+
+static void ti_trace_object(TIEnv *ti_env, ManagedObject* referrer)
+{
+    TIIterationState* state = ti_env->iteration_state;
+    state->objects += 1;
+    state->bytes += ti_get_object_size(ti_env, referrer);
+    TRACE2("ti.trace", "tracing object " << (void*)referrer);
+    Class* ch = ((ManagedObject*)referrer)->vt()->clss;
+    if (class_is_array(ch)) { 
+        if (class_is_non_ref_array(ch)) return;
+
+        // trace reference array
+        int len = get_vector_length(referrer);
+        int i;
+        for (i = 0; i < len; i++) {
+            Slot slot(get_vector_element_address_ref(referrer, i));
+            if (slot.is_null()) continue;
+            ti_trace_reference(
+                    ti_env, referrer, 
+                    (ManagedObject*) slot.dereference(),
+                    JVMTI_REFERENCE_ARRAY_ELEMENT, i);
+        }
+    } else {
+        // trace object fields
+        unsigned num_fields = class_num_instance_fields_recursive(ch);
+        unsigned i;
+        for (i = 0; i < num_fields; i++) {
+            Field_Handle fh = class_get_instance_field_recursive(ch, i);
+            if (field_is_reference(fh)) {
+                int offset = field_get_offset(fh);
+                Slot slot((void*)((UDATA)referrer + offset));
+                if (slot.is_null()) continue;
+                ti_trace_reference(
+                        ti_env, referrer, 
+                        (ManagedObject*) slot.dereference(),
+                        JVMTI_REFERENCE_FIELD, i);
+            }
+        }
+    }
+}
+
+void ti_trace_heap(TIEnv* ti_env)
+{
+    TIIterationState *state = ti_env->iteration_state;
+    state->objects = 0;
+    state->bytes = 0;
+    while (!state->markstack->empty() && !state->abort) {
+        ManagedObject *obj = state->markstack->top();
+        state->markstack->pop();
+        ti_trace_object(ti_env, obj);
+    }
+    INFO2("ti.trace", "traced " << state->objects << " live objects, "
+            << state->bytes << " live bytes");
+}
+
+bool ti_mark_object(Managed_Object_Handle obj, TIIterationState *state)
+{
+    assert((UDATA)obj < (UDATA)Class::heap_end);
+    assert((UDATA)obj >= (UDATA)Class::heap_base);
+    unsigned offset = (UDATA)obj - (UDATA)Class::heap_base;
+    unsigned bitnum = offset / GC_OBJECT_ALIGNMENT;
+    unsigned index = bitnum / 8;
+    unsigned mask = 1 << (bitnum % 8);
+    assert(index < state->markbits_size);
+    bool unmarked = ((state->markbits[index] & mask) == 0);
+    state->markbits[index] = (state->markbits[index] | mask);
+    return unmarked;
+}

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.cpp
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,39 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef _JVMTI_TRACE_H
+#define _JVMTI_TRACE_H
+
+#include "jvmti_direct.h"
+
+/**
+ * @file
+ * Private JVMTI header file used for heap tracing functionality.
+ */
+
+/**
+ * Marks object in temporary markbits.
+ * @return true if object was not marked before.
+ */
+bool ti_mark_object(Managed_Object_Handle obj, TIIterationState *state);
+
+/**
+ * Traces the heap.
+ */
+void ti_trace_heap(TIEnv* ti_env);
+
+#endif // _JVMTI_TRACE_H

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/jvmti_trace.h
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/ulist.h
URL: http://svn.apache.org/viewvc/incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/ulist.h?view=auto&rev=471216
==============================================================================
--- incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/ulist.h (added)
+++ incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/ulist.h Sat Nov  4 07:24:28 2006
@@ -0,0 +1,353 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one or more
+ *  contributor license agreements.  See the NOTICE file distributed with
+ *  this work for additional information regarding copyright ownership.
+ *  The ASF licenses this file to You under the Apache License, Version 2.0
+ *  (the "License"); you may not use this file except in compliance with
+ *  the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License.
+ */
+
+#ifndef ULIST_H
+#define ULIST_H
+
+#include <assert.h>
+
+#ifdef UNIT_TEST
+#include "unit_test.h"
+#endif // UNIT_TEST
+
+/**
+ * Unsorted list container. Features:
+ *     common insertion time O(1), worst case O(log N) if collection has N elements
+ *     linear iteration with ability to erase elements as we go
+ *     mapping from payload pointer to iterator O(log N)
+ *     notification about moved elements
+ *     memory overhead O(log N)
+ *     interface similar to std::list
+ *
+ * BEWARE:
+ *     element ordering is not preserved on modifications
+ *     iterator-- may not usable for dereference operation
+ */
+template <class T>
+class ulist {
+    T* chunk;       // elements' store
+    size_t capacity;    // capacity
+    size_t used;    // number of used elements
+    ulist<T>* next; // next in linked list of chunks
+
+public:
+    struct iterator {
+        ulist<T> *current;
+        int index;
+        iterator()
+            : current(NULL), index(0) {}
+        iterator(ulist<T> *current, int index)
+            : current(current), index(index) {}
+
+        iterator & operator++(int) {
+            assert(current);
+            index++;
+            assert(index >= 0);
+            if ((size_t)index >= current->used) {
+                current = current->next;
+                index = 0;
+            }
+            return *this;
+        }
+
+        // BEWARE x-- is only good for subsequent x++
+        iterator operator--(int) {
+            assert(current);
+            return iterator(current, index--);
+        }
+
+        T & operator*() {
+            return current->chunk[index];
+        }
+
+        T* operator->() {
+            return &current->chunk[index];
+        }
+
+        bool operator!=(iterator i) {
+            return (current != i.current) || (index != i.index);
+        }
+    };
+
+    ulist(int initial)
+        : used(0), capacity(initial), next(NULL)
+    {
+        chunk = new T[capacity];
+        assert(chunk && "out of memory");
+    }
+
+protected:
+    // swap the chunk payload
+    void swap(ulist<T>* other) {
+        T* tmp_chunk = other->chunk;
+        size_t tmp_capacity = other->capacity;
+        size_t tmp_used = other->used;
+
+        other->chunk = chunk;
+        other->capacity = capacity;
+        other->used = used;
+
+        chunk = tmp_chunk;
+        capacity = tmp_capacity;
+        used = tmp_used;
+    }
+
+public:
+
+    void push_back(T& t) {
+        // allocate locally
+        if (used < capacity) {
+            chunk[used++] = t;
+            return;
+        }
+        // try to find available space in existing chunks
+        // approximate the collection size, as well as find the last
+        size_t size = capacity;
+        ulist<T>* other = next;
+        ulist<T>* last = this;
+        while (other) {
+            if (other->used < other->capacity) break;
+            size += other->capacity;
+            last = other;
+            other = other->next;
+        }
+
+        if (other) {
+            // found the other chunk with available space
+            swap(other);
+            // should have space after swap
+            assert(used < capacity);
+            chunk[used++] = t;
+            return;
+        }
+
+        // all existing chunks are full, allocate new one, double the capacity
+        assert(last && last->next == NULL);
+        last->next = new ulist<T>(size);
+        assert(last->next && "out of memory");
+        swap(last->next);
+
+        assert(used == 0 && used < capacity);
+        chunk[used++] = t;
+    }
+
+    T & back() {
+        // addition is always performed on the current chunk
+        assert(used > 0 && "can't use back() before push_back()");
+        return chunk[used-1];
+    }
+
+    void erase(iterator i) {
+        assert(0 <= i.index && (size_t)i.index < i.current->used);
+        i.current->used--;
+        if ((size_t)i.index < i.current->used) {
+            i.current->chunk[i.index] = i.current->chunk[i.current->used];
+            // moving element notification
+            element_moved(&i.current->chunk[i.current->used], &i.current->chunk[i.index]);
+        }
+    }
+
+    iterator find(T* t) {
+        ulist<T>* current = this;
+        while (current) {
+            if (current->chunk <= t && t < current->chunk + current->capacity) {
+                int index = t - current->chunk;
+                assert(0 <= index && (size_t)index < current->used && "deleted or moved element");
+                return iterator(current, t - current->chunk);
+            }
+            current = current->next;
+        }
+        assert(!"can't find element in collection");
+        return iterator(NULL, 0);
+    }
+
+    // iteration is not compatible with adding elements !!!
+    iterator begin() {
+        return iterator(this, 0);
+    }
+
+    iterator end() {
+        return iterator(NULL, 0);
+    }
+
+    // returns the overall size of the unsorted list
+    size_t size() {
+        return used + (next ? next->size() : 0);
+    }
+};
+
+#endif // ULIST_H
+
+#ifdef UNIT_TEST
+
+TEST(push_few) {
+    int N = 10;
+    ulist<int> list(N);
+    for (int j = 0; j < N; j++) {
+        list.push_back(j);
+    }
+    ulist<int>::iterator i;
+    int c = 0;
+    for (i = list.begin(); i != list.end(); i++) {
+        int x = *i;
+        assert(0 <= *i && *i < N);
+        c++;
+    }
+    LOG("expected " << N << " elements, got " << c);
+    assert(c == N);
+    for (int j = 0; j < N; j++) {
+        list.push_back(j);
+    }
+    c = 0;
+    for (i = list.begin(); i != list.end(); i++) {
+        assert(0 <= *i && *i < N);
+        c++;
+    }
+    LOG("expected " << (2*N) << "  elements, got " << c);
+    assert(c == 2*N);
+    assert(c == list.size());
+}
+
+TEST(push_many) {
+    ulist<int> list(10);
+    int N = 10000;
+    int c = 0;
+    for (int j = 0; j < N; j++) {
+        list.push_back(j);
+        c++;
+    }
+    LOG("expected " << N << " elements, got " << c);
+    assert(c == N);
+}
+
+TEST(back) {
+    ulist<int> list(10);
+    int N = 773;
+    for (int j = 0; j < N; j++) {
+        list.push_back(j);
+        assert(j == list.back());
+    }
+}
+
+TEST(erase) {
+    ulist<int> list(10);
+    int N = 78;
+    for (int j = 0; j < N; j++) {
+        list.push_back(j);
+    }
+    ulist<int>::iterator i;
+    for (i = list.begin(); i != list.end(); i++) {
+        if (*i % 2 == 0) {
+            list.erase(i--);
+        }
+    }
+    int c = 0;
+    for (i = list.begin(); i != list.end(); i++) {
+        assert(*i % 2 != 0);
+        c++;
+    }
+    assert(c == N/2);
+}
+
+TEST(erase_all) {
+    ulist<int> list(10);
+    int N = 33;
+    for (int j = 0; j < N; j++) {
+        list.push_back(j);
+    }
+    ulist<int>::iterator i;
+    for (i = list.begin(); i != list.end(); i++) {
+        list.erase(i--);
+    }
+    assert(list.size() == 0);
+}
+
+TEST(erase_all_and_back) {
+    ulist<int> list(10);
+    int N = 333;
+    int j;
+    for (j = 0; j < N; j++) {
+        list.push_back(j);
+    }
+    ulist<int>::iterator i;
+    for (i = list.begin(); i != list.end(); i++) {
+        list.erase(i--);
+    }
+    assert(list.size() == 0);
+    for (j = 0; j < N*2; j++) {
+        list.push_back(j);
+        assert(j == list.back());
+    }
+    for (j = 0, i = list.begin(); i != list.end(); i++, j++) {
+        if (j>1 && j<N*2) list.erase(i--);
+    }
+    assert(list.size() == 2);
+    for (j = 0; j < N*2; j++) {
+        list.push_back(j);
+        assert(j == list.back());
+    }
+    assert(list.size() == 2+N*2);
+}
+
+int **elements = NULL;
+
+// receive notifications about list elements being moved
+void element_moved(int* from, int* to) {
+    assert(*from == *to);
+    // only for the relevant test cases
+    if (!elements) return;
+    // and update elements array to the new element location
+    elements[*from] = to;
+}
+
+TEST(find) {
+    ulist<int> list(10);
+    int N = 333;
+    elements = new int*[N]; assert(elements && "out of memory");
+    int j;
+    // fill the ulist with numbers
+    for (j = 0; j < N; j++) {
+        list.push_back(j);
+        elements[j] = &list.back();
+    }
+
+    ulist<int>::iterator i;
+    for (j = 0; j < N; j++) {
+        i = list.find(elements[j]);
+        assert(j == *i);
+    }
+
+    // drop some of the elements
+    for (j = 0, i = list.begin(); i != list.end() && j < N; i++, j++) {
+        if (N/3 < j && j < 2*N/3 || j%3 == 0) {
+            elements[*i] = NULL;
+            list.erase(i--);
+        }
+    }
+
+    for (j = 0; j < N; j++) {
+        if (elements[j]) {
+            i = list.find(elements[j]);
+            assert(j == *i);
+        }
+    }
+
+    delete[] elements;
+    elements = NULL;
+}
+
+#endif // UNIT_TEST

Propchange: incubator/harmony/enhanced/drlvm/trunk/vm/vmcore/src/jvmti/ulist.h
------------------------------------------------------------------------------
    svn:eol-style = native



Mime
View raw message