GrowableArray<MonitorInfo*>* javaVFrame::locked_monitors() { assert(SafepointSynchronize::is_at_safepoint() || JavaThread::current() == thread(), "must be at safepoint or it's a java frame of the current thread"); GrowableArray<MonitorInfo*>* mons = monitors(); GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(mons->length()); if (mons->is_empty()) return result; bool found_first_monitor = false; ObjectMonitor *pending_monitor = thread()->current_pending_monitor(); ObjectMonitor *waiting_monitor = thread()->current_waiting_monitor(); oop pending_obj = (pending_monitor != NULL ? (oop) pending_monitor->object() : (oop) NULL); oop waiting_obj = (waiting_monitor != NULL ? (oop) waiting_monitor->object() : (oop) NULL); for (int index = (mons->length()-1); index >= 0; index--) { MonitorInfo* monitor = mons->at(index); if (monitor->eliminated() && is_compiled_frame()) continue; // skip eliminated monitor oop obj = monitor->owner(); if (obj == NULL) continue; // skip unowned monitor // // Skip the monitor that the thread is blocked to enter or waiting on // if (!found_first_monitor && (obj == pending_obj || obj == waiting_obj)) { continue; } found_first_monitor = true; result->append(monitor); } return result; }
// ------------------------------------------------------------------ // ciFieldLayout::ciFieldLayout ciFieldLayout::ciFieldLayout(ciInstanceKlass* my_klass) { assert(my_klass->is_loaded(), "must be loaded"); ASSERT_IN_VM; klassOop klass = my_klass->get_klassOop(); Arena* arena = CURRENT_ENV->arena(); GrowableArray<BasicType>* fieldtypes = new (arena) GrowableArray<BasicType>(arena, 8, 0, T_VOID); GrowableArray<int>* aflags = new (arena) GrowableArray<int>(arena, 8, 0, 0); GrowableArray<int>* fieldoffsets = new (arena) GrowableArray<int>(arena, 8, 0, 0); int pos = 0; fill_in_header_fields(fieldtypes, fieldoffsets, pos); _header_count = pos; fill_in_instance_fields(fieldtypes, fieldoffsets, aflags, pos, klass); #if 0 // [RGV] instance size is in word's but pos is number // of fields. int fill_to = my_klass->instance_size(); if (fieldtypes->length() < fill_to) fields->at_put_grow(fill_to-1, T_VOID, T_VOID); if (aflags->length() < fill_to) aflags->at_put_grow(fill_to-1, 0, 0); #endif _fieldtypes = fieldtypes; _access_flags = aflags; _fieldoffsets = fieldoffsets; }
void ScopeDesc::print_on(outputStream* st) const { // header st->print("ScopeDesc[%d]@0x%lx ", _decode_offset, _code->instructions_begin()); print_value_on(st); // decode offsets if (WizardMode) { st->print_cr("offset: %d", _decode_offset); st->print_cr("bci: %d", bci()); st->print_cr("locals: %d", _locals_decode_offset); st->print_cr("stack: %d", _expressions_decode_offset); st->print_cr("monitor: %d", _monitors_decode_offset); st->print_cr("sender: %d", _sender_decode_offset); } // locals { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->locals(); if (l != NULL) { tty->print_cr("Locals"); for (int index = 0; index < l->length(); index++) { st->print(" - l%d: ", index); l->at(index)->print_on(st); st->cr(); } } } // expressions { GrowableArray<ScopeValue*>* l = ((ScopeDesc*) this)->expressions(); if (l != NULL) { st->print_cr("Expression stack"); for (int index = 0; index < l->length(); index++) { st->print(" - @%d: ", index); l->at(index)->print_on(st); st->cr(); } } } // monitors { GrowableArray<MonitorValue*>* l = ((ScopeDesc*) this)->monitors(); if (l != NULL) { st->print_cr("Monitor stack"); for (int index = 0; index < l->length(); index++) { st->print(" - @%d: ", index); l->at(index)->print_on(st); st->cr(); } } } if (!is_top()) { st->print_cr("Sender:"); sender()->print_on(st); } }
// iteration support - return next code blob JvmtiCodeBlobDesc* next() { assert(_pos >= 0, "iteration not started"); if (_pos+1 >= _code_blobs->length()) { return NULL; } return _code_blobs->at(++_pos); }
void InlinedScope::markLocalsDebugVisible(GrowableArray<PReg*>* exprStack) { // this scope has at least one send - mark params & locals as debug-visible int i; if (_nofSends <= 1) { // first time we're called self()->preg()->debug = true; for (i = nofArguments() - 1; i >= 0; i--) { argument(i)->preg()->debug = true; } for (i = nofTemporaries() - 1; i >= 0; i--) { temporary(i)->preg()->debug = true; } // if there's a context, mark all context variables as debug-visible too. GrowableArray<Expr*>* ct = contextTemporaries(); if (ct != NULL) { for (i = 0; i < ct->length(); i++) { ct->at(i)->preg()->debug = true; } } } // also mark expression stack as debug-visible (excluding arguments to // current send) (the args are already excluded from the CallNode's // expression stack, so just use that one instead of this->exprStack) for (i = 0; i < exprStack->length(); i++) { exprStack->at(i)->debug = true; } }
void SendInfo::computeNSends(RScope* rscope, int bci) { GrowableArray<RScope*>* lst = rscope->subScopes(bci); nsends = 0; for (int i = lst->length() - 1; i >= 0; i--) { nsends += lst->at(i)->nsends; } }
void CompactHashtableWriter::allocate_table() { int entries_space = 0; for (int index = 0; index < _num_buckets; index++) { GrowableArray<Entry>* bucket = _buckets[index]; int bucket_size = bucket->length(); if (bucket_size == 1) { entries_space++; } else { entries_space += 2 * bucket_size; } } if (entries_space & ~BUCKET_OFFSET_MASK) { vm_exit_during_initialization("CompactHashtableWriter::allocate_table: Overflow! " "Too many entries."); } Thread* THREAD = VMThread::vm_thread(); ClassLoaderData* loader_data = ClassLoaderData::the_null_class_loader_data(); _compact_buckets = MetadataFactory::new_array<u4>(loader_data, _num_buckets + 1, THREAD); _compact_entries = MetadataFactory::new_array<u4>(loader_data, entries_space, THREAD); _stats->hashentry_count = _num_entries; _stats->hashentry_bytes = entries_space * sizeof(u4); }
// Write the compact table's buckets void CompactHashtableWriter::dump_table(NumberSeq* summary) { u4 offset = 0; for (int index = 0; index < _num_buckets; index++) { GrowableArray<Entry>* bucket = _buckets[index]; int bucket_size = bucket->length(); if (bucket_size == 1) { // bucket with one entry is compacted and only has the symbol offset _compact_buckets->at_put(index, BUCKET_INFO(offset, VALUE_ONLY_BUCKET_TYPE)); Entry ent = bucket->at(0); _compact_entries->at_put(offset++, ent.value()); _num_value_only_buckets++; } else { // regular bucket, each entry is a symbol (hash, offset) pair _compact_buckets->at_put(index, BUCKET_INFO(offset, REGULAR_BUCKET_TYPE)); for (int i=0; i<bucket_size; i++) { Entry ent = bucket->at(i); _compact_entries->at_put(offset++, u4(ent.hash())); // write entry hash _compact_entries->at_put(offset++, ent.value()); } if (bucket_size == 0) { _num_empty_buckets++; } else { _num_other_buckets++; } } summary->add(bucket_size); } // Mark the end of the buckets _compact_buckets->at_put(_num_buckets, BUCKET_INFO(offset, TABLEEND_BUCKET_TYPE)); assert(offset == (u4)_compact_entries->length(), "sanity"); }
void CodeBlobCollector::do_blob(CodeBlob* cb) { // ignore nmethods if (cb->is_nmethod()) { return; } // exclude VtableStubs, which are processed separately if (cb->is_buffer_blob() && strcmp(cb->name(), "vtable chunks") == 0) { return; } // check if this starting address has been seen already - the // assumption is that stubs are inserted into the list before the // enclosing BufferBlobs. address addr = cb->code_begin(); for (int i=0; i<_global_code_blobs->length(); i++) { JvmtiCodeBlobDesc* scb = _global_code_blobs->at(i); if (addr == scb->code_begin()) { return; } } // record the CodeBlob details as a JvmtiCodeBlobDesc JvmtiCodeBlobDesc* scb = new JvmtiCodeBlobDesc(cb->name(), cb->code_begin(), cb->code_end()); _global_code_blobs->append(scb); }
// iteration support - return next code blob nmethodDesc* next() { assert(_pos >= 0, "iteration not started"); if (_pos+1 >= _nmethods->length()) { return NULL; } return _nmethods->at(++_pos); }
// address of an element in _nodes. Used when the element is to be modified PointsToNode *ptnode_adr(uint idx) { if ((uint)_nodes->length() <= idx) { // expand _nodes array PointsToNode dummy = _nodes->at_grow(idx); } return _nodes->adr_at(idx); }
void BytecodeHistogram::print(float cutoff) { ResourceMark rm; GrowableArray<HistoEntry*>* profile = sorted_array(_counters, Bytecodes::number_of_codes); // print profile int tot = total_count(profile); int abs_sum = 0; tty->cr(); //0123456789012345678901234567890123456789012345678901234567890123456789 tty->print_cr("Histogram of %d executed bytecodes:", tot); tty->cr(); tty->print_cr(" absolute relative code name"); tty->print_cr("----------------------------------------------------------------------"); int i = profile->length(); while (i-- > 0) { HistoEntry* e = profile->at(i); int abs = e->count(); float rel = abs * 100.0F / tot; if (cutoff <= rel) { tty->print_cr("%10d %7.2f%% %02x %s", abs, rel, e->index(), name_for(e->index())); abs_sum += abs; } } tty->print_cr("----------------------------------------------------------------------"); float rel_sum = abs_sum * 100.0F / tot; tty->print_cr("%10d %7.2f%% (cutoff = %.2f%%)", abs_sum, rel_sum, cutoff); tty->cr(); }
// Returns MonitorInfos for all objects locked on this thread in youngest to oldest order static GrowableArray<MonitorInfo*>* get_or_compute_monitor_info(JavaThread* thread) { GrowableArray<MonitorInfo*>* info = thread->cached_monitor_info(); if (info != NULL) { return info; } info = new GrowableArray<MonitorInfo*>(); // It's possible for the thread to not have any Java frames on it, // i.e., if it's the main thread and it's already returned from main() if (thread->has_last_Java_frame()) { RegisterMap rm(thread); for (javaVFrame* vf = thread->last_java_vframe(&rm); vf != NULL; vf = vf->java_sender()) { GrowableArray<MonitorInfo*> *monitors = vf->monitors(); if (monitors != NULL) { int len = monitors->length(); // Walk monitors youngest to oldest for (int i = len - 1; i >= 0; i--) { MonitorInfo* mon_info = monitors->at(i); if (mon_info->eliminated()) continue; oop owner = mon_info->owner(); if (owner != NULL) { info->append(mon_info); } } } } } thread->set_cached_monitor_info(info); return info; }
void PerformanceDebugger::report_context(InlinedScope* s) { if (!DebugPerformance) return; Reporter r(this); GrowableArray<Expr*>* temps = s->contextTemporaries(); const int len = temps->length(); int nused = 0; for (int i = 0; i < len; i++) { PReg* r = temps->at(i)->preg(); if (r->uplevelR() || r->uplevelW() || (r->isBlockPReg() && !r->isUnused())) nused++; } if (nused == 0) { str->print(" could not eliminate context of scope %s (fixable compiler restriction; should be eliminated)\n", s->key()->print_string()); } else { str->print(" could not eliminate context of scope %s; temp(s) still used: ", s->key()->print_string()); for (int j = 0; j < len; j++) { PReg* r = temps->at(j)->preg(); if (r->uplevelR() || r->uplevelW()) { str->print("%d ", j); } else if (r->isBlockPReg() && !r->isUnused()) { str->print("%d (non-inlined block)", j); } } str->print("\n"); } }
// // Count the number of objects for a lightweight monitor. The hobj // parameter is object that owns the monitor so this routine will // count the number of times the same object was locked by frames // in java_thread. // jint JvmtiEnvBase::count_locked_objects(JavaThread *java_thread, Handle hobj) { jint ret = 0; if (!java_thread->has_last_Java_frame()) { return ret; // no Java frames so no monitors } ResourceMark rm; HandleMark hm; RegisterMap reg_map(java_thread); for(javaVFrame *jvf=java_thread->last_java_vframe(®_map); jvf != NULL; jvf = jvf->java_sender()) { GrowableArray<MonitorInfo*>* mons = jvf->monitors(); if (!mons->is_empty()) { for (int i = 0; i < mons->length(); i++) { MonitorInfo *mi = mons->at(i); if (mi->owner_is_scalar_replaced()) continue; // see if owner of the monitor is our object if (mi->owner() != NULL && mi->owner() == hobj()) { ret++; } } } } return ret; }
void javaVFrame::print() { ResourceMark rm; vframe::print(); tty->print("\t"); method()->print_value(); tty->cr(); tty->print_cr("\tbci: %d", bci()); print_stack_values("locals", locals()); print_stack_values("expressions", expressions()); GrowableArray<MonitorInfo*>* list = monitors(); if (list->is_empty()) return; tty->print_cr("\tmonitor list:"); for (int index = (list->length()-1); index >= 0; index--) { MonitorInfo* monitor = list->at(index); tty->print("\t obj\t"); if (monitor->owner_is_scalar_replaced()) { Klass* k = java_lang_Class::as_Klass(monitor->owner_klass()); tty->print("( is scalar replaced %s)", k->external_name()); } else if (monitor->owner() == NULL) { tty->print("( null )"); } else { monitor->owner()->print_value(); tty->print("(" INTPTR_FORMAT ")", (address)monitor->owner()); } if (monitor->eliminated() && is_compiled_frame()) tty->print(" ( lock is eliminated )"); tty->cr(); tty->print("\t "); monitor->lock()->print_on(tty); tty->cr(); } }
void PCRecorder::print() { if (counters == NULL) return; tty->cr(); tty->print_cr("Printing compiled methods with PC buckets having more than %d ticks", ProfilerPCTickThreshold); tty->print_cr("==================================================================="); tty->cr(); GrowableArray<CodeBlob*>* candidates = new GrowableArray<CodeBlob*>(20); int s; { MutexLockerEx lm(CodeCache_lock, Mutex::_no_safepoint_check_flag); s = size(); } for (int index = 0; index < s; index++) { int count = counters[index]; if (count > ProfilerPCTickThreshold) { address pc = pc_for(index); CodeBlob* cb = CodeCache::find_blob_unsafe(pc); if (cb != NULL && candidates->find(cb) < 0) { candidates->push(cb); } } } for (int i = 0; i < candidates->length(); i++) { print_blobs(candidates->at(i)); } }
void BytecodePairHistogram::print(float cutoff) { ResourceMark rm; GrowableArray<HistoEntry*>* profile = sorted_array(_counters, number_of_pairs); // print profile int tot = total_count(profile); int abs_sum = 0; tty->cr(); //0123456789012345678901234567890123456789012345678901234567890123456789 tty->print_cr("Histogram of %d executed bytecode pairs:", tot); tty->cr(); tty->print_cr(" absolute relative codes 1st bytecode 2nd bytecode"); tty->print_cr("----------------------------------------------------------------------"); int i = profile->length(); while (i-- > 0) { HistoEntry* e = profile->at(i); int abs = e->count(); float rel = abs * 100.0F / tot; if (cutoff <= rel) { int c1 = e->index() % number_of_codes; int c2 = e->index() / number_of_codes; tty->print_cr("%10d %6.3f%% %02x %02x %-19s %s", abs, rel, c1, c2, name_for(c1), name_for(c2)); abs_sum += abs; } } tty->print_cr("----------------------------------------------------------------------"); float rel_sum = abs_sum * 100.0F / tot; tty->print_cr("%10d %6.3f%% (cutoff = %.3f%%)", abs_sum, rel_sum, cutoff); tty->cr(); }
void IdealGraphPrinter::print_method(ciMethod *method, int bci, InlineTree *tree) { begin_head(METHOD_ELEMENT); stringStream str; method->print_name(&str); stringStream shortStr; method->print_short_name(&shortStr); print_attr(METHOD_NAME_PROPERTY, str.as_string()); print_attr(METHOD_SHORT_NAME_PROPERTY, shortStr.as_string()); print_attr(METHOD_BCI_PROPERTY, bci); end_head(); head(BYTECODES_ELEMENT); _xml->print_cr("<![CDATA["); method->print_codes_on(_xml); _xml->print_cr("]]>"); tail(BYTECODES_ELEMENT); if (tree != NULL && tree->subtrees().length() > 0) { head(INLINE_ELEMENT); GrowableArray<InlineTree *> subtrees = tree->subtrees(); for (int i = 0; i < subtrees.length(); i++) { print_inline_tree(subtrees.at(i)); } tail(INLINE_ELEMENT); } tail(METHOD_ELEMENT); _xml->flush(); }
bool contains_signature(Symbol* query) { for (int i = 0; i < _members.length(); ++i) { if (query == _members.at(i).first->signature()) { return true; } } return false; }
~KeepAliveRegistrar() { for (int i = _keep_alive.length() - 1; i >= 0; --i) { ConstantPool* cp = _keep_alive.at(i); int idx = _thread->metadata_handles()->find_from_end(cp); assert(idx > 0, "Must be in the list"); _thread->metadata_handles()->remove_at(idx); } }
// iteration support - return first code blob JvmtiCodeBlobDesc* first() { assert(_code_blobs != NULL, "not collected"); if (_code_blobs->length() == 0) { return NULL; } _pos = 0; return _code_blobs->at(0); }
void check_send(InterpretedIC* ic) { GrowableArray<RScope*>* sub = rs->subScopes(bci()); if (sub->length() == 1 && sub->first()->isUntakenScope()) { // this send was never taken } else { was_executed = true; // this send was taken in recompilee } }
// iteration support - return first code blob nmethodDesc* first() { assert(_nmethods != NULL, "not collected"); if (_nmethods->length() == 0) { return NULL; } _pos = 0; return _nmethods->at(0); }
~CodeBlobCollector() { if (_code_blobs != NULL) { for (int i=0; i<_code_blobs->length(); i++) { FreeHeap(_code_blobs->at(i)); } delete _code_blobs; } }
GrowableArray<MonitorInfo*>* compiledVFrame::monitors() const { // Natives has no scope if (scope() == NULL) { nmethod* nm = code(); Method* method = nm->method(); assert(method->is_native(), ""); if (!method->is_synchronized()) { return new GrowableArray<MonitorInfo*>(0); } // This monitor is really only needed for UseBiasedLocking, but // return it in all cases for now as it might be useful for stack // traces and tools as well GrowableArray<MonitorInfo*> *monitors = new GrowableArray<MonitorInfo*>(1); // Casting away const frame& fr = (frame&) _fr; MonitorInfo* info = new MonitorInfo( fr.get_native_receiver(), fr.get_native_monitor(), false, false); monitors->push(info); return monitors; } GrowableArray<MonitorValue*>* monitors = scope()->monitors(); if (monitors == NULL) { return new GrowableArray<MonitorInfo*>(0); } GrowableArray<MonitorInfo*>* result = new GrowableArray<MonitorInfo*>(monitors->length()); for (int index = 0; index < monitors->length(); index++) { MonitorValue* mv = monitors->at(index); ScopeValue* ov = mv->owner(); StackValue *owner_sv = create_stack_value(ov); // it is an oop if (ov->is_object() && owner_sv->obj_is_scalar_replaced()) { // The owner object was scalar replaced assert(mv->eliminated(), "monitor should be eliminated for scalar replaced object"); // Put klass for scalar replaced object. ScopeValue* kv = ((ObjectValue *)ov)->klass(); assert(kv->is_constant_oop(), "klass should be oop constant for scalar replaced object"); Handle k(((ConstantOopReadValue*)kv)->value()()); assert(java_lang_Class::is_instance(k()), "must be"); result->push(new MonitorInfo(k(), resolve_monitor_lock(mv->basic_lock()), mv->eliminated(), true)); } else { result->push(new MonitorInfo(owner_sv->get_obj()(), resolve_monitor_lock(mv->basic_lock()), mv->eliminated(), false)); } } return result; }
static Thread* findThread(int thread_id) { for (int index = 0; index < threads->length(); index++) { Thread* thread = threads->at(index); if (thread == NULL) continue; if (thread->thread_id == thread_id) return thread; } return NULL; }
void JvmtiBreakpoint::each_method_version_do(method_action meth_act) { ((methodOopDesc*)_method->*meth_act)(_bci); // add/remove breakpoint to/from versions of the method that // are EMCP. Directly or transitively obsolete methods are // not saved in the PreviousVersionInfo. Thread *thread = Thread::current(); instanceKlassHandle ikh = instanceKlassHandle(thread, _method->method_holder()); Symbol* m_name = _method->name(); Symbol* m_signature = _method->signature(); { ResourceMark rm(thread); // PreviousVersionInfo objects returned via PreviousVersionWalker // contain a GrowableArray of handles. We have to clean up the // GrowableArray _after_ the PreviousVersionWalker destructor // has destroyed the handles. { // search previous versions if they exist PreviousVersionWalker pvw((instanceKlass *)ikh()->klass_part()); for (PreviousVersionInfo * pv_info = pvw.next_previous_version(); pv_info != NULL; pv_info = pvw.next_previous_version()) { GrowableArray<methodHandle>* methods = pv_info->prev_EMCP_method_handles(); if (methods == NULL) { // We have run into a PreviousVersion generation where // all methods were made obsolete during that generation's // RedefineClasses() operation. At the time of that // operation, all EMCP methods were flushed so we don't // have to go back any further. // // A NULL methods array is different than an empty methods // array. We cannot infer any optimizations about older // generations from an empty methods array for the current // generation. break; } for (int i = methods->length() - 1; i >= 0; i--) { methodHandle method = methods->at(i); if (method->name() == m_name && method->signature() == m_signature) { RC_TRACE(0x00000800, ("%sing breakpoint in %s(%s)", meth_act == &methodOopDesc::set_breakpoint ? "sett" : "clear", method->name()->as_C_string(), method->signature()->as_C_string())); assert(!method->is_obsolete(), "only EMCP methods here"); ((methodOopDesc*)method()->*meth_act)(_bci); break; } } } } // pvw is cleaned up } // rm is cleaned up }
~nmethodCollector() { if (_nmethods != NULL) { for (int i=0; i<_nmethods->length(); i++) { nmethodDesc* blob = _nmethods->at(i); if (blob->map()!= NULL) { FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, blob->map()); } } delete _nmethods; } }
GrowableArray<ScopeValue*>* ScopeDesc::decode_object_values(int decode_offset) { if (decode_offset == DebugInformationRecorder::serialized_null) return NULL; GrowableArray<ScopeValue*>* result = new GrowableArray<ScopeValue*>(); DebugInfoReadStream* stream = new DebugInfoReadStream(_code, decode_offset, result); int length = stream->read_int(); for (int index = 0; index < length; index++) { // Objects values are pushed to 'result' array during read so that // object's fields could reference it (OBJECT_ID_CODE). (void)ScopeValue::read_from(stream); } assert(result->length() == length, "inconsistent debug information"); return result; }