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

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: Patch One. 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() {
51 MacroAssembler* masm = this->masm();
52 __ push(VectorLoadICDescriptor::VectorRegister());
53 __ push(VectorLoadICDescriptor::SlotRegister());
54 }
55
56
57 void PropertyHandlerCompiler::PopVectorAndSlot() {
58 MacroAssembler* masm = this->masm();
59 __ pop(VectorLoadICDescriptor::SlotRegister());
60 __ pop(VectorLoadICDescriptor::VectorRegister());
61 }
62
63
64 void PropertyHandlerCompiler::PushVectorAndSlot(Register vector,
65 Register slot) {
66 MacroAssembler* masm = this->masm();
67 __ push(vector);
68 __ push(slot);
69 }
70
71
72 void PropertyHandlerCompiler::PopVectorAndSlot(Register vector, Register slot) {
73 MacroAssembler* masm = this->masm();
74 __ pop(slot);
75 __ pop(vector);
76 }
77
78
79 void PropertyHandlerCompiler::DiscardVectorAndSlot() {
80 MacroAssembler* masm = this->masm();
81 __ add(esp, Immediate(2 * kPointerSize)); // remove vector and slot
Jakob Kummerow 2014/12/02 08:43:07 nit: Capitalization and punctuation, please.
mvstanton 2014/12/03 11:48:30 Done.
82 }
83
84
50 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup( 85 void PropertyHandlerCompiler::GenerateDictionaryNegativeLookup(
51 MacroAssembler* masm, Label* miss_label, Register receiver, 86 MacroAssembler* masm, Label* miss_label, Register receiver,
52 Handle<Name> name, Register scratch0, Register scratch1) { 87 Handle<Name> name, Register scratch0, Register scratch1) {
53 DCHECK(name->IsUniqueName()); 88 DCHECK(name->IsUniqueName());
54 DCHECK(!receiver.is(scratch0)); 89 DCHECK(!receiver.is(scratch0));
55 Counters* counters = masm->isolate()->counters(); 90 Counters* counters = masm->isolate()->counters();
56 __ IncrementCounter(counters->negative_lookups(), 1); 91 __ IncrementCounter(counters->negative_lookups(), 1);
57 __ IncrementCounter(counters->negative_lookups_miss(), 1); 92 __ IncrementCounter(counters->negative_lookups_miss(), 1);
58 93
59 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset)); 94 __ mov(scratch0, FieldOperand(receiver, HeapObject::kMapOffset));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // Load its initial map. The global functions all have initial maps. 138 // Load its initial map. The global functions all have initial maps.
104 __ Move(prototype, Immediate(Handle<Map>(function->initial_map()))); 139 __ Move(prototype, Immediate(Handle<Map>(function->initial_map())));
105 // Load the prototype from the initial map. 140 // Load the prototype from the initial map.
106 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 141 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
107 } 142 }
108 143
109 144
110 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 145 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
111 MacroAssembler* masm, Register receiver, Register scratch1, 146 MacroAssembler* masm, Register receiver, Register scratch1,
112 Register scratch2, Label* miss_label) { 147 Register scratch2, Label* miss_label) {
148 DCHECK(!FLAG_vector_ics);
113 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 149 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
114 __ mov(eax, scratch1); 150 __ mov(eax, scratch1);
115 __ ret(0); 151 __ ret(0);
116 } 152 }
117 153
118 154
119 // Generate call to api function. 155 // Generate call to api function.
120 // This function uses push() to generate smaller, faster code than 156 // This function uses push() to generate smaller, faster code than
121 // the version above. It is an optimization that should will be removed 157 // the version above. It is an optimization that should will be removed
122 // when api call ICs are generated in hydrogen. 158 // when api call ICs are generated in hydrogen.
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 // Return the register containing the holder. 496 // Return the register containing the holder.
461 return reg; 497 return reg;
462 } 498 }
463 499
464 500
465 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 501 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
466 if (!miss->is_unused()) { 502 if (!miss->is_unused()) {
467 Label success; 503 Label success;
468 __ jmp(&success); 504 __ jmp(&success);
469 __ bind(miss); 505 __ bind(miss);
506 if (FLAG_vector_ics) {
507 DCHECK(kind() == Code::LOAD_IC);
508 PopVectorAndSlot();
509 }
470 TailCallBuiltin(masm(), MissBuiltin(kind())); 510 TailCallBuiltin(masm(), MissBuiltin(kind()));
471 __ bind(&success); 511 __ bind(&success);
472 } 512 }
473 } 513 }
474 514
475 515
476 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 516 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
477 if (!miss->is_unused()) { 517 if (!miss->is_unused()) {
478 Label success; 518 Label success;
479 __ jmp(&success); 519 __ jmp(&success);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 // Save necessary data before invoking an interceptor. 599 // Save necessary data before invoking an interceptor.
560 // Requires a frame to make GC aware of pushed pointers. 600 // Requires a frame to make GC aware of pushed pointers.
561 { 601 {
562 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 602 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
563 603
564 if (must_preserve_receiver_reg) { 604 if (must_preserve_receiver_reg) {
565 __ push(receiver()); 605 __ push(receiver());
566 } 606 }
567 __ push(holder_reg); 607 __ push(holder_reg);
568 __ push(this->name()); 608 __ push(this->name());
569 609 if (FLAG_vector_ics &&
610 (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) {
Jakob Kummerow 2014/12/02 08:43:07 Again, can we re-use IC::ICUseVector() instead of
mvstanton 2014/12/03 11:48:30 Done.
611 // The vector and slot values are already saved on the stack.
612 if (!holder_reg.is(receiver())) {
613 PushVectorAndSlot(scratch2(), scratch3());
Jakob Kummerow 2014/12/02 08:43:07 Why the case distinction? Pushing scratch register
mvstanton 2014/12/03 11:48:30 My earlier lengthy comment and the code changes an
614 } else {
615 PushVectorAndSlot();
616 }
617 }
570 // Invoke an interceptor. Note: map checks from receiver to 618 // Invoke an interceptor. Note: map checks from receiver to
571 // interceptor's holder has been compiled before (see a caller 619 // interceptor's holder has been compiled before (see a caller
572 // of this method.) 620 // of this method.)
573 CompileCallLoadPropertyWithInterceptor( 621 CompileCallLoadPropertyWithInterceptor(
574 masm(), receiver(), holder_reg, this->name(), holder(), 622 masm(), receiver(), holder_reg, this->name(), holder(),
575 IC::kLoadPropertyWithInterceptorOnly); 623 IC::kLoadPropertyWithInterceptorOnly);
576 624
577 // Check if interceptor provided a value for property. If it's 625 // Check if interceptor provided a value for property. If it's
578 // the case, return immediately. 626 // the case, return immediately.
579 Label interceptor_failed; 627 Label interceptor_failed;
580 __ cmp(eax, factory()->no_interceptor_result_sentinel()); 628 __ cmp(eax, factory()->no_interceptor_result_sentinel());
581 __ j(equal, &interceptor_failed); 629 __ j(equal, &interceptor_failed);
582 frame_scope.GenerateLeaveFrame(); 630 frame_scope.GenerateLeaveFrame();
583 __ ret(0); 631 __ ret(0);
584 632
585 // Clobber registers when generating debug-code to provoke errors. 633 // Clobber registers when generating debug-code to provoke errors.
586 __ bind(&interceptor_failed); 634 __ bind(&interceptor_failed);
587 if (FLAG_debug_code) { 635 if (FLAG_debug_code) {
588 __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue))); 636 __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue)));
589 __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue))); 637 __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue)));
590 __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue))); 638 __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue)));
591 } 639 }
592 640
641 if (FLAG_vector_ics &&
642 (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) {
643 if (!holder_reg.is(receiver())) {
644 PopVectorAndSlot(scratch2(), scratch3());
645 } else {
646 PopVectorAndSlot();
647 }
648 }
593 __ pop(this->name()); 649 __ pop(this->name());
594 __ pop(holder_reg); 650 __ pop(holder_reg);
595 if (must_preserve_receiver_reg) { 651 if (must_preserve_receiver_reg) {
596 __ pop(receiver()); 652 __ pop(receiver());
597 } 653 }
598 654
599 // Leave the internal frame. 655 // Leave the internal frame.
600 } 656 }
601 657
602 GenerateLoadPostInterceptor(it, holder_reg); 658 GenerateLoadPostInterceptor(it, holder_reg);
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
661 717
662 718
663 Register NamedStoreHandlerCompiler::value() { 719 Register NamedStoreHandlerCompiler::value() {
664 return StoreDescriptor::ValueRegister(); 720 return StoreDescriptor::ValueRegister();
665 } 721 }
666 722
667 723
668 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 724 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
669 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 725 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
670 Label miss; 726 Label miss;
671 727 if (FLAG_vector_ics &&
728 (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) {
729 PushVectorAndSlot();
730 }
672 FrontendHeader(receiver(), name, &miss); 731 FrontendHeader(receiver(), name, &miss);
673 // Get the value from the cell. 732 // Get the value from the cell.
674 Register result = StoreDescriptor::ValueRegister(); 733 Register result = StoreDescriptor::ValueRegister();
675 if (masm()->serializer_enabled()) { 734 if (masm()->serializer_enabled()) {
676 __ mov(result, Immediate(cell)); 735 __ mov(result, Immediate(cell));
677 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); 736 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
678 } else { 737 } else {
679 __ mov(result, Operand::ForCell(cell)); 738 __ mov(result, Operand::ForCell(cell));
680 } 739 }
681 740
682 // Check for deleted property if property can actually be deleted. 741 // Check for deleted property if property can actually be deleted.
683 if (is_configurable) { 742 if (is_configurable) {
684 __ cmp(result, factory()->the_hole_value()); 743 __ cmp(result, factory()->the_hole_value());
685 __ j(equal, &miss); 744 __ j(equal, &miss);
686 } else if (FLAG_debug_code) { 745 } else if (FLAG_debug_code) {
687 __ cmp(result, factory()->the_hole_value()); 746 __ cmp(result, factory()->the_hole_value());
688 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 747 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
689 } 748 }
690 749
691 Counters* counters = isolate()->counters(); 750 Counters* counters = isolate()->counters();
692 __ IncrementCounter(counters->named_load_global_stub(), 1); 751 __ IncrementCounter(counters->named_load_global_stub(), 1);
693 // The code above already loads the result into the return register. 752 // The code above already loads the result into the return register.
753 if (FLAG_vector_ics &&
754 (kind() == Code::LOAD_IC || kind() == Code::KEYED_LOAD_IC)) {
755 DiscardVectorAndSlot();
756 }
694 __ ret(0); 757 __ ret(0);
695 758
696 FrontendFooter(name, &miss); 759 FrontendFooter(name, &miss);
697 760
698 // Return the generated code. 761 // Return the generated code.
699 return GetCode(kind(), Code::NORMAL, name); 762 return GetCode(kind(), Code::NORMAL, name);
700 } 763 }
701 764
702 765
703 #undef __ 766 #undef __
704 } 767 }
705 } // namespace v8::internal 768 } // namespace v8::internal
706 769
707 #endif // V8_TARGET_ARCH_IA32 770 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698