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

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

Issue 2357163003: [ic][ia32][x87] Pass value, slot and vector to StoreIC and KeyedStoreIC through the stack. (Closed)
Patch Set: Created 4 years, 3 months 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 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/ic/handler-compiler.h" 7 #include "src/ic/handler-compiler.h"
8 8
9 #include "src/api-arguments.h" 9 #include "src/api-arguments.h"
10 #include "src/field-type.h" 10 #include "src/field-type.h"
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 // the version above. It is an optimization that should will be removed 158 // the version above. It is an optimization that should will be removed
159 // when api call ICs are generated in hydrogen. 159 // when api call ICs are generated in hydrogen.
160 void PropertyHandlerCompiler::GenerateApiAccessorCall( 160 void PropertyHandlerCompiler::GenerateApiAccessorCall(
161 MacroAssembler* masm, const CallOptimization& optimization, 161 MacroAssembler* masm, const CallOptimization& optimization,
162 Handle<Map> receiver_map, Register receiver, Register scratch, 162 Handle<Map> receiver_map, Register receiver, Register scratch,
163 bool is_store, Register store_parameter, Register accessor_holder, 163 bool is_store, Register store_parameter, Register accessor_holder,
164 int accessor_index) { 164 int accessor_index) {
165 DCHECK(!accessor_holder.is(scratch)); 165 DCHECK(!accessor_holder.is(scratch));
166 // Copy return value. 166 // Copy return value.
167 __ pop(scratch); 167 __ pop(scratch);
168
169 if (is_store) {
170 // Discard stack arguments.
171 __ add(esp, Immediate(StoreWithVectorDescriptor::kStackArgumentsCount *
172 kPointerSize));
173 }
174
168 // receiver 175 // receiver
169 __ push(receiver); 176 __ push(receiver);
170 // Write the arguments to stack frame. 177 // Write the arguments to stack frame.
171 if (is_store) { 178 if (is_store) {
172 DCHECK(!receiver.is(store_parameter)); 179 DCHECK(!receiver.is(store_parameter));
173 DCHECK(!scratch.is(store_parameter)); 180 DCHECK(!scratch.is(store_parameter));
174 __ push(store_parameter); 181 __ push(store_parameter);
175 } 182 }
176 __ push(scratch); 183 __ push(scratch);
177 // Stack now matches JSFunction abi. 184 // Stack now matches JSFunction abi.
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // If we generate a global code snippet for deoptimization only, remember 305 // If we generate a global code snippet for deoptimization only, remember
299 // the place to continue after deoptimization. 306 // the place to continue after deoptimization.
300 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset()); 307 masm->isolate()->heap()->SetSetterStubDeoptPCOffset(masm->pc_offset());
301 } 308 }
302 309
303 // We have to return the passed value, not the return value of the setter. 310 // We have to return the passed value, not the return value of the setter.
304 __ pop(eax); 311 __ pop(eax);
305 // Restore context register. 312 // Restore context register.
306 __ pop(esi); 313 __ pop(esi);
307 } 314 }
308 __ ret(0); 315 if (accessor_index >= 0) {
316 __ ret(StoreWithVectorDescriptor::kStackArgumentsCount * kPointerSize);
317 } else {
318 // If we generate a global code snippet for deoptimization only, don't try
319 // to drop stack arguments for the StoreIC because they are not a part of
320 // expression stack and deoptimizer does not reconstruct them.
321 __ ret(0);
322 }
309 } 323 }
310 324
311 325
312 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver, 326 static void PushInterceptorArguments(MacroAssembler* masm, Register receiver,
313 Register holder, Register name, 327 Register holder, Register name,
314 Handle<JSObject> holder_obj) { 328 Handle<JSObject> holder_obj) {
315 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0); 329 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsNameIndex == 0);
316 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1); 330 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsThisIndex == 1);
317 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2); 331 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsHolderIndex == 2);
318 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3); 332 STATIC_ASSERT(NamedLoadHandlerCompiler::kInterceptorArgsLength == 3);
(...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 // Return the register containing the holder. 515 // Return the register containing the holder.
502 return return_holder ? reg : no_reg; 516 return return_holder ? reg : no_reg;
503 } 517 }
504 518
505 519
506 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 520 void NamedLoadHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
507 if (!miss->is_unused()) { 521 if (!miss->is_unused()) {
508 Label success; 522 Label success;
509 __ jmp(&success); 523 __ jmp(&success);
510 __ bind(miss); 524 __ bind(miss);
511 if (IC::ICUseVector(kind())) { 525 if (IC::ShouldPushPopSlotAndVector(kind())) {
512 DCHECK(kind() == Code::LOAD_IC); 526 DCHECK(kind() == Code::LOAD_IC);
513 PopVectorAndSlot(); 527 PopVectorAndSlot();
514 } 528 }
515 TailCallBuiltin(masm(), MissBuiltin(kind())); 529 TailCallBuiltin(masm(), MissBuiltin(kind()));
516 __ bind(&success); 530 __ bind(&success);
517 } 531 }
518 } 532 }
519 533
520 534
521 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) { 535 void NamedStoreHandlerCompiler::FrontendFooter(Handle<Name> name, Label* miss) {
522 if (!miss->is_unused()) { 536 if (!miss->is_unused()) {
523 Label success; 537 Label success;
524 __ jmp(&success); 538 __ jmp(&success);
525 GenerateRestoreName(miss, name); 539 GenerateRestoreName(miss, name);
526 if (IC::ICUseVector(kind())) PopVectorAndSlot(); 540 DCHECK(!IC::ShouldPushPopSlotAndVector(kind()));
527 TailCallBuiltin(masm(), MissBuiltin(kind())); 541 TailCallBuiltin(masm(), MissBuiltin(kind()));
528 __ bind(&success); 542 __ bind(&success);
529 } 543 }
530 } 544 }
531 545
532 546
533 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) { 547 void NamedLoadHandlerCompiler::GenerateLoadConstant(Handle<Object> value) {
534 // Return the constant value. 548 // Return the constant value.
535 __ LoadObject(eax, value); 549 __ LoadObject(eax, value);
536 __ ret(0); 550 __ ret(0);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
617 __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor); 631 __ TailCallRuntime(Runtime::kLoadPropertyWithInterceptor);
618 } 632 }
619 633
620 634
621 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( 635 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback(
622 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback, 636 Handle<JSObject> object, Handle<Name> name, Handle<AccessorInfo> callback,
623 LanguageMode language_mode) { 637 LanguageMode language_mode) {
624 Register holder_reg = Frontend(name); 638 Register holder_reg = Frontend(name);
625 639
626 __ pop(scratch1()); // remove the return address 640 __ pop(scratch1()); // remove the return address
641 // Discard stack arguments.
642 __ add(esp, Immediate(StoreWithVectorDescriptor::kStackArgumentsCount *
643 kPointerSize));
627 __ push(receiver()); 644 __ push(receiver());
628 __ push(holder_reg); 645 __ push(holder_reg);
629 // If the callback cannot leak, then push the callback directly, 646 // If the callback cannot leak, then push the callback directly,
630 // otherwise wrap it in a weak cell. 647 // otherwise wrap it in a weak cell.
631 if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) { 648 if (callback->data()->IsUndefined(isolate()) || callback->data()->IsSmi()) {
632 __ Push(callback); 649 __ Push(callback);
633 } else { 650 } else {
634 Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback); 651 Handle<WeakCell> cell = isolate()->factory()->NewWeakCell(callback);
635 __ Push(cell); 652 __ Push(cell);
636 } 653 }
(...skipping 11 matching lines...) Expand all
648 665
649 666
650 Register NamedStoreHandlerCompiler::value() { 667 Register NamedStoreHandlerCompiler::value() {
651 return StoreDescriptor::ValueRegister(); 668 return StoreDescriptor::ValueRegister();
652 } 669 }
653 670
654 671
655 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal( 672 Handle<Code> NamedLoadHandlerCompiler::CompileLoadGlobal(
656 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) { 673 Handle<PropertyCell> cell, Handle<Name> name, bool is_configurable) {
657 Label miss; 674 Label miss;
658 if (IC::ICUseVector(kind())) { 675 if (IC::ShouldPushPopSlotAndVector(kind())) {
659 PushVectorAndSlot(); 676 PushVectorAndSlot();
660 } 677 }
661 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING); 678 FrontendHeader(receiver(), name, &miss, DONT_RETURN_ANYTHING);
662 // Get the value from the cell. 679 // Get the value from the cell.
663 Register result = StoreDescriptor::ValueRegister(); 680 Register result = StoreDescriptor::ValueRegister();
664 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell); 681 Handle<WeakCell> weak_cell = factory()->NewWeakCell(cell);
665 __ LoadWeakValue(result, weak_cell, &miss); 682 __ LoadWeakValue(result, weak_cell, &miss);
666 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset)); 683 __ mov(result, FieldOperand(result, PropertyCell::kValueOffset));
667 684
668 // Check for deleted property if property can actually be deleted. 685 // Check for deleted property if property can actually be deleted.
669 if (is_configurable) { 686 if (is_configurable) {
670 __ cmp(result, factory()->the_hole_value()); 687 __ cmp(result, factory()->the_hole_value());
671 __ j(equal, &miss); 688 __ j(equal, &miss);
672 } else if (FLAG_debug_code) { 689 } else if (FLAG_debug_code) {
673 __ cmp(result, factory()->the_hole_value()); 690 __ cmp(result, factory()->the_hole_value());
674 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole); 691 __ Check(not_equal, kDontDeleteCellsCannotContainTheHole);
675 } 692 }
676 693
677 Counters* counters = isolate()->counters(); 694 Counters* counters = isolate()->counters();
678 __ IncrementCounter(counters->ic_named_load_global_stub(), 1); 695 __ IncrementCounter(counters->ic_named_load_global_stub(), 1);
679 // The code above already loads the result into the return register. 696 // The code above already loads the result into the return register.
680 if (IC::ICUseVector(kind())) { 697 if (IC::ShouldPushPopSlotAndVector(kind())) {
681 DiscardVectorAndSlot(); 698 DiscardVectorAndSlot();
682 } 699 }
683 __ ret(0); 700 __ ret(0);
684 701
685 FrontendFooter(name, &miss); 702 FrontendFooter(name, &miss);
686 703
687 // Return the generated code. 704 // Return the generated code.
688 return GetCode(kind(), name); 705 return GetCode(kind(), name);
689 } 706 }
690 707
691 708
692 #undef __ 709 #undef __
693 } // namespace internal 710 } // namespace internal
694 } // namespace v8 711 } // namespace v8
695 712
696 #endif // V8_TARGET_ARCH_IA32 713 #endif // V8_TARGET_ARCH_IA32
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698