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 
00026 
00027 
00028 #include "v8.h"
00029 
00030 #include "codegen-inl.h"
00031 #include "debug.h"
00032 #include "runtime.h"
00033 
00034 namespace v8 { namespace internal {
00035 
00036 
00037 #define __ masm->
00038 
00039 
00040 void Builtins::Generate_Adaptor(MacroAssembler* masm, CFunctionId id) {
00041   
00042   ExternalReference passed = ExternalReference::builtin_passed_function();
00043   __ mov(Operand::StaticVariable(passed), edi);
00044 
00045   
00046   
00047   
00048   __ inc(eax);
00049   __ JumpToBuiltin(ExternalReference(id));
00050 }
00051 
00052 
00053 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) {
00054   
00055   
00056   
00057   
00058 
00059   
00060   __ EnterConstructFrame();
00061 
00062   
00063   __ shl(eax, kSmiTagSize);
00064   __ push(eax);
00065 
00066   
00067   __ push(edi);
00068 
00069   
00070   
00071   Label rt_call, allocated;
00072   if (FLAG_inline_new) {
00073     Label undo_allocation;
00074     ExternalReference debug_step_in_fp =
00075         ExternalReference::debug_step_in_fp_address();
00076     __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0));
00077     __ j(not_equal, &rt_call);
00078     
00079     __ test(edi, Immediate(kSmiTagMask));
00080     __ j(zero, &rt_call);
00081     
00082     __ mov(eax, FieldOperand(edi, JSFunction::kMapOffset));
00083     __ movzx_b(eax, FieldOperand(eax, Map::kInstanceTypeOffset));
00084     __ cmp(eax, JS_FUNCTION_TYPE);
00085     __ j(not_equal, &rt_call);
00086 
00087     
00088     
00089     
00090     __ mov(eax, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset));
00091     
00092     __ test(eax, Immediate(kSmiTagMask));
00093     __ j(zero, &rt_call);
00094     
00095     
00096     __ mov(ebx, FieldOperand(eax, JSFunction::kMapOffset));
00097     __ movzx_b(ebx, FieldOperand(ebx, Map::kInstanceTypeOffset));
00098     __ cmp(ebx, MAP_TYPE);
00099     __ j(not_equal, &rt_call);
00100 
00101     
00102     
00103     
00104     
00105     
00106     __ movzx_b(ebx, FieldOperand(eax, Map::kInstanceTypeOffset));
00107     __ cmp(ebx, JS_FUNCTION_TYPE);
00108     __ j(equal, &rt_call);
00109 
00110     
00111     
00112     
00113     __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset));
00114     __ shl(edi, kPointerSizeLog2);
00115     
00116     
00117     
00118     ASSERT(Heap::MaxHeapObjectSize() >= (1 << kBitsPerByte));
00119     ExternalReference new_space_allocation_top =
00120         ExternalReference::new_space_allocation_top_address();
00121     __ mov(ebx, Operand::StaticVariable(new_space_allocation_top));
00122     __ add(edi, Operand(ebx));  
00123     ExternalReference new_space_allocation_limit =
00124         ExternalReference::new_space_allocation_limit_address();
00125     __ cmp(edi, Operand::StaticVariable(new_space_allocation_limit));
00126     __ j(greater_equal, &rt_call);
00127     
00128     
00129     
00130     
00131     __ mov(Operand(ebx, JSObject::kMapOffset), eax);
00132     __ mov(Operand(ecx), Factory::empty_fixed_array());
00133     __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx);
00134     __ mov(Operand(ebx, JSObject::kElementsOffset), ecx);
00135     
00136     
00137     
00138     
00139     { Label loop, entry;
00140       __ mov(Operand(edx), Factory::undefined_value());
00141       __ lea(ecx, Operand(ebx, JSObject::kHeaderSize));
00142       __ jmp(&entry);
00143       __ bind(&loop);
00144       __ mov(Operand(ecx, 0), edx);
00145       __ add(Operand(ecx), Immediate(kPointerSize));
00146       __ bind(&entry);
00147       __ cmp(ecx, Operand(edi));
00148       __ j(less, &loop);
00149     }
00150 
00151     
00152     
00153     
00154     
00155     
00156     
00157     
00158     __ or_(Operand(ebx), Immediate(kHeapObjectTag));
00159     __ mov(Operand::StaticVariable(new_space_allocation_top), edi);
00160 
00161     
00162     
00163     
00164     
00165     
00166     __ movzx_b(edx, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset));
00167     __ movzx_b(ecx, FieldOperand(eax, Map::kInObjectPropertiesOffset));
00168     
00169     __ sub(edx, Operand(ecx));
00170     __ test(edx, Operand(edx));
00171     
00172     __ j(zero, &allocated);
00173 
00174     
00175     
00176     
00177     
00178     
00179     
00180     ASSERT(Heap::MaxHeapObjectSize() >
00181            (FixedArray::kHeaderSize + 255*kPointerSize));
00182     __ lea(ecx, Operand(edi, edx, times_4, FixedArray::kHeaderSize));
00183     __ cmp(ecx, Operand::StaticVariable(new_space_allocation_limit));
00184     __ j(greater_equal, &undo_allocation);
00185     __ mov(Operand::StaticVariable(new_space_allocation_top), ecx);
00186 
00187     
00188     
00189     
00190     
00191     
00192     __ mov(eax, Factory::fixed_array_map());
00193     __ mov(Operand(edi, JSObject::kMapOffset), eax);  
00194     __ mov(Operand(edi, Array::kLengthOffset), edx);  
00195 
00196     
00197     
00198     
00199     
00200     { Label loop, entry;
00201       __ mov(Operand(edx), Factory::undefined_value());
00202       __ lea(eax, Operand(edi, FixedArray::kHeaderSize));
00203       __ jmp(&entry);
00204       __ bind(&loop);
00205       __ mov(Operand(eax, 0), edx);
00206       __ add(Operand(eax), Immediate(kPointerSize));
00207       __ bind(&entry);
00208       __ cmp(eax, Operand(ecx));
00209       __ j(less, &loop);
00210     }
00211 
00212     
00213     
00214     
00215     
00216     __ or_(Operand(edi), Immediate(kHeapObjectTag));  
00217     __ mov(FieldOperand(ebx, JSObject::kPropertiesOffset), edi);
00218 
00219 
00220     
00221     
00222     __ jmp(&allocated);
00223 
00224     
00225     
00226     
00227     
00228     __ bind(&undo_allocation);
00229     __ xor_(Operand(ebx), Immediate(kHeapObjectTag));  
00230     __ mov(Operand::StaticVariable(new_space_allocation_top), ebx);
00231   }
00232 
00233   
00234   
00235   __ bind(&rt_call);
00236   
00237   __ mov(edi, Operand(esp, 0));
00238   __ push(edi);
00239   __ CallRuntime(Runtime::kNewObject, 1);
00240   __ mov(ebx, Operand(eax));  
00241 
00242   
00243   
00244   __ bind(&allocated);
00245   
00246   __ pop(edi);
00247 
00248   
00249   __ mov(eax, Operand(esp, 0));
00250   __ shr(eax, kSmiTagSize);
00251 
00252   
00253   
00254   
00255   __ push(ebx);
00256   __ push(ebx);
00257 
00258   
00259   __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));
00260 
00261   
00262   Label loop, entry;
00263   __ mov(ecx, Operand(eax));
00264   __ jmp(&entry);
00265   __ bind(&loop);
00266   __ push(Operand(ebx, ecx, times_4, 0));
00267   __ bind(&entry);
00268   __ dec(ecx);
00269   __ j(greater_equal, &loop);
00270 
00271   
00272   ParameterCount actual(eax);
00273   __ InvokeFunction(edi, actual, CALL_FUNCTION);
00274 
00275   
00276   __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
00277 
00278   
00279   
00280   
00281   Label use_receiver, exit;
00282 
00283   
00284   __ test(eax, Immediate(kSmiTagMask));
00285   __ j(zero, &use_receiver, not_taken);
00286 
00287   
00288   
00289   __ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
00290   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
00291   __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
00292   __ j(greater_equal, &exit, not_taken);
00293 
00294   
00295   
00296   __ bind(&use_receiver);
00297   __ mov(eax, Operand(esp, 0));
00298 
00299   
00300   __ bind(&exit);
00301   __ mov(ebx, Operand(esp, kPointerSize));  
00302   __ LeaveConstructFrame();
00303 
00304   
00305   ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
00306   __ pop(ecx);
00307   __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  
00308   __ push(ecx);
00309   __ ret(0);
00310 }
00311 
00312 
00313 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm,
00314                                              bool is_construct) {
00315   
00316   __ xor_(esi, Operand(esi));  
00317 
00318   
00319   __ EnterInternalFrame();
00320 
00321   
00322   __ mov(ebx, Operand(ebp, 0));
00323 
00324   
00325   __ mov(ecx, Operand(ebx, EntryFrameConstants::kFunctionArgOffset));
00326   __ mov(esi, FieldOperand(ecx, JSFunction::kContextOffset));
00327 
00328   
00329   __ push(ecx);
00330   __ push(Operand(ebx, EntryFrameConstants::kReceiverArgOffset));
00331 
00332   
00333   __ mov(eax, Operand(ebx, EntryFrameConstants::kArgcOffset));
00334   __ mov(ebx, Operand(ebx, EntryFrameConstants::kArgvOffset));
00335 
00336   
00337   Label loop, entry;
00338   __ xor_(ecx, Operand(ecx));  
00339   __ jmp(&entry);
00340   __ bind(&loop);
00341   __ mov(edx, Operand(ebx, ecx, times_4, 0));  
00342   __ push(Operand(edx, 0));  
00343   __ inc(Operand(ecx));
00344   __ bind(&entry);
00345   __ cmp(ecx, Operand(eax));
00346   __ j(not_equal, &loop);
00347 
00348   
00349   __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize));  
00350 
00351   
00352   if (is_construct) {
00353     __ call(Handle<Code>(Builtins::builtin(Builtins::JSConstructCall)),
00354             RelocInfo::CODE_TARGET);
00355   } else {
00356     ParameterCount actual(eax);
00357     __ InvokeFunction(edi, actual, CALL_FUNCTION);
00358   }
00359 
00360   
00361   
00362   
00363   __ LeaveInternalFrame();
00364   __ ret(1 * kPointerSize);  
00365 }
00366 
00367 
00368 void Builtins::Generate_JSEntryTrampoline(MacroAssembler* masm) {
00369   Generate_JSEntryTrampolineHelper(masm, false);
00370 }
00371 
00372 
00373 void Builtins::Generate_JSConstructEntryTrampoline(MacroAssembler* masm) {
00374   Generate_JSEntryTrampolineHelper(masm, true);
00375 }
00376 
00377 
00378 void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
00379   
00380   { Label done;
00381     __ test(eax, Operand(eax));
00382     __ j(not_zero, &done, taken);
00383     __ pop(ebx);
00384     __ push(Immediate(Factory::undefined_value()));
00385     __ push(ebx);
00386     __ inc(eax);
00387     __ bind(&done);
00388   }
00389 
00390   
00391   { Label done, non_function, function;
00392     
00393     __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize));
00394     __ test(edi, Immediate(kSmiTagMask));
00395     __ j(zero, &non_function, not_taken);
00396     __ mov(ecx, FieldOperand(edi, HeapObject::kMapOffset));  
00397     __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
00398     __ cmp(ecx, JS_FUNCTION_TYPE);
00399     __ j(equal, &function, taken);
00400 
00401     
00402     __ bind(&non_function);
00403     __ xor_(edi, Operand(edi));
00404     __ jmp(&done);
00405 
00406     
00407     __ bind(&function);
00408     __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
00409 
00410     __ bind(&done);
00411   }
00412 
00413   
00414   { Label call_to_object, use_global_receiver, patch_receiver, done;
00415     __ mov(ebx, Operand(esp, eax, times_4, 0));
00416 
00417     __ test(ebx, Immediate(kSmiTagMask));
00418     __ j(zero, &call_to_object);
00419 
00420     __ cmp(ebx, Factory::null_value());
00421     __ j(equal, &use_global_receiver);
00422     __ cmp(ebx, Factory::undefined_value());
00423     __ j(equal, &use_global_receiver);
00424 
00425     __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
00426     __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
00427     __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
00428     __ j(less, &call_to_object);
00429     __ cmp(ecx, LAST_JS_OBJECT_TYPE);
00430     __ j(less_equal, &done);
00431 
00432     __ bind(&call_to_object);
00433     __ EnterInternalFrame();  
00434 
00435     
00436     ASSERT(kSmiTag == 0);
00437     __ shl(eax, kSmiTagSize);
00438     __ push(eax);
00439 
00440     __ push(edi);  
00441     __ push(ebx);
00442     __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
00443     __ mov(Operand(ebx), eax);
00444     __ pop(edi);  
00445 
00446     
00447     __ pop(eax);
00448     __ shr(eax, kSmiTagSize);
00449 
00450     __ LeaveInternalFrame();
00451     __ jmp(&patch_receiver);
00452 
00453     
00454     __ bind(&use_global_receiver);
00455     const int kGlobalIndex =
00456         Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
00457     __ mov(ebx, FieldOperand(esi, kGlobalIndex));
00458     __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
00459 
00460     __ bind(&patch_receiver);
00461     __ mov(Operand(esp, eax, times_4, 0), ebx);
00462 
00463     __ bind(&done);
00464   }
00465 
00466   
00467   { Label loop;
00468     __ lea(ecx, Operand(eax, +1));  
00469     __ bind(&loop);
00470     __ mov(ebx, Operand(esp, ecx, times_4, 0));
00471     __ mov(Operand(esp, ecx, times_4, kPointerSize), ebx);
00472     __ dec(ecx);
00473     __ j(not_zero, &loop);
00474   }
00475 
00476   
00477   __ pop(ebx);
00478   __ pop(ecx);
00479   __ push(ebx);
00480   __ dec(eax);
00481 
00482   
00483   
00484   
00485   { Label invoke;
00486     __ test(edi, Operand(edi));
00487     __ j(not_zero, &invoke, taken);
00488     __ xor_(ebx, Operand(ebx));
00489     __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
00490     __ jmp(Handle<Code>(builtin(ArgumentsAdaptorTrampoline)),
00491            RelocInfo::CODE_TARGET);
00492 
00493     __ bind(&invoke);
00494     __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
00495     __ mov(ebx,
00496            FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset));
00497     __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
00498     __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
00499     __ cmp(eax, Operand(ebx));
00500     __ j(not_equal, Handle<Code>(builtin(ArgumentsAdaptorTrampoline)));
00501   }
00502 
00503   
00504   ParameterCount expected(0);
00505   __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION);
00506 }
00507 
00508 
00509 void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
00510   __ EnterInternalFrame();
00511 
00512   __ push(Operand(ebp, 4 * kPointerSize));  
00513   __ push(Operand(ebp, 2 * kPointerSize));  
00514   __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
00515 
00516   if (FLAG_check_stack) {
00517     
00518     
00519     ExternalReference stack_guard_limit =
00520         ExternalReference::address_of_stack_guard_limit();
00521     Label retry_preemption;
00522     Label no_preemption;
00523     __ bind(&retry_preemption);
00524     __ mov(edi, Operand::StaticVariable(stack_guard_limit));
00525     __ cmp(esp, Operand(edi));
00526     __ j(above, &no_preemption, taken);
00527 
00528     
00529     
00530     
00531     __ push(eax);
00532     __ push(Immediate(Smi::FromInt(0)));
00533 
00534     
00535     __ CallRuntime(Runtime::kStackGuard, 1);
00536     __ pop(eax);
00537     __ jmp(&retry_preemption);
00538 
00539     __ bind(&no_preemption);
00540 
00541     Label okay;
00542     
00543     __ mov(ecx, Operand(esp));
00544     __ sub(ecx, Operand(edi));
00545     
00546     
00547     __ mov(edx, Operand(eax));
00548     __ shl(edx, kPointerSizeLog2 - kSmiTagSize);
00549     __ cmp(ecx, Operand(edx));
00550     __ j(greater, &okay, taken);
00551 
00552     
00553     __ push(Operand(ebp, 4 * kPointerSize));  
00554     __ push(eax);
00555     __ InvokeBuiltin(Builtins::APPLY_OVERFLOW, CALL_FUNCTION);
00556     __ bind(&okay);
00557   }
00558 
00559   
00560   const int kLimitOffset =
00561       StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
00562   const int kIndexOffset = kLimitOffset - 1 * kPointerSize;
00563   __ push(eax);  
00564   __ push(Immediate(0));  
00565 
00566   
00567   
00568   __ mov(edi, Operand(ebp, 4 * kPointerSize));
00569   __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
00570 
00571   
00572   Label call_to_object, use_global_receiver, push_receiver;
00573   __ mov(ebx, Operand(ebp, 3 * kPointerSize));
00574   __ test(ebx, Immediate(kSmiTagMask));
00575   __ j(zero, &call_to_object);
00576   __ cmp(ebx, Factory::null_value());
00577   __ j(equal, &use_global_receiver);
00578   __ cmp(ebx, Factory::undefined_value());
00579   __ j(equal, &use_global_receiver);
00580 
00581   
00582   
00583   __ mov(ecx, FieldOperand(ebx, HeapObject::kMapOffset));
00584   __ movzx_b(ecx, FieldOperand(ecx, Map::kInstanceTypeOffset));
00585   __ cmp(ecx, FIRST_JS_OBJECT_TYPE);
00586   __ j(less, &call_to_object);
00587   __ cmp(ecx, LAST_JS_OBJECT_TYPE);
00588   __ j(less_equal, &push_receiver);
00589 
00590   
00591   __ bind(&call_to_object);
00592   __ push(ebx);
00593   __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
00594   __ mov(ebx, Operand(eax));
00595   __ jmp(&push_receiver);
00596 
00597   
00598   __ bind(&use_global_receiver);
00599   const int kGlobalOffset =
00600       Context::kHeaderSize + Context::GLOBAL_INDEX * kPointerSize;
00601   __ mov(ebx, FieldOperand(esi, kGlobalOffset));
00602   __ mov(ebx, FieldOperand(ebx, GlobalObject::kGlobalReceiverOffset));
00603 
00604   
00605   __ bind(&push_receiver);
00606   __ push(ebx);
00607 
00608   
00609   Label entry, loop;
00610   __ mov(eax, Operand(ebp, kIndexOffset));
00611   __ jmp(&entry);
00612   __ bind(&loop);
00613   __ mov(ecx, Operand(ebp, 2 * kPointerSize));  
00614   __ push(ecx);
00615   __ push(eax);
00616 
00617   
00618   Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
00619   __ call(ic, RelocInfo::CODE_TARGET);
00620 
00621   
00622   __ add(Operand(esp), Immediate(2 * kPointerSize));
00623   __ push(eax);
00624 
00625   
00626   __ mov(eax, Operand(ebp, kIndexOffset));
00627   __ add(Operand(eax), Immediate(1 << kSmiTagSize));
00628   __ mov(Operand(ebp, kIndexOffset), eax);
00629 
00630   __ bind(&entry);
00631   __ cmp(eax, Operand(ebp, kLimitOffset));
00632   __ j(not_equal, &loop);
00633 
00634   
00635   ParameterCount actual(eax);
00636   __ shr(eax, kSmiTagSize);
00637   __ mov(edi, Operand(ebp, 4 * kPointerSize));
00638   __ InvokeFunction(edi, actual, CALL_FUNCTION);
00639 
00640   __ LeaveInternalFrame();
00641   __ ret(3 * kPointerSize);  
00642 }
00643 
00644 
00645 static void EnterArgumentsAdaptorFrame(MacroAssembler* masm) {
00646   __ push(ebp);
00647   __ mov(ebp, Operand(esp));
00648 
00649   
00650   __ push(Immediate(ArgumentsAdaptorFrame::SENTINEL));
00651 
00652   
00653   __ push(edi);
00654 
00655   
00656   
00657   
00658   ASSERT(kSmiTagSize == 1);
00659   __ lea(ecx, Operand(eax, eax, times_1, kSmiTag));
00660   __ push(Operand(ecx));
00661 }
00662 
00663 
00664 static void LeaveArgumentsAdaptorFrame(MacroAssembler* masm) {
00665   
00666   __ mov(ebx, Operand(ebp, ArgumentsAdaptorFrameConstants::kLengthOffset));
00667 
00668   
00669   __ leave();
00670 
00671   
00672   ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
00673   __ pop(ecx);
00674   __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize));  
00675   __ push(ecx);
00676 }
00677 
00678 
00679 void Builtins::Generate_ArgumentsAdaptorTrampoline(MacroAssembler* masm) {
00680   
00681   
00682   
00683   
00684   
00685 
00686   Label invoke, dont_adapt_arguments;
00687   __ IncrementCounter(&Counters::arguments_adaptors, 1);
00688 
00689   Label enough, too_few;
00690   __ cmp(eax, Operand(ebx));
00691   __ j(less, &too_few);
00692   __ cmp(ebx, SharedFunctionInfo::kDontAdaptArgumentsSentinel);
00693   __ j(equal, &dont_adapt_arguments);
00694 
00695   {  
00696     __ bind(&enough);
00697     EnterArgumentsAdaptorFrame(masm);
00698 
00699     
00700     const int offset = StandardFrameConstants::kCallerSPOffset;
00701     __ lea(eax, Operand(ebp, eax, times_4, offset));
00702     __ mov(ecx, -1);  
00703 
00704     Label copy;
00705     __ bind(©);
00706     __ inc(ecx);
00707     __ push(Operand(eax, 0));
00708     __ sub(Operand(eax), Immediate(kPointerSize));
00709     __ cmp(ecx, Operand(ebx));
00710     __ j(less, ©);
00711     __ jmp(&invoke);
00712   }
00713 
00714   {  
00715     __ bind(&too_few);
00716     EnterArgumentsAdaptorFrame(masm);
00717 
00718     
00719     const int offset = StandardFrameConstants::kCallerSPOffset;
00720     __ lea(edi, Operand(ebp, eax, times_4, offset));
00721     __ mov(ecx, -1);  
00722 
00723     Label copy;
00724     __ bind(©);
00725     __ inc(ecx);
00726     __ push(Operand(edi, 0));
00727     __ sub(Operand(edi), Immediate(kPointerSize));
00728     __ cmp(ecx, Operand(eax));
00729     __ j(less, ©);
00730 
00731     
00732     Label fill;
00733     __ bind(&fill);
00734     __ inc(ecx);
00735     __ push(Immediate(Factory::undefined_value()));
00736     __ cmp(ecx, Operand(ebx));
00737     __ j(less, &fill);
00738 
00739     
00740     __ mov(edi, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
00741   }
00742 
00743   
00744   __ bind(&invoke);
00745   __ call(Operand(edx));
00746 
00747   
00748   LeaveArgumentsAdaptorFrame(masm);
00749   __ ret(0);
00750 
00751   
00752   
00753   
00754   __ bind(&dont_adapt_arguments);
00755   __ jmp(Operand(edx));
00756 }
00757 
00758 
00759 static void Generate_DebugBreakCallHelper(MacroAssembler* masm,
00760                                           RegList pointer_regs,
00761                                           bool convert_call_to_jmp) {
00762   
00763   
00764   
00765   
00766   
00767   
00768   __ SaveRegistersToMemory(kJSCallerSaved);
00769 
00770   
00771   __ EnterInternalFrame();
00772 
00773   
00774   
00775   __ PushRegistersFromMemory(pointer_regs);
00776 
00777 #ifdef DEBUG
00778   __ RecordComment("// Calling from debug break to runtime - come in - over");
00779 #endif
00780   __ Set(eax, Immediate(0));  
00781   __ mov(Operand(ebx), Immediate(ExternalReference::debug_break()));
00782 
00783   CEntryDebugBreakStub ceb;
00784   __ CallStub(&ceb);
00785 
00786   
00787   
00788   __ PopRegistersToMemory(pointer_regs);
00789 
00790   
00791   __ LeaveInternalFrame();
00792 
00793   
00794   
00795   if (convert_call_to_jmp) {
00796     __ pop(eax);
00797   }
00798 
00799   
00800   __ RestoreRegistersFromMemory(kJSCallerSaved);
00801 
00802   
00803   
00804   
00805   ExternalReference after_break_target =
00806       ExternalReference(Debug_Address::AfterBreakTarget());
00807   __ jmp(Operand::StaticVariable(after_break_target));
00808 }
00809 
00810 
00811 void Builtins::Generate_LoadIC_DebugBreak(MacroAssembler* masm) {
00812   
00813   
00814   
00815   
00816   Generate_DebugBreakCallHelper(masm, ecx.bit(), false);
00817 }
00818 
00819 
00820 void Builtins::Generate_StoreIC_DebugBreak(MacroAssembler* masm) {
00821   
00822   
00823   
00824   
00825   
00826   Generate_DebugBreakCallHelper(masm, eax.bit() | ecx.bit(), false);
00827 }
00828 
00829 
00830 void Builtins::Generate_KeyedLoadIC_DebugBreak(MacroAssembler* masm) {
00831   
00832   
00833   
00834   
00835   Generate_DebugBreakCallHelper(masm, 0, false);
00836 }
00837 
00838 
00839 void Builtins::Generate_KeyedStoreIC_DebugBreak(MacroAssembler* masm) {
00840   
00841   
00842   
00843   
00844   
00845   
00846   Generate_DebugBreakCallHelper(masm, eax.bit(), false);
00847 }
00848 
00849 
00850 void Builtins::Generate_CallIC_DebugBreak(MacroAssembler* masm) {
00851   
00852   
00853   
00854   
00855   
00856   Generate_DebugBreakCallHelper(masm, 0, false);
00857 }
00858 
00859 
00860 void Builtins::Generate_ConstructCall_DebugBreak(MacroAssembler* masm) {
00861   
00862   
00863   
00864   
00865   
00866   
00867   
00868   Generate_DebugBreakCallHelper(masm, 0, false);
00869 }
00870 
00871 
00872 void Builtins::Generate_Return_DebugBreak(MacroAssembler* masm) {
00873   
00874   
00875   
00876   
00877   Generate_DebugBreakCallHelper(masm, eax.bit(), true);
00878 }
00879 
00880 
00881 void Builtins::Generate_Return_DebugBreakEntry(MacroAssembler* masm) {
00882   
00883   
00884   ExternalReference debug_break_return =
00885       ExternalReference(Debug_Address::DebugBreakReturn());
00886   __ mov(ebx, Operand::StaticVariable(debug_break_return));
00887   __ add(Operand(ebx), Immediate(Code::kHeaderSize - kHeapObjectTag));
00888   __ jmp(Operand(ebx));
00889 }
00890 
00891 
00892 void Builtins::Generate_StubNoRegisters_DebugBreak(MacroAssembler* masm) {
00893   
00894   
00895   
00896   
00897   Generate_DebugBreakCallHelper(masm, 0, false);
00898 }
00899 
00900 #undef __
00901 
00902 } }