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