Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(9)

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

Issue 767743002: Hydrogen code stubs for vector-based ICs. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase. Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ic/handler-compiler.cc ('k') | src/ic/ia32/ic-compiler-ia32.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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_IA32 7 #if V8_TARGET_ARCH_IA32
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 29 matching lines...) Expand all
40 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset()); 40 masm->isolate()->heap()->SetGetterStubDeoptPCOffset(masm->pc_offset());
41 } 41 }
42 42
43 // Restore context register. 43 // Restore context register.
44 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); 44 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
45 } 45 }
46 __ ret(0); 46 __ ret(0);
47 } 47 }
48 48
49 49
50 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
51 Register slot) {
52 MacroAssembler* masm = this->masm();
53 __ push(vector);
54 __ push(slot);
55 }
56
57
58 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
59 MacroAssembler* masm = this->masm();
60 __ pop(slot);
61 __ pop(vector);
62 }
63
64
65 void PropertyHandlerCompiler::DiscardVectorAndSlot() {
66 MacroAssembler* masm = this->masm();
67 // Remove vector and slot.
68 __ add(esp, Immediate(2 * kPointerSize));
69 }
70
71
50 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 72 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
51 MacroAssembler* masm, Label* miss_label, Register receiver, 73 MacroAssembler* masm, Label* miss_label, Register receiver,
52 Handle<Name> name, Register scratch0, Register scratch1) { 74 Handle<Name> name, Register scratch0, Register scratch1) {
53 DCHECK(name->IsUniqueName()); 75 DCHECK(name->IsUniqueName());
54 DCHECK(!receiver.is(scratch0)); 76 DCHECK(!receiver.is(scratch0));
55 Counters* counters = masm->isolate()->counters(); 77 Counters* counters = masm->isolate()->counters();
56 __ IncrementCounter(counters->negative_lookups(), 1); 78 __ IncrementCounter(counters->negative_lookups(), 1);
57 __ IncrementCounter(counters->negative_lookups_miss(), 1); 79 __ IncrementCounter(counters->negative_lookups_miss(), 1);
58 80
59 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 81 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 __ mov(result, 119 __ mov(result,
98 FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset)); 120 FieldOperand(result, JSFunction::kPrototypeOrInitialMapOffset));
99 // Load the prototype from the initial map. 121 // Load the prototype from the initial map.
100 __ mov(result, FieldOperand(result, Map::kPrototypeOffset)); 122 __ mov(result, FieldOperand(result, Map::kPrototypeOffset));
101 } 123 }
102 124
103 125
104 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 126 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
105 MacroAssembler* masm, Register receiver, Register scratch1, 127 MacroAssembler* masm, Register receiver, Register scratch1,
106 Register scratch2, Label* miss_label) { 128 Register scratch2, Label* miss_label) {
129 DCHECK(!FLAG_vector_ics);
107 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 130 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
108 __ mov(eax, scratch1); 131 __ mov(eax, scratch1);
109 __ ret(0); 132 __ ret(0);
110 } 133 }
111 134
112 135
113 // Generate call to api function. 136 // Generate call to api function.
114 // This function uses push() to generate smaller, faster code than 137 // This function uses push() to generate smaller, faster code than
115 // the version above. It is an optimization that should will be removed 138 // the version above. It is an optimization that should will be removed
116 // when api call ICs are generated in hydrogen. 139 // when api call ICs are generated in hydrogen.
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
482 // Return the register containing the holder. 505 // Return the register containing the holder.
483 return reg; 506 return reg;
484 } 507 }
485 508
486 509
487 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 510 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
488 if (!miss->is_unused()) { 511 if (!miss->is_unused()) {
489 Label success; 512 Label success;
490 __ jmp(&success); 513 __ jmp(&success);
491 __ bind(miss); 514 __ bind(miss);
515 if (IC::ICUseVector(kind())) {
516 DCHECK(kind() == Code::LOAD_IC);
517 PopVectorAndSlot();
518 }
492 TailCallBuiltin(masm(), MissBuiltin(kind())); 519 TailCallBuiltin(masm(), MissBuiltin(kind()));
493 __ bind(&success); 520 __ bind(&success);
494 } 521 }
495 } 522 }
496 523
497 524
498 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 525 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
499 if (!miss->is_unused()) { 526 if (!miss->is_unused()) {
500 Label success; 527 Label success;
501 __ jmp(&success); 528 __ jmp(&success);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 // Save necessary data before invoking an interceptor. 608 // Save necessary data before invoking an interceptor.
582 // Requires a frame to make GC aware of pushed pointers. 609 // Requires a frame to make GC aware of pushed pointers.
583 { 610 {
584 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 611 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
585 612
586 if (must_preserve_receiver_reg) { 613 if (must_preserve_receiver_reg) {
587 __ push(receiver()); 614 __ push(receiver());
588 } 615 }
589 __ push(holder_reg); 616 __ push(holder_reg);
590 __ push(this->name()); 617 __ push(this->name());
591 618 InterceptorVectorSlotPush(holder_reg);
592 // Invoke an interceptor. Note: map checks from receiver to 619 // Invoke an interceptor. Note: map checks from receiver to
593 // interceptor's holder has been compiled before (see a caller 620 // interceptor's holder has been compiled before (see a caller
594 // of this method.) 621 // of this method.)
595 CompileCallLoadPropertyWithInterceptor( 622 CompileCallLoadPropertyWithInterceptor(
596 masm(), receiver(), holder_reg, this->name(), holder(), 623 masm(), receiver(), holder_reg, this->name(), holder(),
597 IC::kLoadPropertyWithInterceptorOnly); 624 IC::kLoadPropertyWithInterceptorOnly);
598 625
599 // Check if interceptor provided a value for property. If it's 626 // Check if interceptor provided a value for property. If it's
600 // the case, return immediately. 627 // the case, return immediately.
601 Label interceptor_failed; 628 Label interceptor_failed;
602 __ cmp(eax, factory()->no_interceptor_result_sentinel()); 629 __ cmp(eax, factory()->no_interceptor_result_sentinel());
603 __ j(equal, &interceptor_failed); 630 __ j(equal, &interceptor_failed);
604 frame_scope.GenerateLeaveFrame(); 631 frame_scope.GenerateLeaveFrame();
605 __ ret(0); 632 __ ret(0);
606 633
607 // Clobber registers when generating debug-code to provoke errors. 634 // Clobber registers when generating debug-code to provoke errors.
608 __ bind(&interceptor_failed); 635 __ bind(&interceptor_failed);
609 if (FLAG_debug_code) { 636 if (FLAG_debug_code) {
610 __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue))); 637 __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue)));
611 __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue))); 638 __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue)));
612 __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue))); 639 __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue)));
613 } 640 }
614 641
642 InterceptorVectorSlotPop(holder_reg);
615 __ pop(this->name()); 643 __ pop(this->name());
616 __ pop(holder_reg); 644 __ pop(holder_reg);
617 if (must_preserve_receiver_reg) { 645 if (must_preserve_receiver_reg) {
618 __ pop(receiver()); 646 __ pop(receiver());
619 } 647 }
620 648
621 // Leave the internal frame. 649 // Leave the internal frame.
622 } 650 }
623 651
624 GenerateLoadPostInterceptor(it, holder_reg); 652 GenerateLoadPostInterceptor(it, holder_reg);
(...skipping 12 matching lines...) Expand all
637 ExternalReference ref = ExternalReference( 665 ExternalReference ref = ExternalReference(
638 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 666 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
639 __ TailCallExternalReference( 667 __ TailCallExternalReference(
640 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 668 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
641 } 669 }
642 670
643 671
644 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 672 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
645 Handle<JSObject> object, Handle<Name> name, 673 Handle<JSObject> object, Handle<Name> name,
646 Handle<ExecutableAccessorInfo> callback) { 674 Handle<ExecutableAccessorInfo> callback) {
647 Register holder_reg = Frontend(receiver(), name); 675 Register holder_reg = Frontend(name);
648 676
649 __ pop(scratch1()); // remove the return address 677 __ pop(scratch1()); // remove the return address
650 __ push(receiver()); 678 __ push(receiver());
651 __ push(holder_reg); 679 __ push(holder_reg);
652 __ Push(callback); 680 __ Push(callback);
653 __ Push(name); 681 __ Push(name);
654 __ push(value()); 682 __ push(value());
655 __ push(scratch1()); // restore return address 683 __ push(scratch1()); // restore return address
656 684
657 // Do tail-call to the runtime system. 685 // Do tail-call to the runtime system.
(...skipping 25 matching lines...) Expand all
683 711
684 712
685 Register NamedStoreHandlerCompiler::value() { 713 Register NamedStoreHandlerCompiler::value() {
686 return StoreDescriptor::ValueRegister(); 714 return StoreDescriptor::ValueRegister();
687 } 715 }
688 716
689 717
690 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 718 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
691 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 719 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
692 Label miss; 720 Label miss;
693 721 if (IC::ICUseVector(kind())) {
722 PushVectorAndSlot();
723 }
694 FrontendHeader(receiver(), name, &miss); 724 FrontendHeader(receiver(), name, &miss);
695 // Get the value from the cell. 725 // Get the value from the cell.
696 Register result = StoreDescriptor::ValueRegister(); 726 Register result = StoreDescriptor::ValueRegister();
697 if (masm()->serializer_enabled()) { 727 if (masm()->serializer_enabled()) {
698 __ mov(result, Immediate(cell)); 728 __ mov(result, Immediate(cell));
699 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); 729 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
700 } else { 730 } else {
701 __ mov(result, Operand::ForCell(cell)); 731 __ mov(result, Operand::ForCell(cell));
702 } 732 }
703 733
704 // Check for deleted property if property can actually be deleted. 734 // Check for deleted property if property can actually be deleted.
705 if (is_configurable) { 735 if (is_configurable) {
706 __ cmp(result, factory()->the_hole_value()); 736 __ cmp(result, factory()->the_hole_value());
707 __ j(equal, &miss); 737 __ j(equal, &miss);
708 } else if (FLAG_debug_code) { 738 } else if (FLAG_debug_code) {
709 __ cmp(result, factory()->the_hole_value()); 739 __ cmp(result, factory()->the_hole_value());
710 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 740 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
711 } 741 }
712 742
713 Counters* counters = isolate()->counters(); 743 Counters* counters = isolate()->counters();
714 __ IncrementCounter(counters->named_load_global_stub(), 1); 744 __ IncrementCounter(counters->named_load_global_stub(), 1);
715 // The code above already loads the result into the return register. 745 // The code above already loads the result into the return register.
746 if (IC::ICUseVector(kind())) {
747 DiscardVectorAndSlot();
748 }
716 __ ret(0); 749 __ ret(0);
717 750
718 FrontendFooter(name, &miss); 751 FrontendFooter(name, &miss);
719 752
720 // Return the generated code. 753 // Return the generated code.
721 return GetCode(kind(), Code::NORMAL, name); 754 return GetCode(kind(), Code::NORMAL, name);
722 } 755 }
723 756
724 757
725 #undef __ 758 #undef __
726 } 759 }
727 } // namespace v8::internal 760 } // namespace v8::internal
728 761
729 #endif // V8_TARGET_ARCH_IA32 762 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ic/handler-compiler.cc ('k') | src/ic/ia32/ic-compiler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698