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/_interpreter.cpp.incl"
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 static const int float_0_offset = oopSize * (frame_temp_offset - 3);
00041 static const int temp_1_offset  = oopSize * (frame_temp_offset - 1);
00042 static const int temp_0_offset  = oopSize * frame_temp_offset;
00043 static const int esi_offset     = oopSize * frame_hp_offset;
00044 static const int self_offset    = oopSize * frame_receiver_offset;
00045 static const int link_offset    = oopSize * frame_link_offset;
00046 static const int ret_addr_offset= oopSize * frame_return_addr_offset;
00047 static const int arg_n_offset   = oopSize * (frame_arg_offset - 1);
00048 
00049 static const int max_nof_temps  = 256;
00050 static const int max_nof_floats = 256;
00051 
00052 
00053 
00054 bool  Interpreter::_is_initialized  = false;
00055 char* Interpreter::_code_begin_addr = NULL;
00056 char* Interpreter::_code_end_addr   = NULL;
00057 extern "C" interpreter_loop_counter;            
00058 extern "C" interpreter_loop_counter_limit;      
00059 
00060 
00061 
00062 extern "C" char* interpreter_begin_addr;
00063 extern "C" char* interpreter_end_addr;
00064 
00065 bool Interpreter::contains(char* pc) {
00066   return
00067     (interpreter_begin_addr <= pc && pc < interpreter_end_addr) ||
00068     (_code_begin_addr       <= pc && pc < _code_end_addr);
00069 }
00070 
00071 
00072 extern "C" char* InterpreterCodeStatus();       
00073 
00074 bool Interpreter::is_optimized()        { return InterpreterCodeStatus()[0] == 1; }
00075 bool Interpreter::can_trace_bytecodes() { return InterpreterCodeStatus()[1] == 1; }
00076 bool Interpreter::can_trace_sends()     { return InterpreterCodeStatus()[2] == 1; }
00077 bool Interpreter::has_assertions()      { return InterpreterCodeStatus()[3] == 1; }
00078 bool Interpreter::has_stack_checks()    { return InterpreterCodeStatus()[4] == 1; }
00079 bool Interpreter::has_timers()          { return InterpreterCodeStatus()[5] == 1; }
00080 
00081 
00082 void Interpreter::print_code_status() {
00083   if (is_optimized()) {
00084     std->print_cr("- Interpreter code is optimized");
00085   } else {
00086     std->print("- Interpreter code is in debug mode: ");
00087     if (can_trace_bytecodes()) std->print("trace_bytecodes ");
00088     if (can_trace_sends())     std->print("trace_sends ");
00089     if (has_assertions())      std->print("assertions ");
00090     if (has_stack_checks())    std->print("stack_checks ");
00091     if (has_timers())          std->print("timers ");
00092     std->cr();
00093   }
00094 }
00095 
00096 
00097 
00098 
00099 extern "C" void loop_counter_overflow() {
00100   
00101   Interpreter::loop_counter_overflow();
00102 }
00103 
00104 
00105 void Interpreter::loop_counter_overflow() {
00106   const bool debug = false;
00107   methodOop method = DeltaProcess::active()->last_frame().method();
00108   method->set_invocation_count(method->invocation_count() + loop_counter_limit());
00109   reset_loop_counter();
00110 
00111   if (debug) {
00112     ResourceMark rm;
00113     int l = loop_counter_limit();
00114     std->print("loop counter > %d in ", l);
00115     method->print_value();
00116     std->cr();
00117   }
00118 }
00119 
00120 
00121 int Interpreter::loop_counter() {
00122   return interpreter_loop_counter;
00123 }
00124 
00125 
00126 void Interpreter::reset_loop_counter() {
00127   interpreter_loop_counter = 0;
00128 }
00129 
00130 
00131 int Interpreter::loop_counter_limit() {
00132   return interpreter_loop_counter_limit;
00133 }
00134 
00135 
00136 void Interpreter::set_loop_counter_limit(int limit) {
00137   assert(0 <= limit, "loop counter limit must be positive");
00138   interpreter_loop_counter_limit = limit;
00139 }
00140 
00141 
00142 
00143 
00144 
00145 
00146 
00147 
00148 extern "C" void inline_cache_miss() {
00149   InterpretedIC::inline_cache_miss();
00150 }
00151 
00152 
00153 extern "C" void verifyPIC(oop pic) {
00154   if (!Universe::is_heap((oop*) pic)) fatal("pic should be in heap");
00155   if (!pic->is_objArray()) fatal("pic should be an objArray");
00156   int length = objArrayOop(pic)->length();
00157   if (!(2*size_of_smallest_interpreterPIC <= length && length <= 2*size_of_largest_interpreterPIC)) fatal("pic has wrong length field");
00158 }
00159 
00160 
00161 extern "C" void trace_send(oop receiver, methodOop method) {
00162   if (TraceMessageSend) {
00163     ResourceMark rm;
00164     std->print("Trace ");
00165     receiver->print_value();
00166     method->selector()->print_value();
00167     std->cr();
00168   }
00169 }
00170 
00171 
00172 
00173 
00174 void Interpreter::trace_bytecode() {
00175   if (TraceBytecodes) {
00176     u_char* ip = DeltaProcess::active()->last_frame().hp();
00177     char* name = Bytecodes::name((Bytecodes::Code)*ip);
00178     std->print("%9d 0x%x: %02x %s\n", NumberOfBytecodesExecuted, ip, *ip, name);
00179   } 
00180 }
00181 
00182 
00183 void Interpreter::wrong_eax() {
00184   fatal("interpreter bug: eax doesn't contain the right value");
00185 }
00186 
00187 
00188 void Interpreter::wrong_ebx() {
00189   fatal("interpreter bug: high 3 bytes of ebx # 0");
00190 }
00191 
00192 
00193 void Interpreter::wrong_esp() {
00194   fatal("interpreter bug: esp doesn't contain the right value");
00195 }
00196 
00197 
00198 void Interpreter::wrong_obj() {
00199   fatal("interpreter bug: register doesn't contain a valid oop");
00200 }
00201 
00202 
00203 void Interpreter::wrong_primitive_result() {
00204   fatal("interpreter bug: primitive failed that is not supposed to fail");
00205 }
00206 
00207 
00208 doubleOop Interpreter::oopify_FloatValue() {
00209   
00210   
00211   frame f = DeltaProcess::active()->last_frame();
00212   assert(*(f.hp() - 3) == Bytecodes::float_unary_op_to_oop && *(f.hp() - 1) == Floats::oopify, "not called by Floats::oopify");
00213   int float_index = *(f.hp() - 2);
00214   assert(0 <= float_index && float_index < max_nof_floats, "illegal float index");
00215   double* float_address = (double*)((char*)f.fp() + (float_0_offset - (max_nof_floats - 1)*floatSize) + float_index*floatSize);
00216   return oopFactory::new_double(*float_address);
00217 }
00218 
00219 
00220 int* Interpreter::_invocation_counter_addr = NULL;
00221 
00222 void Interpreter::set_invocation_counter_limit(int new_limit) {
00223   assert(_invocation_counter_addr != NULL, "invocation counter address unknown");
00224   assert(0 <= new_limit && new_limit <= methodOopDesc::_invocation_count_max, "illegal counter limit");
00225   assert(*((u_char*)_invocation_counter_addr - 2) == 0x81, "not a cmp edx, imm32 instruction anymore?")
00226   *_invocation_counter_addr = new_limit << methodOopDesc::_invocation_count_offset;
00227 }
00228 
00229 
00230 int Interpreter::get_invocation_counter_limit() {
00231   assert(_invocation_counter_addr != NULL, "invocation counter address unknown");
00232   return get_unsigned_bitfield(*_invocation_counter_addr, methodOopDesc::_invocation_count_offset, methodOopDesc::_invocation_count_width);
00233 }
00234 
00235 
00236 
00237 
00238 void Interpreter::init() {
00239   if (_is_initialized) return;
00240   reset_loop_counter();
00241   set_loop_counter_limit(LoopCounterLimit);
00242   set_invocation_counter_limit(InvocationCounterLimit);
00243   _is_initialized = true;
00244 }
00245 
00246 
00247 
00248 
00249 
00250 class InterpreterGenerator: StackObj {
00251  private:
00252   MacroAssembler*       _masm;          
00253   bool                  _debug;         
00254 
00255   Label         _method_entry;          
00256   Label         _block_entry;           
00257   Label         _inline_cache_miss;     
00258   Label         _smi_send_failure;      
00259   Label         _issue_NLR;             
00260   Label         _nlr_testpoint;         
00261 
00262   Label         _boolean_expected;      
00263   Label         _float_expected;        
00264   Label         _NLR_to_dead_frame;     
00265   Label         _halted;                
00266 
00267   
00268   void check_ebx();
00269   void check_oop(Register reg);
00270   void should_not_reach_here();
00271   
00272   
00273   Address arg_addr(int i);
00274   Address arg_addr(Register arg_no);
00275   Address temp_addr(int i);
00276   Address temp_addr(Register temp_no);
00277   Address float_addr(Register float_no);
00278   Address field_addr(Register obj, int i);
00279   Address field_addr(Register obj, Register smi_offset);
00280 
00281   
00282   void skip_words(int n);
00283   void advance_aligned(int n);
00284 
00285   void load_ebx();
00286   void next_ebx();
00287   void jump_ebx();
00288 
00289   void load_edi();
00290   void jump_edi();
00291   
00292   char* entry_point();
00293 
00294   
00295   Address self_addr()           { return Address(ebp, self_offset); }
00296   Address esi_addr()            { return Address(ebp, esi_offset); }
00297   Address context_addr()        { return Address(ebp, temp_0_offset); }
00298 
00299   void save_esi()               { _masm->movl(esi_addr(), esi); }
00300   void restore_esi()            { _masm->movl(esi, esi_addr()); }
00301   void restore_ebx()            { _masm->xorl(ebx, ebx); }
00302 
00303   
00304   Address nil_addr()            { return Address(int(&nilObj), relocInfo::external_word_type); }
00305   Address true_addr()           { return Address(int(&trueObj), relocInfo::external_word_type); }
00306   Address false_addr()          { return Address(int(&falseObj), relocInfo::external_word_type); }
00307   Address smiKlass_addr()       { return Address(int(&smiKlassObj), relocInfo::external_word_type); }
00308   Address doubleKlass_addr()    { return Address(int(&doubleKlassObj), relocInfo::external_word_type); }
00309   Address contextKlass_addr()   { return Address(int(&symbolKlassObj), relocInfo::external_word_type); }
00310 
00311   
00312   void call_C(Label& L);
00313   void call_C(char* entry);
00314   void call_C(Register entry);
00315   
00316   
00317   void load_recv(Bytecodes::ArgumentSpec arg_spec);
00318   void return_tos(Bytecodes::ArgumentSpec arg_spec);
00319 
00320   
00321   char* push_temp(int i);
00322   char* push_temp_n();
00323   char* push_arg(int i);
00324   char* push_arg_n();
00325   char* push_smi(bool negative);
00326   char* push_literal();
00327   char* push_tos();
00328   char* push_self();
00329   char* push_const(Address obj_addr);
00330   char* push_global();
00331   char* push_instVar();
00332   char* return_instVar();
00333   char* only_pop();
00334 
00335   char* store_temp(int i, bool pop = false);
00336   char* store_temp_n(bool pop = false);
00337   char* store_global(bool pop = false);
00338   char* store_instVar(bool pop = false);
00339 
00340   char* allocate_temps(int n);
00341   char* allocate_temps_n();
00342 
00343   char* set_self_via_context();
00344   char* push_context_temp(int contextNo, int tempNo);
00345 
00346   char* float_allocate();
00347   char* float_floatify();
00348   char* float_oopify();
00349   char* float_move();
00350   char* float_set();
00351   char* float_op(int nof_args, bool returns_float = false);
00352 
00353   char* push_closure(char* allocation_routine, bool use_context);
00354   char* install_context(char* allocation_routine, bool for_method);
00355 
00356   char* lookup_primitive();
00357   char* call_primitive();
00358   char* call_primitive_can_fail();
00359   char* call_DLL(bool async);
00360 
00361   void  call_method();
00362   void  call_native(Register entry);
00363   void  generate_error_handler_code();
00364   void  generate_nonlocal_return_code();
00365   void  generate_method_entry_code();
00366   void  generate_inline_cache_miss_handler();
00367   void  generate_predicted_smi_send_failure_handler();
00368   void  generate_redo_send_code();
00369   char* normal_send(Bytecodes::Code code, bool allow_methodOop, bool allow_nmethod);
00370 
00371   char* interpreted_send(Bytecodes::Code code);
00372   char* compiled_send   (Bytecodes::Code code);
00373   char* polymorphic_send(Bytecodes::Code code);
00374   char* megamorphic_send(Bytecodes::Code code);
00375 
00376   void  check_smi_tags();
00377   char* smi_add();
00378   char* smi_sub();
00379   char* smi_mul();
00380   char* smi_compare_op(Bytecodes::Code code);
00381   char* smi_logical_op(Bytecodes::Code code);
00382   char* smi_shift();
00383 
00384   char* objArray_size();
00385   char* objArray_at();
00386   char* objArray_at_put();
00387 
00388   char* special_primitive_send_hint();
00389   char* halt();
00390 
00391   
00392   char* nonlocal_return_tos();
00393   char* nonlocal_return_self();
00394 
00395   
00396   char* generate_instruction(Bytecodes::Code code);
00397 
00398   
00399   void  info(char* name);
00400 
00401   
00402   void  generate_all();
00403 
00404  public:
00405   InterpreterGenerator(CodeBuffer* code, bool debug);
00406 };
00407 
00408 
00409 
00410 
00411 void InterpreterGenerator::check_ebx() {
00412   
00413   if (_debug) {
00414     Label L;
00415     _masm->testl(ebx, 0xFFFFFF00);
00416     _masm->jcc(Assembler::zero, L);
00417     _masm->call_C((char*)Interpreter::wrong_ebx, relocInfo::runtime_call_type);
00418     _masm->bind(L);
00419   }
00420 }
00421 
00422 
00423 void InterpreterGenerator::check_oop(Register reg) {
00424   
00425   if (_debug) {
00426     Label L;
00427     _masm->testb(reg, Mark_Tag_Bit);
00428     _masm->jcc(Assembler::zero, L);
00429     _masm->call_C((char*)Interpreter::wrong_obj, relocInfo::runtime_call_type);
00430     _masm->bind(L);
00431   }
00432 }
00433 
00434 
00435 void InterpreterGenerator::should_not_reach_here() {
00436   
00437   _masm->hlt();
00438 }
00439 
00440 
00441 
00442 
00443 Address InterpreterGenerator::arg_addr(int i) {
00444   assert(1 <= i, "argument number must be positive");
00445   return Address(ebp, arg_n_offset + i*oopSize);
00446 }
00447 
00448 
00449 Address InterpreterGenerator::arg_addr(Register arg_no) {
00450   return Address(ebp, arg_no, Address::times_4, arg_n_offset + 1*oopSize, relocInfo::none);
00451 }
00452 
00453 
00454 Address InterpreterGenerator::temp_addr(int i) {
00455   assert(0 <= i, "temporary number must be positive");
00456   return Address(ebp, temp_0_offset - i*oopSize);
00457 }
00458 
00459 
00460 Address InterpreterGenerator::temp_addr(Register temp_no) {
00461   return Address(ebp, temp_no, Address::times_4, temp_0_offset - (max_nof_temps - 1)*oopSize, relocInfo::none);
00462 }
00463 
00464 
00465 Address InterpreterGenerator::float_addr(Register float_no) {
00466   return Address(ebp, float_no, Address::times_8, float_0_offset - (max_nof_floats - 1)*floatSize, relocInfo::none);
00467 }
00468 
00469 
00470 Address InterpreterGenerator::field_addr(Register obj, int i) {
00471   assert(2 <= i, "illegal field offset");
00472   return Address(obj, byteOffset(i));
00473 }
00474 
00475 
00476 Address InterpreterGenerator::field_addr(Register obj, Register smi_offset) {
00477   return Address(obj, smi_offset, Address::times_1, -Mem_Tag, relocInfo::none);
00478 }
00479 
00480 
00481 
00482 
00483 void InterpreterGenerator::skip_words(int n) {
00484   _masm->addl(esi, (n+1)*oopSize);      
00485   _masm->andl(esi, -oopSize);           
00486 }
00487 
00488 
00489 void InterpreterGenerator::advance_aligned(int n) {
00490   _masm->addl(esi, n + oopSize - 1);    
00491   _masm->andl(esi, -oopSize);           
00492 }
00493 
00494 
00495 void InterpreterGenerator::load_ebx() {
00496   check_ebx();
00497   _masm->movb(ebx, Address(esi));
00498 }
00499 
00500 
00501 void InterpreterGenerator::next_ebx() {
00502   check_ebx();
00503   _masm->movb(ebx, Address(esi, 1));
00504   _masm->incl(esi);
00505 }
00506 
00507 
00508 void InterpreterGenerator::jump_ebx() {
00509   if (TraceBytecodes || CountBytecodes || StopInterpreterAt > 0) {
00510     _masm->incl(Address(int(&NumberOfBytecodesExecuted), relocInfo::external_word_type));
00511     if (StopInterpreterAt > 0) {
00512       Label cont;
00513       _masm->cmpl(Address(int(&NumberOfBytecodesExecuted), relocInfo::external_word_type), StopInterpreterAt);
00514       _masm->jcc(Assembler::less, cont);
00515       _masm->int3();
00516       _masm->bind(cont);
00517     }
00518   }
00519   if (TraceBytecodes) {
00520     _masm->pushl(eax);  
00521     call_C((char*)Interpreter::trace_bytecode);
00522     _masm->popl(eax);   
00523     load_ebx();
00524   }
00525   check_oop(eax);
00526   _masm->jmp(Address(noreg, ebx, Address::times_4, (int)dispatchTable::table()));
00527 }
00528 
00529 
00530 void InterpreterGenerator::load_edi() {
00531   _masm->movl(edi, Address(noreg, ebx, Address::times_4, (int)dispatchTable::table()));
00532 }
00533 
00534 
00535 void InterpreterGenerator::jump_edi() {
00536   if (TraceBytecodes || CountBytecodes || StopInterpreterAt > 0) {
00537     _masm->incl(Address(int(&NumberOfBytecodesExecuted), relocInfo::external_word_type));
00538     if (StopInterpreterAt > 0) {
00539       Label cont;
00540       _masm->cmpl(Address(int(&NumberOfBytecodesExecuted), relocInfo::external_word_type), StopInterpreterAt);
00541       _masm->jcc(Assembler::less, cont);
00542       _masm->int3();
00543       _masm->bind(cont);
00544     }
00545   }
00546   if (TraceBytecodes) {
00547     _masm->pushl(eax);  
00548     call_C((char*)Interpreter::trace_bytecode);
00549     _masm->popl(eax);   
00550     load_ebx();
00551   }
00552   check_oop(eax);
00553   _masm->jmp(edi);
00554 }
00555 
00556 
00557 char* InterpreterGenerator::entry_point() {
00558   char* ep = _masm->pc();
00559   if (_debug) {
00560     check_ebx();
00561     check_oop(eax);
00562   }
00563   return ep;
00564 }
00565 
00566 
00567 
00568 
00569 
00570 
00571 
00572 void InterpreterGenerator::call_C(Label& L) {
00573   save_esi();
00574   _masm->call_C(L, _nlr_testpoint);
00575   restore_esi();
00576   restore_ebx();
00577 }
00578 
00579 
00580 void InterpreterGenerator::call_C(char* entry) {
00581   save_esi();
00582   _masm->call_C(entry, relocInfo::runtime_call_type, _nlr_testpoint);
00583   restore_esi();
00584   restore_ebx();
00585 }
00586 
00587 
00588 void InterpreterGenerator::call_C(Register entry) {
00589   save_esi();
00590   _masm->call_C(entry, _nlr_testpoint);
00591   restore_esi();
00592   restore_ebx();
00593 }
00594 
00595 
00596 
00597 
00598 
00599 
00600 
00601 
00602 
00603 
00604 
00605 
00606 
00607 
00608 
00609 
00610 void InterpreterGenerator::load_recv(Bytecodes::ArgumentSpec arg_spec) {
00611   _masm->pushl(eax); 
00612   switch (arg_spec) {
00613     case Bytecodes::recv_0_args: break; 
00614     case Bytecodes::recv_1_args: _masm->movl(eax, Address(esp, 1*oopSize)); break;
00615     case Bytecodes::recv_2_args: _masm->movl(eax, Address(esp, 2*oopSize)); break;
00616     case Bytecodes::recv_n_args:
00617       
00618       _masm->movb(ebx, Address(esi, 1));
00619       _masm->movl(eax, Address(esp, ebx, Address::times_4));
00620       break;
00621     case Bytecodes::args_only  : _masm->movl(eax, self_addr()); break;
00622     default                    : ShouldNotReachHere();
00623   }
00624 }
00625 
00626 
00627 
00628 
00629 
00630 char* InterpreterGenerator::push_temp(int i) {
00631   char* ep = entry_point();
00632   next_ebx();
00633   _masm->pushl(eax);
00634   load_edi();
00635   _masm->movl(eax, temp_addr(i));
00636   jump_edi();
00637   return ep;
00638 }
00639 
00640 
00641 char* InterpreterGenerator::push_temp_n() {
00642   char* ep = entry_point();
00643   _masm->addl(esi, 2);
00644   _masm->movb(ebx, Address(esi, -1));
00645   _masm->pushl(eax);
00646   _masm->movl(eax, temp_addr(ebx));
00647   load_ebx();
00648   jump_ebx();
00649   return ep;
00650 }
00651 
00652 
00653 char* InterpreterGenerator::push_arg(int i) {
00654   char* ep = entry_point();
00655   next_ebx();
00656   _masm->pushl(eax);
00657   load_edi();
00658   _masm->movl(eax, arg_addr(i));
00659   jump_edi();
00660   return ep;
00661 }
00662 
00663 
00664 char* InterpreterGenerator::push_arg_n() {
00665   char* ep = entry_point();
00666   _masm->addl(esi, 2);
00667   _masm->movb(ebx, Address(esi, -1));
00668   _masm->pushl(eax);
00669   _masm->movl(eax, arg_addr(ebx));
00670   load_ebx();
00671   jump_ebx();
00672   return ep;
00673 }
00674 
00675 
00676 char* InterpreterGenerator::push_smi(bool negative) {
00677   char* ep = entry_point();
00678   _masm->movb(ebx, Address(esi, 1));    
00679   _masm->addl(esi, 2);                  
00680   _masm->pushl(eax);                    
00681   if (negative) {
00682     _masm->leal(eax, Address(noreg, ebx, Address::times_4));
00683     _masm->negl(eax);
00684   } else {
00685     _masm->leal(eax, Address(noreg, ebx, Address::times_4, 4, relocInfo::none));
00686   }
00687   load_ebx();
00688   jump_ebx();
00689   return ep;
00690 }
00691 
00692 
00693 char* InterpreterGenerator::push_literal() {
00694   char* ep = entry_point();
00695   _masm->pushl(eax);
00696   skip_words(1);
00697   load_ebx();
00698   _masm->movl(eax, Address(esi, -4));
00699   jump_ebx();
00700   return ep;
00701 }
00702 
00703 
00704 char* InterpreterGenerator::push_tos() {
00705   char* ep = entry_point();
00706   next_ebx();
00707   _masm->pushl(eax);
00708   jump_ebx();
00709   return ep;
00710 }
00711 
00712 
00713 char* InterpreterGenerator::push_self() {
00714   char* ep = entry_point();
00715   next_ebx();
00716   _masm->pushl(eax);
00717   load_edi();
00718   _masm->movl(eax, self_addr());
00719   jump_edi();
00720   return ep;
00721 }
00722 
00723 
00724 char* InterpreterGenerator::push_const(Address obj_addr) {
00725   char* ep = entry_point();
00726   _masm->pushl(eax);
00727   next_ebx();
00728   _masm->movl(eax, obj_addr);
00729   jump_ebx();
00730   return ep;
00731 }
00732 
00733 
00734 char* InterpreterGenerator::push_instVar() {
00735   char* ep = entry_point();
00736   advance_aligned(1 + oopSize);
00737   _masm->movl(ecx, self_addr());
00738   _masm->movl(edx, Address(esi, -oopSize));
00739   _masm->pushl(eax);
00740   load_ebx();
00741   _masm->movl(eax, field_addr(ecx, edx));
00742   jump_ebx();
00743   return ep;
00744 }
00745 
00746 
00747 char* InterpreterGenerator::store_instVar(bool pop) {
00748   char* ep = entry_point();
00749   advance_aligned(1 + oopSize);
00750   _masm->movl(ecx, self_addr());
00751   _masm->movl(edx, Address(esi, -oopSize));
00752   load_ebx();
00753   _masm->movl(field_addr(ecx, edx), eax);
00754   _masm->store_check(ecx, edx);
00755   if (pop) _masm->popl(eax);
00756   jump_ebx();
00757   return ep;
00758 }
00759 
00760 
00761 char* InterpreterGenerator::return_instVar() {
00762   char* ep = entry_point();
00763   advance_aligned(1 + oopSize);
00764   _masm->movl(ecx, self_addr());
00765   _masm->movl(edx, Address(esi, -oopSize));
00766   _masm->movl(eax, field_addr(ecx, edx));
00767   return_tos(Bytecodes::recv_0_args);
00768   return ep;
00769 }
00770 
00771 
00772 char* InterpreterGenerator::only_pop() {
00773   char* ep = entry_point();
00774   next_ebx();
00775   _masm->popl(eax);
00776   jump_ebx();
00777   return ep;
00778 }
00779 
00780 
00781 char* InterpreterGenerator::store_temp(int i, bool pop) {
00782   char* ep = entry_point();
00783   next_ebx();
00784   _masm->movl(temp_addr(i), eax);
00785   if (pop) _masm->popl(eax);
00786   jump_ebx();
00787   return ep;
00788 }
00789 
00790 
00791 char* InterpreterGenerator::store_temp_n(bool pop) {
00792   char* ep = entry_point();
00793   _masm->addl(esi, 2);
00794   _masm->movb(ebx, Address(esi, -1));
00795   _masm->movl(temp_addr(ebx), eax);
00796   load_ebx();
00797   if (pop) _masm->popl(eax);
00798   jump_ebx();
00799   return ep;
00800 }
00801 
00802 
00803 char* InterpreterGenerator::push_global() {
00804   char* ep = entry_point();
00805   skip_words(1);
00806   _masm->pushl(eax);
00807   _masm->movl(ecx, Address(esi, -oopSize));                                     
00808   load_ebx();
00809   _masm->movl(eax, field_addr(ecx, associationOopDesc::value_offset()));        
00810   jump_ebx();
00811   return ep;
00812 }
00813 
00814 
00815 char* InterpreterGenerator::store_global(bool pop) {
00816   char* ep = entry_point();
00817   skip_words(1);
00818   _masm->movl(ecx, Address(esi, -oopSize));                                     
00819   load_ebx();
00820   _masm->movl(field_addr(ecx, associationOopDesc::value_offset()), eax);        
00821   _masm->store_check(ecx, edx);
00822   if (pop) _masm->popl(eax);
00823   jump_ebx();
00824   return ep;
00825 }
00826 
00827 
00828 char* InterpreterGenerator::allocate_temps(int n) {
00829   char* ep = entry_point();
00830   assert(n > 0, "just checkin'");
00831   next_ebx();
00832   _masm->pushl(eax);
00833   _masm->movl(eax, nil_addr());
00834   while (--n > 0) _masm->pushl(eax);
00835   jump_ebx();
00836   return ep;
00837 }
00838 
00839 
00840 char* InterpreterGenerator::allocate_temps_n() {
00841   Label entry, loop;
00842 
00843   _masm->bind(loop);
00844   _masm->pushl(eax);
00845   _masm->bind(entry);
00846   _masm->decb(ebx);
00847   _masm->jcc(Assembler::notZero, loop);
00848   load_ebx();
00849   jump_ebx();
00850 
00851   char* ep = entry_point();
00852   _masm->movb(ebx, Address(esi, 1));            
00853   _masm->addl(esi, 2);                          
00854   _masm->pushl(eax);
00855   _masm->movl(eax, nil_addr());
00856   _masm->jmp(entry);
00857 
00858   return ep;
00859 }
00860 
00861 
00862 
00863 
00864 
00865 
00866 
00867 char* InterpreterGenerator::set_self_via_context() {
00868   Label loop;
00869   char* ep = entry_point();
00870   next_ebx();
00871   _masm->movl(edx, self_addr());                
00872   _masm->bind(loop);                            
00873   _masm->movl(ecx, edx);                        
00874   _masm->movl(edx, Address(edx, contextOopDesc::parent_byte_offset()));
00875   _masm->test(edx, Mem_Tag);                    
00876   _masm->jcc(Assembler::notZero, loop);         
00877   _masm->movl(edx, Address(ecx, contextOopDesc::temp0_byte_offset()));
00878   _masm->movl(self_addr(), edx);                
00879   jump_ebx();
00880   return ep;
00881 }
00882 
00883 
00884 char* InterpreterGenerator::push_context_temp(int contextNo, int tempNo) {
00885   assert(contextNo >= 0, "illegal context no.");
00886   assert(tempNo >= 0, "illegal temporary no.");
00887   char* ep = entry_point();
00888   _masm->pushl(eax);
00889   _masm->movl(ecx, context_addr());
00890   next_ebx();
00891   for (int i = 0; i < contextNo; i++) _masm->movl(ecx, Address(ecx, contextOopDesc::parent_byte_offset()));
00892   _masm->movl(eax, Address(ecx, contextOopDesc::temp0_byte_offset() + tempNo*oopSize));
00893   jump_ebx();
00894   return ep;
00895 }
00896 
00897 
00898 
00899 
00900 
00901 
00902 
00903 
00904 
00905 
00906 
00907 
00908 extern "C" oop allocateBlock(smiOop nofArgs);   
00909 
00910 
00911 extern "C" oop allocateBlock0();
00912 extern "C" oop allocateBlock1();
00913 extern "C" oop allocateBlock2();
00914 
00915 
00916 char* InterpreterGenerator::push_closure(char* allocation_routine, bool use_context) {
00917   char* ep = entry_point();
00918   _masm->pushl(eax);                                                    
00919   if (allocation_routine == (char*)allocateBlock) {
00920     
00921     _masm->movb(ebx, Address(esi, 1));                                  
00922     advance_aligned(2 + oopSize);                                       
00923     _masm->shll(ebx, Tag_Size);                                         
00924     save_esi();                                                         
00925     _masm->pushl(ebx);                                                  
00926     _masm->set_last_Delta_frame_before_call();                          
00927     _masm->call((char*)allocateBlock, relocInfo::runtime_call_type);    
00928     _masm->reset_last_Delta_frame();
00929     _masm->popl(ebx);                                                   
00930   } else {
00931     
00932     advance_aligned(1 + oopSize);                                       
00933     save_esi();                                                         
00934     _masm->call(allocation_routine, relocInfo::runtime_call_type);      
00935   }
00936   restore_esi();                                                        
00937   _masm->movl(ecx, Address(esi, -oopSize));                             
00938   if (use_context) {                                                    
00939     _masm->movl(edx, context_addr());                                   
00940     if (_debug) {
00941       
00942       
00943       
00944     }
00945   } else {                                                              
00946     _masm->popl(edx);                                                   
00947   }
00948   
00949   
00950   
00951   
00952   
00953   
00954   _masm->movl(ebx, Address(ecx, methodOopDesc::selector_or_method_byte_offset()));      
00955   _masm->movl(Address(eax, blockClosureOopDesc::method_or_entry_byte_offset()), ecx);   
00956   _masm->movl(ecx, Address(ebx, methodOopDesc::counters_byte_offset()));
00957   _masm->movl(Address(eax, blockClosureOopDesc::context_byte_offset()), edx);           
00958   _masm->addl(ecx, 1 << methodOopDesc::_invocation_count_offset);       
00959   _masm->movl(edx, eax);                                                
00960   _masm->movl(Address(ebx, methodOopDesc::counters_byte_offset()), ecx);
00961   restore_ebx();
00962   load_ebx();                                                           
00963   _masm->store_check(edx, ecx);                                         
00964   jump_ebx();
00965   return ep;
00966 }
00967 
00968 
00969 
00970 
00971 
00972 
00973 
00974 
00975 
00976 
00977 
00978 
00979 extern "C" oop allocateContext(smiOop nofVars);
00980 extern "C" oop allocateContext0();
00981 extern "C" oop allocateContext1();
00982 extern "C" oop allocateContext2();
00983 
00984 char* InterpreterGenerator::install_context(char* allocation_routine, bool for_method) {
00985   char* ep = entry_point();
00986   _masm->pushl(eax);                            
00987   if (allocation_routine == (char*)allocateContext) {
00988     
00989     _masm->movb(ebx, Address(esi, 1));          
00990     _masm->addl(esi, 2);                        
00991     _masm->shll(ebx, Tag_Size);                 
00992     save_esi();                                 
00993     _masm->pushl(ebx);                          
00994     _masm->call((char*)allocateContext, relocInfo::runtime_call_type);          
00995     _masm->popl(ebx);                           
00996   } else {
00997     
00998     _masm->incl(esi);                           
00999     save_esi();                                 
01000     _masm->call(allocation_routine, relocInfo::runtime_call_type);              
01001   }
01002   restore_esi();                                
01003   restore_ebx();
01004   if (for_method) {                             
01005     _masm->movl(Address(eax, contextOopDesc::parent_byte_offset()), ebp);       
01006   } else {                                      
01007     _masm->movl(ecx, context_addr());           
01008     if (_debug) {
01009       
01010       
01011       
01012     }
01013     _masm->movl(Address(eax, contextOopDesc::parent_byte_offset()), ecx);       
01014   }
01015   load_ebx();                                   
01016   _masm->movl(context_addr(), eax);             
01017   _masm->store_check(eax, ecx);                 
01018   _masm->popl(eax);                             
01019   jump_ebx();
01020   return ep;
01021 }
01022 
01023 
01024 
01025 
01026 
01027 
01028 
01029 
01030 
01031 
01032 
01033 
01034 
01035 
01036 
01037 
01038 
01039 
01040 
01041 
01042 
01043 
01044 
01045 
01046 
01047 
01048 
01049 
01050 
01051 
01052 
01053 
01054 
01055 
01056 
01057 
01058 
01059 char* InterpreterGenerator::float_allocate() {
01060 
01061 
01062 
01063 
01064 
01065 
01066 
01067 
01068 
01069   Label tLoop, tDone, fLoop, fDone;
01070   assert(oop(Floats::magic)->is_smi(), "must be a smi");
01071   char* ep = entry_point();
01072   if (_debug) {
01073     
01074     Label L1, L2;
01075     
01076     _masm->leal(ecx, Address(ebp, esi_offset));
01077     _masm->cmpl(esp, ecx);
01078     _masm->jcc(Assembler::equal, L1);
01079     _masm->call_C((char*)Interpreter::wrong_esp, relocInfo::runtime_call_type);
01080     should_not_reach_here();
01081     _masm->bind(L1);
01082 
01083     
01084     _masm->cmpl(eax, nil_addr());
01085     _masm->jcc(Assembler::equal, L2);
01086     _masm->call_C((char*)Interpreter::wrong_eax, relocInfo::runtime_call_type);
01087     should_not_reach_here();
01088     _masm->bind(L2);
01089   }
01090   _masm->addl(esi, 4);                          
01091   _masm->pushl(eax);                            
01092   _masm->pushl(Floats::magic);                  
01093 
01094   
01095   _masm->movb(ebx, Address(esi, -3));           
01096   _masm->testl(ebx, ebx);                       
01097   _masm->jcc(Assembler::zero, tDone);
01098   _masm->movl(eax, nil_addr());
01099   _masm->bind(tLoop);
01100   _masm->pushl(eax);                            
01101   _masm->pushl(eax);                            
01102   _masm->decl(ebx);
01103   _masm->jcc(Assembler::notZero, tLoop);
01104   _masm->bind(tDone);
01105   
01106   
01107   _masm->movb(ebx, Address(esi, -2));           
01108   _masm->testl(ebx, ebx);                       
01109   _masm->jcc(Assembler::zero, fDone);
01110   _masm->xorl(eax, eax);                        
01111   _masm->bind(fLoop);
01112   _masm->pushl(eax);                            
01113   _masm->pushl(eax);
01114   _masm->decb(ebx);
01115   _masm->jcc(Assembler::notZero, fLoop);
01116   _masm->bind(fDone);
01117 
01118   
01119   assert(floatSize == 8, "change the constant for shhl below");
01120   _masm->movb(ebx, Address(esi, -1));           
01121   _masm->shll(ebx, 3);                          
01122   _masm->subl(esp, ebx);                        
01123   restore_ebx();
01124 
01125   
01126   load_ebx();                                   
01127   _masm->popl(eax);                             
01128   jump_ebx();
01129 
01130   return ep;
01131 }
01132     
01133   
01134 char* InterpreterGenerator::float_floatify() {
01135   Label is_smi;
01136   char* ep = entry_point();
01137   _masm->addl(esi, 2);                          
01138   _masm->testb(eax, Mem_Tag);                   
01139   _masm->jcc(Assembler::zero, is_smi);
01140   _masm->movl(ecx, Address(eax, memOopDesc::klass_byte_offset()));      
01141   _masm->cmpl(ecx, doubleKlass_addr());
01142   _masm->jcc(Assembler::notEqual, _float_expected);
01143 
01144   
01145   _masm->movb(ebx, Address(esi, -1));           
01146   _masm->fld_d(Address(eax, byteOffset(doubleOopDesc::value_offset()))); 
01147   _masm->fstp_d(float_addr(ebx));               
01148   load_ebx();
01149   _masm->popl(eax);                             
01150   jump_ebx();
01151 
01152   
01153   _masm->bind(is_smi);
01154   _masm->movb(ebx, Address(esi, -1));           
01155   _masm->leal(ecx, float_addr(ebx));
01156   _masm->sarl(eax, Tag_Size);                   
01157   _masm->movl(Address(ecx), eax);               
01158   _masm->fild_s(Address(ecx));                  
01159   _masm->fstp_d(Address(ecx));                  
01160   load_ebx();
01161   _masm->popl(eax);                             
01162   jump_ebx();
01163 
01164   return ep;
01165 }
01166 
01167 
01168 char* InterpreterGenerator::float_oopify() {
01169 
01170 
01171 
01172 
01173   char* ep = entry_point();
01174   
01175   
01176   _masm->popl(eax);                             
01177   _masm->fpop();                                
01178   call_C((char*)Interpreter::oopify_FloatValue);
01179   load_ebx();
01180   jump_ebx();
01181   return ep;
01182 }
01183     
01184   
01185 char* InterpreterGenerator::float_move() {
01186   char* ep = entry_point();
01187   _masm->pushl(eax);                            
01188   _masm->addl(esi, 3);                          
01189   _masm->xorl(ecx, ecx);                        
01190   _masm->movb(ebx, Address(esi, -1));           
01191   _masm->movb(ecx, Address(esi, -2));           
01192   _masm->fld_d(float_addr(ebx));                
01193   load_ebx();
01194   _masm->fstp_d(float_addr(ecx));               
01195   _masm->popl(eax);                             
01196   jump_ebx();
01197   return ep;
01198 }
01199     
01200   
01201 char* InterpreterGenerator::float_set() {
01202   char* ep = entry_point();
01203   _masm->pushl(eax);                            
01204   _masm->movb(ebx, Address(esi, 1));            
01205   advance_aligned(2 + oopSize);                 
01206   _masm->movl(ecx, Address(esi, -oopSize));     
01207   _masm->fld_d(Address(ecx, byteOffset(doubleOopDesc::value_offset()))); 
01208   _masm->fstp_d(float_addr(ebx));               
01209   load_ebx();
01210   _masm->popl(eax);                             
01211   jump_ebx();
01212   return ep;
01213 }
01214     
01215   
01216 char* InterpreterGenerator::float_op(int nof_args, bool returns_float) {
01217   assert(0 <= nof_args && nof_args <= 8, "illegal nof_args specification");
01218   char* ep = entry_point();
01219   _masm->pushl(eax);                            
01220   _masm->addl(esi, 3);                          
01221   _masm->movb(ebx, Address(esi, -2));           
01222   _masm->leal(edx, float_addr(ebx));            
01223   _masm->movb(ebx, Address(esi, -1));           
01224   _masm->movl(ecx, Address(noreg, ebx, Address::times_4, int(Floats::_function_table), relocInfo::external_word_type));
01225   for (int i = 0; i < nof_args; i++) _masm->fld_d(Address(edx, -i*floatSize));
01226   _masm->call(ecx);                             
01227   load_ebx();                                   
01228   if (returns_float) {
01229     _masm->fstp_d(Address(edx));                
01230     _masm->popl(eax);                           
01231   }                                             
01232   jump_ebx();
01233   return ep;
01234 }
01235     
01236   
01237 
01238 
01239 
01240 
01241 
01242 
01243 
01244 
01245 char* InterpreterGenerator::lookup_primitive() {
01246   char* ep = entry_point();
01247   _masm->pushl(eax);                            
01248   call_C((char*)primitives::lookup_and_patch);  
01249   load_ebx();
01250   _masm->popl(eax);                             
01251   jump_ebx();
01252   return ep;
01253 }
01254 
01255 
01256 char* InterpreterGenerator::call_primitive() {
01257   char* ep = entry_point();
01258   advance_aligned(1 + oopSize);
01259   _masm->pushl(eax);                            
01260   _masm->movl(eax, Address(esi, -oopSize));     
01261   call_C(eax);                                  
01262   if (_debug) {                                 
01263     Label L;
01264     _masm->testb(eax, Mark_Tag_Bit);
01265     _masm->jcc(Assembler::zero, L);
01266     _masm->call_C((char*)Interpreter::wrong_primitive_result, relocInfo::runtime_call_type);
01267     _masm->bind(L);
01268   }
01269   load_ebx();
01270   jump_ebx();
01271   return ep;
01272 }
01273 
01274 
01275 char* InterpreterGenerator::call_primitive_can_fail() {
01276   Label failed;
01277   char* ep = entry_point();
01278   advance_aligned(1 + 2*oopSize);
01279   _masm->pushl(eax);                            
01280   _masm->movl(eax, Address(esi, -2*oopSize));   
01281   call_C(eax);                                  
01282   _masm->testb(eax, Mark_Tag_Bit);              
01283   _masm->jcc(Assembler::notZero, failed);
01284   _masm->movl(ecx, Address(esi, -oopSize));     
01285   _masm->addl(esi, ecx);                        
01286   load_ebx();
01287   jump_ebx();
01288 
01289   _masm->bind(failed);
01290   _masm->andl(eax, ~Mark_Tag_Bit);              
01291   load_ebx();                                   
01292   jump_ebx();
01293   return ep;
01294 }
01295 
01296 
01297 
01298 
01299 
01300 
01301 
01302 
01303 
01304 
01305 
01306 
01307 
01308 
01309 
01310 
01311 
01312 
01313 
01314 
01315 
01316 
01317 
01318 
01319 
01320 
01321 
01322 
01323 
01324 
01325 
01326 
01327 
01328 
01329 
01330 
01331 
01332 
01333 char* InterpreterGenerator::call_DLL(bool async) {
01334   char* ep = entry_point();
01335   Label L;
01336   advance_aligned(1 + 3*oopSize);               
01337   _masm->incl(esi);                             
01338   _masm->pushl(eax);                            
01339   _masm->movl(edx, Address(esi, -1 - oopSize)); 
01340   _masm->testl(edx, edx);                       
01341   _masm->jcc(Assembler::notZero, L);            
01342   call_C((char*)DLLs::lookup_and_patch_InterpretedDLL_Cache);   
01343   _masm->movl(edx, eax);                        
01344   _masm->bind(L);                               
01345   _masm->movb(ebx, Address(esi, -1));           
01346   _masm->movl(ecx, esp);                        
01347   save_esi();                                   
01348   _masm->call(StubRoutines::call_DLL_entry(async), relocInfo::runtime_call_type);
01349   _masm->ic_info(_nlr_testpoint, 0);
01350   restore_esi();
01351   restore_ebx();
01352   _masm->movb(ebx, Address(esi, -1));           
01353   _masm->leal(esp, Address(esp, ebx, Address::times_4)); 
01354   _masm->popl(ecx);                             
01355   _masm->movl(Address(ecx, pointer_offset), eax); 
01356   load_ebx();
01357   _masm->movl(eax, ecx);                        
01358   jump_ebx();
01359   return ep;
01360 }
01361 
01362 
01363 
01364 
01365 
01366 
01367 
01368 
01369 
01370 char* Interpreter::_redo_send_entry = NULL;
01371 
01372 void InterpreterGenerator::generate_redo_send_code() {
01373   assert(Interpreter::_redo_send_entry == NULL, "code generated twice");
01374   Interpreter::_redo_send_entry = _masm->pc();
01375   restore_esi();                                
01376   restore_ebx();                                
01377   load_ebx();
01378   _masm->popl(eax);                             
01379   jump_ebx();                                   
01380 }
01381 
01382 
01383 
01384 
01385 
01386 
01387 
01388 
01389 
01390 
01391 
01392 
01393 
01394 void InterpreterGenerator::call_method() {
01395   
01396   save_esi();
01397   _masm->call(_method_entry);
01398   _masm->ic_info(_nlr_testpoint, 0);
01399   restore_esi();
01400 }
01401 
01402 
01403 char* Interpreter::_last_native_called = NULL;          
01404 
01405 void InterpreterGenerator::call_native(Register entry) {
01406   
01407   save_esi();
01408   _masm->movl(Address(int(&Interpreter::_last_native_called), relocInfo::external_word_type), entry);
01409   _masm->call(entry);
01410   _masm->ic_info(_nlr_testpoint, 0);                    
01411   restore_esi();
01412   restore_ebx();
01413 }
01414 
01415 
01416 extern "C" char* method_entry_point = NULL;             
01417 extern "C" char* block_entry_point  = NULL;             
01418 
01419 void InterpreterGenerator::generate_method_entry_code() {
01420 
01421 
01422 
01423 
01424   const int counter_offset = methodOopDesc::counters_byte_offset();
01425   const int code_offset    = methodOopDesc::codes_byte_offset();
01426 
01427   assert(!_method_entry.is_bound(), "code has been generated before");
01428   Label start_setup, counter_overflow, start_execution, handle_counter_overflow, is_interpreted;
01429 
01430   
01431   
01432   
01433   
01434   method_entry_point = _masm->pc();
01435   _masm->bind(_method_entry);
01436   _masm->movl(edi, nil_addr());
01437 
01438   
01439   
01440   
01441   
01442   
01443   _masm->bind(start_setup);
01444   _masm->enter();                                                       
01445   _masm->pushl(eax);                                                    
01446   _masm->movl(edx, Address(ecx, counter_offset));                       
01447   _masm->leal(esi, Address(ecx, code_offset));                          
01448   _masm->addl(edx, 1 << methodOopDesc::_invocation_count_offset);       
01449   _masm->pushl(esi);                                                    
01450   _masm->movl(Address(ecx, counter_offset), edx);                       
01451   load_ebx();                                                           
01452   _masm->cmpl(edx, 0xFFFF << methodOopDesc::_invocation_count_offset);  
01453   Interpreter::_invocation_counter_addr = (int*)(_masm->pc() - oopSize);
01454   _masm->jcc(Assembler::aboveEqual, counter_overflow);                  
01455   _masm->bind(start_execution);                                         
01456   _masm->movl(eax, edi);                                                
01457   jump_ebx();                                                           
01458 
01459   
01460   _masm->bind(counter_overflow);
01461   
01462   _masm->pushl(edi);                                                    
01463   _masm->set_last_Delta_frame_before_call();
01464   _masm->call(handle_counter_overflow);                                 
01465   _masm->reset_last_Delta_frame();
01466   _masm->popl(edi);                                                     
01467   
01468   
01469   
01470   
01471   
01472   
01473   restore_esi();
01474   restore_ebx();
01475   load_ebx();
01476   _masm->jmp(start_execution);
01477 
01478   
01479   
01480   
01481   _masm->bind(handle_counter_overflow);
01482   _masm->pushl(ecx);                                                    
01483   _masm->pushl(eax);                                                    
01484   _masm->call((char*)Recompilation::methodOop_invocation_counter_overflow, relocInfo::runtime_call_type); 
01485   _masm->addl(esp, 2*oopSize);                                          
01486   _masm->ret(0);
01487 
01488 
01489 
01490 
01491 
01492 
01493   
01494   
01495   block_entry_point = _masm->pc();
01496   _masm->bind(_block_entry);
01497   _masm->movl(ecx, Address(eax, blockClosureOopDesc::method_or_entry_byte_offset()));   
01498   _masm->reset_last_Delta_frame();                                      
01499   _masm->test(ecx, Mem_Tag);                                            
01500   _masm->jcc(Assembler::notZero, is_interpreted);                       
01501   _masm->jmp(ecx);                                                      
01502 
01503   _masm->bind(is_interpreted);
01504   
01505   
01506   restore_ebx();                                                        
01507   _masm->movl(eax, Address(eax, blockClosureOopDesc::context_byte_offset()));           
01508   _masm->movl(edi, eax);                                                
01509   
01510   
01511   
01512   
01513   
01514   _masm->jmp(start_setup);
01515 }
01516 
01517 
01518 
01519 
01520 
01521 void InterpreterGenerator::generate_inline_cache_miss_handler() {
01522   assert(!_inline_cache_miss.is_bound(), "code has been generated before");
01523   _masm->bind(_inline_cache_miss);
01524   
01525   
01526   call_C((char*)InterpretedIC::inline_cache_miss);
01527   load_ebx();
01528   _masm->popl(eax);
01529   jump_ebx();
01530 }
01531 
01532 
01533 
01534 
01535 
01536 
01537 void InterpreterGenerator::generate_predicted_smi_send_failure_handler() {
01538   assert(!_smi_send_failure.is_bound(), "code has been generated before");
01539   char* ep = normal_send(Bytecodes::interpreted_send_1, true, false);
01540   
01541   
01542   _masm->bind(_smi_send_failure);
01543   _masm->pushl(edx);                                    
01544   _masm->jmp(ep, relocInfo::runtime_call_type);
01545 }
01546 
01547 
01548 void InterpreterGenerator::check_smi_tags() {
01549   
01550   
01551   _masm->popl(edx);                                     
01552   _masm->movl(ecx, eax);                                
01553   _masm->orl(ecx, edx);                                 
01554   _masm->test(ecx, Mem_Tag);                            
01555   _masm->jcc(Assembler::notZero, _smi_send_failure);    
01556   
01557   
01558 }
01559 
01560 
01561 char* InterpreterGenerator::smi_add() {
01562   Label overflow;
01563   char* ep = entry_point();
01564   check_smi_tags();
01565   _masm->addl(eax, edx);
01566   _masm->jcc(Assembler::overflow, overflow);
01567   advance_aligned(1 + 2*oopSize);
01568   load_ebx();
01569   jump_ebx();
01570 
01571   _masm->bind(overflow);
01572   
01573   
01574   _masm->subl(eax, edx);
01575   _masm->jmp(_smi_send_failure);
01576   return ep;
01577 }
01578 
01579 
01580 char* InterpreterGenerator::smi_sub() {
01581   Label overflow;
01582   char* ep = entry_point();
01583   check_smi_tags();
01584   _masm->subl(edx, eax);
01585   _masm->jcc(Assembler::overflow, overflow);
01586   advance_aligned(1 + 2*oopSize);
01587   _masm->movl(eax, edx);
01588   load_ebx();
01589   jump_ebx();
01590 
01591   _masm->bind(overflow);
01592   
01593   
01594   _masm->addl(edx, eax);
01595   _masm->jmp(_smi_send_failure);
01596   return ep;
01597 }
01598 
01599 
01600 char* InterpreterGenerator::smi_mul() {
01601   Label overflow;
01602   char* ep = entry_point();
01603   check_smi_tags();
01604   _masm->movl(ecx, eax);                                
01605   _masm->sarl(edx, Tag_Size);
01606   _masm->imull(eax, edx);
01607   _masm->jcc(Assembler::overflow, overflow);
01608   advance_aligned(1 + 2*oopSize);
01609   load_ebx();
01610   jump_ebx();
01611 
01612   _masm->bind(overflow);
01613   
01614   
01615   
01616   _masm->movl(eax, ecx);                                
01617   _masm->shll(edx, Tag_Size);                           
01618   _masm->jmp(_smi_send_failure);
01619   return ep;
01620 }
01621 
01622 
01623 char* InterpreterGenerator::smi_compare_op(Bytecodes::Code code) {
01624   Label is_true;
01625   char* ep = entry_point();
01626   check_smi_tags();
01627   advance_aligned(1 + 2*oopSize);
01628   load_ebx();
01629   _masm->cmpl(edx, eax);
01630   Assembler::Condition cc;
01631   switch (code) {
01632     case Bytecodes::smi_equal           : cc = Assembler::equal;        break;
01633     case Bytecodes::smi_not_equal       : cc = Assembler::notEqual;     break;
01634     case Bytecodes::smi_less            : cc = Assembler::less;         break;
01635     case Bytecodes::smi_less_equal      : cc = Assembler::lessEqual;    break;
01636     case Bytecodes::smi_greater         : cc = Assembler::greater;      break;
01637     case Bytecodes::smi_greater_equal   : cc = Assembler::greaterEqual; break;
01638     default                             : ShouldNotReachHere();
01639   }
01640   _masm->jcc(cc, is_true);
01641   _masm->movl(eax, false_addr());
01642   jump_ebx();
01643 
01644   _masm->bind(is_true);
01645   _masm->movl(eax, true_addr());
01646   jump_ebx();
01647   return ep;
01648 }
01649 
01650 
01651 char* InterpreterGenerator::smi_logical_op(Bytecodes::Code code) {
01652   char* ep = entry_point();
01653   check_smi_tags();
01654   advance_aligned(1 + 2*oopSize);
01655   load_ebx();
01656   switch (code) {
01657     case Bytecodes::smi_and: _masm->andl(eax, edx); break;
01658     case Bytecodes::smi_or : _masm->orl (eax, edx); break;
01659     case Bytecodes::smi_xor: _masm->xorl(eax, edx); break;
01660     default                : ShouldNotReachHere();
01661   }
01662   jump_ebx();
01663   return ep;
01664 }
01665 
01666 
01667 char* InterpreterGenerator::smi_shift() {
01668   
01669   assert(Int_Tag == 0, "check this code");
01670   Label shift_right;
01671 
01672   char* ep = entry_point();
01673   check_smi_tags();
01674   advance_aligned(1 + 2*oopSize);
01675   load_ebx();
01676   _masm->sarl(eax, Tag_Size);                           
01677   _masm->movl(ecx, eax);                                
01678   _masm->jcc(Assembler::negative, shift_right);         
01679 
01680   
01681   _masm->shll(edx);                                     
01682   _masm->movl(eax, edx);                                
01683   jump_ebx();
01684   
01685   
01686   _masm->bind(shift_right);
01687   _masm->negl(ecx);
01688   _masm->sarl(edx);                                     
01689   _masm->andl(edx, -1 << Tag_Size);                     
01690   _masm->movl(eax, edx);                                
01691   jump_ebx();
01692   return ep;
01693 }
01694   
01695 
01696 
01697 
01698 
01699 
01700 
01701 
01702 
01703 
01704 char* InterpreterGenerator::objArray_size() {
01705   char* ep = entry_point();
01706   Unimplemented();
01707   return ep;
01708 }
01709 
01710 
01711 char* InterpreterGenerator::objArray_at() {
01712   char* ep = entry_point();
01713   Unimplemented();
01714   return ep;
01715 }
01716 
01717 
01718 char* InterpreterGenerator::objArray_at_put() {
01719   char* ep = entry_point();
01720   Unimplemented();
01721   return ep;
01722 }
01723 
01724 
01725 
01726 
01727 
01728 
01729 
01730 void InterpreterGenerator::return_tos(Bytecodes::ArgumentSpec arg_spec) {
01731   _masm->leave();
01732   switch (arg_spec) {
01733     case Bytecodes::recv_0_args: _masm->ret(0*oopSize); break;
01734     case Bytecodes::recv_1_args: _masm->ret(1*oopSize); break;
01735     case Bytecodes::recv_2_args: _masm->ret(2*oopSize); break;
01736     case Bytecodes::recv_n_args: {
01737       
01738       _masm->movb(ebx, Address(esi, 1));                        
01739       _masm->popl(ecx);                                         
01740       _masm->leal(esp, Address(esp, ebx, Address::times_4));    
01741       _masm->jmp(ecx);                                          
01742       break;
01743     }
01744     default: ShouldNotReachHere();
01745   }
01746 }
01747 
01748 
01749 
01750 
01751 
01752 
01753 
01754 
01755 
01756 extern "C" void suspend_on_error(InterpreterErrorConstants error_code);
01757 
01758 void InterpreterGenerator::generate_error_handler_code() {
01759   assert(!_boolean_expected.is_bound(), "code has been generated before");
01760 
01761   Label suspend, call_suspend;
01762   
01763   
01764   
01765   _masm->bind(suspend);
01766   _masm->pushl(eax);                            
01767   call_C(call_suspend);
01768   should_not_reach_here();
01769 
01770   _masm->bind(call_suspend);                    
01771   _masm->pushl(ecx);                            
01772   _masm->call((char*)suspend_on_error, relocInfo::runtime_call_type);
01773   should_not_reach_here();
01774   
01775   _masm->bind(_boolean_expected);
01776   _masm->movl(ecx, boolean_expected);
01777   _masm->jmp(suspend);
01778 
01779   _masm->bind(_float_expected);
01780   _masm->movl(ecx, float_expected);
01781   _masm->jmp(suspend);
01782 
01783   _masm->bind(_NLR_to_dead_frame);
01784   _masm->movl(ecx, nonlocal_return_error);
01785   _masm->jmp(suspend);
01786 
01787   _masm->bind(_halted);
01788   _masm->movl(ecx, halted);
01789   _masm->jmp(suspend);
01790 }
01791 
01792 
01793 
01794 
01795 
01796 
01797 
01798 
01799 
01800 
01801 
01802 
01803 
01804 
01805 
01806 
01807 
01808 
01809 
01810 
01811 
01812 
01813 
01814 
01815 
01816 
01817 
01818 
01819 
01820 extern "C" char* nlr_testpoint_entry = NULL;    
01821 extern "C" contextOop nlr_home_context;
01822 
01823 void InterpreterGenerator::generate_nonlocal_return_code() {
01824   assert(eax == NLR_result_reg, "NLR register use changed");
01825   assert(edi == NLR_home_reg  , "NLR register use changed");
01826   assert(esi == NLR_homeId_reg, "NLR register use changed");
01827 
01828   assert(!_issue_NLR.is_bound()    , "code has been generated before");
01829   assert(!_nlr_testpoint.is_bound(), "code has been generated before");
01830 
01831   Label zapped_context, loop, no_zapping, compiled_code_NLR;
01832 
01833   
01834   _masm->bind(zapped_context);
01835   _masm->popl(eax);                             
01836   _masm->addl(esi, 2);                          
01837   _masm->jmp(_NLR_to_dead_frame);
01838 
01839   _masm->bind(_issue_NLR);
01840   _masm->pushl(eax);                            
01841   _masm->movl(edi, context_addr());             
01842   if (_debug) {
01843     
01844   }
01845 
01846   
01847   
01848   _masm->bind(loop);                            
01849   _masm->movl(eax, edi);                        
01850   _masm->movl(edi, Address(edi, contextOopDesc::parent_byte_offset()));
01851   _masm->test(edi, Mem_Tag);                    
01852   _masm->jcc(Assembler::notZero, loop);         
01853   _masm->testl(edi, edi);                       
01854   _masm->jcc(Assembler::zero, zapped_context);  
01855   _masm->movl(Address(int(&nlr_home_context), relocInfo::external_word_type), eax); 
01856                                                 
01857   _masm->movb(ebx, Address(esi, 1));            
01858   _masm->popl(eax);                             
01859   _masm->movl(esi, ebx);                        
01860   _masm->notl(esi);                             
01861   
01862   
01863   
01864   
01865   
01866   
01867   
01868   nlr_testpoint_entry = _masm->pc();
01869   _masm->bind(_nlr_testpoint);
01870 
01871   
01872   
01873   
01874   
01875   
01876 
01877   _masm->movl(ecx, context_addr());             
01878   _masm->test(ecx, Mem_Tag);                    
01879   _masm->jcc(Assembler::zero, no_zapping);      
01880   _masm->movl(edx, Address(ecx, memOopDesc::klass_byte_offset()));      
01881   _masm->cmpl(edx, contextKlass_addr());        
01882   _masm->jcc(Assembler::notEqual, no_zapping);  
01883   _masm->movl(ebx, Address(ecx, contextOopDesc::parent_byte_offset())); 
01884   _masm->cmpl(ebx, ebp);                        
01885   _masm->jcc(Assembler::notEqual, no_zapping);  
01886   _masm->movl(Address(ecx, contextOopDesc::parent_byte_offset()), 0);   
01887 
01888   _masm->bind(no_zapping);
01889   _masm->cmpl(edi, ebp);
01890   _masm->jcc(Assembler::notEqual, StubRoutines::continue_NLR_entry());
01891 
01892   
01893   
01894   
01895   
01896   restore_ebx();                                
01897   _masm->leave();                               
01898   _masm->popl(ecx);                             
01899   _masm->notl(esi);                             
01900   _masm->leal(esp, Address(esp, esi, Address::times_4));        
01901   _masm->jmp(ecx);                              
01902 
01903   
01904   
01905   
01906   
01907   
01908   
01909   
01910   
01911   
01912 }
01913 
01914 
01915 char* InterpreterGenerator::nonlocal_return_tos() {
01916   char* ep = entry_point();
01917   _masm->jmp(_issue_NLR);
01918   return ep;
01919 }
01920 
01921 
01922 char* InterpreterGenerator::nonlocal_return_self() {
01923   char* ep = entry_point();
01924   _masm->pushl(eax);
01925   _masm->movl(eax, self_addr());
01926   _masm->jmp(_issue_NLR);
01927   return ep;
01928 }
01929 
01930 
01931 
01932 
01933 
01934 
01935 
01936 
01937 
01938 
01939 
01940 
01941 
01942 
01943 
01944 
01945 
01946 
01947 
01948 
01949 
01950 char* InterpreterGenerator::normal_send(Bytecodes::Code code, bool allow_methodOop, bool allow_nmethod) {
01951   assert(allow_methodOop || allow_nmethod, "must allow at least one method representation");
01952 
01953   Label is_smi, compare_class, is_methodOop, is_nmethod;
01954 
01955   Bytecodes::ArgumentSpec arg_spec = Bytecodes::argument_spec(code);
01956   bool pop_tos = Bytecodes::pop_tos(code);
01957 
01958   
01959   int     length      = (arg_spec == Bytecodes::recv_n_args ? 2 : 1) + 2*oopSize;
01960   Address method_addr = Address(esi, -2*oopSize);
01961   Address klass_addr  = Address(esi, -1*oopSize);
01962   
01963   _masm->bind(is_smi);                          
01964   _masm->movl(edi, smiKlass_addr());            
01965   _masm->jmp(compare_class);
01966 
01967   char* ep = entry_point();
01968   load_recv(arg_spec);
01969   advance_aligned(length);
01970   _masm->test(eax, Mem_Tag);                    
01971   _masm->movl(ecx, method_addr);                
01972   _masm->movl(edx, klass_addr);                 
01973   _masm->jcc(Assembler::zero, is_smi);
01974   _masm->movl(edi, Address(eax, memOopDesc::klass_byte_offset()));      
01975 
01976   _masm->bind(compare_class);
01977   
01978   
01979   
01980   
01981   
01982   
01983   _masm->cmpl(edx, edi);                        
01984   _masm->jcc(Assembler::notEqual, _inline_cache_miss);
01985 
01986   if (allow_methodOop && allow_nmethod) {
01987     
01988     _masm->test(ecx, Mem_Tag);                  
01989     _masm->jcc(Assembler::zero, is_nmethod);    
01990   }
01991 
01992   if (allow_methodOop) {
01993     _masm->bind(is_methodOop);
01994     call_method();
01995     if (arg_spec != Bytecodes::args_only) _masm->popl(ecx);
01996     load_ebx();
01997     if (pop_tos) _masm->popl(eax);              
01998     jump_ebx();
01999   }
02000 
02001   if (allow_nmethod) {
02002     _masm->bind(is_nmethod);
02003     call_native(ecx);
02004     if (arg_spec != Bytecodes::args_only) _masm->popl(ecx);
02005     load_ebx();
02006     if (pop_tos) _masm->popl(eax);              
02007     jump_ebx();
02008   }
02009 
02010   return ep;
02011 }
02012 
02013 
02014 char* InterpreterGenerator::interpreted_send(Bytecodes::Code code) {
02015   return normal_send(code, true, false);
02016 }
02017 
02018 
02019 char* InterpreterGenerator::compiled_send(Bytecodes::Code code) {
02020   return normal_send(code, false, true);
02021 }
02022 
02023 
02024 char* InterpreterGenerator::megamorphic_send(Bytecodes::Code code) {
02025   
02026   if (Bytecodes::is_super_send(code)) return normal_send(code, true, true);
02027   
02028   Label is_smi, probe_primary_cache, is_methodOop, is_nmethod, probe_secondary_cache;
02029   Bytecodes::ArgumentSpec arg_spec = Bytecodes::argument_spec(code);
02030   
02031   
02032   int     length        = (arg_spec == Bytecodes::recv_n_args ? 2 : 1) + 2*oopSize;
02033   bool    pop_tos       = Bytecodes::pop_tos(code);
02034   Address selector_addr = Address(esi, -2*oopSize);
02035   Address klass_addr    = Address(esi, -1*oopSize);
02036 
02037   _masm->bind(is_smi);                          
02038   _masm->movl(ecx, smiKlass_addr());            
02039   _masm->jmp(probe_primary_cache);
02040 
02041   char* ep = entry_point();
02042   load_recv(arg_spec);
02043   advance_aligned(length);
02044   _masm->test(eax, Mem_Tag);                    
02045   _masm->jcc(Assembler::zero, is_smi);          
02046   _masm->movl(ecx, Address(eax, memOopDesc::klass_byte_offset()));      
02047 
02048   
02049   
02050   
02051   
02052   
02053   
02054   _masm->bind(probe_primary_cache);             
02055   _masm->movl(edx, selector_addr);              
02056   
02057   _masm->movl(edi, ecx);
02058   _masm->xorl(edi, edx);
02059   _masm->andl(edi, (primary_cache_size - 1) << 4);
02060   
02061   _masm->cmpl(ecx, Address(edi, lookupCache::primary_cache_address() + 0*oopSize));
02062   _masm->jcc(Assembler::notEqual, probe_secondary_cache);
02063   _masm->cmpl(edx, Address(edi, lookupCache::primary_cache_address() + 1*oopSize));
02064   _masm->jcc(Assembler::notEqual, probe_secondary_cache);
02065   _masm->movl(ecx, Address(edi, lookupCache::primary_cache_address() + 2*oopSize));
02066   _masm->test(ecx, Mem_Tag);                    
02067   _masm->jcc(Assembler::zero, is_nmethod);      
02068 
02069   _masm->bind(is_methodOop);
02070   call_method();
02071   if (arg_spec != Bytecodes::args_only) _masm->popl(ecx);
02072   load_ebx();
02073   if (pop_tos) _masm->popl(eax);                
02074   jump_ebx();
02075 
02076   _masm->bind(is_nmethod);
02077   call_native(ecx);
02078   if (arg_spec != Bytecodes::args_only) _masm->popl(ecx);
02079   load_ebx();
02080   if (pop_tos) _masm->popl(eax);                
02081   jump_ebx();
02082 
02083   
02084   
02085   
02086   
02087   
02088   
02089   
02090   
02091   _masm->bind(probe_secondary_cache);
02092   _masm->andl(edi, (secondary_cache_size - 1) << 4);
02093   
02094   _masm->cmpl(ecx, Address(edi, lookupCache::secondary_cache_address() + 0*oopSize));
02095   _masm->jcc(Assembler::notEqual, _inline_cache_miss);
02096   _masm->cmpl(edx, Address(edi, lookupCache::secondary_cache_address() + 1*oopSize));
02097   _masm->jcc(Assembler::notEqual, _inline_cache_miss);
02098   _masm->movl(ecx, Address(edi, lookupCache::secondary_cache_address() + 2*oopSize));
02099   _masm->test(ecx, Mem_Tag);                    
02100   _masm->jcc(Assembler::zero, is_nmethod);      
02101   _masm->jmp(is_methodOop);
02102 
02103   return ep;
02104 }
02105 
02106 
02107 
02108 
02109 
02110 
02111 
02112 
02113 
02114 
02115 
02116 
02117 
02118 
02119 char* InterpreterGenerator::polymorphic_send(Bytecodes::Code code) {
02120   Label loop, found, is_nmethod;
02121 
02122   Bytecodes::ArgumentSpec arg_spec = Bytecodes::argument_spec(code);
02123   bool pop_tos = Bytecodes::pop_tos(code);
02124 
02125   
02126   int     length        = (arg_spec == Bytecodes::recv_n_args ? 2 : 1) + 2*oopSize;
02127   Address selector_addr = Address(esi, -2*oopSize);
02128   Address pic_addr      = Address(esi, -1*oopSize);
02129   
02130   
02131   int length_offset = 2*oopSize - Mem_Tag;      
02132   int data_offset   = 3*oopSize - Mem_Tag;      
02133 
02134   char* ep = entry_point();
02135   load_recv(arg_spec);
02136   advance_aligned(length);
02137   _masm->movl(ebx, pic_addr);                   
02138   _masm->movl(ecx, Address(ebx, length_offset));
02139   _masm->sarl(ecx, Tag_Size + 1);               
02140   
02141 
02142   _masm->movl(edx, smiKlass_addr());            
02143   _masm->testl(eax, Mem_Tag);                   
02144   _masm->jcc(Assembler::zero, loop);            
02145   _masm->movl(edx, Address(eax, memOopDesc::klass_byte_offset()));      
02146 
02147   
02148   _masm->bind(loop);
02149   
02150   
02151   
02152   
02153   
02154   _masm->cmpl(edx, Address(ebx, ecx, Address::times_8, data_offset - 1*oopSize, relocInfo::none));
02155   _masm->jcc(Assembler::equal, found);
02156   _masm->decl(ecx);
02157   _masm->jcc(Assembler::notZero, loop);
02158 
02159   
02160   _masm->jmp(_inline_cache_miss);
02161 
02162   _masm->bind(found);
02163   
02164   
02165   
02166   
02167   
02168   _masm->movl(ecx, Address(ebx, ecx, Address::times_8, data_offset - 2*oopSize, relocInfo::none));
02169   _masm->testl(ecx, Mem_Tag);
02170   _masm->jcc(Assembler::zero, is_nmethod);
02171   restore_ebx();
02172 
02173   
02174   call_method();
02175   if (arg_spec != Bytecodes::args_only) _masm->popl(ecx);       
02176   load_ebx();
02177   if (pop_tos) _masm->popl(eax);                                
02178   jump_ebx();
02179 
02180   
02181   _masm->bind(is_nmethod);
02182   call_native(ecx);
02183   if (arg_spec != Bytecodes::args_only) _masm->popl(ecx);       
02184   load_ebx();
02185   if (pop_tos) _masm->popl(eax);                                
02186   jump_ebx();
02187 
02188   return ep;
02189 }
02190 
02191 
02192 
02193 
02194 
02195 char* InterpreterGenerator::special_primitive_send_hint() {
02196   char* ep = entry_point();
02197   assert(Bytecodes::format(Bytecodes::special_primitive_send_1_hint) == Bytecodes::BB, "unexpected format");
02198   _masm->addl(esi, 2);                          
02199   load_ebx();
02200   jump_ebx();
02201   return ep;
02202 }
02203 
02204 
02205 char* InterpreterGenerator::halt() {
02206   char* ep = entry_point();
02207   _masm->incl(esi);                             
02208   _masm->jmp(_halted);
02209   return ep;
02210 }
02211 
02212 
02213 
02214 
02215 
02216 char* InterpreterGenerator::generate_instruction(Bytecodes::Code code) {
02217   const bool pop                = true; 
02218   const bool returns_float      = true; 
02219 
02220   switch (code) {
02221     
02222     case Bytecodes::push_temp_0                         : return push_temp(0);
02223     case Bytecodes::push_temp_1                         : return push_temp(1);
02224     case Bytecodes::push_temp_2                         : return push_temp(2);
02225     case Bytecodes::push_temp_3                         : return push_temp(3);
02226     case Bytecodes::push_temp_4                         : return push_temp(4);
02227     case Bytecodes::push_temp_5                         : return push_temp(5);
02228     case Bytecodes::push_temp_n                         : return push_temp_n();
02229 
02230     case Bytecodes::store_temp_0_pop                    : return store_temp(0, pop);
02231     case Bytecodes::store_temp_1_pop                    : return store_temp(1, pop);
02232     case Bytecodes::store_temp_2_pop                    : return store_temp(2, pop);
02233     case Bytecodes::store_temp_3_pop                    : return store_temp(3, pop);
02234     case Bytecodes::store_temp_4_pop                    : return store_temp(4, pop);
02235     case Bytecodes::store_temp_5_pop                    : return store_temp(5, pop);
02236     case Bytecodes::store_temp_n_pop                    : return store_temp_n(pop);
02237     case Bytecodes::store_temp_n                        : return store_temp_n();
02238 
02239     
02240     case Bytecodes::push_arg_1                          : return push_arg(1);
02241     case Bytecodes::push_arg_2                          : return push_arg(2);
02242     case Bytecodes::push_arg_3                          : return push_arg(3);
02243     case Bytecodes::push_arg_n                          : return push_arg_n();
02244 
02245     
02246     case Bytecodes::allocate_temp_1                     : return allocate_temps(1);
02247     case Bytecodes::allocate_temp_2                     : return allocate_temps(2);
02248     case Bytecodes::allocate_temp_3                     : return allocate_temps(3);
02249     case Bytecodes::allocate_temp_n                     : return allocate_temps_n();
02250 
02251     
02252     case Bytecodes::push_neg_n                          : return push_smi(true);
02253     case Bytecodes::push_succ_n                         : return push_smi(false);
02254     case Bytecodes::push_literal                        : return push_literal();
02255     case Bytecodes::push_tos                            : return push_tos();
02256     case Bytecodes::push_self                           : return push_self();
02257     case Bytecodes::push_nil                            : return push_const(nil_addr());
02258     case Bytecodes::push_true                           : return push_const(true_addr());
02259     case Bytecodes::push_false                          : return push_const(false_addr());
02260     case Bytecodes::only_pop                            : return only_pop();
02261 
02262     
02263     case Bytecodes::return_instVar                      : return return_instVar();
02264     case Bytecodes::push_instVar                        : return push_instVar();
02265     case Bytecodes::store_instVar_pop                   : return store_instVar(pop);
02266     case Bytecodes::store_instVar                       : return store_instVar();
02267     
02268     
02269     case Bytecodes::push_temp_0_context_0               : return push_context_temp(0, 0);
02270     case Bytecodes::push_temp_1_context_0               : return push_context_temp(0, 1);
02271     case Bytecodes::push_temp_2_context_0               : return push_context_temp(0, 2);
02272 
02273     case Bytecodes::push_temp_0_context_1               : return push_context_temp(1, 0);
02274     case Bytecodes::push_temp_1_context_1               : return push_context_temp(1, 1);
02275     case Bytecodes::push_temp_2_context_1               : return push_context_temp(1, 2);
02276     
02277     
02278     case Bytecodes::set_self_via_context                : return set_self_via_context();
02279 
02280     
02281     case Bytecodes::push_new_closure_context_0          : return push_closure((char*)allocateBlock0, true);
02282     case Bytecodes::push_new_closure_context_1          : return push_closure((char*)allocateBlock1, true);
02283     case Bytecodes::push_new_closure_context_2          : return push_closure((char*)allocateBlock2, true);
02284     case Bytecodes::push_new_closure_context_n          : return push_closure((char*)allocateBlock , true);
02285 
02286     case Bytecodes::push_new_closure_tos_0              : return push_closure((char*)allocateBlock0, false);
02287     case Bytecodes::push_new_closure_tos_1              : return push_closure((char*)allocateBlock1, false);
02288     case Bytecodes::push_new_closure_tos_2              : return push_closure((char*)allocateBlock2, false);
02289     case Bytecodes::push_new_closure_tos_n              : return push_closure((char*)allocateBlock , false);
02290     
02291     
02292     case Bytecodes::install_new_context_method_0        : return install_context((char*)allocateContext0, true);
02293     case Bytecodes::install_new_context_method_1        : return install_context((char*)allocateContext1, true);
02294     case Bytecodes::install_new_context_method_2        : return install_context((char*)allocateContext2, true);
02295     case Bytecodes::install_new_context_method_n        : return install_context((char*)allocateContext , true);
02296 
02297     case Bytecodes::install_new_context_block_1         : return install_context((char*)allocateContext1, false);
02298     case Bytecodes::install_new_context_block_2         : return install_context((char*)allocateContext2, false);
02299     case Bytecodes::install_new_context_block_n         : return install_context((char*)allocateContext , false);
02300 
02301     
02302     case Bytecodes::prim_call                           : 
02303     case Bytecodes::prim_call_self                      : return call_primitive();
02304     case Bytecodes::prim_call_failure                   : 
02305     case Bytecodes::prim_call_self_failure              : return call_primitive_can_fail();
02306 
02307     case Bytecodes::prim_call_lookup                    : 
02308     case Bytecodes::prim_call_self_lookup               : 
02309     case Bytecodes::prim_call_failure_lookup            : 
02310     case Bytecodes::prim_call_self_failure_lookup       : return lookup_primitive();
02311     
02312     case Bytecodes::dll_call_sync                       : return call_DLL(false);
02313     case Bytecodes::dll_call_async                      : return call_DLL(true);
02314 
02315     
02316     case Bytecodes::float_allocate                      : return float_allocate();
02317     case Bytecodes::float_floatify_pop                  : return float_floatify();
02318     case Bytecodes::float_move                          : return float_move();
02319     case Bytecodes::float_set                           : return float_set();
02320     case Bytecodes::float_nullary_op                    : return float_op(0, returns_float);
02321     case Bytecodes::float_unary_op                      : return float_op(1, returns_float);
02322     case Bytecodes::float_binary_op                     : return float_op(2, returns_float);
02323     case Bytecodes::float_unary_op_to_oop               : return float_op(1);
02324     case Bytecodes::float_binary_op_to_oop              : return float_op(2);
02325   
02326     
02327     case Bytecodes::interpreted_send_0                  : 
02328     case Bytecodes::interpreted_send_1                  : 
02329     case Bytecodes::interpreted_send_2                  : 
02330     case Bytecodes::interpreted_send_n                  : 
02331 
02332     case Bytecodes::interpreted_send_0_pop              : 
02333     case Bytecodes::interpreted_send_1_pop              : 
02334     case Bytecodes::interpreted_send_2_pop              : 
02335     case Bytecodes::interpreted_send_n_pop              : 
02336 
02337     case Bytecodes::interpreted_send_self               : 
02338     case Bytecodes::interpreted_send_self_pop           : 
02339 
02340     case Bytecodes::interpreted_send_super              : 
02341     case Bytecodes::interpreted_send_super_pop          : return interpreted_send(code);
02342 
02343     
02344     case Bytecodes::compiled_send_0                     : 
02345     case Bytecodes::compiled_send_1                     : 
02346     case Bytecodes::compiled_send_2                     : 
02347     case Bytecodes::compiled_send_n                     : 
02348 
02349     case Bytecodes::compiled_send_0_pop                 : 
02350     case Bytecodes::compiled_send_1_pop                 : 
02351     case Bytecodes::compiled_send_2_pop                 : 
02352     case Bytecodes::compiled_send_n_pop                 : 
02353 
02354     case Bytecodes::compiled_send_self                  : 
02355     case Bytecodes::compiled_send_self_pop              : 
02356 
02357     case Bytecodes::compiled_send_super                 : 
02358     case Bytecodes::compiled_send_super_pop             : return compiled_send(code);
02359 
02360     
02361     case Bytecodes::polymorphic_send_0                  : 
02362     case Bytecodes::polymorphic_send_1                  : 
02363     case Bytecodes::polymorphic_send_2                  : 
02364     case Bytecodes::polymorphic_send_n                  : 
02365 
02366     case Bytecodes::polymorphic_send_0_pop              : 
02367     case Bytecodes::polymorphic_send_1_pop              : 
02368     case Bytecodes::polymorphic_send_2_pop              : 
02369     case Bytecodes::polymorphic_send_n_pop              : 
02370 
02371     case Bytecodes::polymorphic_send_self               : 
02372     case Bytecodes::polymorphic_send_self_pop           : 
02373 
02374     case Bytecodes::polymorphic_send_super              : 
02375     case Bytecodes::polymorphic_send_super_pop          : return polymorphic_send(code);
02376 
02377     
02378     case Bytecodes::megamorphic_send_0                  : 
02379     case Bytecodes::megamorphic_send_1                  : 
02380     case Bytecodes::megamorphic_send_2                  : 
02381     case Bytecodes::megamorphic_send_n                  : 
02382 
02383     case Bytecodes::megamorphic_send_0_pop              : 
02384     case Bytecodes::megamorphic_send_1_pop              : 
02385     case Bytecodes::megamorphic_send_2_pop              : 
02386     case Bytecodes::megamorphic_send_n_pop              : 
02387 
02388     case Bytecodes::megamorphic_send_self               : 
02389     case Bytecodes::megamorphic_send_self_pop           : 
02390 
02391     case Bytecodes::megamorphic_send_super              : 
02392     case Bytecodes::megamorphic_send_super_pop          : return megamorphic_send(code);
02393 
02394     
02395     case Bytecodes::smi_add                             : return smi_add();
02396     case Bytecodes::smi_sub                             : return smi_sub();
02397     case Bytecodes::smi_mult                            : return smi_mul();
02398 
02399     case Bytecodes::smi_equal                           : 
02400     case Bytecodes::smi_not_equal                       : 
02401     case Bytecodes::smi_less                            : 
02402     case Bytecodes::smi_less_equal                      : 
02403     case Bytecodes::smi_greater                         : 
02404     case Bytecodes::smi_greater_equal                   : return smi_compare_op(code);
02405     
02406     case Bytecodes::smi_and                             : 
02407     case Bytecodes::smi_or                              : 
02408     case Bytecodes::smi_xor                             : return smi_logical_op(code);
02409     case Bytecodes::smi_shift                           : return smi_shift();
02410 
02411     
02412     case Bytecodes::non_local_return_tos_pop_n          : return nonlocal_return_tos();
02413     case Bytecodes::non_local_return_self_pop_n         : return nonlocal_return_self();
02414 
02415     
02416     case Bytecodes::push_global                         : return push_global();
02417     case Bytecodes::store_global_pop                    : return store_global(pop);
02418     case Bytecodes::store_global                        : return store_global();
02419 
02420     case Bytecodes::push_classVar                       : return push_global();         
02421     case Bytecodes::store_classVar_pop                  : return store_global(pop);     
02422     case Bytecodes::store_classVar                      : return store_global();        
02423 
02424     case Bytecodes::halt                                : return halt();
02425 
02426     
02427     case Bytecodes::special_primitive_send_1_hint       : return special_primitive_send_hint();
02428     default                                             : return NULL;
02429   }
02430   ShouldNotReachHere();
02431 }
02432 
02433 
02434 void InterpreterGenerator::info(char* name) {
02435   if (!Disclaimer::is_product() && PrintInterpreter) {
02436     std->print("%s\n", name);
02437     _masm->code()->decode();
02438     std->cr();
02439   }
02440 }
02441 
02442 
02443 void InterpreterGenerator::generate_all() {
02444   Interpreter::_code_begin_addr = _masm->pc();
02445 
02446   
02447   Floats::init(_masm);
02448   Floats::_function_table[Floats::oopify] = float_oopify();     
02449   info("Floats::oopify patch");
02450 
02451   
02452   generate_error_handler_code();
02453   info("error handler code");
02454 
02455   generate_nonlocal_return_code();
02456   info("non-local return code");
02457 
02458   generate_method_entry_code();
02459   info("method entry code");
02460 
02461   generate_inline_cache_miss_handler();
02462   info("inline cache miss handler");
02463 
02464   generate_predicted_smi_send_failure_handler();
02465   info("predicted smi send failure handler");
02466 
02467   generate_redo_send_code();
02468   info("redo send code");
02469 
02470   
02471   for (int i = 0; i < Bytecodes::number_of_codes; i++) {
02472     char* start_point = _masm->pc();
02473     char* entry_point = generate_instruction((Bytecodes::Code)i);
02474     if (entry_point != NULL) {
02475       
02476       Bytecodes::set_entry_point(Bytecodes::Code(i), entry_point);
02477       if (!Disclaimer::is_product() && PrintInterpreter) {
02478       #ifndef PRODUCT
02479         int length = _masm->pc() - start_point;
02480         char* name = Bytecodes::name((Bytecodes::Code)i);
02481         std->print("Bytecode 0x%02x: %s (%d bytes), entry point = 0x%x\n", i, name, length, entry_point);
02482         _masm->code()->decode();
02483         std->cr();
02484       #endif
02485       }
02486     }
02487   }
02488 
02489   _masm->finalize();
02490   Interpreter::_code_end_addr = _masm->pc();
02491 }
02492 
02493 
02494 InterpreterGenerator::InterpreterGenerator(CodeBuffer* code, bool debug) {
02495   _masm = new MacroAssembler(code);
02496   _debug = debug;
02497   generate_all();
02498 }
02499 
02500 
02501 
02502 
02503 static const int interpreter_size = 40000;
02504 static char interpreter_code[interpreter_size];
02505 
02506 
02507 void interpreter_init() {
02508   const bool debug = false; 
02509   if (!Disclaimer::is_product() && PrintInterpreter) {
02510     std->print("\nBytecode Interpreter\n\n");
02511   }
02512 
02513   CodeBuffer* code = new CodeBuffer(&interpreter_code[0], interpreter_size);
02514   InterpreterGenerator g(code, debug);
02515 
02516   if (!Disclaimer::is_product() && PrintInterpreter) {
02517     std->print("%d bytes generated for the interpreter\n", code->code_size());
02518     exit(0);
02519   }
02520 
02521   Interpreter::init();
02522 }