StackValueCollection* interpretedVFrame::expressions() const { int length = fr().interpreter_frame_expression_stack_size(); if (method()->is_native()) { // If the method is native, there is no expression stack length = 0; } int nof_locals = method()->max_locals(); StackValueCollection* result = new StackValueCollection(length); // Get oopmap describing oops and int for current bci InterpreterOopMap oop_mask; method()->mask_for(bci(), &oop_mask); // handle locals for(int i=0; i < length; i++) { // Find stack location intptr_t *addr = expression_stack_addr_at(i); // Depending on oop/int put it in the right package StackValue *sv; if (oop_mask.is_oop(i + nof_locals)) { // oop value Handle h(*(oop *)addr); sv = new StackValue(h); } else { // integer sv = new StackValue(*addr); } assert(sv != NULL, "sanity check"); result->add(sv); } return result; }
StackValueCollection* compiledVFrame::expressions() const { // Natives has no scope if (scope() == NULL) return new StackValueCollection(0); GrowableArray<ScopeValue*>* scv_list = scope()->expressions(); if (scv_list == NULL) return new StackValueCollection(0); // scv_list is the list of ScopeValues describing the JVM stack state. // There is one scv_list entry for every JVM stack state in use. int length = scv_list->length(); StackValueCollection* result = new StackValueCollection(length); for( int i = 0; i < length; i++ ) result->add( create_stack_value(scv_list->at(i)) ); return result; }
StackValueCollection* interpretedVFrame::locals() const { int length = method()->max_locals(); if (method()->is_native()) { // If the method is native, max_locals is not telling the truth. // maxlocals then equals the size of parameters length = method()->size_of_parameters(); } StackValueCollection* result = new StackValueCollection(length); // Get oopmap describing oops and int for current bci InterpreterOopMap oop_mask; if (TraceDeoptimization && Verbose) { methodHandle m_h(thread(), method()); OopMapCache::compute_one_oop_map(m_h, bci(), &oop_mask); } else { method()->mask_for(bci(), &oop_mask); } // handle locals for(int i=0; i < length; i++) { // Find stack location intptr_t *addr = locals_addr_at(i); // Depending on oop/int put it in the right package StackValue *sv; if (oop_mask.is_oop(i)) { // oop value Handle h(*(oop *)addr); sv = new StackValue(h); } else { // integer sv = new StackValue(*addr); } assert(sv != NULL, "sanity check"); result->add(sv); } return result; }
StackValueCollection* compiledVFrame::locals() const { // Natives has no scope if (scope() == NULL) return new StackValueCollection(0); GrowableArray<ScopeValue*>* scv_list = scope()->locals(); if (scv_list == NULL) return new StackValueCollection(0); // scv_list is the list of ScopeValues describing the JVM stack state. // There is one scv_list entry for every JVM stack state in use. int length = scv_list->length(); StackValueCollection* result = new StackValueCollection(length); // In rare instances set_locals may have occurred in which case // there are local values that are not described by the ScopeValue anymore GrowableArray<jvmtiDeferredLocalVariable*>* deferred = NULL; GrowableArray<jvmtiDeferredLocalVariableSet*>* list = thread()->deferred_locals(); if (list != NULL ) { // In real life this never happens or is typically a single element search for (int i = 0; i < list->length(); i++) { if (list->at(i)->matches((vframe*)this)) { deferred = list->at(i)->locals(); break; } } } for( int i = 0; i < length; i++ ) { result->add( create_stack_value(scv_list->at(i)) ); } // Replace specified locals with any deferred writes that are present if (deferred != NULL) { for ( int l = 0; l < deferred->length() ; l ++) { jvmtiDeferredLocalVariable* val = deferred->at(l); switch (val->type()) { case T_BOOLEAN: result->set_int_at(val->index(), val->value().z); break; case T_CHAR: result->set_int_at(val->index(), val->value().c); break; case T_FLOAT: result->set_float_at(val->index(), val->value().f); break; case T_DOUBLE: result->set_double_at(val->index(), val->value().d); break; case T_BYTE: result->set_int_at(val->index(), val->value().b); break; case T_SHORT: result->set_int_at(val->index(), val->value().s); break; case T_INT: result->set_int_at(val->index(), val->value().i); break; case T_LONG: result->set_long_at(val->index(), val->value().j); break; case T_OBJECT: { Handle obj((oop)val->value().l); result->set_obj_at(val->index(), obj); } break; default: ShouldNotReachHere(); } } } return result; }