| 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 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 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1623 | 1495 |
| 1624 // 5. Allocate a JSValue wrapper for the number. | 1496 // 5. Allocate a JSValue wrapper for the number. |
| 1625 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); | 1497 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); |
| 1626 __ Ret(); | 1498 __ Ret(); |
| 1627 | 1499 |
| 1628 // 6. Fallback to the runtime to create new object. | 1500 // 6. Fallback to the runtime to create new object. |
| 1629 __ bind(&new_object); | 1501 __ bind(&new_object); |
| 1630 { | 1502 { |
| 1631 FrameScope scope(masm, StackFrame::INTERNAL); | 1503 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1632 __ Push(ebx); // the first argument | 1504 __ Push(ebx); // the first argument |
| 1633 __ Push(edi); // constructor function | 1505 FastNewObjectStub stub(masm->isolate()); |
| 1634 __ Push(edx); // new target | 1506 __ CallStub(&stub); |
| 1635 __ CallRuntime(Runtime::kNewObject); | |
| 1636 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 1507 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |
| 1637 } | 1508 } |
| 1638 __ Ret(); | 1509 __ Ret(); |
| 1639 } | 1510 } |
| 1640 | 1511 |
| 1641 | 1512 |
| 1642 // static | 1513 // static |
| 1643 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { | 1514 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { |
| 1644 // ----------- S t a t e ------------- | 1515 // ----------- S t a t e ------------- |
| 1645 // -- eax : number of arguments | 1516 // -- eax : number of arguments |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1757 | 1628 |
| 1758 // 5. Allocate a JSValue wrapper for the string. | 1629 // 5. Allocate a JSValue wrapper for the string. |
| 1759 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); | 1630 __ AllocateJSValue(eax, edi, ebx, ecx, &new_object); |
| 1760 __ Ret(); | 1631 __ Ret(); |
| 1761 | 1632 |
| 1762 // 6. Fallback to the runtime to create new object. | 1633 // 6. Fallback to the runtime to create new object. |
| 1763 __ bind(&new_object); | 1634 __ bind(&new_object); |
| 1764 { | 1635 { |
| 1765 FrameScope scope(masm, StackFrame::INTERNAL); | 1636 FrameScope scope(masm, StackFrame::INTERNAL); |
| 1766 __ Push(ebx); // the first argument | 1637 __ Push(ebx); // the first argument |
| 1767 __ Push(edi); // constructor function | 1638 FastNewObjectStub stub(masm->isolate()); |
| 1768 __ Push(edx); // new target | 1639 __ CallStub(&stub); |
| 1769 __ CallRuntime(Runtime::kNewObject); | |
| 1770 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); | 1640 __ Pop(FieldOperand(eax, JSValue::kValueOffset)); |
| 1771 } | 1641 } |
| 1772 __ Ret(); | 1642 __ Ret(); |
| 1773 } | 1643 } |
| 1774 | 1644 |
| 1775 | 1645 |
| 1776 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, | 1646 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, |
| 1777 Label* stack_overflow) { | 1647 Label* stack_overflow) { |
| 1778 // ----------- S t a t e ------------- | 1648 // ----------- S t a t e ------------- |
| 1779 // -- eax : actual number of arguments | 1649 // -- eax : actual number of arguments |
| (...skipping 1025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2805 | 2675 |
| 2806 __ bind(&ok); | 2676 __ bind(&ok); |
| 2807 __ ret(0); | 2677 __ ret(0); |
| 2808 } | 2678 } |
| 2809 | 2679 |
| 2810 #undef __ | 2680 #undef __ |
| 2811 } // namespace internal | 2681 } // namespace internal |
| 2812 } // namespace v8 | 2682 } // namespace v8 |
| 2813 | 2683 |
| 2814 #endif // V8_TARGET_ARCH_X87 | 2684 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |