示例#1
0
static void trace_by_addr(void *obj_addr, int distance)
{
    // An arbitrary cut-off for a search that's too deep to be useful.
    if(distance > 20) {
        return;
    }

    Object_With_Header *obj = (Object_With_Header *) GC::pinned_objects;
    while(obj) {
        uint64 sz = get_object_size(obj);
        void **obj_start = (void **)obj->start();
        void **obj_end = (void **)(((Byte *)obj_start) + sz);
        for(void **p = obj_start; p < obj_end; p++) {
            if(obj_addr == *p) {
                printf("GC TRACE: [%d] %p in obj %p(+%d): %s\n",
                       distance,
                       obj_addr,
                       obj_start,
                       (int)(((Byte *)p) - ((Byte *)obj_start)),
                       class_get_name(obj->vt()->gcvt->ch));
                if(!is_marked(obj)) {
                    printf("GC TRACE: %p is not marked\n", obj_start);
                    trace_by_addr(obj_start, distance + 1);
                }
            }
        }
        obj = next_object(obj);
    }
} //trace_by_addr
示例#2
0
MTable::MethodInfo::MethodInfo(Method_Handle _mh, size_t _num) {
    num = _num;
    mh = _mh;
    Class_Handle ch = method_get_class(mh);
    className = class_get_name(ch);
    methodName = method_get_name(mh);
    signature = method_get_descriptor(mh);
    assert(!className.empty() && !methodName.empty() && !signature.empty());
}
示例#3
0
/**
 * Prints graph structure in stderr.
 */
void vf_Graph::DumpGraph()
{
#if _VF_DEBUG
    VF_DEBUG("Method: " << class_get_name(m_ctx->m_class) << "::"
             << m_ctx->m_name << m_ctx->m_descriptor << endl);
    VF_DEBUG("-- start --");
    ResetNodeIterator();
    while (HasMoreElements()) {
        DumpNode(GetNextNode());
    }
#endif // _VF_DEBUG
}                               // vf_Graph::DumpGraph
示例#4
0
static void logReadyProfile(const std::string& catName, const std::string& profilerName, EBMethodProfile* mp) {
    const char* methodName = method_get_name(mp->mh);
    Class_Handle ch = method_get_class(mp->mh);
    const char* className = class_get_name(ch);
    const char* signature = method_get_descriptor(mp->mh);

    std::ostringstream msg;
    msg <<"EM: profiler["<<profilerName.c_str()<<"] profile is ready [e:"
        << mp->entryCounter <<" b:"<<mp->backedgeCounter<<"] "
        <<className<<"::"<<methodName<<signature;
    INFO2(catName.c_str(), msg.str().c_str());
}
示例#5
0
void trace_by_id()
{
    if(GC::trace_obj == NULL) {
        // No tracing or the object hasn't been allocated yet.
        return;
    }
    if(GC::trace_collection_number >= 0) {
        // Object has been already traced
        return;
    }
    Object_With_Header *obj = GC::trace_obj;
    if(is_marked(obj)) {
        // This GC hasn't reclaimed the object
        return;
    }
    GC::trace_collection_number = GC::num_collections;
    printf("GC TRACE: Tracing unmarked object %p: %s\n", obj->start(), class_get_name(obj->vt()->gcvt->ch));
    void *obj_addr = obj->start();
    trace_by_addr(obj_addr, 0);
} //trace_by_id
示例#6
0
static jint skip_old_frames(VM_thread *thread)
{
    if (NULL == getLastStackFrame(thread))
        return 0;

    StackFrame* first_frame = (StackFrame*)(thread->firstFrame);

    if (first_frame)
    {
        Class *clss = method_get_class(first_frame->method);
        assert(clss);

        if (strcmp(method_get_name(first_frame->method), "runImpl") == 0 &&
            strcmp(class_get_name(clss), "java/lang/Thread") == 0)
        {
            return 1;
        }
    }

    return 0;
}
示例#7
0
	ClassPtr _class_define_property(ClassPtr cls, Symbol name, Value getter, Value setter) {
		Property* property = new Property;
		property->getter = getter;
		property->setter = setter;
		Method key = { .name = name, .type = MethodTypeProperty, .function = NULL, .property = property };
		if (!class_define_method_or_property(cls, key)) {
			delete property;
			throw_exception_with_description("Method or property '%@' is already defined in class %@@%@.", snow::sym_to_cstr(name), class_get_name(cls), format::pointer(cls));
		}
		return cls;
	}
示例#8
0
	ClassPtr _class_define_method(ClassPtr cls, Symbol name, Value function) {
		ASSERT(!snow::is_symbol(function));
		Method key = { .name = name, .type = MethodTypeFunction, .function = function, .property = NULL };
		if (!class_define_method_or_property(cls, key)) {
			throw_exception_with_description("Method or property '%@' is already defined in class %@@%@.", snow::sym_to_cstr(name), class_get_name(cls), format::pointer(cls));
		}
		return cls;
	}
示例#9
0
		VALUE class_inspect(const CallFrame* here, VALUE self, VALUE it) {
			if (!is_class(self)) throw_exception_with_description("Class#inspect called for object that is not a class: %@.", value_inspect(self));
			return format_string("[Class@%@ name:%@]", format::pointer(self), class_get_name(self));
		}
