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

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

Powered by Google App Engine
This is Rietveld 408576698