OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
63 __ pop(scratch); // Save return address. | 63 __ pop(scratch); // Save return address. |
64 __ push(edi); | 64 __ push(edi); |
65 __ push(scratch); // Restore return address. | 65 __ push(scratch); // Restore return address. |
66 } else { | 66 } else { |
67 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); | 67 ASSERT(extra_args == NO_EXTRA_ARGUMENTS); |
68 } | 68 } |
69 | 69 |
70 // JumpToExternalReference expects eax to contain the number of arguments | 70 // JumpToExternalReference expects eax to contain the number of arguments |
71 // including the receiver and the extra arguments. | 71 // including the receiver and the extra arguments. |
72 __ add(Operand(eax), Immediate(num_extra_args + 1)); | 72 __ add(Operand(eax), Immediate(num_extra_args + 1)); |
73 __ JumpToExternalReference(ExternalReference(id)); | 73 __ JumpToExternalReference(ExternalReference(id, masm->isolate())); |
74 } | 74 } |
75 | 75 |
76 | 76 |
77 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { | 77 void Builtins::Generate_JSConstructCall(MacroAssembler* masm) { |
78 // ----------- S t a t e ------------- | 78 // ----------- S t a t e ------------- |
79 // -- eax: number of arguments | 79 // -- eax: number of arguments |
80 // -- edi: constructor function | 80 // -- edi: constructor function |
81 // ----------------------------------- | 81 // ----------------------------------- |
82 | 82 |
83 Label non_function_call; | 83 Label non_function_call; |
84 // Check that function is not a smi. | 84 // Check that function is not a smi. |
85 __ test(edi, Immediate(kSmiTagMask)); | 85 __ test(edi, Immediate(kSmiTagMask)); |
86 __ j(zero, &non_function_call); | 86 __ j(zero, &non_function_call); |
87 // Check that function is a JSFunction. | 87 // Check that function is a JSFunction. |
88 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); | 88 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); |
89 __ j(not_equal, &non_function_call); | 89 __ j(not_equal, &non_function_call); |
90 | 90 |
91 // Jump to the function-specific construct stub. | 91 // Jump to the function-specific construct stub. |
92 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 92 __ mov(ebx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
93 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kConstructStubOffset)); | 93 __ mov(ebx, FieldOperand(ebx, SharedFunctionInfo::kConstructStubOffset)); |
94 __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize)); | 94 __ lea(ebx, FieldOperand(ebx, Code::kHeaderSize)); |
95 __ jmp(Operand(ebx)); | 95 __ jmp(Operand(ebx)); |
96 | 96 |
97 // edi: called object | 97 // edi: called object |
98 // eax: number of arguments | 98 // eax: number of arguments |
99 __ bind(&non_function_call); | 99 __ bind(&non_function_call); |
100 // Set expected number of arguments to zero (not changing eax). | 100 // Set expected number of arguments to zero (not changing eax). |
101 __ Set(ebx, Immediate(0)); | 101 __ Set(ebx, Immediate(0)); |
102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); | 102 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR); |
103 __ jmp(Handle<Code>(Isolate::Current()->builtins()->builtin( | 103 __ jmp(Handle<Code>(masm->isolate()->builtins()->builtin( |
104 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET); | 104 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET); |
105 } | 105 } |
106 | 106 |
107 | 107 |
108 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 108 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
109 bool is_api_function, | 109 bool is_api_function, |
110 bool count_constructions) { | 110 bool count_constructions) { |
111 // Should never count constructions for api objects. | 111 // Should never count constructions for api objects. |
112 ASSERT(!is_api_function || !count_constructions); | 112 ASSERT(!is_api_function || !count_constructions); |
113 | 113 |
114 // Enter a construct frame. | 114 // Enter a construct frame. |
115 __ EnterConstructFrame(); | 115 __ EnterConstructFrame(); |
116 | 116 |
117 // Store a smi-tagged arguments count on the stack. | 117 // Store a smi-tagged arguments count on the stack. |
118 __ SmiTag(eax); | 118 __ SmiTag(eax); |
119 __ push(eax); | 119 __ push(eax); |
120 | 120 |
121 // Push the function to invoke on the stack. | 121 // Push the function to invoke on the stack. |
122 __ push(edi); | 122 __ push(edi); |
123 | 123 |
124 // Try to allocate the object without transitioning into C code. If any of the | 124 // Try to allocate the object without transitioning into C code. If any of the |
125 // preconditions is not met, the code bails out to the runtime call. | 125 // preconditions is not met, the code bails out to the runtime call. |
126 Label rt_call, allocated; | 126 Label rt_call, allocated; |
127 if (FLAG_inline_new) { | 127 if (FLAG_inline_new) { |
128 Label undo_allocation; | 128 Label undo_allocation; |
129 #ifdef ENABLE_DEBUGGER_SUPPORT | 129 #ifdef ENABLE_DEBUGGER_SUPPORT |
130 ExternalReference debug_step_in_fp = | 130 ExternalReference debug_step_in_fp = |
131 ExternalReference::debug_step_in_fp_address(); | 131 ExternalReference::debug_step_in_fp_address(masm->isolate()); |
132 __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0)); | 132 __ cmp(Operand::StaticVariable(debug_step_in_fp), Immediate(0)); |
133 __ j(not_equal, &rt_call); | 133 __ j(not_equal, &rt_call); |
134 #endif | 134 #endif |
135 | 135 |
136 // Verified that the constructor is a JSFunction. | 136 // Verified that the constructor is a JSFunction. |
137 // Load the initial map and verify that it is in fact a map. | 137 // Load the initial map and verify that it is in fact a map. |
138 // edi: constructor | 138 // edi: constructor |
139 __ mov(eax, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); | 139 __ mov(eax, FieldOperand(edi, JSFunction::kPrototypeOrInitialMapOffset)); |
140 // Will both indicate a NULL and a Smi | 140 // Will both indicate a NULL and a Smi |
141 __ test(eax, Immediate(kSmiTagMask)); | 141 __ test(eax, Immediate(kSmiTagMask)); |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 __ bind(&loop); | 328 __ bind(&loop); |
329 __ push(Operand(ebx, ecx, times_4, 0)); | 329 __ push(Operand(ebx, ecx, times_4, 0)); |
330 __ bind(&entry); | 330 __ bind(&entry); |
331 __ dec(ecx); | 331 __ dec(ecx); |
332 __ j(greater_equal, &loop); | 332 __ j(greater_equal, &loop); |
333 | 333 |
334 // Call the function. | 334 // Call the function. |
335 if (is_api_function) { | 335 if (is_api_function) { |
336 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); | 336 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); |
337 Handle<Code> code = Handle<Code>( | 337 Handle<Code> code = Handle<Code>( |
338 Isolate::Current()->builtins()->builtin( | 338 masm->isolate()->builtins()->builtin(Builtins::HandleApiCallConstruct)); |
339 Builtins::HandleApiCallConstruct)); | |
340 ParameterCount expected(0); | 339 ParameterCount expected(0); |
341 __ InvokeCode(code, expected, expected, | 340 __ InvokeCode(code, expected, expected, |
342 RelocInfo::CODE_TARGET, CALL_FUNCTION); | 341 RelocInfo::CODE_TARGET, CALL_FUNCTION); |
343 } else { | 342 } else { |
344 ParameterCount actual(eax); | 343 ParameterCount actual(eax); |
345 __ InvokeFunction(edi, actual, CALL_FUNCTION); | 344 __ InvokeFunction(edi, actual, CALL_FUNCTION); |
346 } | 345 } |
347 | 346 |
348 // Restore context from the frame. | 347 // Restore context from the frame. |
349 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 348 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
430 __ inc(Operand(ecx)); | 429 __ inc(Operand(ecx)); |
431 __ bind(&entry); | 430 __ bind(&entry); |
432 __ cmp(ecx, Operand(eax)); | 431 __ cmp(ecx, Operand(eax)); |
433 __ j(not_equal, &loop); | 432 __ j(not_equal, &loop); |
434 | 433 |
435 // Get the function from the stack and call it. | 434 // Get the function from the stack and call it. |
436 __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver | 435 __ mov(edi, Operand(esp, eax, times_4, +1 * kPointerSize)); // +1 ~ receiver |
437 | 436 |
438 // Invoke the code. | 437 // Invoke the code. |
439 if (is_construct) { | 438 if (is_construct) { |
440 __ call(Handle<Code>(Isolate::Current()->builtins()->builtin( | 439 __ call(Handle<Code>(masm->isolate()->builtins()->builtin( |
441 Builtins::JSConstructCall)), RelocInfo::CODE_TARGET); | 440 Builtins::JSConstructCall)), RelocInfo::CODE_TARGET); |
442 } else { | 441 } else { |
443 ParameterCount actual(eax); | 442 ParameterCount actual(eax); |
444 __ InvokeFunction(edi, actual, CALL_FUNCTION); | 443 __ InvokeFunction(edi, actual, CALL_FUNCTION); |
445 } | 444 } |
446 | 445 |
447 // Exit the JS frame. Notice that this also removes the empty | 446 // Exit the JS frame. Notice that this also removes the empty |
448 // context and the function left on the stack by the code | 447 // context and the function left on the stack by the code |
449 // invocation. | 448 // invocation. |
450 __ LeaveInternalFrame(); | 449 __ LeaveInternalFrame(); |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
668 __ pop(ebx); // Discard copy of return address. | 667 __ pop(ebx); // Discard copy of return address. |
669 __ dec(eax); // One fewer argument (first argument is new receiver). | 668 __ dec(eax); // One fewer argument (first argument is new receiver). |
670 } | 669 } |
671 | 670 |
672 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. | 671 // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. |
673 { Label function; | 672 { Label function; |
674 __ test(edi, Operand(edi)); | 673 __ test(edi, Operand(edi)); |
675 __ j(not_zero, &function, taken); | 674 __ j(not_zero, &function, taken); |
676 __ Set(ebx, Immediate(0)); | 675 __ Set(ebx, Immediate(0)); |
677 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); | 676 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); |
678 __ jmp(Handle<Code>(Isolate::Current()->builtins()->builtin( | 677 __ jmp(Handle<Code>(masm->isolate()->builtins()->builtin( |
679 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET); | 678 ArgumentsAdaptorTrampoline)), RelocInfo::CODE_TARGET); |
680 __ bind(&function); | 679 __ bind(&function); |
681 } | 680 } |
682 | 681 |
683 // 5b. Get the code to call from the function and check that the number of | 682 // 5b. Get the code to call from the function and check that the number of |
684 // expected arguments matches what we're providing. If so, jump | 683 // expected arguments matches what we're providing. If so, jump |
685 // (tail-call) to the code in register edx without checking arguments. | 684 // (tail-call) to the code in register edx without checking arguments. |
686 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); | 685 __ mov(edx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); |
687 __ mov(ebx, | 686 __ mov(ebx, |
688 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); | 687 FieldOperand(edx, SharedFunctionInfo::kFormalParameterCountOffset)); |
689 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); | 688 __ mov(edx, FieldOperand(edi, JSFunction::kCodeEntryOffset)); |
690 __ SmiUntag(ebx); | 689 __ SmiUntag(ebx); |
691 __ cmp(eax, Operand(ebx)); | 690 __ cmp(eax, Operand(ebx)); |
692 __ j(not_equal, Handle<Code>(Isolate::Current()->builtins()->builtin( | 691 __ j(not_equal, Handle<Code>(masm->isolate()->builtins()->builtin( |
693 ArgumentsAdaptorTrampoline))); | 692 ArgumentsAdaptorTrampoline))); |
694 | 693 |
695 ParameterCount expected(0); | 694 ParameterCount expected(0); |
696 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); | 695 __ InvokeCode(Operand(edx), expected, expected, JUMP_FUNCTION); |
697 } | 696 } |
698 | 697 |
699 | 698 |
700 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { | 699 void Builtins::Generate_FunctionApply(MacroAssembler* masm) { |
701 __ EnterInternalFrame(); | 700 __ EnterInternalFrame(); |
702 | 701 |
703 __ push(Operand(ebp, 4 * kPointerSize)); // push this | 702 __ push(Operand(ebp, 4 * kPointerSize)); // push this |
704 __ push(Operand(ebp, 2 * kPointerSize)); // push arguments | 703 __ push(Operand(ebp, 2 * kPointerSize)); // push arguments |
705 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); | 704 __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); |
706 | 705 |
707 // Check the stack for overflow. We are not trying need to catch | 706 // Check the stack for overflow. We are not trying need to catch |
708 // interruptions (e.g. debug break and preemption) here, so the "real stack | 707 // interruptions (e.g. debug break and preemption) here, so the "real stack |
709 // limit" is checked. | 708 // limit" is checked. |
710 Label okay; | 709 Label okay; |
711 ExternalReference real_stack_limit = | 710 ExternalReference real_stack_limit = |
712 ExternalReference::address_of_real_stack_limit(); | 711 ExternalReference::address_of_real_stack_limit(masm->isolate()); |
713 __ mov(edi, Operand::StaticVariable(real_stack_limit)); | 712 __ mov(edi, Operand::StaticVariable(real_stack_limit)); |
714 // Make ecx the space we have left. The stack might already be overflowed | 713 // Make ecx the space we have left. The stack might already be overflowed |
715 // here which will cause ecx to become negative. | 714 // here which will cause ecx to become negative. |
716 __ mov(ecx, Operand(esp)); | 715 __ mov(ecx, Operand(esp)); |
717 __ sub(ecx, Operand(edi)); | 716 __ sub(ecx, Operand(edi)); |
718 // Make edx the space we need for the array when it is unrolled onto the | 717 // Make edx the space we need for the array when it is unrolled onto the |
719 // stack. | 718 // stack. |
720 __ mov(edx, Operand(eax)); | 719 __ mov(edx, Operand(eax)); |
721 __ shl(edx, kPointerSizeLog2 - kSmiTagSize); | 720 __ shl(edx, kPointerSizeLog2 - kSmiTagSize); |
722 // Check if the arguments will overflow the stack. | 721 // Check if the arguments will overflow the stack. |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
790 __ push(ebx); | 789 __ push(ebx); |
791 | 790 |
792 // Copy all arguments from the array to the stack. | 791 // Copy all arguments from the array to the stack. |
793 Label entry, loop; | 792 Label entry, loop; |
794 __ mov(eax, Operand(ebp, kIndexOffset)); | 793 __ mov(eax, Operand(ebp, kIndexOffset)); |
795 __ jmp(&entry); | 794 __ jmp(&entry); |
796 __ bind(&loop); | 795 __ bind(&loop); |
797 __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments | 796 __ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments |
798 | 797 |
799 // Use inline caching to speed up access to arguments. | 798 // Use inline caching to speed up access to arguments. |
800 Handle<Code> ic(Isolate::Current()->builtins()->builtin( | 799 Handle<Code> ic(masm->isolate()->builtins()->builtin( |
801 Builtins::KeyedLoadIC_Initialize)); | 800 Builtins::KeyedLoadIC_Initialize)); |
802 __ call(ic, RelocInfo::CODE_TARGET); | 801 __ call(ic, RelocInfo::CODE_TARGET); |
803 // It is important that we do not have a test instruction after the | 802 // It is important that we do not have a test instruction after the |
804 // call. A test instruction after the call is used to indicate that | 803 // call. A test instruction after the call is used to indicate that |
805 // we have generated an inline version of the keyed load. In this | 804 // we have generated an inline version of the keyed load. In this |
806 // case, we know that we are not generating a test instruction next. | 805 // case, we know that we are not generating a test instruction next. |
807 | 806 |
808 // Push the nth argument. | 807 // Push the nth argument. |
809 __ push(eax); | 808 __ push(eax); |
810 | 809 |
(...skipping 417 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1228 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1227 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
1229 __ Assert(equal, "Unexpected initial map for Array function"); | 1228 __ Assert(equal, "Unexpected initial map for Array function"); |
1230 } | 1229 } |
1231 | 1230 |
1232 // Run the native code for the Array function called as a normal function. | 1231 // Run the native code for the Array function called as a normal function. |
1233 ArrayNativeCode(masm, false, &generic_array_code); | 1232 ArrayNativeCode(masm, false, &generic_array_code); |
1234 | 1233 |
1235 // Jump to the generic array code in case the specialized code cannot handle | 1234 // Jump to the generic array code in case the specialized code cannot handle |
1236 // the construction. | 1235 // the construction. |
1237 __ bind(&generic_array_code); | 1236 __ bind(&generic_array_code); |
1238 Code* code = Isolate::Current()->builtins()->builtin( | 1237 Code* code = masm->isolate()->builtins()->builtin(Builtins::ArrayCodeGeneric); |
1239 Builtins::ArrayCodeGeneric); | |
1240 Handle<Code> array_code(code); | 1238 Handle<Code> array_code(code); |
1241 __ jmp(array_code, RelocInfo::CODE_TARGET); | 1239 __ jmp(array_code, RelocInfo::CODE_TARGET); |
1242 } | 1240 } |
1243 | 1241 |
1244 | 1242 |
1245 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { | 1243 void Builtins::Generate_ArrayConstructCode(MacroAssembler* masm) { |
1246 // ----------- S t a t e ------------- | 1244 // ----------- S t a t e ------------- |
1247 // -- eax : argc | 1245 // -- eax : argc |
1248 // -- edi : constructor | 1246 // -- edi : constructor |
1249 // -- esp[0] : return address | 1247 // -- esp[0] : return address |
(...skipping 13 matching lines...) Expand all Loading... |
1263 __ CmpObjectType(ebx, MAP_TYPE, ecx); | 1261 __ CmpObjectType(ebx, MAP_TYPE, ecx); |
1264 __ Assert(equal, "Unexpected initial map for Array function"); | 1262 __ Assert(equal, "Unexpected initial map for Array function"); |
1265 } | 1263 } |
1266 | 1264 |
1267 // Run the native code for the Array function called as constructor. | 1265 // Run the native code for the Array function called as constructor. |
1268 ArrayNativeCode(masm, true, &generic_constructor); | 1266 ArrayNativeCode(masm, true, &generic_constructor); |
1269 | 1267 |
1270 // Jump to the generic construct code in case the specialized code cannot | 1268 // Jump to the generic construct code in case the specialized code cannot |
1271 // handle the construction. | 1269 // handle the construction. |
1272 __ bind(&generic_constructor); | 1270 __ bind(&generic_constructor); |
1273 Code* code = Isolate::Current()->builtins()->builtin( | 1271 Code* code = masm->isolate()->builtins()->builtin( |
1274 Builtins::JSConstructStubGeneric); | 1272 Builtins::JSConstructStubGeneric); |
1275 Handle<Code> generic_construct_stub(code); | 1273 Handle<Code> generic_construct_stub(code); |
1276 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 1274 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
1277 } | 1275 } |
1278 | 1276 |
1279 | 1277 |
1280 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { | 1278 void Builtins::Generate_StringConstructCode(MacroAssembler* masm) { |
1281 // ----------- S t a t e ------------- | 1279 // ----------- S t a t e ------------- |
1282 // -- eax : number of arguments | 1280 // -- eax : number of arguments |
1283 // -- edi : constructor function | 1281 // -- edi : constructor function |
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1513 // ------------------------------------------- | 1511 // ------------------------------------------- |
1514 __ bind(&dont_adapt_arguments); | 1512 __ bind(&dont_adapt_arguments); |
1515 __ jmp(Operand(edx)); | 1513 __ jmp(Operand(edx)); |
1516 } | 1514 } |
1517 | 1515 |
1518 | 1516 |
1519 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { | 1517 void Builtins::Generate_OnStackReplacement(MacroAssembler* masm) { |
1520 // We shouldn't be performing on-stack replacement in the first | 1518 // We shouldn't be performing on-stack replacement in the first |
1521 // place if the CPU features we need for the optimized Crankshaft | 1519 // place if the CPU features we need for the optimized Crankshaft |
1522 // code aren't supported. | 1520 // code aren't supported. |
1523 CpuFeatures* cpu_features = Isolate::Current()->cpu_features(); | 1521 CpuFeatures* cpu_features = masm->isolate()->cpu_features(); |
1524 cpu_features->Probe(false); | 1522 cpu_features->Probe(false); |
1525 if (!cpu_features->IsSupported(SSE2)) { | 1523 if (!cpu_features->IsSupported(SSE2)) { |
1526 __ Abort("Unreachable code: Cannot optimize without SSE2 support."); | 1524 __ Abort("Unreachable code: Cannot optimize without SSE2 support."); |
1527 return; | 1525 return; |
1528 } | 1526 } |
1529 | 1527 |
1530 // Get the loop depth of the stack guard check. This is recorded in | 1528 // Get the loop depth of the stack guard check. This is recorded in |
1531 // a test(eax, depth) instruction right after the call. | 1529 // a test(eax, depth) instruction right after the call. |
1532 Label stack_check; | 1530 Label stack_check; |
1533 __ mov(ebx, Operand(esp, 0)); // return address | 1531 __ mov(ebx, Operand(esp, 0)); // return address |
(...skipping 25 matching lines...) Expand all Loading... |
1559 NearLabel skip; | 1557 NearLabel skip; |
1560 __ cmp(Operand(eax), Immediate(Smi::FromInt(-1))); | 1558 __ cmp(Operand(eax), Immediate(Smi::FromInt(-1))); |
1561 __ j(not_equal, &skip); | 1559 __ j(not_equal, &skip); |
1562 __ ret(0); | 1560 __ ret(0); |
1563 | 1561 |
1564 // If we decide not to perform on-stack replacement we perform a | 1562 // If we decide not to perform on-stack replacement we perform a |
1565 // stack guard check to enable interrupts. | 1563 // stack guard check to enable interrupts. |
1566 __ bind(&stack_check); | 1564 __ bind(&stack_check); |
1567 NearLabel ok; | 1565 NearLabel ok; |
1568 ExternalReference stack_limit = | 1566 ExternalReference stack_limit = |
1569 ExternalReference::address_of_stack_limit(); | 1567 ExternalReference::address_of_stack_limit(masm->isolate()); |
1570 __ cmp(esp, Operand::StaticVariable(stack_limit)); | 1568 __ cmp(esp, Operand::StaticVariable(stack_limit)); |
1571 __ j(above_equal, &ok, taken); | 1569 __ j(above_equal, &ok, taken); |
1572 StackCheckStub stub; | 1570 StackCheckStub stub; |
1573 __ TailCallStub(&stub); | 1571 __ TailCallStub(&stub); |
1574 __ Abort("Unreachable code: returned from tail call."); | 1572 __ Abort("Unreachable code: returned from tail call."); |
1575 __ bind(&ok); | 1573 __ bind(&ok); |
1576 __ ret(0); | 1574 __ ret(0); |
1577 | 1575 |
1578 __ bind(&skip); | 1576 __ bind(&skip); |
1579 // Untag the AST id and push it on the stack. | 1577 // Untag the AST id and push it on the stack. |
1580 __ SmiUntag(eax); | 1578 __ SmiUntag(eax); |
1581 __ push(eax); | 1579 __ push(eax); |
1582 | 1580 |
1583 // Generate the code for doing the frame-to-frame translation using | 1581 // Generate the code for doing the frame-to-frame translation using |
1584 // the deoptimizer infrastructure. | 1582 // the deoptimizer infrastructure. |
1585 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); | 1583 Deoptimizer::EntryGenerator generator(masm, Deoptimizer::OSR); |
1586 generator.Generate(); | 1584 generator.Generate(); |
1587 } | 1585 } |
1588 | 1586 |
1589 | 1587 |
1590 #undef __ | 1588 #undef __ |
1591 | 1589 |
1592 } } // namespace v8::internal | 1590 } } // namespace v8::internal |
1593 | 1591 |
1594 #endif // V8_TARGET_ARCH_IA32 | 1592 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |