| 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_IA32 |     5 #if V8_TARGET_ARCH_IA32 | 
|     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 121 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   132   { |   132   { | 
|   133     FrameScope scope(masm, StackFrame::CONSTRUCT); |   133     FrameScope scope(masm, StackFrame::CONSTRUCT); | 
|   134  |   134  | 
|   135     // Preserve the incoming parameters on the stack. |   135     // Preserve the incoming parameters on the stack. | 
|   136     __ AssertUndefinedOrAllocationSite(ebx); |   136     __ AssertUndefinedOrAllocationSite(ebx); | 
|   137     __ push(ebx); |   137     __ push(ebx); | 
|   138     __ SmiTag(eax); |   138     __ SmiTag(eax); | 
|   139     __ push(eax); |   139     __ push(eax); | 
|   140  |   140  | 
|   141     if (create_implicit_receiver) { |   141     if (create_implicit_receiver) { | 
|   142       __ push(edi); |   142       // Allocate the new receiver object. | 
|   143       __ push(edx); |   143       __ Push(edi); | 
 |   144       __ Push(edx); | 
 |   145       FastNewObjectStub stub(masm->isolate()); | 
 |   146       __ CallStub(&stub); | 
 |   147       __ mov(ebx, eax); | 
 |   148       __ Pop(edx); | 
 |   149       __ Pop(edi); | 
|   144  |   150  | 
|   145       // Try to allocate the object without transitioning into C code. If any of |   151       // ----------- S t a t e ------------- | 
|   146       // the preconditions is not met, the code bails out to the runtime call. |   152       //  -- edi: constructor function | 
|   147       Label rt_call, allocated; |   153       //  -- ebx: newly allocated object | 
|   148       if (FLAG_inline_new) { |   154       //  -- edx: new target | 
|   149         // Verify that the new target is a JSFunction. |   155       // ----------------------------------- | 
|   150         __ CmpObjectType(edx, JS_FUNCTION_TYPE, ebx); |  | 
|   151         __ j(not_equal, &rt_call); |  | 
|   152  |  | 
|   153         // Load the initial map and verify that it is in fact a map. |  | 
|   154         // edx: new target |  | 
|   155         __ mov(eax, |  | 
|   156                FieldOperand(edx, JSFunction::kPrototypeOrInitialMapOffset)); |  | 
|   157         // Will both indicate a NULL and a Smi |  | 
|   158         __ JumpIfSmi(eax, &rt_call); |  | 
|   159         // edi: constructor |  | 
|   160         // eax: initial map (if proven valid below) |  | 
|   161         __ CmpObjectType(eax, MAP_TYPE, ebx); |  | 
|   162         __ j(not_equal, &rt_call); |  | 
|   163  |  | 
|   164         // Fall back to runtime if the expected base constructor and base |  | 
|   165         // constructor differ. |  | 
|   166         __ cmp(edi, FieldOperand(eax, Map::kConstructorOrBackPointerOffset)); |  | 
|   167         __ j(not_equal, &rt_call); |  | 
|   168  |  | 
|   169         // Check that the constructor is not constructing a JSFunction (see |  | 
|   170         // comments in Runtime_NewObject in runtime.cc). In which case the |  | 
|   171         // initial map's instance type would be JS_FUNCTION_TYPE. |  | 
|   172         // edi: constructor |  | 
|   173         // eax: initial map |  | 
|   174         __ CmpInstanceType(eax, JS_FUNCTION_TYPE); |  | 
|   175         __ j(equal, &rt_call); |  | 
|   176  |  | 
|   177         // Now allocate the JSObject on the heap. |  | 
|   178         // edi: constructor |  | 
|   179         // eax: initial map |  | 
|   180         __ movzx_b(edi, FieldOperand(eax, Map::kInstanceSizeOffset)); |  | 
|   181         __ shl(edi, kPointerSizeLog2); |  | 
|   182  |  | 
|   183         __ Allocate(edi, ebx, edi, no_reg, &rt_call, NO_ALLOCATION_FLAGS); |  | 
|   184  |  | 
|   185         Factory* factory = masm->isolate()->factory(); |  | 
|   186  |  | 
|   187         // Allocated the JSObject, now initialize the fields. |  | 
|   188         // eax: initial map |  | 
|   189         // ebx: JSObject (not HeapObject tagged - the actual address). |  | 
|   190         // edi: start of next object |  | 
|   191         __ mov(Operand(ebx, JSObject::kMapOffset), eax); |  | 
|   192         __ mov(ecx, factory->empty_fixed_array()); |  | 
|   193         __ mov(Operand(ebx, JSObject::kPropertiesOffset), ecx); |  | 
|   194         __ mov(Operand(ebx, JSObject::kElementsOffset), ecx); |  | 
|   195         __ lea(ecx, Operand(ebx, JSObject::kHeaderSize)); |  | 
|   196  |  | 
|   197         // Add the object tag to make the JSObject real, so that we can continue |  | 
|   198         // and jump into the continuation code at any time from now on. |  | 
|   199         __ or_(ebx, Immediate(kHeapObjectTag)); |  | 
|   200  |  | 
|   201         // Fill all the in-object properties with the appropriate filler. |  | 
|   202         // ebx: JSObject (tagged) |  | 
|   203         // ecx: First in-object property of JSObject (not tagged) |  | 
|   204         __ mov(edx, factory->undefined_value()); |  | 
|   205  |  | 
|   206         if (!is_api_function) { |  | 
|   207           Label no_inobject_slack_tracking; |  | 
|   208  |  | 
|   209           // The code below relies on these assumptions. |  | 
|   210           STATIC_ASSERT(Map::kNoSlackTracking == 0); |  | 
|   211           STATIC_ASSERT(Map::ConstructionCounter::kNext == 32); |  | 
|   212           // Check if slack tracking is enabled. |  | 
|   213           __ mov(esi, FieldOperand(eax, Map::kBitField3Offset)); |  | 
|   214           __ shr(esi, Map::ConstructionCounter::kShift); |  | 
|   215           __ j(zero, &no_inobject_slack_tracking);  // Map::kNoSlackTracking |  | 
|   216           __ push(esi);  // Save allocation count value. |  | 
|   217           // Decrease generous allocation count. |  | 
|   218           __ sub(FieldOperand(eax, Map::kBitField3Offset), |  | 
|   219                  Immediate(1 << Map::ConstructionCounter::kShift)); |  | 
|   220  |  | 
|   221           // Allocate object with a slack. |  | 
|   222           __ movzx_b(esi, FieldOperand(eax, Map::kUnusedPropertyFieldsOffset)); |  | 
|   223           __ neg(esi); |  | 
|   224           __ lea(esi, Operand(edi, esi, times_pointer_size, 0)); |  | 
|   225           // esi: offset of first field after pre-allocated fields |  | 
|   226           if (FLAG_debug_code) { |  | 
|   227             __ cmp(ecx, esi); |  | 
|   228             __ Assert(less_equal, |  | 
|   229                       kUnexpectedNumberOfPreAllocatedPropertyFields); |  | 
|   230           } |  | 
|   231           __ InitializeFieldsWithFiller(ecx, esi, edx); |  | 
|   232  |  | 
|   233           // To allow truncation fill the remaining fields with one pointer |  | 
|   234           // filler map. |  | 
|   235           __ mov(edx, factory->one_pointer_filler_map()); |  | 
|   236           __ InitializeFieldsWithFiller(ecx, edi, edx); |  | 
|   237  |  | 
|   238           __ pop(esi);  // Restore allocation count value before decreasing. |  | 
|   239           __ cmp(esi, Map::kSlackTrackingCounterEnd); |  | 
|   240           __ j(not_equal, &allocated); |  | 
|   241  |  | 
|   242           // Push the object to the stack, and then the initial map as |  | 
|   243           // an argument to the runtime call. |  | 
|   244           __ push(ebx); |  | 
|   245           __ push(eax);  // initial map |  | 
|   246           __ CallRuntime(Runtime::kFinalizeInstanceSize); |  | 
|   247           __ pop(ebx); |  | 
|   248  |  | 
|   249           // Continue with JSObject being successfully allocated |  | 
|   250           // ebx: JSObject (tagged) |  | 
|   251           __ jmp(&allocated); |  | 
|   252  |  | 
|   253           __ bind(&no_inobject_slack_tracking); |  | 
|   254         } |  | 
|   255  |  | 
|   256         __ InitializeFieldsWithFiller(ecx, edi, edx); |  | 
|   257  |  | 
|   258         // Continue with JSObject being successfully allocated |  | 
|   259         // ebx: JSObject (tagged) |  | 
|   260         __ jmp(&allocated); |  | 
|   261       } |  | 
|   262  |  | 
|   263       // Allocate the new receiver object using the runtime call. |  | 
|   264       // edx: new target |  | 
|   265       __ bind(&rt_call); |  | 
|   266       int offset = kPointerSize; |  | 
|   267  |  | 
|   268       // Must restore esi (context) and edi (constructor) before calling |  | 
|   269       // runtime. |  | 
|   270       __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |  | 
|   271       __ mov(edi, Operand(esp, offset)); |  | 
|   272       __ push(edi);  // constructor function |  | 
|   273       __ push(edx);  // new target |  | 
|   274       __ CallRuntime(Runtime::kNewObject); |  | 
|   275       __ mov(ebx, eax);  // store result in ebx |  | 
|   276  |  | 
|   277       // New object allocated. |  | 
|   278       // ebx: newly allocated object |  | 
|   279       __ bind(&allocated); |  | 
|   280  |  | 
|   281       // Restore the parameters. |  | 
|   282       __ pop(edx);  // new.target |  | 
|   283       __ pop(edi);  // Constructor function. |  | 
|   284  |   156  | 
|   285       // Retrieve smi-tagged arguments count from the stack. |   157       // Retrieve smi-tagged arguments count from the stack. | 
|   286       __ mov(eax, Operand(esp, 0)); |   158       __ mov(eax, Operand(esp, 0)); | 
|   287     } |   159     } | 
|   288  |   160  | 
|   289     __ SmiUntag(eax); |   161     __ SmiUntag(eax); | 
|   290  |   162  | 
|   291     if (create_implicit_receiver) { |   163     if (create_implicit_receiver) { | 
|   292       // Push the allocated receiver to the stack. We need two copies |   164       // Push the allocated receiver to the stack. We need two copies | 
|   293       // because we may have to return the original one and the calling |   165       // because we may have to return the original one and the calling | 
| (...skipping 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1605  |  1477  | 
|  1606   // 5. Allocate a JSValue wrapper for the number. |  1478   // 5. Allocate a JSValue wrapper for the number. | 
|  1607   __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); |  1479   __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); | 
|  1608   __ Ret(); |  1480   __ Ret(); | 
|  1609  |  1481  | 
|  1610   // 6. Fallback to the runtime to create new object. |  1482   // 6. Fallback to the runtime to create new object. | 
|  1611   __ bind(&new_object); |  1483   __ bind(&new_object); | 
|  1612   { |  1484   { | 
|  1613     FrameScope scope(masm, StackFrame::INTERNAL); |  1485     FrameScope scope(masm, StackFrame::INTERNAL); | 
|  1614     __ Push(ebx);  // the first argument |  1486     __ Push(ebx);  // the first argument | 
|  1615     __ Push(edi);  // constructor function |  1487     FastNewObjectStub stub(masm->isolate()); | 
|  1616     __ Push(edx);  // new target |  1488     __ CallStub(&stub); | 
|  1617     __ CallRuntime(Runtime::kNewObject); |  | 
|  1618     __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |  1489     __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 
|  1619   } |  1490   } | 
|  1620   __ Ret(); |  1491   __ Ret(); | 
|  1621 } |  1492 } | 
|  1622  |  1493  | 
|  1623  |  1494  | 
|  1624 // static |  1495 // static | 
|  1625 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |  1496 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 
|  1626   // ----------- S t a t e ------------- |  1497   // ----------- S t a t e ------------- | 
|  1627   //  -- eax                 : number of arguments |  1498   //  -- eax                 : number of arguments | 
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1739  |  1610  | 
|  1740   // 5. Allocate a JSValue wrapper for the string. |  1611   // 5. Allocate a JSValue wrapper for the string. | 
|  1741   __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); |  1612   __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); | 
|  1742   __ Ret(); |  1613   __ Ret(); | 
|  1743  |  1614  | 
|  1744   // 6. Fallback to the runtime to create new object. |  1615   // 6. Fallback to the runtime to create new object. | 
|  1745   __ bind(&new_object); |  1616   __ bind(&new_object); | 
|  1746   { |  1617   { | 
|  1747     FrameScope scope(masm, StackFrame::INTERNAL); |  1618     FrameScope scope(masm, StackFrame::INTERNAL); | 
|  1748     __ Push(ebx);  // the first argument |  1619     __ Push(ebx);  // the first argument | 
|  1749     __ Push(edi);  // constructor function |  1620     FastNewObjectStub stub(masm->isolate()); | 
|  1750     __ Push(edx);  // new target |  1621     __ CallStub(&stub); | 
|  1751     __ CallRuntime(Runtime::kNewObject); |  | 
|  1752     __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |  1622     __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 
|  1753   } |  1623   } | 
|  1754   __ Ret(); |  1624   __ Ret(); | 
|  1755 } |  1625 } | 
|  1756  |  1626  | 
|  1757  |  1627  | 
|  1758 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |  1628 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 
|  1759                                        Label* stack_overflow) { |  1629                                        Label* stack_overflow) { | 
|  1760   // ----------- S t a t e ------------- |  1630   // ----------- S t a t e ------------- | 
|  1761   //  -- eax : actual number of arguments |  1631   //  -- eax : actual number of arguments | 
| (...skipping 1018 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  2780  |  2650  | 
|  2781   __ bind(&ok); |  2651   __ bind(&ok); | 
|  2782   __ ret(0); |  2652   __ ret(0); | 
|  2783 } |  2653 } | 
|  2784  |  2654  | 
|  2785 #undef __ |  2655 #undef __ | 
|  2786 }  // namespace internal |  2656 }  // namespace internal | 
|  2787 }  // namespace v8 |  2657 }  // namespace v8 | 
|  2788  |  2658  | 
|  2789 #endif  // V8_TARGET_ARCH_IA32 |  2659 #endif  // V8_TARGET_ARCH_IA32 | 
| OLD | NEW |