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 } }