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_MIPS | 7 #if V8_TARGET_ARCH_MIPS |
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" |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
85 // We have to return the passed value, not the return value of the setter. | 85 // We have to return the passed value, not the return value of the setter. |
86 __ pop(v0); | 86 __ pop(v0); |
87 | 87 |
88 // Restore context register. | 88 // Restore context register. |
89 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); | 89 __ lw(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); |
90 } | 90 } |
91 __ Ret(); | 91 __ Ret(); |
92 } | 92 } |
93 | 93 |
94 | 94 |
| 95 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector, |
| 96 Register slot) { |
| 97 MacroAssembler* masm = this->masm(); |
| 98 __ Push(vector, slot); |
| 99 } |
| 100 |
| 101 |
| 102 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) { |
| 103 MacroAssembler* masm = this->masm(); |
| 104 __ Pop(vector, slot); |
| 105 } |
| 106 |
| 107 |
| 108 void PropertyHandlerCompiler::DiscardVectorAndSlot() { |
| 109 MacroAssembler* masm = this->masm(); |
| 110 // Remove vector and slot. |
| 111 __ Addu(sp, sp, Operand(2 * kPointerSize)); |
| 112 } |
| 113 |
| 114 |
95 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( | 115 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( |
96 MacroAssembler* masm, Label* miss_label, Register receiver, | 116 MacroAssembler* masm, Label* miss_label, Register receiver, |
97 Handle<Name> name, Register scratch0, Register scratch1) { | 117 Handle<Name> name, Register scratch0, Register scratch1) { |
98 DCHECK(name->IsUniqueName()); | 118 DCHECK(name->IsUniqueName()); |
99 DCHECK(!receiver.is(scratch0)); | 119 DCHECK(!receiver.is(scratch0)); |
100 Counters* counters = masm->isolate()->counters(); | 120 Counters* counters = masm->isolate()->counters(); |
101 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); | 121 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); |
102 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); | 122 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); |
103 | 123 |
104 Label done; | 124 Label done; |
(...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
474 // Return the register containing the holder. | 494 // Return the register containing the holder. |
475 return reg; | 495 return reg; |
476 } | 496 } |
477 | 497 |
478 | 498 |
479 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 499 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
480 if (!miss->is_unused()) { | 500 if (!miss->is_unused()) { |
481 Label success; | 501 Label success; |
482 __ Branch(&success); | 502 __ Branch(&success); |
483 __ bind(miss); | 503 __ bind(miss); |
| 504 if (IC::ICUseVector(kind())) { |
| 505 DCHECK(kind() == Code::LOAD_IC); |
| 506 PopVectorAndSlot(); |
| 507 } |
484 TailCallBuiltin(masm(), MissBuiltin(kind())); | 508 TailCallBuiltin(masm(), MissBuiltin(kind())); |
485 __ bind(&success); | 509 __ bind(&success); |
486 } | 510 } |
487 } | 511 } |
488 | 512 |
489 | 513 |
490 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { | 514 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { |
491 if (!miss->is_unused()) { | 515 if (!miss->is_unused()) { |
492 Label success; | 516 Label success; |
493 __ Branch(&success); | 517 __ Branch(&success); |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 | 599 |
576 // Save necessary data before invoking an interceptor. | 600 // Save necessary data before invoking an interceptor. |
577 // Requires a frame to make GC aware of pushed pointers. | 601 // Requires a frame to make GC aware of pushed pointers. |
578 { | 602 { |
579 FrameScope frame_scope(masm(), StackFrame::INTERNAL); | 603 FrameScope frame_scope(masm(), StackFrame::INTERNAL); |
580 if (must_preserve_receiver_reg) { | 604 if (must_preserve_receiver_reg) { |
581 __ Push(receiver(), holder_reg, this->name()); | 605 __ Push(receiver(), holder_reg, this->name()); |
582 } else { | 606 } else { |
583 __ Push(holder_reg, this->name()); | 607 __ Push(holder_reg, this->name()); |
584 } | 608 } |
| 609 InterceptorVectorSlotPush(holder_reg); |
585 // Invoke an interceptor. Note: map checks from receiver to | 610 // Invoke an interceptor. Note: map checks from receiver to |
586 // interceptor's holder has been compiled before (see a caller | 611 // interceptor's holder has been compiled before (see a caller |
587 // of this method). | 612 // of this method). |
588 CompileCallLoadPropertyWithInterceptor( | 613 CompileCallLoadPropertyWithInterceptor( |
589 masm(), receiver(), holder_reg, this->name(), holder(), | 614 masm(), receiver(), holder_reg, this->name(), holder(), |
590 IC::kLoadPropertyWithInterceptorOnly); | 615 IC::kLoadPropertyWithInterceptorOnly); |
591 | 616 |
592 // Check if interceptor provided a value for property. If it's | 617 // Check if interceptor provided a value for property. If it's |
593 // the case, return immediately. | 618 // the case, return immediately. |
594 Label interceptor_failed; | 619 Label interceptor_failed; |
595 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); | 620 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); |
596 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); | 621 __ Branch(&interceptor_failed, eq, v0, Operand(scratch1())); |
597 frame_scope.GenerateLeaveFrame(); | 622 frame_scope.GenerateLeaveFrame(); |
598 __ Ret(); | 623 __ Ret(); |
599 | 624 |
600 __ bind(&interceptor_failed); | 625 __ bind(&interceptor_failed); |
| 626 InterceptorVectorSlotPop(holder_reg); |
601 if (must_preserve_receiver_reg) { | 627 if (must_preserve_receiver_reg) { |
602 __ Pop(receiver(), holder_reg, this->name()); | 628 __ Pop(receiver(), holder_reg, this->name()); |
603 } else { | 629 } else { |
604 __ Pop(holder_reg, this->name()); | 630 __ Pop(holder_reg, this->name()); |
605 } | 631 } |
606 // Leave the internal frame. | 632 // Leave the internal frame. |
607 } | 633 } |
608 | 634 |
609 GenerateLoadPostInterceptor(it, holder_reg); | 635 GenerateLoadPostInterceptor(it, holder_reg); |
610 } | 636 } |
611 | 637 |
612 | 638 |
613 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { | 639 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { |
614 // Call the runtime system to load the interceptor. | 640 // Call the runtime system to load the interceptor. |
615 DCHECK(holder()->HasNamedInterceptor()); | 641 DCHECK(holder()->HasNamedInterceptor()); |
616 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); | 642 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); |
617 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), | 643 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), |
618 holder()); | 644 holder()); |
619 | 645 |
620 ExternalReference ref = ExternalReference( | 646 ExternalReference ref = ExternalReference( |
621 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); | 647 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); |
622 __ TailCallExternalReference( | 648 __ TailCallExternalReference( |
623 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); | 649 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); |
624 } | 650 } |
625 | 651 |
626 | 652 |
627 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 653 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
628 Handle<JSObject> object, Handle<Name> name, | 654 Handle<JSObject> object, Handle<Name> name, |
629 Handle<ExecutableAccessorInfo> callback) { | 655 Handle<ExecutableAccessorInfo> callback) { |
630 Register holder_reg = Frontend(receiver(), name); | 656 Register holder_reg = Frontend(name); |
631 | 657 |
632 __ Push(receiver(), holder_reg); // Receiver. | 658 __ Push(receiver(), holder_reg); // Receiver. |
633 __ li(at, Operand(callback)); // Callback info. | 659 __ li(at, Operand(callback)); // Callback info. |
634 __ push(at); | 660 __ push(at); |
635 __ li(at, Operand(name)); | 661 __ li(at, Operand(name)); |
636 __ Push(at, value()); | 662 __ Push(at, value()); |
637 | 663 |
638 // Do tail-call to the runtime system. | 664 // Do tail-call to the runtime system. |
639 ExternalReference store_callback_property = | 665 ExternalReference store_callback_property = |
640 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); | 666 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); |
(...skipping 19 matching lines...) Expand all Loading... |
660 | 686 |
661 | 687 |
662 Register NamedStoreHandlerCompiler::value() { | 688 Register NamedStoreHandlerCompiler::value() { |
663 return StoreDescriptor::ValueRegister(); | 689 return StoreDescriptor::ValueRegister(); |
664 } | 690 } |
665 | 691 |
666 | 692 |
667 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( | 693 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( |
668 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { | 694 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { |
669 Label miss; | 695 Label miss; |
| 696 if (IC::ICUseVector(kind())) { |
| 697 PushVectorAndSlot(); |
| 698 } |
670 | 699 |
671 FrontendHeader(receiver(), name, &miss); | 700 FrontendHeader(receiver(), name, &miss); |
672 | 701 |
673 // Get the value from the cell. | 702 // Get the value from the cell. |
674 Register result = StoreDescriptor::ValueRegister(); | 703 Register result = StoreDescriptor::ValueRegister(); |
675 __ li(result, Operand(cell)); | 704 __ li(result, Operand(cell)); |
676 __ lw(result, FieldMemOperand(result, Cell::kValueOffset)); | 705 __ lw(result, FieldMemOperand(result, Cell::kValueOffset)); |
677 | 706 |
678 // Check for deleted property if property can actually be deleted. | 707 // Check for deleted property if property can actually be deleted. |
679 if (is_configurable) { | 708 if (is_configurable) { |
680 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); | 709 __ LoadRoot(at, Heap::kTheHoleValueRootIndex); |
681 __ Branch(&miss, eq, result, Operand(at)); | 710 __ Branch(&miss, eq, result, Operand(at)); |
682 } | 711 } |
683 | 712 |
684 Counters* counters = isolate()->counters(); | 713 Counters* counters = isolate()->counters(); |
685 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); | 714 __ IncrementCounter(counters->named_load_global_stub(), 1, a1, a3); |
| 715 if (IC::ICUseVector(kind())) { |
| 716 DiscardVectorAndSlot(); |
| 717 } |
686 __ Ret(USE_DELAY_SLOT); | 718 __ Ret(USE_DELAY_SLOT); |
687 __ mov(v0, result); | 719 __ mov(v0, result); |
688 | 720 |
689 FrontendFooter(name, &miss); | 721 FrontendFooter(name, &miss); |
690 | 722 |
691 // Return the generated code. | 723 // Return the generated code. |
692 return GetCode(kind(), Code::NORMAL, name); | 724 return GetCode(kind(), Code::NORMAL, name); |
693 } | 725 } |
694 | 726 |
695 | 727 |
696 #undef __ | 728 #undef __ |
697 } | 729 } |
698 } // namespace v8::internal | 730 } // namespace v8::internal |
699 | 731 |
700 #endif // V8_TARGET_ARCH_MIPS | 732 #endif // V8_TARGET_ARCH_MIPS |
OLD | NEW |