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

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

Issue 1232833002: X87: Remove separate construct stub for new.target users. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 5 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #if V8_TARGET_ARCH_X87 7 #if V8_TARGET_ARCH_X87
8 8
9 #include "src/code-factory.h" 9 #include "src/code-factory.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 __ bind(&ok); 98 __ bind(&ok);
99 GenerateTailCallToSharedCode(masm); 99 GenerateTailCallToSharedCode(masm);
100 } 100 }
101 101
102 102
103 static void Generate_Runtime_NewObject(MacroAssembler* masm, 103 static void Generate_Runtime_NewObject(MacroAssembler* masm,
104 bool create_memento, 104 bool create_memento,
105 Register original_constructor, 105 Register original_constructor,
106 Label* count_incremented, 106 Label* count_incremented,
107 Label* allocated) { 107 Label* allocated) {
108 int offset = 0; 108 int offset = kPointerSize;
109 if (create_memento) { 109 if (create_memento) {
110 // Get the cell or allocation site. 110 // Get the cell or allocation site.
111 __ mov(edi, Operand(esp, kPointerSize * 2)); 111 __ mov(edi, Operand(esp, kPointerSize * 3));
112 __ push(edi); 112 __ push(edi);
113 offset = kPointerSize; 113 offset += kPointerSize;
114 } 114 }
115 115
116 // Must restore esi (context) and edi (constructor) before calling 116 // Must restore esi (context) and edi (constructor) before calling
117 // runtime. 117 // runtime.
118 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 118 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
119 __ mov(edi, Operand(esp, offset)); 119 __ mov(edi, Operand(esp, offset));
120 __ push(edi); 120 __ push(edi);
121 __ push(original_constructor); 121 __ push(original_constructor);
122 if (create_memento) { 122 if (create_memento) {
123 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); 123 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3);
124 } else { 124 } else {
125 __ CallRuntime(Runtime::kNewObject, 2); 125 __ CallRuntime(Runtime::kNewObject, 2);
126 } 126 }
127 __ mov(ebx, eax); // store result in ebx 127 __ mov(ebx, eax); // store result in ebx
128 128
129 // Runtime_NewObjectWithAllocationSite increments allocation count. 129 // Runtime_NewObjectWithAllocationSite increments allocation count.
130 // Skip the increment. 130 // Skip the increment.
131 if (create_memento) { 131 if (create_memento) {
132 __ jmp(count_incremented); 132 __ jmp(count_incremented);
133 } else { 133 } else {
134 __ jmp(allocated); 134 __ jmp(allocated);
135 } 135 }
136 } 136 }
137 137
138 138
139 static void Generate_JSConstructStubHelper(MacroAssembler* masm, 139 static void Generate_JSConstructStubHelper(MacroAssembler* masm,
140 bool is_api_function, 140 bool is_api_function,
141 bool use_new_target,
142 bool create_memento) { 141 bool create_memento) {
143 // ----------- S t a t e ------------- 142 // ----------- S t a t e -------------
144 // -- eax: number of arguments 143 // -- eax: number of arguments
145 // -- edi: constructor function 144 // -- edi: constructor function
146 // -- ebx: allocation site or undefined 145 // -- ebx: allocation site or undefined
147 // -- edx: original constructor 146 // -- edx: original constructor
148 // ----------------------------------- 147 // -----------------------------------
149 148
150 // Should never create mementos for api functions. 149 // Should never create mementos for api functions.
151 DCHECK(!is_api_function || !create_memento); 150 DCHECK(!is_api_function || !create_memento);
152 151
153 // Enter a construct frame. 152 // Enter a construct frame.
154 { 153 {
155 FrameScope scope(masm, StackFrame::CONSTRUCT); 154 FrameScope scope(masm, StackFrame::CONSTRUCT);
156 155
157 if (create_memento) { 156 if (create_memento) {
158 __ AssertUndefinedOrAllocationSite(ebx); 157 __ AssertUndefinedOrAllocationSite(ebx);
159 __ push(ebx); 158 __ push(ebx);
160 } 159 }
161 160
162 // Preserve the incoming parameters on the stack. 161 // Preserve the incoming parameters on the stack.
163 __ SmiTag(eax); 162 __ SmiTag(eax);
164 __ push(eax); 163 __ push(eax);
165 __ push(edi); 164 __ push(edi);
166 if (use_new_target) { 165 __ push(edx);
167 __ push(edx);
168 }
169 166
170 __ cmp(edx, edi); 167 __ cmp(edx, edi);
171 Label normal_new; 168 Label normal_new;
172 Label count_incremented; 169 Label count_incremented;
173 Label allocated; 170 Label allocated;
174 __ j(equal, &normal_new); 171 __ j(equal, &normal_new);
175 172
176 // Original constructor and function are different. 173 // Original constructor and function are different.
177 Generate_Runtime_NewObject(masm, create_memento, edx, &count_incremented, 174 Generate_Runtime_NewObject(masm, create_memento, edx, &count_incremented,
178 &allocated); 175 &allocated);
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
317 314
318 // Allocate the new receiver object using the runtime call. 315 // Allocate the new receiver object using the runtime call.
319 __ bind(&rt_call); 316 __ bind(&rt_call);
320 Generate_Runtime_NewObject(masm, create_memento, edi, &count_incremented, 317 Generate_Runtime_NewObject(masm, create_memento, edi, &count_incremented,
321 &allocated); 318 &allocated);
322 // New object allocated. 319 // New object allocated.
323 // ebx: newly allocated object 320 // ebx: newly allocated object
324 __ bind(&allocated); 321 __ bind(&allocated);
325 322
326 if (create_memento) { 323 if (create_memento) {
327 int offset = (use_new_target ? 3 : 2) * kPointerSize; 324 __ mov(ecx, Operand(esp, 3 * kPointerSize));
328 __ mov(ecx, Operand(esp, offset));
329 __ cmp(ecx, masm->isolate()->factory()->undefined_value()); 325 __ cmp(ecx, masm->isolate()->factory()->undefined_value());
330 __ j(equal, &count_incremented); 326 __ j(equal, &count_incremented);
331 // ecx is an AllocationSite. We are creating a memento from it, so we 327 // ecx is an AllocationSite. We are creating a memento from it, so we
332 // need to increment the memento create count. 328 // need to increment the memento create count.
333 __ add(FieldOperand(ecx, AllocationSite::kPretenureCreateCountOffset), 329 __ add(FieldOperand(ecx, AllocationSite::kPretenureCreateCountOffset),
334 Immediate(Smi::FromInt(1))); 330 Immediate(Smi::FromInt(1)));
335 __ bind(&count_incremented); 331 __ bind(&count_incremented);
336 } 332 }
337 333
338 // Restore the parameters. 334 // Restore the parameters.
339 if (use_new_target) { 335 __ pop(edx); // new.target
340 __ pop(edx); // new.target
341 }
342 __ pop(edi); // Constructor function. 336 __ pop(edi); // Constructor function.
343 337
344 // Retrieve smi-tagged arguments count from the stack. 338 // Retrieve smi-tagged arguments count from the stack.
345 __ mov(eax, Operand(esp, 0)); 339 __ mov(eax, Operand(esp, 0));
346 __ SmiUntag(eax); 340 __ SmiUntag(eax);
347 341
348 // Push new.target onto the construct frame. This is stored just below the 342 // Push new.target onto the construct frame. This is stored just below the
349 // receiver on the stack. 343 // receiver on the stack.
350 if (use_new_target) { 344 __ push(edx);
351 __ push(edx);
352 }
353 345
354 // Push the allocated receiver to the stack. We need two copies 346 // Push the allocated receiver to the stack. We need two copies
355 // because we may have to return the original one and the calling 347 // because we may have to return the original one and the calling
356 // conventions dictate that the called function pops the receiver. 348 // conventions dictate that the called function pops the receiver.
357 __ push(ebx); 349 __ push(ebx);
358 __ push(ebx); 350 __ push(ebx);
359 351
360 // Set up pointer to last argument. 352 // Set up pointer to last argument.
361 __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset)); 353 __ lea(ebx, Operand(ebp, StandardFrameConstants::kCallerSPOffset));
362 354
(...skipping 13 matching lines...) Expand all
376 Handle<Code> code = 368 Handle<Code> code =
377 masm->isolate()->builtins()->HandleApiCallConstruct(); 369 masm->isolate()->builtins()->HandleApiCallConstruct();
378 __ call(code, RelocInfo::CODE_TARGET); 370 __ call(code, RelocInfo::CODE_TARGET);
379 } else { 371 } else {
380 ParameterCount actual(eax); 372 ParameterCount actual(eax);
381 __ InvokeFunction(edi, actual, CALL_FUNCTION, 373 __ InvokeFunction(edi, actual, CALL_FUNCTION,
382 NullCallWrapper()); 374 NullCallWrapper());
383 } 375 }
384 376
385 // Store offset of return address for deoptimizer. 377 // Store offset of return address for deoptimizer.
386 // TODO(arv): Remove the "!use_new_target" before supporting optimization 378 if (!is_api_function) {
387 // of functions that reference new.target
388 if (!is_api_function && !use_new_target) {
389 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset()); 379 masm->isolate()->heap()->SetConstructStubDeoptPCOffset(masm->pc_offset());
390 } 380 }
391 381
392 // Restore context from the frame. 382 // Restore context from the frame.
393 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 383 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
394 384
395 // If the result is an object (in the ECMA sense), we should get rid 385 // If the result is an object (in the ECMA sense), we should get rid
396 // of the receiver and use the result; see ECMA-262 section 13.2.2-7 386 // of the receiver and use the result; see ECMA-262 section 13.2.2-7
397 // on page 74. 387 // on page 74.
398 Label use_receiver, exit; 388 Label use_receiver, exit;
399 389
400 // If the result is a smi, it is *not* an object in the ECMA sense. 390 // If the result is a smi, it is *not* an object in the ECMA sense.
401 __ JumpIfSmi(eax, &use_receiver); 391 __ JumpIfSmi(eax, &use_receiver);
402 392
403 // If the type of the result (stored in its map) is less than 393 // If the type of the result (stored in its map) is less than
404 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense. 394 // FIRST_SPEC_OBJECT_TYPE, it is not an object in the ECMA sense.
405 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx); 395 __ CmpObjectType(eax, FIRST_SPEC_OBJECT_TYPE, ecx);
406 __ j(above_equal, &exit); 396 __ j(above_equal, &exit);
407 397
408 // Throw away the result of the constructor invocation and use the 398 // Throw away the result of the constructor invocation and use the
409 // on-stack receiver as the result. 399 // on-stack receiver as the result.
410 __ bind(&use_receiver); 400 __ bind(&use_receiver);
411 __ mov(eax, Operand(esp, 0)); 401 __ mov(eax, Operand(esp, 0));
412 402
413 // Restore the arguments count and leave the construct frame. The arguments 403 // Restore the arguments count and leave the construct frame. The arguments
414 // count is stored below the reciever and the new.target. 404 // count is stored below the reciever and the new.target.
415 __ bind(&exit); 405 __ bind(&exit);
416 int offset = (use_new_target ? 2 : 1) * kPointerSize; 406 __ mov(ebx, Operand(esp, 2 * kPointerSize));
417 __ mov(ebx, Operand(esp, offset));
418 407
419 // Leave construct frame. 408 // Leave construct frame.
420 } 409 }
421 410
422 // Remove caller arguments from the stack and return. 411 // Remove caller arguments from the stack and return.
423 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0); 412 STATIC_ASSERT(kSmiTagSize == 1 && kSmiTag == 0);
424 __ pop(ecx); 413 __ pop(ecx);
425 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver 414 __ lea(esp, Operand(esp, ebx, times_2, 1 * kPointerSize)); // 1 ~ receiver
426 __ push(ecx); 415 __ push(ecx);
427 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1); 416 __ IncrementCounter(masm->isolate()->counters()->constructed_objects(), 1);
428 __ ret(0); 417 __ ret(0);
429 } 418 }
430 419
431 420
432 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { 421 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) {
433 Generate_JSConstructStubHelper(masm, false, false, FLAG_pretenuring_call_new); 422 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new);
434 } 423 }
435 424
436 425
437 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { 426 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) {
438 Generate_JSConstructStubHelper(masm, true, false, false); 427 Generate_JSConstructStubHelper(masm, true, false);
439 } 428 }
440 429
441 430
442 void Builtins::Generate_JSConstructStubNewTarget(MacroAssembler* masm) {
443 Generate_JSConstructStubHelper(masm, false, true, FLAG_pretenuring_call_new);
444 }
445
446
447 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { 431 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) {
448 // ----------- S t a t e ------------- 432 // ----------- S t a t e -------------
449 // -- eax: number of arguments 433 // -- eax: number of arguments
450 // -- edi: constructor function 434 // -- edi: constructor function
451 // -- ebx: allocation site or undefined 435 // -- ebx: allocation site or undefined
452 // -- edx: original constructor 436 // -- edx: original constructor
453 // ----------------------------------- 437 // -----------------------------------
454 438
455 // TODO(dslomov): support pretenuring 439 // TODO(dslomov): support pretenuring
456 CHECK(!FLAG_pretenuring_call_new); 440 CHECK(!FLAG_pretenuring_call_new);
(...skipping 1202 matching lines...) Expand 10 before | Expand all | Expand 10 after
1659 1643
1660 __ bind(&ok); 1644 __ bind(&ok);
1661 __ ret(0); 1645 __ ret(0);
1662 } 1646 }
1663 1647
1664 #undef __ 1648 #undef __
1665 } // namespace internal 1649 } // namespace internal
1666 } // namespace v8 1650 } // namespace v8
1667 1651
1668 #endif // V8_TARGET_ARCH_X87 1652 #endif // V8_TARGET_ARCH_X87
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698