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

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: Comment response. 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
103 // Load its initial map. The global functions all have initial maps. 125 // Load its initial map. The global functions all have initial maps.
104 __ Move(prototype, Immediate(Handle<Map>(function->initial_map()))); 126 __ Move(prototype, Immediate(Handle<Map>(function->initial_map())));
105 // Load the prototype from the initial map. 127 // Load the prototype from the initial map.
106 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 128 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
107 } 129 }
108 130
109 131
110 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype( 132 void NamedLoadHandlerCompiler::GenerateLoadFunctionPrototype(
111 MacroAssembler* masm, Register receiver, Register scratch1, 133 MacroAssembler* masm, Register receiver, Register scratch1,
112 Register scratch2, Label* miss_label) { 134 Register scratch2, Label* miss_label) {
135 DCHECK(!FLAG_vector_ics);
113 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label); 136 __ TryGetFunctionPrototype(receiver, scratch1, scratch2, miss_label);
114 __ mov(eax, scratch1); 137 __ mov(eax, scratch1);
115 __ ret(0); 138 __ ret(0);
116 } 139 }
117 140
118 141
119 // Generate call to api function. 142 // Generate call to api function.
120 // This function uses push() to generate smaller, faster code than 143 // This function uses push() to generate smaller, faster code than
121 // the version above. It is an optimization that should will be removed 144 // the version above. It is an optimization that should will be removed
122 // when api call ICs are generated in hydrogen. 145 // 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. 483 // Return the register containing the holder.
461 return reg; 484 return reg;
462 } 485 }
463 486
464 487
465 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 488 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
466 if (!miss->is_unused()) { 489 if (!miss->is_unused()) {
467 Label success; 490 Label success;
468 __ jmp(&success); 491 __ jmp(&success);
469 __ bind(miss); 492 __ bind(miss);
493 if (IC::ICUseVector(kind())) {
494 DCHECK(kind() == Code::LOAD_IC);
495 PopVectorAndSlot();
496 }
470 TailCallBuiltin(masm(), MissBuiltin(kind())); 497 TailCallBuiltin(masm(), MissBuiltin(kind()));
471 __ bind(&success); 498 __ bind(&success);
472 } 499 }
473 } 500 }
474 501
475 502
476 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 503 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
477 if (!miss->is_unused()) { 504 if (!miss->is_unused()) {
478 Label success; 505 Label success;
479 __ jmp(&success); 506 __ jmp(&success);
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
559 // Save necessary data before invoking an interceptor. 586 // Save necessary data before invoking an interceptor.
560 // Requires a frame to make GC aware of pushed pointers. 587 // Requires a frame to make GC aware of pushed pointers.
561 { 588 {
562 FrameScope frame_scope(masm(), StackFrame::INTERNAL); 589 FrameScope frame_scope(masm(), StackFrame::INTERNAL);
563 590
564 if (must_preserve_receiver_reg) { 591 if (must_preserve_receiver_reg) {
565 __ push(receiver()); 592 __ push(receiver());
566 } 593 }
567 __ push(holder_reg); 594 __ push(holder_reg);
568 __ push(this->name()); 595 __ push(this->name());
569 596 InterceptorVectorSlotPush(holder_reg);
570 // Invoke an interceptor. Note: map checks from receiver to 597 // Invoke an interceptor. Note: map checks from receiver to
571 // interceptor's holder has been compiled before (see a caller 598 // interceptor's holder has been compiled before (see a caller
572 // of this method.) 599 // of this method.)
573 CompileCallLoadPropertyWithInterceptor( 600 CompileCallLoadPropertyWithInterceptor(
574 masm(), receiver(), holder_reg, this->name(), holder(), 601 masm(), receiver(), holder_reg, this->name(), holder(),
575 IC::kLoadPropertyWithInterceptorOnly); 602 IC::kLoadPropertyWithInterceptorOnly);
576 603
577 // Check if interceptor provided a value for property. If it's 604 // Check if interceptor provided a value for property. If it's
578 // the case, return immediately. 605 // the case, return immediately.
579 Label interceptor_failed; 606 Label interceptor_failed;
580 __ cmp(eax, factory()->no_interceptor_result_sentinel()); 607 __ cmp(eax, factory()->no_interceptor_result_sentinel());
581 __ j(equal, &interceptor_failed); 608 __ j(equal, &interceptor_failed);
582 frame_scope.GenerateLeaveFrame(); 609 frame_scope.GenerateLeaveFrame();
583 __ ret(0); 610 __ ret(0);
584 611
585 // Clobber registers when generating debug-code to provoke errors. 612 // Clobber registers when generating debug-code to provoke errors.
586 __ bind(&interceptor_failed); 613 __ bind(&interceptor_failed);
587 if (FLAG_debug_code) { 614 if (FLAG_debug_code) {
588 __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue))); 615 __ mov(receiver(), Immediate(bit_cast<int32_t>(kZapValue)));
589 __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue))); 616 __ mov(holder_reg, Immediate(bit_cast<int32_t>(kZapValue)));
590 __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue))); 617 __ mov(this->name(), Immediate(bit_cast<int32_t>(kZapValue)));
591 } 618 }
592 619
620 InterceptorVectorSlotPop(holder_reg);
593 __ pop(this->name()); 621 __ pop(this->name());
594 __ pop(holder_reg); 622 __ pop(holder_reg);
595 if (must_preserve_receiver_reg) { 623 if (must_preserve_receiver_reg) {
596 __ pop(receiver()); 624 __ pop(receiver());
597 } 625 }
598 626
599 // Leave the internal frame. 627 // Leave the internal frame.
600 } 628 }
601 629
602 GenerateLoadPostInterceptor(it, holder_reg); 630 GenerateLoadPostInterceptor(it, holder_reg);
(...skipping 12 matching lines...) Expand all
615 ExternalReference ref = ExternalReference( 643 ExternalReference ref = ExternalReference(
616 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate()); 644 IC_Utility(IC::kLoadPropertyWithInterceptor), isolate());
617 __ TailCallExternalReference( 645 __ TailCallExternalReference(
618 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1); 646 ref, NamedLoadHandlerCompiler::kInterceptorArgsLength, 1);
619 } 647 }
620 648
621 649
622 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 650 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
623 Handle<JSObject> object, Handle<Name> name, 651 Handle<JSObject> object, Handle<Name> name,
624 Handle<ExecutableAccessorInfo> callback) { 652 Handle<ExecutableAccessorInfo> callback) {
625 Register holder_reg = Frontend(receiver(), name); 653 Register holder_reg = Frontend(name);
626 654
627 __ pop(scratch1()); // remove the return address 655 __ pop(scratch1()); // remove the return address
628 __ push(receiver()); 656 __ push(receiver());
629 __ push(holder_reg); 657 __ push(holder_reg);
630 __ Push(callback); 658 __ Push(callback);
631 __ Push(name); 659 __ Push(name);
632 __ push(value()); 660 __ push(value());
633 __ push(scratch1()); // restore return address 661 __ push(scratch1()); // restore return address
634 662
635 // Do tail-call to the runtime system. 663 // Do tail-call to the runtime system.
(...skipping 25 matching lines...) Expand all
661 689
662 690
663 Register NamedStoreHandlerCompiler::value() { 691 Register NamedStoreHandlerCompiler::value() {
664 return StoreDescriptor::ValueRegister(); 692 return StoreDescriptor::ValueRegister();
665 } 693 }
666 694
667 695
668 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 696 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
669 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 697 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
670 Label miss; 698 Label miss;
671 699 if (IC::ICUseVector(kind())) {
700 PushVectorAndSlot();
701 }
672 FrontendHeader(receiver(), name, &miss); 702 FrontendHeader(receiver(), name, &miss);
673 // Get the value from the cell. 703 // Get the value from the cell.
674 Register result = StoreDescriptor::ValueRegister(); 704 Register result = StoreDescriptor::ValueRegister();
675 if (masm()->serializer_enabled()) { 705 if (masm()->serializer_enabled()) {
676 __ mov(result, Immediate(cell)); 706 __ mov(result, Immediate(cell));
677 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); 707 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
678 } else { 708 } else {
679 __ mov(result, Operand::ForCell(cell)); 709 __ mov(result, Operand::ForCell(cell));
680 } 710 }
681 711
682 // Check for deleted property if property can actually be deleted. 712 // Check for deleted property if property can actually be deleted.
683 if (is_configurable) { 713 if (is_configurable) {
684 __ cmp(result, factory()->the_hole_value()); 714 __ cmp(result, factory()->the_hole_value());
685 __ j(equal, &miss); 715 __ j(equal, &miss);
686 } else if (FLAG_debug_code) { 716 } else if (FLAG_debug_code) {
687 __ cmp(result, factory()->the_hole_value()); 717 __ cmp(result, factory()->the_hole_value());
688 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 718 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
689 } 719 }
690 720
691 Counters* counters = isolate()->counters(); 721 Counters* counters = isolate()->counters();
692 __ IncrementCounter(counters->named_load_global_stub(), 1); 722 __ IncrementCounter(counters->named_load_global_stub(), 1);
693 // The code above already loads the result into the return register. 723 // The code above already loads the result into the return register.
724 if (IC::ICUseVector(kind())) {
725 DiscardVectorAndSlot();
726 }
694 __ ret(0); 727 __ ret(0);
695 728
696 FrontendFooter(name, &miss); 729 FrontendFooter(name, &miss);
697 730
698 // Return the generated code. 731 // Return the generated code.
699 return GetCode(kind(), Code::NORMAL, name); 732 return GetCode(kind(), Code::NORMAL, name);
700 } 733 }
701 734
702 735
703 #undef __ 736 #undef __
704 } 737 }
705 } // namespace v8::internal 738 } // namespace v8::internal
706 739
707 #endif // V8_TARGET_ARCH_IA32 740 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698