OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #if V8_TARGET_ARCH_X87 | 5 #if V8_TARGET_ARCH_X87 |
6 | 6 |
7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/deoptimizer.h" | 9 #include "src/deoptimizer.h" |
10 #include "src/full-codegen/full-codegen.h" | 10 #include "src/full-codegen/full-codegen.h" |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 __ InitializeFieldsWithFiller(ecx, edi, edx); | 234 __ InitializeFieldsWithFiller(ecx, edi, edx); |
235 | 235 |
236 __ pop(esi); // Restore allocation count value before decreasing. | 236 __ pop(esi); // Restore allocation count value before decreasing. |
237 __ cmp(esi, Map::kSlackTrackingCounterEnd); | 237 __ cmp(esi, Map::kSlackTrackingCounterEnd); |
238 __ j(not_equal, &allocated); | 238 __ j(not_equal, &allocated); |
239 | 239 |
240 // Push the object to the stack, and then the initial map as | 240 // Push the object to the stack, and then the initial map as |
241 // an argument to the runtime call. | 241 // an argument to the runtime call. |
242 __ push(ebx); | 242 __ push(ebx); |
243 __ push(eax); // initial map | 243 __ push(eax); // initial map |
244 __ CallRuntime(Runtime::kFinalizeInstanceSize, 1); | 244 __ CallRuntime(Runtime::kFinalizeInstanceSize); |
245 __ pop(ebx); | 245 __ pop(ebx); |
246 | 246 |
247 // Continue with JSObject being successfully allocated | 247 // Continue with JSObject being successfully allocated |
248 // ebx: JSObject (tagged) | 248 // ebx: JSObject (tagged) |
249 __ jmp(&allocated); | 249 __ jmp(&allocated); |
250 | 250 |
251 __ bind(&no_inobject_slack_tracking); | 251 __ bind(&no_inobject_slack_tracking); |
252 } | 252 } |
253 | 253 |
254 __ InitializeFieldsWithFiller(ecx, edi, edx); | 254 __ InitializeFieldsWithFiller(ecx, edi, edx); |
255 | 255 |
256 // Continue with JSObject being successfully allocated | 256 // Continue with JSObject being successfully allocated |
257 // ebx: JSObject (tagged) | 257 // ebx: JSObject (tagged) |
258 __ jmp(&allocated); | 258 __ jmp(&allocated); |
259 } | 259 } |
260 | 260 |
261 // Allocate the new receiver object using the runtime call. | 261 // Allocate the new receiver object using the runtime call. |
262 // edx: new target | 262 // edx: new target |
263 __ bind(&rt_call); | 263 __ bind(&rt_call); |
264 int offset = kPointerSize; | 264 int offset = kPointerSize; |
265 | 265 |
266 // Must restore esi (context) and edi (constructor) before calling | 266 // Must restore esi (context) and edi (constructor) before calling |
267 // runtime. | 267 // runtime. |
268 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 268 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
269 __ mov(edi, Operand(esp, offset)); | 269 __ mov(edi, Operand(esp, offset)); |
270 __ push(edi); // constructor function | 270 __ push(edi); // constructor function |
271 __ push(edx); // new target | 271 __ push(edx); // new target |
272 __ CallRuntime(Runtime::kNewObject, 2); | 272 __ CallRuntime(Runtime::kNewObject); |
273 __ mov(ebx, eax); // store result in ebx | 273 __ mov(ebx, eax); // store result in ebx |
274 | 274 |
275 // New object allocated. | 275 // New object allocated. |
276 // ebx: newly allocated object | 276 // ebx: newly allocated object |
277 __ bind(&allocated); | 277 __ bind(&allocated); |
278 | 278 |
279 // Restore the parameters. | 279 // Restore the parameters. |
280 __ pop(edx); // new.target | 280 __ pop(edx); // new.target |
281 __ pop(edi); // Constructor function. | 281 __ pop(edi); // Constructor function. |
282 | 282 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 | 382 |
383 | 383 |
384 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { | 384 void Builtins::Generate_JSBuiltinsConstructStub(MacroAssembler* masm) { |
385 Generate_JSConstructStubHelper(masm, false, false); | 385 Generate_JSConstructStubHelper(masm, false, false); |
386 } | 386 } |
387 | 387 |
388 | 388 |
389 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { | 389 void Builtins::Generate_ConstructedNonConstructable(MacroAssembler* masm) { |
390 FrameScope scope(masm, StackFrame::INTERNAL); | 390 FrameScope scope(masm, StackFrame::INTERNAL); |
391 __ push(edi); | 391 __ push(edi); |
392 __ CallRuntime(Runtime::kThrowConstructedNonConstructable, 1); | 392 __ CallRuntime(Runtime::kThrowConstructedNonConstructable); |
393 } | 393 } |
394 | 394 |
395 | 395 |
396 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; | 396 enum IsTagged { kEaxIsSmiTagged, kEaxIsUntaggedInt }; |
397 | 397 |
398 | 398 |
399 // Clobbers ecx, edx, edi; preserves all other registers. | 399 // Clobbers ecx, edx, edi; preserves all other registers. |
400 static void Generate_CheckStackOverflow(MacroAssembler* masm, | 400 static void Generate_CheckStackOverflow(MacroAssembler* masm, |
401 IsTagged eax_is_tagged) { | 401 IsTagged eax_is_tagged) { |
402 // eax : the number of items to be pushed to the stack | 402 // eax : the number of items to be pushed to the stack |
(...skipping 12 matching lines...) Expand all Loading... |
415 // Make edx the space we need for the array when it is unrolled onto the | 415 // Make edx the space we need for the array when it is unrolled onto the |
416 // stack. | 416 // stack. |
417 __ mov(edx, eax); | 417 __ mov(edx, eax); |
418 int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0; | 418 int smi_tag = eax_is_tagged == kEaxIsSmiTagged ? kSmiTagSize : 0; |
419 __ shl(edx, kPointerSizeLog2 - smi_tag); | 419 __ shl(edx, kPointerSizeLog2 - smi_tag); |
420 // Check if the arguments will overflow the stack. | 420 // Check if the arguments will overflow the stack. |
421 __ cmp(ecx, edx); | 421 __ cmp(ecx, edx); |
422 __ j(greater, &okay); // Signed comparison. | 422 __ j(greater, &okay); // Signed comparison. |
423 | 423 |
424 // Out of stack space. | 424 // Out of stack space. |
425 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 425 __ CallRuntime(Runtime::kThrowStackOverflow); |
426 | 426 |
427 __ bind(&okay); | 427 __ bind(&okay); |
428 } | 428 } |
429 | 429 |
430 | 430 |
431 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, | 431 static void Generate_JSEntryTrampolineHelper(MacroAssembler* masm, |
432 bool is_construct) { | 432 bool is_construct) { |
433 ProfileEntryHookStub::MaybeCallEntryHook(masm); | 433 ProfileEntryHookStub::MaybeCallEntryHook(masm); |
434 | 434 |
435 // Clear the context before we push it when entering the internal frame. | 435 // Clear the context before we push it when entering the internal frame. |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
552 BytecodeArray::kFrameSizeOffset)); | 552 BytecodeArray::kFrameSizeOffset)); |
553 | 553 |
554 // Do a stack check to ensure we don't go over the limit. | 554 // Do a stack check to ensure we don't go over the limit. |
555 Label ok; | 555 Label ok; |
556 __ mov(ecx, esp); | 556 __ mov(ecx, esp); |
557 __ sub(ecx, ebx); | 557 __ sub(ecx, ebx); |
558 ExternalReference stack_limit = | 558 ExternalReference stack_limit = |
559 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 559 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
560 __ cmp(ecx, Operand::StaticVariable(stack_limit)); | 560 __ cmp(ecx, Operand::StaticVariable(stack_limit)); |
561 __ j(above_equal, &ok); | 561 __ j(above_equal, &ok); |
562 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 562 __ CallRuntime(Runtime::kThrowStackOverflow); |
563 __ bind(&ok); | 563 __ bind(&ok); |
564 | 564 |
565 // If ok, push undefined as the initial value for all register file entries. | 565 // If ok, push undefined as the initial value for all register file entries. |
566 Label loop_header; | 566 Label loop_header; |
567 Label loop_check; | 567 Label loop_check; |
568 __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value())); | 568 __ mov(eax, Immediate(masm->isolate()->factory()->undefined_value())); |
569 __ jmp(&loop_check); | 569 __ jmp(&loop_check); |
570 __ bind(&loop_header); | 570 __ bind(&loop_header); |
571 // TODO(rmcilroy): Consider doing more than one push per loop iteration. | 571 // TODO(rmcilroy): Consider doing more than one push per loop iteration. |
572 __ push(eax); | 572 __ push(eax); |
(...skipping 11 matching lines...) Expand all Loading... |
584 // - Code aging of the BytecodeArray object. | 584 // - Code aging of the BytecodeArray object. |
585 | 585 |
586 // Perform stack guard check. | 586 // Perform stack guard check. |
587 { | 587 { |
588 Label ok; | 588 Label ok; |
589 ExternalReference stack_limit = | 589 ExternalReference stack_limit = |
590 ExternalReference::address_of_stack_limit(masm->isolate()); | 590 ExternalReference::address_of_stack_limit(masm->isolate()); |
591 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 591 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
592 __ j(above_equal, &ok); | 592 __ j(above_equal, &ok); |
593 __ push(kInterpreterBytecodeArrayRegister); | 593 __ push(kInterpreterBytecodeArrayRegister); |
594 __ CallRuntime(Runtime::kStackGuard, 0); | 594 __ CallRuntime(Runtime::kStackGuard); |
595 __ pop(kInterpreterBytecodeArrayRegister); | 595 __ pop(kInterpreterBytecodeArrayRegister); |
596 __ bind(&ok); | 596 __ bind(&ok); |
597 } | 597 } |
598 | 598 |
599 // Load accumulator, register file, bytecode offset, dispatch table into | 599 // Load accumulator, register file, bytecode offset, dispatch table into |
600 // registers. | 600 // registers. |
601 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); | 601 __ LoadRoot(kInterpreterAccumulatorRegister, Heap::kUndefinedValueRootIndex); |
602 __ mov(kInterpreterRegisterFileRegister, ebp); | 602 __ mov(kInterpreterRegisterFileRegister, ebp); |
603 __ add(kInterpreterRegisterFileRegister, | 603 __ add(kInterpreterRegisterFileRegister, |
604 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); | 604 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); |
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
742 static void Generate_InterpreterNotifyDeoptimizedHelper( | 742 static void Generate_InterpreterNotifyDeoptimizedHelper( |
743 MacroAssembler* masm, Deoptimizer::BailoutType type) { | 743 MacroAssembler* masm, Deoptimizer::BailoutType type) { |
744 // Enter an internal frame. | 744 // Enter an internal frame. |
745 { | 745 { |
746 FrameScope scope(masm, StackFrame::INTERNAL); | 746 FrameScope scope(masm, StackFrame::INTERNAL); |
747 __ Push(kInterpreterAccumulatorRegister); // Save accumulator register. | 747 __ Push(kInterpreterAccumulatorRegister); // Save accumulator register. |
748 | 748 |
749 // Pass the deoptimization type to the runtime system. | 749 // Pass the deoptimization type to the runtime system. |
750 __ Push(Smi::FromInt(static_cast<int>(type))); | 750 __ Push(Smi::FromInt(static_cast<int>(type))); |
751 | 751 |
752 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); | 752 __ CallRuntime(Runtime::kNotifyDeoptimized); |
753 | 753 |
754 __ Pop(kInterpreterAccumulatorRegister); // Restore accumulator register. | 754 __ Pop(kInterpreterAccumulatorRegister); // Restore accumulator register. |
755 // Tear down internal frame. | 755 // Tear down internal frame. |
756 } | 756 } |
757 | 757 |
758 // Initialize register file register. | 758 // Initialize register file register. |
759 __ mov(kInterpreterRegisterFileRegister, ebp); | 759 __ mov(kInterpreterRegisterFileRegister, ebp); |
760 __ add(kInterpreterRegisterFileRegister, | 760 __ add(kInterpreterRegisterFileRegister, |
761 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); | 761 Immediate(InterpreterFrameConstants::kRegisterFilePointerFromFp)); |
762 | 762 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
925 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, | 925 static void Generate_NotifyStubFailureHelper(MacroAssembler* masm, |
926 SaveFPRegsMode save_doubles) { | 926 SaveFPRegsMode save_doubles) { |
927 // Enter an internal frame. | 927 // Enter an internal frame. |
928 { | 928 { |
929 FrameScope scope(masm, StackFrame::INTERNAL); | 929 FrameScope scope(masm, StackFrame::INTERNAL); |
930 | 930 |
931 // Preserve registers across notification, this is important for compiled | 931 // Preserve registers across notification, this is important for compiled |
932 // stubs that tail call the runtime on deopts passing their parameters in | 932 // stubs that tail call the runtime on deopts passing their parameters in |
933 // registers. | 933 // registers. |
934 __ pushad(); | 934 __ pushad(); |
935 __ CallRuntime(Runtime::kNotifyStubFailure, 0, save_doubles); | 935 __ CallRuntime(Runtime::kNotifyStubFailure, save_doubles); |
936 __ popad(); | 936 __ popad(); |
937 // Tear down internal frame. | 937 // Tear down internal frame. |
938 } | 938 } |
939 | 939 |
940 __ pop(MemOperand(esp, 0)); // Ignore state offset | 940 __ pop(MemOperand(esp, 0)); // Ignore state offset |
941 __ ret(0); // Return to IC Miss stub, continuation still on stack. | 941 __ ret(0); // Return to IC Miss stub, continuation still on stack. |
942 } | 942 } |
943 | 943 |
944 | 944 |
945 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { | 945 void Builtins::Generate_NotifyStubFailure(MacroAssembler* masm) { |
946 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); | 946 Generate_NotifyStubFailureHelper(masm, kDontSaveFPRegs); |
947 } | 947 } |
948 | 948 |
949 | 949 |
950 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { | 950 void Builtins::Generate_NotifyStubFailureSaveDoubles(MacroAssembler* masm) { |
951 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); | 951 Generate_NotifyStubFailureHelper(masm, kSaveFPRegs); |
952 } | 952 } |
953 | 953 |
954 | 954 |
955 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, | 955 static void Generate_NotifyDeoptimizedHelper(MacroAssembler* masm, |
956 Deoptimizer::BailoutType type) { | 956 Deoptimizer::BailoutType type) { |
957 { | 957 { |
958 FrameScope scope(masm, StackFrame::INTERNAL); | 958 FrameScope scope(masm, StackFrame::INTERNAL); |
959 | 959 |
960 // Pass deoptimization type to the runtime system. | 960 // Pass deoptimization type to the runtime system. |
961 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); | 961 __ push(Immediate(Smi::FromInt(static_cast<int>(type)))); |
962 __ CallRuntime(Runtime::kNotifyDeoptimized, 1); | 962 __ CallRuntime(Runtime::kNotifyDeoptimized); |
963 | 963 |
964 // Tear down internal frame. | 964 // Tear down internal frame. |
965 } | 965 } |
966 | 966 |
967 // Get the full codegen state from the stack and untag it. | 967 // Get the full codegen state from the stack and untag it. |
968 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 968 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
969 __ SmiUntag(ecx); | 969 __ SmiUntag(ecx); |
970 | 970 |
971 // Switch on the state. | 971 // Switch on the state. |
972 Label not_no_registers, not_tos_eax; | 972 Label not_no_registers, not_tos_eax; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1065 __ bind(&no_arguments); | 1065 __ bind(&no_arguments); |
1066 { | 1066 { |
1067 __ Set(eax, 0); | 1067 __ Set(eax, 0); |
1068 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); | 1068 __ Jump(masm->isolate()->builtins()->Call(), RelocInfo::CODE_TARGET); |
1069 } | 1069 } |
1070 | 1070 |
1071 // 4c. The receiver is not callable, throw an appropriate TypeError. | 1071 // 4c. The receiver is not callable, throw an appropriate TypeError. |
1072 __ bind(&receiver_not_callable); | 1072 __ bind(&receiver_not_callable); |
1073 { | 1073 { |
1074 __ mov(Operand(esp, kPointerSize), edi); | 1074 __ mov(Operand(esp, kPointerSize), edi); |
1075 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1); | 1075 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1076 } | 1076 } |
1077 } | 1077 } |
1078 | 1078 |
1079 | 1079 |
1080 // static | 1080 // static |
1081 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { | 1081 void Builtins::Generate_FunctionPrototypeCall(MacroAssembler* masm) { |
1082 // Stack Layout: | 1082 // Stack Layout: |
1083 // esp[0] : Return address | 1083 // esp[0] : Return address |
1084 // esp[8] : Argument n | 1084 // esp[8] : Argument n |
1085 // esp[16] : Argument n-1 | 1085 // esp[16] : Argument n-1 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1174 | 1174 |
1175 // 3a. Apply the target to the given argumentsList (passing undefined for | 1175 // 3a. Apply the target to the given argumentsList (passing undefined for |
1176 // new.target). | 1176 // new.target). |
1177 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); | 1177 __ LoadRoot(edx, Heap::kUndefinedValueRootIndex); |
1178 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1178 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
1179 | 1179 |
1180 // 3b. The target is not callable, throw an appropriate TypeError. | 1180 // 3b. The target is not callable, throw an appropriate TypeError. |
1181 __ bind(&target_not_callable); | 1181 __ bind(&target_not_callable); |
1182 { | 1182 { |
1183 __ mov(Operand(esp, kPointerSize), edi); | 1183 __ mov(Operand(esp, kPointerSize), edi); |
1184 __ TailCallRuntime(Runtime::kThrowApplyNonFunction, 1); | 1184 __ TailCallRuntime(Runtime::kThrowApplyNonFunction); |
1185 } | 1185 } |
1186 } | 1186 } |
1187 | 1187 |
1188 | 1188 |
1189 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { | 1189 void Builtins::Generate_ReflectConstruct(MacroAssembler* masm) { |
1190 // ----------- S t a t e ------------- | 1190 // ----------- S t a t e ------------- |
1191 // -- eax : argc | 1191 // -- eax : argc |
1192 // -- esp[0] : return address | 1192 // -- esp[0] : return address |
1193 // -- esp[4] : new.target (optional) | 1193 // -- esp[4] : new.target (optional) |
1194 // -- esp[8] : argumentsList | 1194 // -- esp[8] : argumentsList |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); | 1244 __ test_b(FieldOperand(ecx, Map::kBitFieldOffset), 1 << Map::kIsConstructor); |
1245 __ j(zero, &new_target_not_constructor, Label::kNear); | 1245 __ j(zero, &new_target_not_constructor, Label::kNear); |
1246 | 1246 |
1247 // 4a. Construct the target with the given new.target and argumentsList. | 1247 // 4a. Construct the target with the given new.target and argumentsList. |
1248 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); | 1248 __ Jump(masm->isolate()->builtins()->Apply(), RelocInfo::CODE_TARGET); |
1249 | 1249 |
1250 // 4b. The target is not a constructor, throw an appropriate TypeError. | 1250 // 4b. The target is not a constructor, throw an appropriate TypeError. |
1251 __ bind(&target_not_constructor); | 1251 __ bind(&target_not_constructor); |
1252 { | 1252 { |
1253 __ mov(Operand(esp, kPointerSize), edi); | 1253 __ mov(Operand(esp, kPointerSize), edi); |
1254 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1254 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
1255 } | 1255 } |
1256 | 1256 |
1257 // 4c. The new.target is not a constructor, throw an appropriate TypeError. | 1257 // 4c. The new.target is not a constructor, throw an appropriate TypeError. |
1258 __ bind(&new_target_not_constructor); | 1258 __ bind(&new_target_not_constructor); |
1259 { | 1259 { |
1260 __ mov(Operand(esp, kPointerSize), edx); | 1260 __ mov(Operand(esp, kPointerSize), edx); |
1261 __ TailCallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1261 __ TailCallRuntime(Runtime::kThrowCalledNonCallable); |
1262 } | 1262 } |
1263 } | 1263 } |
1264 | 1264 |
1265 | 1265 |
1266 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { | 1266 void Builtins::Generate_InternalArrayCode(MacroAssembler* masm) { |
1267 // ----------- S t a t e ------------- | 1267 // ----------- S t a t e ------------- |
1268 // -- eax : argc | 1268 // -- eax : argc |
1269 // -- esp[0] : return address | 1269 // -- esp[0] : return address |
1270 // -- esp[4] : last argument | 1270 // -- esp[4] : last argument |
1271 // ----------------------------------- | 1271 // ----------------------------------- |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1370 ToStringStub stub(masm->isolate()); | 1370 ToStringStub stub(masm->isolate()); |
1371 __ TailCallStub(&stub); | 1371 __ TailCallStub(&stub); |
1372 } | 1372 } |
1373 | 1373 |
1374 // 3b. Convert symbol in eax to a string. | 1374 // 3b. Convert symbol in eax to a string. |
1375 __ bind(&symbol_descriptive_string); | 1375 __ bind(&symbol_descriptive_string); |
1376 { | 1376 { |
1377 __ PopReturnAddressTo(ecx); | 1377 __ PopReturnAddressTo(ecx); |
1378 __ Push(eax); | 1378 __ Push(eax); |
1379 __ PushReturnAddressFrom(ecx); | 1379 __ PushReturnAddressFrom(ecx); |
1380 __ TailCallRuntime(Runtime::kSymbolDescriptiveString, 1); | 1380 __ TailCallRuntime(Runtime::kSymbolDescriptiveString); |
1381 } | 1381 } |
1382 } | 1382 } |
1383 | 1383 |
1384 | 1384 |
1385 // static | 1385 // static |
1386 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { | 1386 void Builtins::Generate_StringConstructor_ConstructStub(MacroAssembler* masm) { |
1387 // ----------- S t a t e ------------- | 1387 // ----------- S t a t e ------------- |
1388 // -- eax : number of arguments | 1388 // -- eax : number of arguments |
1389 // -- edi : constructor function | 1389 // -- edi : constructor function |
1390 // -- edx : new target | 1390 // -- edx : new target |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1456 __ Ret(); | 1456 __ Ret(); |
1457 } | 1457 } |
1458 | 1458 |
1459 // 5. Fallback to the runtime to create new object. | 1459 // 5. Fallback to the runtime to create new object. |
1460 __ bind(&new_object); | 1460 __ bind(&new_object); |
1461 { | 1461 { |
1462 FrameScope scope(masm, StackFrame::INTERNAL); | 1462 FrameScope scope(masm, StackFrame::INTERNAL); |
1463 __ Push(ebx); // the first argument | 1463 __ Push(ebx); // the first argument |
1464 __ Push(edi); // constructor function | 1464 __ Push(edi); // constructor function |
1465 __ Push(edx); // new target | 1465 __ Push(edx); // new target |
1466 __ CallRuntime(Runtime::kNewObject, 2); | 1466 __ CallRuntime(Runtime::kNewObject); |
1467 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 1467 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |
1468 } | 1468 } |
1469 __ Ret(); | 1469 __ Ret(); |
1470 } | 1470 } |
1471 | 1471 |
1472 | 1472 |
1473 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1473 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
1474 Label* stack_overflow) { | 1474 Label* stack_overflow) { |
1475 // ----------- S t a t e ------------- | 1475 // ----------- S t a t e ------------- |
1476 // -- eax : actual number of arguments | 1476 // -- eax : actual number of arguments |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1562 __ CmpInstanceType(ecx, JS_ARRAY_TYPE); | 1562 __ CmpInstanceType(ecx, JS_ARRAY_TYPE); |
1563 __ j(equal, &create_array); | 1563 __ j(equal, &create_array); |
1564 | 1564 |
1565 // Ask the runtime to create the list (actually a FixedArray). | 1565 // Ask the runtime to create the list (actually a FixedArray). |
1566 __ bind(&create_runtime); | 1566 __ bind(&create_runtime); |
1567 { | 1567 { |
1568 FrameScope scope(masm, StackFrame::INTERNAL); | 1568 FrameScope scope(masm, StackFrame::INTERNAL); |
1569 __ Push(edi); | 1569 __ Push(edi); |
1570 __ Push(edx); | 1570 __ Push(edx); |
1571 __ Push(eax); | 1571 __ Push(eax); |
1572 __ CallRuntime(Runtime::kCreateListFromArrayLike, 1); | 1572 __ CallRuntime(Runtime::kCreateListFromArrayLike); |
1573 __ Pop(edx); | 1573 __ Pop(edx); |
1574 __ Pop(edi); | 1574 __ Pop(edi); |
1575 __ mov(ebx, FieldOperand(eax, FixedArray::kLengthOffset)); | 1575 __ mov(ebx, FieldOperand(eax, FixedArray::kLengthOffset)); |
1576 __ SmiUntag(ebx); | 1576 __ SmiUntag(ebx); |
1577 } | 1577 } |
1578 __ jmp(&done_create); | 1578 __ jmp(&done_create); |
1579 | 1579 |
1580 // Try to create the list from an arguments object. | 1580 // Try to create the list from an arguments object. |
1581 __ bind(&create_arguments); | 1581 __ bind(&create_arguments); |
1582 __ mov(ebx, | 1582 __ mov(ebx, |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1616 ExternalReference::address_of_real_stack_limit(masm->isolate()); | 1616 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
1617 __ mov(ecx, Operand::StaticVariable(real_stack_limit)); | 1617 __ mov(ecx, Operand::StaticVariable(real_stack_limit)); |
1618 // Make ecx the space we have left. The stack might already be overflowed | 1618 // Make ecx the space we have left. The stack might already be overflowed |
1619 // here which will cause ecx to become negative. | 1619 // here which will cause ecx to become negative. |
1620 __ neg(ecx); | 1620 __ neg(ecx); |
1621 __ add(ecx, esp); | 1621 __ add(ecx, esp); |
1622 __ sar(ecx, kPointerSizeLog2); | 1622 __ sar(ecx, kPointerSizeLog2); |
1623 // Check if the arguments will overflow the stack. | 1623 // Check if the arguments will overflow the stack. |
1624 __ cmp(ecx, ebx); | 1624 __ cmp(ecx, ebx); |
1625 __ j(greater, &done, Label::kNear); // Signed comparison. | 1625 __ j(greater, &done, Label::kNear); // Signed comparison. |
1626 __ TailCallRuntime(Runtime::kThrowStackOverflow, 1); | 1626 __ TailCallRuntime(Runtime::kThrowStackOverflow); |
1627 __ bind(&done); | 1627 __ bind(&done); |
1628 } | 1628 } |
1629 | 1629 |
1630 // ----------- S t a t e ------------- | 1630 // ----------- S t a t e ------------- |
1631 // -- edi : target | 1631 // -- edi : target |
1632 // -- eax : args (a FixedArray built from argumentsList) | 1632 // -- eax : args (a FixedArray built from argumentsList) |
1633 // -- ebx : len (number of elements to push from args) | 1633 // -- ebx : len (number of elements to push from args) |
1634 // -- edx : new.target (checked to be constructor or undefined) | 1634 // -- edx : new.target (checked to be constructor or undefined) |
1635 // -- esp[0] : return address. | 1635 // -- esp[0] : return address. |
1636 // -- esp[4] : thisArgument | 1636 // -- esp[4] : thisArgument |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1767 __ SmiUntag(ebx); | 1767 __ SmiUntag(ebx); |
1768 ParameterCount actual(eax); | 1768 ParameterCount actual(eax); |
1769 ParameterCount expected(ebx); | 1769 ParameterCount expected(ebx); |
1770 __ InvokeFunctionCode(edi, no_reg, expected, actual, JUMP_FUNCTION, | 1770 __ InvokeFunctionCode(edi, no_reg, expected, actual, JUMP_FUNCTION, |
1771 CheckDebugStepCallWrapper()); | 1771 CheckDebugStepCallWrapper()); |
1772 // The function is a "classConstructor", need to raise an exception. | 1772 // The function is a "classConstructor", need to raise an exception. |
1773 __ bind(&class_constructor); | 1773 __ bind(&class_constructor); |
1774 { | 1774 { |
1775 FrameScope frame(masm, StackFrame::INTERNAL); | 1775 FrameScope frame(masm, StackFrame::INTERNAL); |
1776 __ push(edi); | 1776 __ push(edi); |
1777 __ CallRuntime(Runtime::kThrowConstructorNonCallableError, 1); | 1777 __ CallRuntime(Runtime::kThrowConstructorNonCallableError); |
1778 } | 1778 } |
1779 } | 1779 } |
1780 | 1780 |
1781 | 1781 |
1782 namespace { | 1782 namespace { |
1783 | 1783 |
1784 void Generate_PushBoundArguments(MacroAssembler* masm) { | 1784 void Generate_PushBoundArguments(MacroAssembler* masm) { |
1785 // ----------- S t a t e ------------- | 1785 // ----------- S t a t e ------------- |
1786 // -- eax : the number of arguments (not including the receiver) | 1786 // -- eax : the number of arguments (not including the receiver) |
1787 // -- edx : new.target (only in case of [[Construct]]) | 1787 // -- edx : new.target (only in case of [[Construct]]) |
(...skipping 24 matching lines...) Expand all Loading... |
1812 // Check the stack for overflow. We are not trying to catch interruptions | 1812 // Check the stack for overflow. We are not trying to catch interruptions |
1813 // (i.e. debug break and preemption) here, so check the "real stack | 1813 // (i.e. debug break and preemption) here, so check the "real stack |
1814 // limit". | 1814 // limit". |
1815 __ CompareRoot(esp, ecx, Heap::kRealStackLimitRootIndex); | 1815 __ CompareRoot(esp, ecx, Heap::kRealStackLimitRootIndex); |
1816 __ j(greater, &done, Label::kNear); // Signed comparison. | 1816 __ j(greater, &done, Label::kNear); // Signed comparison. |
1817 // Restore the stack pointer. | 1817 // Restore the stack pointer. |
1818 __ lea(esp, Operand(esp, ebx, times_pointer_size, 0)); | 1818 __ lea(esp, Operand(esp, ebx, times_pointer_size, 0)); |
1819 { | 1819 { |
1820 FrameScope scope(masm, StackFrame::MANUAL); | 1820 FrameScope scope(masm, StackFrame::MANUAL); |
1821 __ EnterFrame(StackFrame::INTERNAL); | 1821 __ EnterFrame(StackFrame::INTERNAL); |
1822 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 1822 __ CallRuntime(Runtime::kThrowStackOverflow); |
1823 } | 1823 } |
1824 __ bind(&done); | 1824 __ bind(&done); |
1825 } | 1825 } |
1826 | 1826 |
1827 // Adjust effective number of arguments to include return address. | 1827 // Adjust effective number of arguments to include return address. |
1828 __ inc(eax); | 1828 __ inc(eax); |
1829 | 1829 |
1830 // Relocate arguments and return address down the stack. | 1830 // Relocate arguments and return address down the stack. |
1831 { | 1831 { |
1832 Label loop; | 1832 Label loop; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1932 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, edi); | 1932 __ LoadGlobalFunction(Context::CALL_AS_FUNCTION_DELEGATE_INDEX, edi); |
1933 __ Jump(masm->isolate()->builtins()->CallFunction( | 1933 __ Jump(masm->isolate()->builtins()->CallFunction( |
1934 ConvertReceiverMode::kNotNullOrUndefined), | 1934 ConvertReceiverMode::kNotNullOrUndefined), |
1935 RelocInfo::CODE_TARGET); | 1935 RelocInfo::CODE_TARGET); |
1936 | 1936 |
1937 // 3. Call to something that is not callable. | 1937 // 3. Call to something that is not callable. |
1938 __ bind(&non_callable); | 1938 __ bind(&non_callable); |
1939 { | 1939 { |
1940 FrameScope scope(masm, StackFrame::INTERNAL); | 1940 FrameScope scope(masm, StackFrame::INTERNAL); |
1941 __ Push(edi); | 1941 __ Push(edi); |
1942 __ CallRuntime(Runtime::kThrowCalledNonCallable, 1); | 1942 __ CallRuntime(Runtime::kThrowCalledNonCallable); |
1943 } | 1943 } |
1944 } | 1944 } |
1945 | 1945 |
1946 | 1946 |
1947 // static | 1947 // static |
1948 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { | 1948 void Builtins::Generate_ConstructFunction(MacroAssembler* masm) { |
1949 // ----------- S t a t e ------------- | 1949 // ----------- S t a t e ------------- |
1950 // -- eax : the number of arguments (not including the receiver) | 1950 // -- eax : the number of arguments (not including the receiver) |
1951 // -- edx : the new target (checked to be a constructor) | 1951 // -- edx : the new target (checked to be a constructor) |
1952 // -- edi : the constructor to call (checked to be a JSFunction) | 1952 // -- edi : the constructor to call (checked to be a JSFunction) |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2119 | 2119 |
2120 // What we really care about is the required number of arguments. | 2120 // What we really care about is the required number of arguments. |
2121 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kLengthOffset)); | 2121 __ mov(ecx, FieldOperand(ecx, SharedFunctionInfo::kLengthOffset)); |
2122 __ SmiUntag(ecx); | 2122 __ SmiUntag(ecx); |
2123 __ cmp(eax, ecx); | 2123 __ cmp(eax, ecx); |
2124 __ j(greater_equal, &no_strong_error, Label::kNear); | 2124 __ j(greater_equal, &no_strong_error, Label::kNear); |
2125 | 2125 |
2126 { | 2126 { |
2127 FrameScope frame(masm, StackFrame::MANUAL); | 2127 FrameScope frame(masm, StackFrame::MANUAL); |
2128 EnterArgumentsAdaptorFrame(masm); | 2128 EnterArgumentsAdaptorFrame(masm); |
2129 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments, 0); | 2129 __ CallRuntime(Runtime::kThrowStrongModeTooFewArguments); |
2130 } | 2130 } |
2131 | 2131 |
2132 __ bind(&no_strong_error); | 2132 __ bind(&no_strong_error); |
2133 EnterArgumentsAdaptorFrame(masm); | 2133 EnterArgumentsAdaptorFrame(masm); |
2134 ArgumentsAdaptorStackCheck(masm, &stack_overflow); | 2134 ArgumentsAdaptorStackCheck(masm, &stack_overflow); |
2135 | 2135 |
2136 // Remember expected arguments in ecx. | 2136 // Remember expected arguments in ecx. |
2137 __ mov(ecx, ebx); | 2137 __ mov(ecx, ebx); |
2138 | 2138 |
2139 // Copy receiver and all actual arguments. | 2139 // Copy receiver and all actual arguments. |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2185 // ------------------------------------------- | 2185 // ------------------------------------------- |
2186 // Dont adapt arguments. | 2186 // Dont adapt arguments. |
2187 // ------------------------------------------- | 2187 // ------------------------------------------- |
2188 __ bind(&dont_adapt_arguments); | 2188 __ bind(&dont_adapt_arguments); |
2189 __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 2189 __ mov(ecx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
2190 __ jmp(ecx); | 2190 __ jmp(ecx); |
2191 | 2191 |
2192 __ bind(&stack_overflow); | 2192 __ bind(&stack_overflow); |
2193 { | 2193 { |
2194 FrameScope frame(masm, StackFrame::MANUAL); | 2194 FrameScope frame(masm, StackFrame::MANUAL); |
2195 __ CallRuntime(Runtime::kThrowStackOverflow, 0); | 2195 __ CallRuntime(Runtime::kThrowStackOverflow); |
2196 __ int3(); | 2196 __ int3(); |
2197 } | 2197 } |
2198 } | 2198 } |
2199 | 2199 |
2200 | 2200 |
2201 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, | 2201 static void CompatibleReceiverCheck(MacroAssembler* masm, Register receiver, |
2202 Register function_template_info, | 2202 Register function_template_info, |
2203 Register scratch0, Register scratch1, | 2203 Register scratch0, Register scratch1, |
2204 Label* receiver_check_failed) { | 2204 Label* receiver_check_failed) { |
2205 // If receiver is not an object, jump to receiver_check_failed. | 2205 // If receiver is not an object, jump to receiver_check_failed. |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2314 // Compatible receiver check failed: pop return address, arguments and | 2314 // Compatible receiver check failed: pop return address, arguments and |
2315 // receiver and throw an Illegal Invocation exception. | 2315 // receiver and throw an Illegal Invocation exception. |
2316 __ bind(&receiver_check_failed); | 2316 __ bind(&receiver_check_failed); |
2317 __ Pop(eax); | 2317 __ Pop(eax); |
2318 __ PopReturnAddressTo(ebx); | 2318 __ PopReturnAddressTo(ebx); |
2319 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); | 2319 __ lea(eax, Operand(eax, times_pointer_size, 1 * kPointerSize)); |
2320 __ add(esp, eax); | 2320 __ add(esp, eax); |
2321 __ PushReturnAddressFrom(ebx); | 2321 __ PushReturnAddressFrom(ebx); |
2322 { | 2322 { |
2323 FrameScope scope(masm, StackFrame::INTERNAL); | 2323 FrameScope scope(masm, StackFrame::INTERNAL); |
2324 __ TailCallRuntime(Runtime::kThrowIllegalInvocation, 0); | 2324 __ TailCallRuntime(Runtime::kThrowIllegalInvocation); |
2325 } | 2325 } |
2326 } | 2326 } |
2327 | 2327 |
2328 | 2328 |
2329 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 2329 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
2330 // Lookup the function in the JavaScript frame. | 2330 // Lookup the function in the JavaScript frame. |
2331 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); | 2331 __ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset)); |
2332 { | 2332 { |
2333 FrameScope scope(masm, StackFrame::INTERNAL); | 2333 FrameScope scope(masm, StackFrame::INTERNAL); |
2334 // Pass function as argument. | 2334 // Pass function as argument. |
2335 __ push(eax); | 2335 __ push(eax); |
2336 __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1); | 2336 __ CallRuntime(Runtime::kCompileForOnStackReplacement); |
2337 } | 2337 } |
2338 | 2338 |
2339 Label skip; | 2339 Label skip; |
2340 // If the code object is null, just return to the unoptimized code. | 2340 // If the code object is null, just return to the unoptimized code. |
2341 __ cmp(eax, Immediate(0)); | 2341 __ cmp(eax, Immediate(0)); |
2342 __ j(not_equal, &skip, Label::kNear); | 2342 __ j(not_equal, &skip, Label::kNear); |
2343 __ ret(0); | 2343 __ ret(0); |
2344 | 2344 |
2345 __ bind(&skip); | 2345 __ bind(&skip); |
2346 | 2346 |
(...skipping 18 matching lines...) Expand all Loading... |
2365 | 2365 |
2366 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { | 2366 void Builtins::Generate_OsrAfterStackCheck(MacroAssembler* masm) { |
2367 // We check the stack limit as indicator that recompilation might be done. | 2367 // We check the stack limit as indicator that recompilation might be done. |
2368 Label ok; | 2368 Label ok; |
2369 ExternalReference stack_limit = | 2369 ExternalReference stack_limit = |
2370 ExternalReference::address_of_stack_limit(masm->isolate()); | 2370 ExternalReference::address_of_stack_limit(masm->isolate()); |
2371 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 2371 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
2372 __ j(above_equal, &ok, Label::kNear); | 2372 __ j(above_equal, &ok, Label::kNear); |
2373 { | 2373 { |
2374 FrameScope scope(masm, StackFrame::INTERNAL); | 2374 FrameScope scope(masm, StackFrame::INTERNAL); |
2375 __ CallRuntime(Runtime::kStackGuard, 0); | 2375 __ CallRuntime(Runtime::kStackGuard); |
2376 } | 2376 } |
2377 __ jmp(masm->isolate()->builtins()->OnStackReplacement(), | 2377 __ jmp(masm->isolate()->builtins()->OnStackReplacement(), |
2378 RelocInfo::CODE_TARGET); | 2378 RelocInfo::CODE_TARGET); |
2379 | 2379 |
2380 __ bind(&ok); | 2380 __ bind(&ok); |
2381 __ ret(0); | 2381 __ ret(0); |
2382 } | 2382 } |
2383 | 2383 |
2384 #undef __ | 2384 #undef __ |
2385 } // namespace internal | 2385 } // namespace internal |
2386 } // namespace v8 | 2386 } // namespace v8 |
2387 | 2387 |
2388 #endif // V8_TARGET_ARCH_X87 | 2388 #endif // V8_TARGET_ARCH_X87 |
OLD | NEW |