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