Chromium Code Reviews

Side by Side Diff: src/ic/arm/handler-compiler-arm.cc

Issue 767743002: Hydrogen code stubs for vector-based ICs. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Code comment response (mostly). Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff |
OLDNEW
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_ARM 7 #if V8_TARGET_ARCH_ARM
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...)
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(r0); 86 __ pop(r0);
87 87
88 // Restore context register. 88 // Restore context register.
89 __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); 89 __ ldr(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);
99 __ push(slot);
100 }
101
102
103 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
104 MacroAssembler* masm = this->masm();
105 __ pop(slot);
106 __ pop(vector);
107 }
108
109
110 void PropertyHandlerCompiler::DiscardVectorAndSlot() {
111 MacroAssembler* masm = this->masm();
112 // Remove vector and slot.
113 __ add(sp, sp, Operand(2 * kPointerSize));
114 }
115
116
95 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 117 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
96 MacroAssembler* masm, Label* miss_label, Register receiver, 118 MacroAssembler* masm, Label* miss_label, Register receiver,
97 Handle<Name> name, Register scratch0, Register scratch1) { 119 Handle<Name> name, Register scratch0, Register scratch1) {
98 DCHECK(name->IsUniqueName()); 120 DCHECK(name->IsUniqueName());
99 DCHECK(!receiver.is(scratch0)); 121 DCHECK(!receiver.is(scratch0));
100 Counters* counters = masm->isolate()->counters(); 122 Counters* counters = masm->isolate()->counters();
101 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1); 123 __ IncrementCounter(counters->negative_lookups(), 1, scratch0, scratch1);
102 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1); 124 __ IncrementCounter(counters->negative_lookups_miss(), 1, scratch0, scratch1);
103 125
104 Label done; 126 Label done;
(...skipping 359 matching lines...)
464 // Return the register containing the holder. 486 // Return the register containing the holder.
465 return reg; 487 return reg;
466 } 488 }
467 489
468 490
469 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 491 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
470 if (!miss->is_unused()) { 492 if (!miss->is_unused()) {
471 Label success; 493 Label success;
472 __ b(&success); 494 __ b(&success);
473 __ bind(miss); 495 __ bind(miss);
496 if (IC::ICUseVector(kind())) {
497 DCHECK(kind() == Code::LOAD_IC);
498 PopVectorAndSlot();
499 }
474 TailCallBuiltin(masm(), MissBuiltin(kind())); 500 TailCallBuiltin(masm(), MissBuiltin(kind()));
475 __ bind(&success); 501 __ bind(&success);
476 } 502 }
477 } 503 }
478 504
479 505
480 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 506 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
481 if (!miss->is_unused()) { 507 if (!miss->is_unused()) {
482 Label success; 508 Label success;
483 __ b(&success); 509 __ b(&success);
(...skipping 78 matching lines...)
562 588
563 // Save necessary data before invoking an interceptor. 589 // Save necessary data before invoking an interceptor.
564 // Requires a frame to make GC aware of pushed pointers. 590 // Requires a frame to make GC aware of pushed pointers.
565 { 591 {
566 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL); 592 FrameAndConstantPoolScope frame_scope(masm(), StackFrame::INTERNAL);
567 if (must_preserve_receiver_reg) { 593 if (must_preserve_receiver_reg) {
568 __ Push(receiver(), holder_reg, this->name()); 594 __ Push(receiver(), holder_reg, this->name());
569 } else { 595 } else {
570 __ Push(holder_reg, this->name()); 596 __ Push(holder_reg, this->name());
571 } 597 }
598 InterceptorVectorSlotPush(holder_reg);
572 // Invoke an interceptor. Note: map checks from receiver to 599 // Invoke an interceptor. Note: map checks from receiver to
573 // interceptor's holder has been compiled before (see a caller 600 // interceptor's holder has been compiled before (see a caller
574 // of this method.) 601 // of this method.)
575 CompileCallLoadPropertyWithInterceptor( 602 CompileCallLoadPropertyWithInterceptor(
576 masm(), receiver(), holder_reg, this->name(), holder(), 603 masm(), receiver(), holder_reg, this->name(), holder(),
577 IC::kLoadPropertyWithInterceptorOnly); 604 IC::kLoadPropertyWithInterceptorOnly);
578 605
579 // Check if interceptor provided a value for property. If it's 606 // Check if interceptor provided a value for property. If it's
580 // the case, return immediately. 607 // the case, return immediately.
581 Label interceptor_failed; 608 Label interceptor_failed;
582 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex); 609 __ LoadRoot(scratch1(), Heap::kNoInterceptorResultSentinelRootIndex);
583 __ cmp(r0, scratch1()); 610 __ cmp(r0, scratch1());
584 __ b(eq, &interceptor_failed); 611 __ b(eq, &interceptor_failed);
585 frame_scope.GenerateLeaveFrame(); 612 frame_scope.GenerateLeaveFrame();
586 __ Ret(); 613 __ Ret();
587 614
588 __ bind(&interceptor_failed); 615 __ bind(&interceptor_failed);
616 InterceptorVectorSlotPop(holder_reg);
589 __ pop(this->name()); 617 __ pop(this->name());
590 __ pop(holder_reg); 618 __ pop(holder_reg);
591 if (must_preserve_receiver_reg) { 619 if (must_preserve_receiver_reg) {
592 __ pop(receiver()); 620 __ pop(receiver());
593 } 621 }
594 // Leave the internal frame. 622 // Leave the internal frame.
595 } 623 }
596 624
597 GenerateLoadPostInterceptor(it, holder_reg); 625 GenerateLoadPostInterceptor(it, holder_reg);
598 } 626 }
599 627
600 628
601 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) { 629 void NamedLoadHandlerCompiler::GenerateLoadInterceptor(Register holder_reg) {
602 // Call the runtime system to load the interceptor. 630 // Call the runtime system to load the interceptor.
603 DCHECK(holder()->HasNamedInterceptor()); 631 DCHECK(holder()->HasNamedInterceptor());
604 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined()); 632 DCHECK(!holder()->GetNamedInterceptor()->getter()->IsUndefined());
605 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(), 633 PushInterceptorArguments(masm(), receiver(), holder_reg, this->name(),
606 holder()); 634 holder());
607 635
608 ExternalReference ref = ExternalReference( 636 ExternalReference ref = ExternalReference(
609 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 637 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
610 __ TailCallExternalReference( 638 __ TailCallExternalReference(
611 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 639 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
612 } 640 }
613 641
614 642
615 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 643 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
616 Handle<JSObject> object, Handle<Name> name, 644 Handle<JSObject> object, Handle<Name> name,
617 Handle<ExecutableAccessorInfo> callback) { 645 Handle<ExecutableAccessorInfo> callback) {
618 Register holder_reg = Frontend(receiver(), name); 646 Register holder_reg = Frontend(name);
619 647
620 __ push(receiver()); // receiver 648 __ push(receiver()); // receiver
621 __ push(holder_reg); 649 __ push(holder_reg);
622 __ mov(ip, Operand(callback)); // callback info 650 __ mov(ip, Operand(callback)); // callback info
623 __ push(ip); 651 __ push(ip);
624 __ mov(ip, Operand(name)); 652 __ mov(ip, Operand(name));
625 __ Push(ip, value()); 653 __ Push(ip, value());
626 654
627 // Do tail-call to the runtime system. 655 // Do tail-call to the runtime system.
628 ExternalReference store_callback_property = 656 ExternalReference store_callback_property =
(...skipping 20 matching lines...)
649 677
650 678
651 Register NamedStoreHandlerCompiler::value() { 679 Register NamedStoreHandlerCompiler::value() {
652 return StoreDescriptor::ValueRegister(); 680 return StoreDescriptor::ValueRegister();
653 } 681 }
654 682
655 683
656 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 684 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
657 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 685 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
658 Label miss; 686 Label miss;
687 if (IC::ICUseVector(kind())) {
688 PushVectorAndSlot();
689 }
659 FrontendHeader(receiver(), name, &miss); 690 FrontendHeader(receiver(), name, &miss);
660 691
661 // Get the value from the cell. 692 // Get the value from the cell.
662 Register result = StoreDescriptor::ValueRegister(); 693 Register result = StoreDescriptor::ValueRegister();
663 __ mov(result, Operand(cell)); 694 __ mov(result, Operand(cell));
664 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset)); 695 __ ldr(result, FieldMemOperand(result, Cell::kValueOffset));
665 696
666 // Check for deleted property if property can actually be deleted. 697 // Check for deleted property if property can actually be deleted.
667 if (is_configurable) { 698 if (is_configurable) {
668 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex); 699 __ LoadRoot(ip, Heap::kTheHoleValueRootIndex);
669 __ cmp(result, ip); 700 __ cmp(result, ip);
670 __ b(eq, &miss); 701 __ b(eq, &miss);
671 } 702 }
672 703
673 Counters* counters = isolate()->counters(); 704 Counters* counters = isolate()->counters();
674 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3); 705 __ IncrementCounter(counters->named_load_global_stub(), 1, r1, r3);
706 if (IC::ICUseVector(kind())) {
707 DiscardVectorAndSlot();
708 }
675 __ Ret(); 709 __ Ret();
676 710
677 FrontendFooter(name, &miss); 711 FrontendFooter(name, &miss);
678 712
679 // Return the generated code. 713 // Return the generated code.
680 return GetCode(kind(), Code::NORMAL, name); 714 return GetCode(kind(), Code::NORMAL, name);
681 } 715 }
682 716
683 717
684 #undef __ 718 #undef __
685 } 719 }
686 } // namespace v8::internal 720 } // namespace v8::internal
687 721
688 #endif // V8_TARGET_ARCH_ARM 722 #endif // V8_TARGET_ARCH_ARM
OLDNEW

Powered by Google App Engine