示例#10
0
void mark_recursive(Managed_Object_Handle ref, bool ref_is_compressed)
{
    // If ref_is_compressed, ref is a compressed reference: the uint32 offset to an object in the heap.
    // ref_is_compressed => (GC::compressing_references && is_compressed_reference(ref))
    assert(!ref_is_compressed || (GC::compressing_references && is_compressed_reference((COMPRESSED_REFERENCE)ref)));

    uint64 null_ref = (GC::compressing_references? GC::heap_base : NULL);
    if (ref_is_compressed) {
        if (ref == 0) {
            return;
        }
    } else {
        if ((uint64)ref == null_ref) {
            return;
        }
    }

    Object_With_Header *obj;
    if (ref_is_compressed) {
        Managed_Object_Handle ref2 = (Managed_Object_Handle)(GC::heap_base + (COMPRESSED_REFERENCE)ref);
        obj = (Object_With_Header *)(((Byte *)ref2) - sizeof(GC_Overhead));
    } else {
        obj = (Object_With_Header *)(((Byte *)ref)  - sizeof(GC_Overhead));
    }

    unsigned space = obj->header.semispace;
    validate_object(obj);
    if(false && GC::verbosegc) {
#ifdef GC_STATS
        printf("Marking object: %s%p [id=%I64d]\n", (ref_is_compressed? "compressed " : ""), ref, obj->header.id);
#endif //GC_STATS
    }

    if(is_marked(obj)) {
        return;
    }

    set_marked(obj);
    Vtable_GC *vt = obj->vt();
    if(false && GC::verbosegc) {
        printf("\tObject of type %s\n", class_get_name(vt->gcvt->ch));
    }
    if(vt->gcvt->is_scannable_array) {
        scan_array(obj);
    } else {
        uint16 *offsets = vt->gcvt->offsets;
        Managed_Object_Handle ref2 = ref;
        if (ref_is_compressed) {
            ref2 = (Managed_Object_Handle)(GC::heap_base + (COMPRESSED_REFERENCE)ref);
        }
        if (GC::compressing_references) {
            while(*offsets) {
                COMPRESSED_REFERENCE *slot = (COMPRESSED_REFERENCE *)(((Byte *)ref2) + (*offsets));
                COMPRESSED_REFERENCE val_offset = (COMPRESSED_REFERENCE)(*slot);
                assert(is_compressed_reference(val_offset));
                Managed_Object_Handle val = (Managed_Object_Handle)(GC::heap_base + val_offset);
                push_on_mark_stack(val); 
                offsets++;
            }
        } else {
            while(*offsets) {
                Managed_Object_Handle *slot = (Managed_Object_Handle *)(((Byte *)ref2) + *offsets);
                push_on_mark_stack(*slot);
                offsets++;
            }
        }   
    }
} //mark_recursive
示例#11
0
/**
 * Dumps graph node in file in DOT format.
 */
void vf_Graph::DumpDotGraph()
{
#if _VF_DEBUG
    /**
     * Graphviz has a hardcoded label length limit. Windows has a file
     * name length limit as well.
     */
    const int MAX_LABEL_LENGTH = 80;

    // get class and method name
    const char *class_name = class_get_name(m_ctx->m_class);

    // create file name
    size_t len = strlen(class_name) + strlen(m_ctx->m_name)
        + strlen(m_ctx->m_descriptor) + 6;
    char *fname = (char *) STD_ALLOCA(len);
    sprintf(fname, "%s_%s%s", class_name, m_ctx->m_name, m_ctx->m_descriptor);

    char *f_start;
    char *pointer;
    if (len > MAX_LABEL_LENGTH) {
        f_start = fname + len - MAX_LABEL_LENGTH;
        // shift to the start of the nearest lexem
        for (pointer = f_start;; pointer++) {
            if (isalnum(*pointer)) {
                continue;
            } else if (!*pointer) {     // end of the string
                break;
            } else {
                // record the first matching position
                f_start = pointer;
                break;
            }
        }
    } else {
        f_start = fname;
    }

    for (pointer = f_start;; pointer++) {
        if (isalnum(*pointer)) {
            continue;
        } else if (!*pointer) { // end of the string
            break;
        } else {
            *pointer = '_';
        }
    }
    // pointer currently points to the end of the string
    sprintf(pointer, ".dot");

    // create .dot file
    ofstream fout(f_start);
    if (fout.fail()) {
        VF_DEBUG("vf_Graph::DumpDotGraph: error opening file: " << f_start);
        return;
    }
    // create name of graph
    sprintf(fname, "%s.%s%s", class_name, m_ctx->m_name, m_ctx->m_descriptor);

    // print graph to file
    DumpDotHeader(f_start, fout);
    ResetNodeIterator();
    while (HasMoreElements()) {
        DumpDotNode(GetNextNode(), fout);
    }
    DumpDotEnd(fout);

    // close file
    fout.flush();
    fout.close();
#endif // _VF_DEBUG
}                               // vf_Graph::DumpDotGraph