00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 # include "incls/_precompiled.incl"
00026 # include "incls/_interpretedIC.cpp.incl"
00027
00028
00029
00030
00031
00032
00033 class Interpreter_PICs : AllStatic {
00034 public:
00035 static objArrayOop free_list() { return Universe::pic_free_list(); }
00036
00037 static objArrayOop allocate(int size) {
00038 oop first = free_list()->obj_at(size - 1);
00039 if (first == nilObj) {
00040 return objArrayKlass::allocate_tenured_pic(size*2);
00041 }
00042 free_list()->obj_at_put(size - 1, objArrayOop(first)->obj_at(1));
00043
00044 objArrayOop result = objArrayOop(first);
00045 assert(result->is_objArray(), "must be object array");
00046 assert(result->is_old(), "must be tenures");
00047 assert(result->length() == size * 2, "checking size");
00048 return result;
00049 }
00050
00051 static objArrayOop extend(objArrayOop old_pic) {
00052 int old_size = old_pic->length()/2;
00053 if (old_size >= size_of_largest_interpreterPIC) return NULL;
00054 objArrayOop result = allocate(old_size + 1);
00055 for (int index = 1; index <= old_size*2; index++) {
00056 result->obj_at_put(index, old_pic->obj_at(index));
00057 }
00058 return result;
00059 }
00060
00061 static void deallocate(objArrayOop pic) {
00062 int entry = (pic->length()/2) - 1;
00063 oop first = free_list()->obj_at(entry);
00064 pic->obj_at_put(1, first);
00065 free_list()->obj_at_put(entry, pic);
00066 }
00067
00068 static void set_first(objArrayOop pic, oop first, oop second) {
00069 pic->obj_at_put(1, first);
00070 pic->obj_at_put(2, second);
00071 }
00072
00073 static void set_second(objArrayOop pic, oop first, oop second) {
00074 pic->obj_at_put(3, first);
00075 pic->obj_at_put(4, second);
00076 }
00077
00078 static void set_last(objArrayOop pic, oop first, oop second) {
00079 int size = pic->length();
00080 pic->obj_at_put(size--, second);
00081 pic->obj_at_put(size, first);
00082 }
00083 };
00084
00085
00086
00087
00088 void InterpretedIC::set(Bytecodes::Code send_code, oop first_word, oop second_word) {
00089
00090
00091
00092
00093 *send_code_addr() = send_code;
00094 Universe::store(first_word_addr(), first_word, first_word->is_new());
00095 Universe::store(second_word_addr(), second_word, second_word->is_new());
00096 }
00097
00098
00099 u_char* InterpretedIC::findStartOfSend(u_char* sel_addr) {
00100 u_char* p = sel_addr;
00101 while (*--p == Bytecodes::halt) ;
00102 if (*p < 128) --p;
00103
00104 if (!Bytecodes::is_send_code(Bytecodes::Code(*p))) {
00105 return NULL;
00106 }
00107 return p;
00108
00109
00110
00111
00112
00113 }
00114
00115
00116 int InterpretedIC::findStartOfSend(methodOop m, int bci) {
00117 u_char* p = findStartOfSend(m->codes(bci));
00118 return (p == NULL) ? IllegalBCI : p - m->codes() + 1;
00119 }
00120
00121
00122 symbolOop InterpretedIC::selector() const {
00123 oop fw = first_word();
00124 if (fw->is_symbol()) {
00125 return symbolOop(fw);
00126 } else if (fw->is_method()) {
00127 return methodOop(fw)->selector();
00128 } else {
00129 jumpTableEntry* e = jump_table_entry();
00130 nmethod* nm = e->method();
00131 assert(nm != NULL, "must have an nmethod");
00132 return nm->key.selector();
00133 }
00134 }
00135
00136
00137 jumpTableEntry* InterpretedIC::jump_table_entry() const {
00138 assert(send_type() == Bytecodes::compiled_send ||
00139 send_type() == Bytecodes::megamorphic_send, "must be a compiled call");
00140 assert(first_word()->is_smi(), "must be smi");
00141 return (jumpTableEntry*) first_word();
00142 }
00143
00144
00145 int InterpretedIC::nof_arguments() const {
00146 u_char* p = send_code_addr();
00147 switch (Bytecodes::argument_spec(Bytecodes::Code(*p))) {
00148 case Bytecodes::recv_0_args: return 0;
00149 case Bytecodes::recv_1_args: return 1;
00150 case Bytecodes::recv_2_args: return 2;
00151 case Bytecodes::recv_n_args: {
00152 int n = selector()->number_of_arguments();
00153 assert(n = int(*(p+1)), "just checkin'...");
00154 return n;
00155 }
00156 case Bytecodes::args_only: return selector()->number_of_arguments();
00157 }
00158 ShouldNotReachHere();
00159 return 0;
00160 }
00161
00162
00163 Bytecodes::SendType InterpretedIC::send_type() const {
00164 return Bytecodes::send_type(send_code());
00165 }
00166
00167
00168 Bytecodes::ArgumentSpec InterpretedIC::argument_spec() const {
00169 return Bytecodes::argument_spec(send_code());
00170 }
00171
00172
00173 void InterpretedIC::clear() {
00174 if (is_empty()) return;
00175 if (send_type() == Bytecodes::polymorphic_send) {
00176
00177 assert(second_word()->is_objArray(), "must be a pic");
00178 Interpreter_PICs::deallocate(objArrayOop(second_word()));
00179 }
00180 set(Bytecodes::original_send_code_for(send_code()), oop(selector()), smiOop_zero);
00181 }
00182
00183
00184 void InterpretedIC::replace(LookupResult result, klassOop receiver_klass) {
00185
00186 Bytecodes::Code code_before = send_code();
00187 oop word1_before = first_word();
00188 oop word2_before = second_word();
00189 int transition = 0;
00190
00191 guarantee(word2_before == receiver_klass, "klass should be the same");
00192 if (result.is_empty()) {
00193 clear();
00194 transition = 1;
00195 } else if (result.is_method()) {
00196 if (send_type() == Bytecodes::megamorphic_send) {
00197 set(send_code(), result.method(), receiver_klass);
00198 transition = 2;
00199 } else {
00200
00201
00202 clear();
00203 transition = 3;
00204 }
00205 } else {
00206 if (send_type() == Bytecodes::megamorphic_send) {
00207 set(send_code(), oop(result.entry()), receiver_klass);
00208 transition = 4;
00209 } else {
00210 assert(result.is_entry(), "must be jump table entry");
00211
00212 set(Bytecodes::compiled_send_code_for(send_code()), oop(result.entry()), receiver_klass);
00213 transition = 5;
00214 }
00215 }
00216
00217 Bytecodes::Code code_after = send_code();
00218 oop word1_after = first_word();
00219 oop word2_after = second_word();
00220
00221 LOG_EVENT3("InterpretedIC::replace: IC at 0x%x: entry for klass 0x%x replaced (transition %d)", this, receiver_klass, transition);
00222 LOG_EVENT3(" from (%s, 0x%x, 0x%x)", Bytecodes::name(code_before), word1_before, word2_before);
00223 LOG_EVENT3(" to (%s, 0x%x, 0x%x)", Bytecodes::name(code_after ), word1_after , word2_after );
00224 }
00225
00226
00227 void InterpretedIC::cleanup() {
00228 if (is_empty()) return;
00229
00230 switch (send_type()) {
00231 case Bytecodes::accessor_send:
00232 case Bytecodes::primitive_send:
00233 case Bytecodes::predicted_send:
00234 case Bytecodes::interpreted_send:
00235 {
00236 klassOop receiver_klass = klassOop(second_word());
00237 assert(receiver_klass->is_klass(), "receiver klass must be a klass");
00238 methodOop method = methodOop(first_word());
00239 assert(method->is_method(), "first word in interpreter IC must be method");
00240 if (!Bytecodes::is_super_send(send_code())) {
00241
00242 LookupKey key(receiver_klass, selector());
00243 LookupResult result = lookupCache::lookup(&key);
00244 if (!result.matches(method)) {
00245 replace(result, receiver_klass);
00246 }
00247 }
00248 }
00249 break;
00250 case Bytecodes::compiled_send:
00251 {
00252 klassOop receiver_klass = klassOop(second_word());
00253 assert(receiver_klass->is_klass(), "receiver klass must be a klass");
00254 jumpTableEntry* entry = (jumpTableEntry*) first_word();
00255 nmethod* nm = entry->method();
00256 LookupResult result = lookupCache::lookup(&nm->key);
00257 if (!result.matches(nm)) {
00258 replace(result, receiver_klass);
00259 }
00260 }
00261 break;
00262 case Bytecodes::megamorphic_send:
00263
00264
00265
00266 { klassOop receiver_klass = klassOop(second_word());
00267 if (first_word()->is_smi()) {
00268 jumpTableEntry* entry = (jumpTableEntry*) first_word();
00269 nmethod* nm = entry->method();
00270 LookupResult result = lookupCache::lookup(&nm->key);
00271 if (!result.matches(nm)) {
00272 replace(result, receiver_klass);
00273 }
00274 } else {
00275 methodOop method = methodOop(first_word());
00276 assert(method->is_method(), "first word in interpreter IC must be method");
00277 if (!Bytecodes::is_super_send(send_code())) {
00278
00279 LookupKey key(receiver_klass, selector());
00280 LookupResult result = lookupCache::lookup(&key);
00281 if (!result.matches(method)) {
00282 replace(result, receiver_klass);
00283 }
00284 }
00285 }
00286 }
00287 break;
00288 case Bytecodes::polymorphic_send:
00289 {
00290
00291
00292
00293
00294
00295
00296
00297
00298 if (!Bytecodes::is_super_send(send_code())) {
00299 objArrayOop pic = pic_array();
00300 for (int index = pic->length(); index > 0; index -= 2) {
00301 klassOop klass = klassOop(pic->obj_at(index));
00302 assert(klass->is_klass(), "receiver klass must be klass");
00303 oop first = pic->obj_at(index-1);
00304 if (first->is_smi()) {
00305 jumpTableEntry* entry = (jumpTableEntry*) first;
00306 nmethod* nm = entry->method();
00307 LookupResult result = lookupCache::lookup(&nm->key);
00308 if (!result.matches(nm)) {
00309 pic->obj_at_put(index-1, result.value());
00310 }
00311 } else {
00312 methodOop method = methodOop(first);
00313 assert(method->is_method(), "first word in interpreter IC must be method");
00314 LookupKey key(klass, selector());
00315 LookupResult result = lookupCache::lookup(&key);
00316 if (!result.matches(method)) {
00317 pic->obj_at_put(index-1, result.value());
00318 }
00319 }
00320 }
00321 }
00322 }
00323 }
00324 }
00325
00326 void InterpretedIC::clear_without_deallocation_pic() {
00327 if (is_empty()) return;
00328 set(Bytecodes::original_send_code_for(send_code()), oop(selector()), smiOop_zero);
00329 }
00330
00331
00332 void InterpretedIC::replace(nmethod* nm) {
00333
00334 smiOop entry_point = smiOop(nm->jump_table_entry()->entry_point());
00335 assert(selector() == nm->key.selector(), "mismatched selector");
00336 if (is_empty()) return;
00337
00338 switch (send_type()) {
00339 case Bytecodes::accessor_send:
00340 case Bytecodes::primitive_send:
00341 case Bytecodes::predicted_send:
00342 case Bytecodes::interpreted_send:
00343 {
00344 klassOop receiver_klass = klassOop(second_word());
00345 assert(receiver_klass->is_klass(), "receiver klass must be a klass");
00346 if (receiver_klass == nm->key.klass()) {
00347 set(Bytecodes::compiled_send_code_for(send_code()), entry_point, nm->key.klass());
00348 }
00349 }
00350 break;
00351 case Bytecodes::compiled_send:
00352 case Bytecodes::megamorphic_send:
00353
00354 set(send_code(), entry_point, nm->key.klass());
00355 break;
00356 case Bytecodes::polymorphic_send:
00357 { objArrayOop pic = pic_array();
00358 for (int index = pic->length(); index > 0; index -= 2) {
00359 klassOop receiver_klass = klassOop(pic->obj_at(index));
00360 assert(receiver_klass->is_klass(), "receiver klass must be klass");
00361 if (receiver_klass == nm->key.klass()) {
00362 pic->obj_at_put(index-1, entry_point);
00363 return;
00364 }
00365 }
00366 }
00367
00368 break;
00369 default: fatal("unknown send type");
00370 }
00371 LOG_EVENT3("interpreted IC at 0x%x: new nmethod 0x%x for klass 0x%x replaces old entry", this, nm, nm->key.klass());
00372 }
00373
00374
00375 void InterpretedIC::print() {
00376 std->print("Inline cache (");
00377 if (is_empty()) {
00378 std->print("empty");
00379 } else {
00380 std->print(Bytecodes::send_type_as_string(send_type()));
00381 }
00382 std->print(") ");
00383 selector()->print_value();
00384 std->cr();
00385 InterpretedIC_Iterator it(this);
00386 while (!it.at_end()) {
00387 std->print("\t- klass: ");
00388 it.klass()->print_value();
00389 if (it.is_interpreted()) {
00390 std->print(";\tmethod %#x\n", it.interpreted_method());
00391 } else {
00392 std->print(";\tnmethod %#x\n", it.compiled_method());
00393 }
00394 it.advance();
00395 }
00396 }
00397
00398 objArrayOop InterpretedIC::pic_array() {
00399 assert(send_type() == Bytecodes::polymorphic_send, "Must be a polymorphic send site");
00400 objArrayOop result = objArrayOop(second_word());
00401 assert(result->is_objArray(), "interpreter pic must be object array");
00402 assert(result->length() >= 4, "pic should contain at least two entries");
00403 return result;
00404 }
00405
00406 void InterpretedIC::update_inline_cache(InterpretedIC* ic, frame* f, Bytecodes::Code send_code, klassOop klass, LookupResult result) {
00407
00408 if (ic->is_empty() && ic->send_type() != Bytecodes::megamorphic_send) {
00409
00410 Bytecodes::Code new_send_code = Bytecodes::halt;
00411 if (result.is_entry()) {
00412
00413 methodOop method = result.method();
00414 if (UseAccessMethods && Bytecodes::has_access_send_code(send_code) && method->is_accessMethod()) {
00415
00416 new_send_code = Bytecodes::access_send_code_for(send_code);
00417 ic->set(new_send_code, method, klass);
00418
00419 } else if (UsePredictedMethods && Bytecodes::has_predicted_send_code(send_code) && method->is_special_primitiveMethod()) {
00420
00421
00422
00423
00424 new_send_code = method->special_primitive_code();
00425 method = methodOop(ic->selector());
00426 klass = NULL;
00427 ic->set(new_send_code, method, klass);
00428
00429 } else {
00430
00431 new_send_code = Bytecodes::compiled_send_code_for(send_code);
00432 ic->set(new_send_code, oop(result.entry()->entry_point()), klass);
00433 }
00434 } else {
00435
00436 methodOop method = result.method();
00437
00438 if (UseAccessMethods && Bytecodes::has_access_send_code(send_code) && method->is_accessMethod()) {
00439
00440 new_send_code = Bytecodes::access_send_code_for(send_code);
00441
00442 } else if (UsePredictedMethods && Bytecodes::has_predicted_send_code(send_code) && method->is_special_primitiveMethod()) {
00443
00444
00445
00446
00447 new_send_code = method->special_primitive_code();
00448 method = methodOop(ic->selector());
00449 klass = NULL;
00450
00451 } else if (UsePrimitiveMethods && method->is_primitiveMethod()) {
00452
00453 new_send_code = Bytecodes::primitive_send_code_for(send_code);
00454 Unimplemented();
00455
00456 } else {
00457
00458 new_send_code = send_code;
00459 assert(new_send_code == Bytecodes::original_send_code_for(send_code), "bytecode should not change");
00460 }
00461 assert(new_send_code != Bytecodes::halt, "new_send_code not set");
00462 ic->set(new_send_code, method, klass);
00463 }
00464 } else {
00465
00466 switch (ic->send_type()) {
00467
00468 case Bytecodes::accessor_send :
00469 case Bytecodes::predicted_send :
00470 case Bytecodes::compiled_send :
00471 case Bytecodes::interpreted_send: {
00472
00473 objArrayOop pic = Interpreter_PICs::allocate(2);
00474 Interpreter_PICs::set_first(pic, ic->first_word(), ic->second_word());
00475 Interpreter_PICs::set_second(pic, result.value(), klass);
00476 ic->set(Bytecodes::polymorphic_send_code_for(send_code), ic->selector(), pic);
00477 break;
00478 }
00479
00480
00481 case Bytecodes::polymorphic_send: {
00482
00483 objArrayOop old_pic = ic->pic_array();
00484 objArrayOop new_pic = Interpreter_PICs::extend(old_pic);
00485 if (new_pic == NULL) {
00486
00487 if (Bytecodes::is_super_send(send_code)) {
00488 ic->set(Bytecodes::megamorphic_send_code_for(send_code), result.value(), klass);
00489 } else {
00490 ic->set(Bytecodes::megamorphic_send_code_for(send_code), ic->selector(), NULL);
00491 }
00492 } else {
00493
00494 Interpreter_PICs::set_last(new_pic, result.value(), klass);
00495 ic->set(send_code, ic->selector(), new_pic);
00496 }
00497
00498 Interpreter_PICs::deallocate(old_pic);
00499 break;
00500 }
00501
00502
00503 case Bytecodes::megamorphic_send: {
00504 if (Bytecodes::is_super_send(send_code)) {
00505 ic->set(send_code, result.value(), klass);
00506 }
00507 break;
00508 }
00509
00510 default: ShouldNotReachHere();
00511 }
00512 }
00513
00514
00515 f->set_hp(ic->send_code_addr());
00516 }
00517
00518
00519 extern "C" bool have_nlr_through_C;
00520
00521 void InterpretedIC::does_not_understand(oop receiver, InterpretedIC* ic, frame* f) {
00522
00523 BlockScavenge bs;
00524 klassOop msgKlass = klassOop(Universe::find_global("Message"));
00525 oop obj = msgKlass->klass_part()->allocateObject();
00526 assert(obj->is_mem(), "just checkin'...");
00527 memOop msg = memOop(obj);
00528 int nofArgs = ic->selector()->number_of_arguments();
00529 objArrayOop args = oopFactory::new_objArray(nofArgs);
00530 for (int i = 1; i <= nofArgs; i++) {
00531 args->obj_at_put(i, f->expr(nofArgs - i));
00532 }
00533
00534
00535
00536
00537
00538 msg->raw_at_put(2, receiver);
00539 msg->raw_at_put(3, ic->selector());
00540 msg->raw_at_put(4, args);
00541 symbolOop sel = oopFactory::new_symbol("doesNotUnderstand:");
00542 if (interpreter_normal_lookup(receiver->klass(), sel).is_empty()) {
00543
00544 { ResourceMark rm;
00545 std->print("LOOKUP ERROR\n");
00546 sel->print_value(); std->print(" not found\n");
00547 }
00548 if (DeltaProcess::active()->is_scheduler()) {
00549 DeltaProcess::active()->trace_stack();
00550 fatal("lookup error in scheduler");
00551 } else {
00552 DeltaProcess::active()->suspend(::lookup_error);
00553 }
00554 ShouldNotReachHere();
00555 }
00556
00557 oop result = Delta::call(receiver, sel, msg);
00558
00559
00560
00561
00562
00563
00564
00565 }
00566
00567
00568 void InterpretedIC::trace_inline_cache_miss(InterpretedIC* ic, klassOop klass, LookupResult result) {
00569 std->print("InterpretedIC lookup (");
00570 klass->print_value();
00571 std->print(", ");
00572 ic->selector()->print_value();
00573 std->print(") --> ");
00574 result.print_short_on(std);
00575 std->cr();
00576 }
00577
00578
00579
00580
00581
00582
00583
00584 void InterpretedIC::inline_cache_miss() {
00585 NoGCVerifier noGC;
00586
00587
00588 frame f = DeltaProcess::active()->last_frame();
00589 InterpretedIC* ic = f.current_interpretedIC();
00590 Bytecodes::Code send_code = ic->send_code();
00591
00592 oop receiver = ic->argument_spec() == Bytecodes::args_only
00593 ? f.receiver()
00594 : f.expr(ic->nof_arguments());
00595
00596
00597 klassOop klass = receiver->klass();
00598 LookupResult result = Bytecodes::is_super_send(send_code)
00599 ? interpreter_super_lookup(ic->selector())
00600 : interpreter_normal_lookup(klass, ic->selector());
00601
00602
00603 if (TraceMessageSend) std->print_cr("inline cache miss");
00604 if (TraceLookup) trace_inline_cache_miss(ic, klass, result);
00605
00606
00607 if (!result.is_empty())
00608 update_inline_cache(ic, &f, send_code, klass, result);
00609 else {
00610 does_not_understand(receiver, ic, &f);
00611
00612 if (!have_nlr_through_C) inline_cache_miss();
00613 }
00614 }
00615
00616
00617
00618
00619 InterpretedIC_Iterator::InterpretedIC_Iterator(InterpretedIC* ic) {
00620 _ic = ic;
00621 init_iteration();
00622 }
00623
00624
00625 void InterpretedIC_Iterator::set_klass(oop k) {
00626 assert(k->is_klass(), "not a klass");
00627 _klass = klassOop(k);
00628 }
00629
00630
00631 void InterpretedIC_Iterator::set_method(oop m) {
00632 if (m->is_mem()) {
00633 assert(m->is_method(), "must be a method");
00634 _method = (methodOop)m;
00635 _nm = NULL;
00636 } else {
00637 jumpTableEntry* e = (jumpTableEntry*)m;
00638 _nm = e->method();
00639 _method = _nm->method();
00640 }
00641 }
00642
00643
00644 void InterpretedIC_Iterator::init_iteration() {
00645 _pic = NULL;
00646 _index = 0;
00647
00648 switch (_ic->send_type()) {
00649 case Bytecodes::interpreted_send:
00650 if (_ic->is_empty()) {
00651
00652 _number_of_targets = 0;
00653 _info = anamorphic;
00654 } else {
00655
00656 _number_of_targets = 1;
00657 _info = monomorphic;
00658 set_klass(_ic->second_word());
00659 set_method(_ic->first_word());
00660 }
00661 break;
00662 case Bytecodes::compiled_send :
00663 _number_of_targets = 1;
00664 _info = monomorphic;
00665 set_klass(_ic->second_word());
00666 assert(_ic->first_word()->is_smi(), "must have jumpTableEntry");
00667 set_method(_ic->first_word());
00668 assert(is_compiled(), "bad type");
00669 break;
00670 case Bytecodes::accessor_send :
00671 case Bytecodes::primitive_send :
00672 _number_of_targets = 1;
00673 _info = monomorphic;
00674 set_klass(_ic->second_word());
00675 set_method(_ic->first_word());
00676 assert(is_interpreted(), "bad type");
00677 break;
00678 case Bytecodes::megamorphic_send:
00679
00680 _number_of_targets = 0;
00681 _info = megamorphic;
00682 break;
00683 case Bytecodes::polymorphic_send:
00684
00685 _pic = objArrayOop(_ic->second_word());
00686 _number_of_targets = _pic->length() / 2;
00687 _info = polymorphic;
00688 set_klass(_pic->obj_at(2));
00689 set_method(_pic->obj_at(1));
00690 break;
00691 case Bytecodes::predicted_send:
00692 if (_ic->is_empty() || _ic->second_word() == smiKlassObj) {
00693 _number_of_targets = 1;
00694 _info = monomorphic;
00695 } else {
00696 _number_of_targets = 2;
00697 _info = polymorphic;
00698 }
00699 set_klass(smiKlassObj);
00700 set_method(interpreter_normal_lookup(smiKlassObj, selector()).value());
00701 assert(_method != NULL && _method->is_mem(), "this method must be there");
00702 break;
00703 default: ShouldNotReachHere();
00704 }
00705 assert((number_of_targets() > 1) == (_info == polymorphic), "inconsistency");
00706 }
00707
00708
00709 void InterpretedIC_Iterator::advance() {
00710 assert(!at_end(), "iterated over the end");
00711 _index++;
00712 if (! at_end()) {
00713 if (_pic != NULL) {
00714
00715 int index = _index + 1;
00716 set_klass (_pic->obj_at(2 * index));
00717 set_method(_pic->obj_at(2 * index - 1));
00718 } else {
00719
00720 assert(_index < 2, "illegal index");
00721 set_klass(_ic->second_word());
00722 set_method(_ic->first_word());
00723 }
00724 }
00725 }
00726
00727
00728 methodOop InterpretedIC_Iterator::interpreted_method() const {
00729 if (is_interpreted()) {
00730 methodOop m = (methodOop)_method;
00731 #ifdef ASSERT
00732 assert(m->is_old(), "methods must be old");
00733 m->verify();
00734 #endif
00735 return m;
00736 } else {
00737 return compiled_method()->method();
00738 }
00739 }
00740
00741
00742 nmethod* InterpretedIC_Iterator::compiled_method() const {
00743 if (!is_compiled()) return NULL;
00744 #ifdef ASSERT
00745 if (!_nm->isNMethod()) fatal("not an nmethod");
00746
00747 #endif
00748 return _nm;
00749 }
00750
00751
00752 bool InterpretedIC_Iterator::is_super_send() const {
00753 return Bytecodes::is_super_send(_ic->send_code());
00754 }
00755
00756
00757 void InterpretedIC_Iterator::print() {
00758 std->print_cr("InterpretedIC_Iterator %#x for ic %#x (%s)", this, _ic, selector()->as_string());
00759 }
00760
00761 InterpretedIC* as_InterpretedIC(char* address_of_next_instr) {
00762 return (InterpretedIC*)(address_of_next_instr - InterpretedIC::size);
00763 }
00764