OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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_ARM64 | 5 #if V8_TARGET_ARCH_ARM64 |
6 | 6 |
7 #include "src/arm64/frames-arm64.h" | 7 #include "src/arm64/frames-arm64.h" |
8 #include "src/codegen.h" | 8 #include "src/codegen.h" |
9 #include "src/debug/debug.h" | 9 #include "src/debug/debug.h" |
10 #include "src/deoptimizer.h" | 10 #include "src/deoptimizer.h" |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
308 | 308 |
309 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); | 309 CallRuntimePassFunction(masm, Runtime::kTryInstallOptimizedCode); |
310 GenerateTailCallToReturnedCode(masm); | 310 GenerateTailCallToReturnedCode(masm); |
311 | 311 |
312 __ Bind(&ok); | 312 __ Bind(&ok); |
313 GenerateTailCallToSharedCode(masm); | 313 GenerateTailCallToSharedCode(masm); |
314 } | 314 } |
315 | 315 |
316 | 316 |
317 static void Generate_JSConstructStubHelper(MacroAssembler* masm, | 317 static void Generate_JSConstructStubHelper(MacroAssembler* masm, |
318 bool is_api_function, | 318 bool is_api_function) { |
319 bool create_memento) { | |
320 // ----------- S t a t e ------------- | 319 // ----------- S t a t e ------------- |
321 // -- x0 : number of arguments | 320 // -- x0 : number of arguments |
322 // -- x1 : constructor function | 321 // -- x1 : constructor function |
323 // -- x2 : allocation site or undefined | 322 // -- x2 : allocation site or undefined |
324 // -- x3 : original constructor | 323 // -- x3 : original constructor |
325 // -- lr : return address | 324 // -- lr : return address |
326 // -- sp[...]: constructor arguments | 325 // -- sp[...]: constructor arguments |
327 // ----------------------------------- | 326 // ----------------------------------- |
328 | 327 |
329 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); | 328 ASM_LOCATION("Builtins::Generate_JSConstructStubHelper"); |
330 // Should never create mementos for api functions. | |
331 DCHECK(!is_api_function || !create_memento); | |
332 | 329 |
333 Isolate* isolate = masm->isolate(); | 330 Isolate* isolate = masm->isolate(); |
334 | 331 |
335 // Enter a construct frame. | 332 // Enter a construct frame. |
336 { | 333 { |
337 FrameScope scope(masm, StackFrame::CONSTRUCT); | 334 FrameScope scope(masm, StackFrame::CONSTRUCT); |
338 | 335 |
339 // Preserve the four incoming parameters on the stack. | 336 // Preserve the four incoming parameters on the stack. |
340 Register argc = x0; | 337 Register argc = x0; |
341 Register constructor = x1; | 338 Register constructor = x1; |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 __ Pop(init_map, constructor); | 399 __ Pop(init_map, constructor); |
403 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); | 400 __ Mov(constructon_count, Operand(Map::kSlackTrackingCounterEnd - 1)); |
404 __ Bind(&allocate); | 401 __ Bind(&allocate); |
405 } | 402 } |
406 | 403 |
407 // Now allocate the JSObject on the heap. | 404 // Now allocate the JSObject on the heap. |
408 Label rt_call_reload_new_target; | 405 Label rt_call_reload_new_target; |
409 Register obj_size = x3; | 406 Register obj_size = x3; |
410 Register new_obj = x4; | 407 Register new_obj = x4; |
411 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); | 408 __ Ldrb(obj_size, FieldMemOperand(init_map, Map::kInstanceSizeOffset)); |
412 if (create_memento) { | 409 __ Allocate(obj_size, new_obj, x10, x11, &rt_call_reload_new_target, |
413 __ Add(x7, obj_size, | 410 SIZE_IN_WORDS); |
414 Operand(AllocationMemento::kSize / kPointerSize)); | |
415 __ Allocate(x7, new_obj, x10, x11, &rt_call_reload_new_target, | |
416 SIZE_IN_WORDS); | |
417 } else { | |
418 __ Allocate(obj_size, new_obj, x10, x11, &rt_call_reload_new_target, | |
419 SIZE_IN_WORDS); | |
420 } | |
421 | 411 |
422 // Allocated the JSObject, now initialize the fields. Map is set to | 412 // Allocated the JSObject, now initialize the fields. Map is set to |
423 // initial map and properties and elements are set to empty fixed array. | 413 // initial map and properties and elements are set to empty fixed array. |
424 // NB. the object pointer is not tagged, so MemOperand is used. | 414 // NB. the object pointer is not tagged, so MemOperand is used. |
425 Register empty = x5; | 415 Register empty = x5; |
426 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); | 416 __ LoadRoot(empty, Heap::kEmptyFixedArrayRootIndex); |
427 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); | 417 __ Str(init_map, MemOperand(new_obj, JSObject::kMapOffset)); |
428 STATIC_ASSERT(JSObject::kElementsOffset == | 418 STATIC_ASSERT(JSObject::kElementsOffset == |
429 (JSObject::kPropertiesOffset + kPointerSize)); | 419 (JSObject::kPropertiesOffset + kPointerSize)); |
430 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); | 420 __ Stp(empty, empty, MemOperand(new_obj, JSObject::kPropertiesOffset)); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 __ Cmp(first_prop, obj_end); | 470 __ Cmp(first_prop, obj_end); |
481 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); | 471 __ Assert(le, kUnexpectedNumberOfPreAllocatedPropertyFields); |
482 } | 472 } |
483 | 473 |
484 // Fill the remaining fields with one pointer filler map. | 474 // Fill the remaining fields with one pointer filler map. |
485 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); | 475 __ LoadRoot(filler, Heap::kOnePointerFillerMapRootIndex); |
486 __ Sub(prop_fields, prop_fields, prealloc_fields); | 476 __ Sub(prop_fields, prop_fields, prealloc_fields); |
487 | 477 |
488 __ bind(&no_inobject_slack_tracking); | 478 __ bind(&no_inobject_slack_tracking); |
489 } | 479 } |
490 if (create_memento) { | 480 |
491 // Fill the pre-allocated fields with undef. | 481 // Fill all of the property fields with undef. |
492 __ FillFields(first_prop, prop_fields, filler); | 482 __ FillFields(first_prop, prop_fields, filler); |
493 __ Add(first_prop, new_obj, Operand(obj_size, LSL, kPointerSizeLog2)); | 483 first_prop = NoReg; |
494 __ LoadRoot(x14, Heap::kAllocationMementoMapRootIndex); | 484 prop_fields = NoReg; |
495 DCHECK_EQ(0 * kPointerSize, AllocationMemento::kMapOffset); | |
496 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | |
497 // Load the AllocationSite | |
498 __ Peek(x14, 3 * kXRegSize); | |
499 __ AssertUndefinedOrAllocationSite(x14, x10); | |
500 DCHECK_EQ(1 * kPointerSize, AllocationMemento::kAllocationSiteOffset); | |
501 __ Str(x14, MemOperand(first_prop, kPointerSize, PostIndex)); | |
502 first_prop = NoReg; | |
503 } else { | |
504 // Fill all of the property fields with undef. | |
505 __ FillFields(first_prop, prop_fields, filler); | |
506 first_prop = NoReg; | |
507 prop_fields = NoReg; | |
508 } | |
509 | 485 |
510 // Add the object tag to make the JSObject real, so that we can continue | 486 // Add the object tag to make the JSObject real, so that we can continue |
511 // and jump into the continuation code at any time from now on. | 487 // and jump into the continuation code at any time from now on. |
512 __ Add(new_obj, new_obj, kHeapObjectTag); | 488 __ Add(new_obj, new_obj, kHeapObjectTag); |
513 | 489 |
514 // Continue with JSObject being successfully allocated. | 490 // Continue with JSObject being successfully allocated. |
515 __ B(&allocated); | 491 __ B(&allocated); |
516 | 492 |
517 // Reload the original constructor and fall-through. | 493 // Reload the original constructor and fall-through. |
518 __ Bind(&rt_call_reload_new_target); | 494 __ Bind(&rt_call_reload_new_target); |
519 __ Peek(x3, 0 * kXRegSize); | 495 __ Peek(x3, 0 * kXRegSize); |
520 } | 496 } |
521 | 497 |
522 // Allocate the new receiver object using the runtime call. | 498 // Allocate the new receiver object using the runtime call. |
523 // x1: constructor function | 499 // x1: constructor function |
524 // x3: original constructor | 500 // x3: original constructor |
525 __ Bind(&rt_call); | 501 __ Bind(&rt_call); |
526 Label count_incremented; | 502 __ Push(constructor, original_constructor); // arguments 1-2 |
527 if (create_memento) { | 503 __ CallRuntime(Runtime::kNewObject, 2); |
528 // Get the cell or allocation site. | 504 __ Mov(x4, x0); |
529 __ Peek(x4, 3 * kXRegSize); | |
530 __ Push(x4, constructor, original_constructor); // arguments 1-3 | |
531 __ CallRuntime(Runtime::kNewObjectWithAllocationSite, 3); | |
532 __ Mov(x4, x0); | |
533 // If we ended up using the runtime, and we want a memento, then the | |
534 // runtime call made it for us, and we shouldn't do create count | |
535 // increment. | |
536 __ B(&count_incremented); | |
537 } else { | |
538 __ Push(constructor, original_constructor); // arguments 1-2 | |
539 __ CallRuntime(Runtime::kNewObject, 2); | |
540 __ Mov(x4, x0); | |
541 } | |
542 | 505 |
543 // Receiver for constructor call allocated. | 506 // Receiver for constructor call allocated. |
544 // x4: JSObject | 507 // x4: JSObject |
545 __ Bind(&allocated); | 508 __ Bind(&allocated); |
546 | 509 |
547 if (create_memento) { | |
548 __ Peek(x10, 3 * kXRegSize); | |
549 __ JumpIfRoot(x10, Heap::kUndefinedValueRootIndex, &count_incremented); | |
550 // r2 is an AllocationSite. We are creating a memento from it, so we | |
551 // need to increment the memento create count. | |
552 __ Ldr(x5, FieldMemOperand(x10, | |
553 AllocationSite::kPretenureCreateCountOffset)); | |
554 __ Add(x5, x5, Operand(Smi::FromInt(1))); | |
555 __ Str(x5, FieldMemOperand(x10, | |
556 AllocationSite::kPretenureCreateCountOffset)); | |
557 __ bind(&count_incremented); | |
558 } | |
559 | |
560 // Restore the parameters. | 510 // Restore the parameters. |
561 __ Pop(original_constructor); | 511 __ Pop(original_constructor); |
562 __ Pop(constructor); | 512 __ Pop(constructor); |
563 | 513 |
564 // Reload the number of arguments from the stack. | 514 // Reload the number of arguments from the stack. |
565 // Set it up in x0 for the function call below. | 515 // Set it up in x0 for the function call below. |
566 // jssp[0]: number of arguments (smi-tagged) | 516 // jssp[0]: number of arguments (smi-tagged) |
567 __ Peek(argc, 0); // Load number of arguments. | 517 __ Peek(argc, 0); // Load number of arguments. |
568 __ SmiUntag(argc); | 518 __ SmiUntag(argc); |
569 | 519 |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
655 } | 605 } |
656 | 606 |
657 __ DropBySMI(x1); | 607 __ DropBySMI(x1); |
658 __ Drop(1); | 608 __ Drop(1); |
659 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); | 609 __ IncrementCounter(isolate->counters()->constructed_objects(), 1, x1, x2); |
660 __ Ret(); | 610 __ Ret(); |
661 } | 611 } |
662 | 612 |
663 | 613 |
664 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { | 614 void Builtins::Generate_JSConstructStubGeneric(MacroAssembler* masm) { |
665 Generate_JSConstructStubHelper(masm, false, FLAG_pretenuring_call_new); | 615 Generate_JSConstructStubHelper(masm, false); |
666 } | 616 } |
667 | 617 |
668 | 618 |
669 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { | 619 void Builtins::Generate_JSConstructStubApi(MacroAssembler* masm) { |
670 Generate_JSConstructStubHelper(masm, true, false); | 620 Generate_JSConstructStubHelper(masm, true); |
671 } | 621 } |
672 | 622 |
673 | 623 |
674 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { | 624 void Builtins::Generate_JSConstructStubForDerived(MacroAssembler* masm) { |
675 // ----------- S t a t e ------------- | 625 // ----------- S t a t e ------------- |
676 // -- x0 : number of arguments | 626 // -- x0 : number of arguments |
677 // -- x1 : constructor function | 627 // -- x1 : constructor function |
678 // -- x2 : allocation site or undefined | 628 // -- x2 : allocation site or undefined |
679 // -- x3 : original constructor | 629 // -- x3 : original constructor |
680 // -- lr : return address | 630 // -- lr : return address |
(...skipping 1248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 } | 1879 } |
1930 } | 1880 } |
1931 | 1881 |
1932 | 1882 |
1933 #undef __ | 1883 #undef __ |
1934 | 1884 |
1935 } // namespace internal | 1885 } // namespace internal |
1936 } // namespace v8 | 1886 } // namespace v8 |
1937 | 1887 |
1938 #endif // V8_TARGET_ARCH_ARM | 1888 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |