OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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_X64 | 7 #if V8_TARGET_ARCH_X64 |
8 | 8 |
9 #include "src/ic/call-optimization.h" | 9 #include "src/ic/call-optimization.h" |
10 #include "src/ic/handler-compiler.h" | 10 #include "src/ic/handler-compiler.h" |
11 #include "src/ic/ic.h" | 11 #include "src/ic/ic.h" |
12 | 12 |
13 namespace v8 { | 13 namespace v8 { |
14 namespace internal { | 14 namespace internal { |
15 | 15 |
16 #define __ ACCESS_MASM(masm) | 16 #define __ ACCESS_MASM(masm) |
17 | 17 |
| 18 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector, |
| 19 Register slot) { |
| 20 MacroAssembler* masm = this->masm(); |
| 21 __ Push(vector); |
| 22 __ Push(slot); |
| 23 } |
| 24 |
| 25 |
| 26 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { |
| 27 MacroAssembler* masm = this->masm(); |
| 28 __ Pop(slot); |
| 29 __ Pop(vector); |
| 30 } |
| 31 |
| 32 |
| 33 void PropertyHandlerCompiler::DiscardVectorAndSlot() { |
| 34 MacroAssembler* masm = this->masm(); |
| 35 // Remove vector and slot. |
| 36 __ addp(rsp, Immediate(2 * kPointerSize)); |
| 37 } |
| 38 |
| 39 |
18 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 40 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
19 MacroAssembler* masm, Label* miss_label, Register receiver, | 41 MacroAssembler* masm, Label* miss_label, Register receiver, |
20 Handle<Name> name, Register scratch0, Register scratch1) { | 42 Handle<Name> name, Register scratch0, Register scratch1) { |
21 DCHECK(name->IsUniqueName()); | 43 DCHECK(name->IsUniqueName()); |
22 DCHECK(!receiver.is(scratch0)); | 44 DCHECK(!receiver.is(scratch0)); |
23 Counters* counters = masm->isolate()->counters(); | 45 Counters* counters = masm->isolate()->counters(); |
24 __ IncrementCounter(counters->negative_lookups(), 1); | 46 __ IncrementCounter(counters->negative_lookups(), 1); |
25 __ IncrementCounter(counters->negative_lookups_miss(), 1); | 47 __ IncrementCounter(counters->negative_lookups_miss(), 1); |
26 | 48 |
27 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); | 49 __ movp(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); |
(...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
460 // Return the register containing the holder. | 482 // Return the register containing the holder. |
461 return reg; | 483 return reg; |
462 } | 484 } |
463 | 485 |
464 | 486 |
465 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 487 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
466 if (!miss->is_unused()) { | 488 if (!miss->is_unused()) { |
467 Label success; | 489 Label success; |
468 __ jmp(&success); | 490 __ jmp(&success); |
469 __ bind(miss); | 491 __ bind(miss); |
| 492 if (IC::ICUseVector(kind())) { |
| 493 DCHECK(kind() == Code::LOAD_IC); |
| 494 PopVectorAndSlot(); |
| 495 } |
470 TailCallBuiltin(masm(), MissBuiltin(kind())); | 496 TailCallBuiltin(masm(), MissBuiltin(kind())); |
471 __ bind(&success); | 497 __ bind(&success); |
472 } | 498 } |
473 } | 499 } |
474 | 500 |
475 | 501 |
476 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 502 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
477 if (!miss->is_unused()) { | 503 if (!miss->is_unused()) { |
478 Label success; | 504 Label success; |
479 __ jmp(&success); | 505 __ jmp(&success); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 // Save necessary data before invoking an interceptor. | 584 // Save necessary data before invoking an interceptor. |
559 // Requires a frame to make GC aware of pushed pointers. | 585 // Requires a frame to make GC aware of pushed pointers. |
560 { | 586 { |
561 FrameScope frame_scope(masm(), StackFrame::INTERNAL); | 587 FrameScope frame_scope(masm(), StackFrame::INTERNAL); |
562 | 588 |
563 if (must_preserve_receiver_reg) { | 589 if (must_preserve_receiver_reg) { |
564 __ Push(receiver()); | 590 __ Push(receiver()); |
565 } | 591 } |
566 __ Push(holder_reg); | 592 __ Push(holder_reg); |
567 __ Push(this->name()); | 593 __ Push(this->name()); |
| 594 InterceptorVectorSlotPush(holder_reg); |
568 | 595 |
569 // Invoke an interceptor. Note: map checks from receiver to | 596 // Invoke an interceptor. Note: map checks from receiver to |
570 // interceptor's holder has been compiled before (see a caller | 597 // interceptor's holder has been compiled before (see a caller |
571 // of this method.) | 598 // of this method.) |
572 CompileCallLoadPropertyWithInterceptor( | 599 CompileCallLoadPropertyWithInterceptor( |
573 masm(), receiver(), holder_reg, this->name(), holder(), | 600 masm(), receiver(), holder_reg, this->name(), holder(), |
574 IC::kLoadPropertyWithInterceptorOnly); | 601 IC::kLoadPropertyWithInterceptorOnly); |
575 | 602 |
576 // Check if interceptor provided a value for property. If it's | 603 // Check if interceptor provided a value for property. If it's |
577 // the case, return immediately. | 604 // the case, return immediately. |
578 Label interceptor_failed; | 605 Label interceptor_failed; |
579 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); | 606 __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); |
580 __ j(equal, &interceptor_failed); | 607 __ j(equal, &interceptor_failed); |
581 frame_scope.GenerateLeaveFrame(); | 608 frame_scope.GenerateLeaveFrame(); |
582 __ ret(0); | 609 __ ret(0); |
583 | 610 |
584 __ bind(&interceptor_failed); | 611 __ bind(&interceptor_failed); |
| 612 InterceptorVectorSlotPop(holder_reg); |
585 __ Pop(this->name()); | 613 __ Pop(this->name()); |
586 __ Pop(holder_reg); | 614 __ Pop(holder_reg); |
587 if (must_preserve_receiver_reg) { | 615 if (must_preserve_receiver_reg) { |
588 __ Pop(receiver()); | 616 __ Pop(receiver()); |
589 } | 617 } |
590 | 618 |
591 // Leave the internal frame. | 619 // Leave the internal frame. |
592 } | 620 } |
593 | 621 |
594 GenerateLoadPostInterceptor(it, holder_reg); | 622 GenerateLoadPostInterceptor(it, holder_reg); |
(...skipping 12 matching lines...) Expand all Loading... |
607 ExternalReference ref = ExternalReference( | 635 ExternalReference ref = ExternalReference( |
608 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 636 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); |
609 __ TailCallExternalReference( | 637 __ TailCallExternalReference( |
610 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); | 638 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); |
611 } | 639 } |
612 | 640 |
613 | 641 |
614 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 642 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
615 Handle<JSObject> object, Handle<Name> name, | 643 Handle<JSObject> object, Handle<Name> name, |
616 Handle<ExecutableAccessorInfo> callback) { | 644 Handle<ExecutableAccessorInfo> callback) { |
617 Register holder_reg = Frontend(receiver(), name); | 645 Register holder_reg = Frontend(name); |
618 | 646 |
619 __ PopReturnAddressTo(scratch1()); | 647 __ PopReturnAddressTo(scratch1()); |
620 __ Push(receiver()); | 648 __ Push(receiver()); |
621 __ Push(holder_reg); | 649 __ Push(holder_reg); |
622 __ Push(callback); // callback info | 650 __ Push(callback); // callback info |
623 __ Push(name); | 651 __ Push(name); |
624 __ Push(value()); | 652 __ Push(value()); |
625 __ PushReturnAddressFrom(scratch1()); | 653 __ PushReturnAddressFrom(scratch1()); |
626 | 654 |
627 // Do tail-call to the runtime system. | 655 // Do tail-call to the runtime system. |
(...skipping 25 matching lines...) Expand all Loading... |
653 | 681 |
654 | 682 |
655 Register NamedStoreHandlerCompiler::value() { | 683 Register NamedStoreHandlerCompiler::value() { |
656 return StoreDescriptor::ValueRegister(); | 684 return StoreDescriptor::ValueRegister(); |
657 } | 685 } |
658 | 686 |
659 | 687 |
660 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 688 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
661 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { | 689 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { |
662 Label miss; | 690 Label miss; |
| 691 if (IC::ICUseVector(kind())) { |
| 692 PushVectorAndSlot(); |
| 693 } |
663 FrontendHeader(receiver(), name, &miss); | 694 FrontendHeader(receiver(), name, &miss); |
664 | 695 |
665 // Get the value from the cell. | 696 // Get the value from the cell. |
666 Register result = StoreDescriptor::ValueRegister(); | 697 Register result = StoreDescriptor::ValueRegister(); |
667 __ Move(result, cell); | 698 __ Move(result, cell); |
668 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); | 699 __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); |
669 | 700 |
670 // Check for deleted property if property can actually be deleted. | 701 // Check for deleted property if property can actually be deleted. |
671 if (is_configurable) { | 702 if (is_configurable) { |
672 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 703 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
673 __ j(equal, &miss); | 704 __ j(equal, &miss); |
674 } else if (FLAG_debug_code) { | 705 } else if (FLAG_debug_code) { |
675 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 706 __ CompareRoot(result, Heap::kTheHoleValueRootIndex); |
676 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); | 707 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); |
677 } | 708 } |
678 | 709 |
679 Counters* counters = isolate()->counters(); | 710 Counters* counters = isolate()->counters(); |
680 __ IncrementCounter(counters->named_load_global_stub(), 1); | 711 __ IncrementCounter(counters->named_load_global_stub(), 1); |
| 712 if (IC::ICUseVector(kind())) { |
| 713 DiscardVectorAndSlot(); |
| 714 } |
681 __ ret(0); | 715 __ ret(0); |
682 | 716 |
683 FrontendFooter(name, &miss); | 717 FrontendFooter(name, &miss); |
684 | 718 |
685 // Return the generated code. | 719 // Return the generated code. |
686 return GetCode(kind(), Code::NORMAL, name); | 720 return GetCode(kind(), Code::NORMAL, name); |
687 } | 721 } |
688 | 722 |
689 | 723 |
690 #undef __ | 724 #undef __ |
691 } | 725 } |
692 } // namespace v8::internal | 726 } // namespace v8::internal |
693 | 727 |
694 #endif // V8_TARGET_ARCH_X64 | 728 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |