| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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_X87 | 5 #if V8_TARGET_ARCH_X87 |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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_X87 | 713 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |