| 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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 477   // Return the register containing the holder. | 499   // Return the register containing the holder. | 
| 478   return reg; | 500   return reg; | 
| 479 } | 501 } | 
| 480 | 502 | 
| 481 | 503 | 
| 482 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 504 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 483   if (!miss->is_unused()) { | 505   if (!miss->is_unused()) { | 
| 484     Label success; | 506     Label success; | 
| 485     __ jmp(&success); | 507     __ jmp(&success); | 
| 486     __ bind(miss); | 508     __ bind(miss); | 
|  | 509     if (IC::ICUseVector(kind())) { | 
|  | 510       DCHECK(kind() == Code::LOAD_IC); | 
|  | 511       PopVectorAndSlot(); | 
|  | 512     } | 
| 487     TailCallBuiltin(masm(), MissBuiltin(kind())); | 513     TailCallBuiltin(masm(), MissBuiltin(kind())); | 
| 488     __ bind(&success); | 514     __ bind(&success); | 
| 489   } | 515   } | 
| 490 } | 516 } | 
| 491 | 517 | 
| 492 | 518 | 
| 493 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 519 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 
| 494   if (!miss->is_unused()) { | 520   if (!miss->is_unused()) { | 
| 495     Label success; | 521     Label success; | 
| 496     __ jmp(&success); | 522     __ jmp(&success); | 
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 575   // Save necessary data before invoking an interceptor. | 601   // Save necessary data before invoking an interceptor. | 
| 576   // Requires a frame to make GC aware of pushed pointers. | 602   // Requires a frame to make GC aware of pushed pointers. | 
| 577   { | 603   { | 
| 578     FrameScope frame_scope(masm(), StackFrame::INTERNAL); | 604     FrameScope frame_scope(masm(), StackFrame::INTERNAL); | 
| 579 | 605 | 
| 580     if (must_preserve_receiver_reg) { | 606     if (must_preserve_receiver_reg) { | 
| 581       __ Push(receiver()); | 607       __ Push(receiver()); | 
| 582     } | 608     } | 
| 583     __ Push(holder_reg); | 609     __ Push(holder_reg); | 
| 584     __ Push(this->name()); | 610     __ Push(this->name()); | 
|  | 611     InterceptorVectorSlotPush(holder_reg); | 
| 585 | 612 | 
| 586     // Invoke an interceptor.  Note: map checks from receiver to | 613     // Invoke an interceptor.  Note: map checks from receiver to | 
| 587     // interceptor's holder has been compiled before (see a caller | 614     // interceptor's holder has been compiled before (see a caller | 
| 588     // of this method.) | 615     // of this method.) | 
| 589     CompileCallLoadPropertyWithInterceptor( | 616     CompileCallLoadPropertyWithInterceptor( | 
| 590         masm(), receiver(), holder_reg, this->name(), holder(), | 617         masm(), receiver(), holder_reg, this->name(), holder(), | 
| 591         IC::kLoadPropertyWithInterceptorOnly); | 618         IC::kLoadPropertyWithInterceptorOnly); | 
| 592 | 619 | 
| 593     // Check if interceptor provided a value for property.  If it's | 620     // Check if interceptor provided a value for property.  If it's | 
| 594     // the case, return immediately. | 621     // the case, return immediately. | 
| 595     Label interceptor_failed; | 622     Label interceptor_failed; | 
| 596     __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); | 623     __ CompareRoot(rax, Heap::kNoInterceptorResultSentinelRootIndex); | 
| 597     __ j(equal, &interceptor_failed); | 624     __ j(equal, &interceptor_failed); | 
| 598     frame_scope.GenerateLeaveFrame(); | 625     frame_scope.GenerateLeaveFrame(); | 
| 599     __ ret(0); | 626     __ ret(0); | 
| 600 | 627 | 
| 601     __ bind(&interceptor_failed); | 628     __ bind(&interceptor_failed); | 
|  | 629     InterceptorVectorSlotPop(holder_reg); | 
| 602     __ Pop(this->name()); | 630     __ Pop(this->name()); | 
| 603     __ Pop(holder_reg); | 631     __ Pop(holder_reg); | 
| 604     if (must_preserve_receiver_reg) { | 632     if (must_preserve_receiver_reg) { | 
| 605       __ Pop(receiver()); | 633       __ Pop(receiver()); | 
| 606     } | 634     } | 
| 607 | 635 | 
| 608     // Leave the internal frame. | 636     // Leave the internal frame. | 
| 609   } | 637   } | 
| 610 | 638 | 
| 611   GenerateLoadPostInterceptor(it, holder_reg); | 639   GenerateLoadPostInterceptor(it, holder_reg); | 
| (...skipping 12 matching lines...) Expand all  Loading... | 
| 624   ExternalReference ref = ExternalReference( | 652   ExternalReference ref = ExternalReference( | 
| 625       IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 653       IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 
| 626   __ TailCallExternalReference( | 654   __ TailCallExternalReference( | 
| 627       ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); | 655       ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); | 
| 628 } | 656 } | 
| 629 | 657 | 
| 630 | 658 | 
| 631 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 659 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 
| 632     Handle<JSObject> object, Handle<Name> name, | 660     Handle<JSObject> object, Handle<Name> name, | 
| 633     Handle<ExecutableAccessorInfo> callback) { | 661     Handle<ExecutableAccessorInfo> callback) { | 
| 634   Register holder_reg = Frontend(receiver(), name); | 662   Register holder_reg = Frontend(name); | 
| 635 | 663 | 
| 636   __ PopReturnAddressTo(scratch1()); | 664   __ PopReturnAddressTo(scratch1()); | 
| 637   __ Push(receiver()); | 665   __ Push(receiver()); | 
| 638   __ Push(holder_reg); | 666   __ Push(holder_reg); | 
| 639   __ Push(callback);  // callback info | 667   __ Push(callback);  // callback info | 
| 640   __ Push(name); | 668   __ Push(name); | 
| 641   __ Push(value()); | 669   __ Push(value()); | 
| 642   __ PushReturnAddressFrom(scratch1()); | 670   __ PushReturnAddressFrom(scratch1()); | 
| 643 | 671 | 
| 644   // Do tail-call to the runtime system. | 672   // Do tail-call to the runtime system. | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 670 | 698 | 
| 671 | 699 | 
| 672 Register NamedStoreHandlerCompiler::value() { | 700 Register NamedStoreHandlerCompiler::value() { | 
| 673   return StoreDescriptor::ValueRegister(); | 701   return StoreDescriptor::ValueRegister(); | 
| 674 } | 702 } | 
| 675 | 703 | 
| 676 | 704 | 
| 677 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 705 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 
| 678     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { | 706     Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { | 
| 679   Label miss; | 707   Label miss; | 
|  | 708   if (IC::ICUseVector(kind())) { | 
|  | 709     PushVectorAndSlot(); | 
|  | 710   } | 
| 680   FrontendHeader(receiver(), name, &miss); | 711   FrontendHeader(receiver(), name, &miss); | 
| 681 | 712 | 
| 682   // Get the value from the cell. | 713   // Get the value from the cell. | 
| 683   Register result = StoreDescriptor::ValueRegister(); | 714   Register result = StoreDescriptor::ValueRegister(); | 
| 684   __ Move(result, cell); | 715   __ Move(result, cell); | 
| 685   __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); | 716   __ movp(result, FieldOperand(result, PropertyCell::kValueOffset)); | 
| 686 | 717 | 
| 687   // Check for deleted property if property can actually be deleted. | 718   // Check for deleted property if property can actually be deleted. | 
| 688   if (is_configurable) { | 719   if (is_configurable) { | 
| 689     __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 720     __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 
| 690     __ j(equal, &miss); | 721     __ j(equal, &miss); | 
| 691   } else if (FLAG_debug_code) { | 722   } else if (FLAG_debug_code) { | 
| 692     __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 723     __ CompareRoot(result, Heap::kTheHoleValueRootIndex); | 
| 693     __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); | 724     __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); | 
| 694   } | 725   } | 
| 695 | 726 | 
| 696   Counters* counters = isolate()->counters(); | 727   Counters* counters = isolate()->counters(); | 
| 697   __ IncrementCounter(counters->named_load_global_stub(), 1); | 728   __ IncrementCounter(counters->named_load_global_stub(), 1); | 
|  | 729   if (IC::ICUseVector(kind())) { | 
|  | 730     DiscardVectorAndSlot(); | 
|  | 731   } | 
| 698   __ ret(0); | 732   __ ret(0); | 
| 699 | 733 | 
| 700   FrontendFooter(name, &miss); | 734   FrontendFooter(name, &miss); | 
| 701 | 735 | 
| 702   // Return the generated code. | 736   // Return the generated code. | 
| 703   return GetCode(kind(), Code::NORMAL, name); | 737   return GetCode(kind(), Code::NORMAL, name); | 
| 704 } | 738 } | 
| 705 | 739 | 
| 706 | 740 | 
| 707 #undef __ | 741 #undef __ | 
| 708 } | 742 } | 
| 709 }  // namespace v8::internal | 743 }  // namespace v8::internal | 
| 710 | 744 | 
| 711 #endif  // V8_TARGET_ARCH_X64 | 745 #endif  // V8_TARGET_ARCH_X64 | 
| OLD | NEW | 
|---|