Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Side by Side Diff: src/x64/builtins-x64.cc

Issue 1708313002: [stubs] Introduce a dedicated FastNewObjectStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Remove TODO. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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_X64 5 #if V8_TARGET_ARCH_X64
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 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 { 133 {
134 FrameScope scope(masm, StackFrame::CONSTRUCT); 134 FrameScope scope(masm, StackFrame::CONSTRUCT);
135 135
136 // Preserve the incoming parameters on the stack. 136 // Preserve the incoming parameters on the stack.
137 __ AssertUndefinedOrAllocationSite(rbx); 137 __ AssertUndefinedOrAllocationSite(rbx);
138 __ Push(rbx); 138 __ Push(rbx);
139 __ Integer32ToSmi(rcx, rax); 139 __ Integer32ToSmi(rcx, rax);
140 __ Push(rcx); 140 __ Push(rcx);
141 141
142 if (create_implicit_receiver) { 142 if (create_implicit_receiver) {
143 // Try to allocate the object without transitioning into C code. If any of 143 // Allocate the new receiver object.
144 // the preconditions is not met, the code bails out to the runtime call.
145 Label rt_call, allocated;
146 if (FLAG_inline_new) {
147 // Verify that the new target is a JSFunction.
148 __ CmpObjectType(rdx, JS_FUNCTION_TYPE, rbx);
149 __ j(not_equal, &rt_call);
150
151 // Load the initial map and verify that it is in fact a map.
152 // rdx: new target
153 __ movp(rax,
154 FieldOperand(rdx, JSFunction::kPrototypeOrInitialMapOffset));
155 // Will both indicate a NULL and a Smi
156 DCHECK(kSmiTag == 0);
157 __ JumpIfSmi(rax, &rt_call);
158 // rdi: constructor
159 // rax: initial map (if proven valid below)
160 __ CmpObjectType(rax, MAP_TYPE, rbx);
161 __ j(not_equal, &rt_call);
162
163 // Fall back to runtime if the expected base constructor and base
164 // constructor differ.
165 __ cmpp(rdi, FieldOperand(rax, Map::kConstructorOrBackPointerOffset));
166 __ j(not_equal, &rt_call);
167
168 // Now allocate the JSObject on the heap.
169 __ movzxbp(r9, FieldOperand(rax, Map::kInstanceSizeOffset));
170 __ shlp(r9, Immediate(kPointerSizeLog2));
171 // r9: size of new object
172 __ Allocate(r9, rbx, r9, no_reg, &rt_call, NO_ALLOCATION_FLAGS);
173 // Allocated the JSObject, now initialize the fields.
174 // rdi: constructor
175 // rdx: new target
176 // rax: initial map
177 // rbx: JSObject (not HeapObject tagged - the actual address).
178 // r9: start of next object
179 __ movp(Operand(rbx, JSObject::kMapOffset), rax);
180 __ LoadRoot(rcx, Heap::kEmptyFixedArrayRootIndex);
181 __ movp(Operand(rbx, JSObject::kPropertiesOffset), rcx);
182 __ movp(Operand(rbx, JSObject::kElementsOffset), rcx);
183 __ leap(rcx, Operand(rbx, JSObject::kHeaderSize));
184
185 // Add the object tag to make the JSObject real, so that we can continue
186 // and jump into the continuation code at any time from now on.
187 __ orp(rbx, Immediate(kHeapObjectTag));
188
189 // Fill all the in-object properties with the appropriate filler.
190 // rbx: JSObject (tagged)
191 // rcx: First in-object property of JSObject (not tagged)
192 __ LoadRoot(r11, Heap::kUndefinedValueRootIndex);
193
194 if (!is_api_function) {
195 Label no_inobject_slack_tracking;
196
197 // The code below relies on these assumptions.
198 STATIC_ASSERT(Map::kNoSlackTracking == 0);
199 STATIC_ASSERT(Map::ConstructionCounter::kNext == 32);
200 // Check if slack tracking is enabled.
201 __ movl(rsi, FieldOperand(rax, Map::kBitField3Offset));
202 __ shrl(rsi, Immediate(Map::ConstructionCounter::kShift));
203 __ j(zero, &no_inobject_slack_tracking); // Map::kNoSlackTracking
204 __ Push(rsi); // Save allocation count value.
205 // Decrease generous allocation count.
206 __ subl(FieldOperand(rax, Map::kBitField3Offset),
207 Immediate(1 << Map::ConstructionCounter::kShift));
208
209 // Allocate object with a slack.
210 __ movzxbp(rsi, FieldOperand(rax, Map::kUnusedPropertyFieldsOffset));
211 __ negp(rsi);
212 __ leap(rsi, Operand(r9, rsi, times_pointer_size, 0));
213 // rsi: offset of first field after pre-allocated fields
214 if (FLAG_debug_code) {
215 __ cmpp(rcx, rsi);
216 __ Assert(less_equal,
217 kUnexpectedNumberOfPreAllocatedPropertyFields);
218 }
219 __ InitializeFieldsWithFiller(rcx, rsi, r11);
220
221 // To allow truncation fill the remaining fields with one pointer
222 // filler map.
223 __ LoadRoot(r11, Heap::kOnePointerFillerMapRootIndex);
224 __ InitializeFieldsWithFiller(rcx, r9, r11);
225
226 __ Pop(rsi); // Restore allocation count value before decreasing.
227 __ cmpl(rsi, Immediate(Map::kSlackTrackingCounterEnd));
228 __ j(not_equal, &allocated);
229
230 // Push the constructor, new_target and the object to the stack,
231 // and then the initial map as an argument to the runtime call.
232 __ Push(rdi);
233 __ Push(rdx);
234 __ Push(rbx);
235
236 __ Push(rax); // initial map
237 __ CallRuntime(Runtime::kFinalizeInstanceSize);
238
239 __ Pop(rbx);
240 __ Pop(rdx);
241 __ Pop(rdi);
242
243 // Continue with JSObject being successfully allocated.
244 // rdi: constructor
245 // rdx: new target
246 // rbx: JSObject (tagged)
247 __ jmp(&allocated);
248
249 __ bind(&no_inobject_slack_tracking);
250 }
251
252 __ InitializeFieldsWithFiller(rcx, r9, r11);
253
254 // Continue with JSObject being successfully allocated
255 // rdi: constructor
256 // rdx: new target
257 // rbx: JSObject (tagged)
258 __ jmp(&allocated);
259 }
260
261 // Allocate the new receiver object using the runtime call.
262 // rdi: constructor
263 // rdx: new target
264 __ bind(&rt_call);
265
266 // Must restore rsi (context) before calling runtime.
267 __ movp(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
268
269 // Push the constructor and new_target twice, second pair as arguments
270 // to the runtime call.
271 __ Push(rdi); 144 __ Push(rdi);
272 __ Push(rdx); 145 __ Push(rdx);
273 __ Push(rdi); // constructor function 146 FastNewObjectStub stub(masm->isolate());
274 __ Push(rdx); // new target 147 __ CallStub(&stub);
275 __ CallRuntime(Runtime::kNewObject); 148 __ movp(rbx, rax);
276 __ movp(rbx, rax); // store result in rbx
277 __ Pop(rdx); 149 __ Pop(rdx);
278 __ Pop(rdi); 150 __ Pop(rdi);
279 151
280 // Receiver for constructor call allocated. 152 // ----------- S t a t e -------------
281 // rdi: constructor 153 // -- rdi: constructor function
282 // rdx: new target 154 // -- rbx: newly allocated object
283 // rbx: newly allocated object 155 // -- rdx: new target
284 __ bind(&allocated); 156 // -----------------------------------
285 157
286 // Retrieve smi-tagged arguments count from the stack. 158 // Retrieve smi-tagged arguments count from the stack.
287 __ movp(rax, Operand(rsp, 0)); 159 __ SmiToInteger32(rax, Operand(rsp, 0 * kPointerSize));
288 __ SmiToInteger32(rax, rax);
289 } 160 }
290 161
291 if (create_implicit_receiver) { 162 if (create_implicit_receiver) {
292 // Push the allocated receiver to the stack. We need two copies 163 // Push the allocated receiver to the stack. We need two copies
293 // because we may have to return the original one and the calling 164 // because we may have to return the original one and the calling
294 // conventions dictate that the called function pops the receiver. 165 // conventions dictate that the called function pops the receiver.
295 __ Push(rbx); 166 __ Push(rbx);
296 __ Push(rbx); 167 __ Push(rbx);
297 } else { 168 } else {
298 __ PushRoot(Heap::kTheHoleValueRootIndex); 169 __ PushRoot(Heap::kTheHoleValueRootIndex);
(...skipping 1374 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 1544
1674 // 5. Allocate a JSValue wrapper for the number. 1545 // 5. Allocate a JSValue wrapper for the number.
1675 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); 1546 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object);
1676 __ Ret(); 1547 __ Ret();
1677 1548
1678 // 6. Fallback to the runtime to create new object. 1549 // 6. Fallback to the runtime to create new object.
1679 __ bind(&new_object); 1550 __ bind(&new_object);
1680 { 1551 {
1681 FrameScope scope(masm, StackFrame::INTERNAL); 1552 FrameScope scope(masm, StackFrame::INTERNAL);
1682 __ Push(rbx); // the first argument 1553 __ Push(rbx); // the first argument
1683 __ Push(rdi); // constructor function 1554 FastNewObjectStub stub(masm->isolate());
1684 __ Push(rdx); // new target 1555 __ CallStub(&stub);
1685 __ CallRuntime(Runtime::kNewObject);
1686 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); 1556 __ Pop(FieldOperand(rax, JSValue::kValueOffset));
1687 } 1557 }
1688 __ Ret(); 1558 __ Ret();
1689 } 1559 }
1690 1560
1691 1561
1692 // static 1562 // static
1693 void Builtins::Generate_StringConstructor(MacroAssembler* masm) { 1563 void Builtins::Generate_StringConstructor(MacroAssembler* masm) {
1694 // ----------- S t a t e ------------- 1564 // ----------- S t a t e -------------
1695 // -- rax : number of arguments 1565 // -- rax : number of arguments
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1809 1679
1810 // 5. Allocate a JSValue wrapper for the string. 1680 // 5. Allocate a JSValue wrapper for the string.
1811 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object); 1681 __ AllocateJSValue(rax, rdi, rbx, rcx, &new_object);
1812 __ Ret(); 1682 __ Ret();
1813 1683
1814 // 6. Fallback to the runtime to create new object. 1684 // 6. Fallback to the runtime to create new object.
1815 __ bind(&new_object); 1685 __ bind(&new_object);
1816 { 1686 {
1817 FrameScope scope(masm, StackFrame::INTERNAL); 1687 FrameScope scope(masm, StackFrame::INTERNAL);
1818 __ Push(rbx); // the first argument 1688 __ Push(rbx); // the first argument
1819 __ Push(rdi); // constructor function 1689 FastNewObjectStub stub(masm->isolate());
1820 __ Push(rdx); // new target 1690 __ CallStub(&stub);
1821 __ CallRuntime(Runtime::kNewObject);
1822 __ Pop(FieldOperand(rax, JSValue::kValueOffset)); 1691 __ Pop(FieldOperand(rax, JSValue::kValueOffset));
1823 } 1692 }
1824 __ Ret(); 1693 __ Ret();
1825 } 1694 }
1826 1695
1827 1696
1828 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm, 1697 static void ArgumentsAdaptorStackCheck(MacroAssembler* masm,
1829 Label* stack_overflow) { 1698 Label* stack_overflow) {
1830 // ----------- S t a t e ------------- 1699 // ----------- S t a t e -------------
1831 // -- rax : actual number of arguments 1700 // -- rax : actual number of arguments
(...skipping 1026 matching lines...) Expand 10 before | Expand all | Expand 10 after
2858 __ ret(0); 2727 __ ret(0);
2859 } 2728 }
2860 2729
2861 2730
2862 #undef __ 2731 #undef __
2863 2732
2864 } // namespace internal 2733 } // namespace internal
2865 } // namespace v8 2734 } // namespace v8
2866 2735
2867 #endif // V8_TARGET_ARCH_X64 2736 #endif // V8_TARGET_ARCH_X64
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698