OLD | NEW |
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/ic/handler-compiler.h" | 5 #include "src/ic/handler-compiler.h" |
6 | 6 |
7 #include "src/field-type.h" | 7 #include "src/field-type.h" |
8 #include "src/ic/call-optimization.h" | 8 #include "src/ic/call-optimization.h" |
9 #include "src/ic/handler-configuration.h" | 9 #include "src/ic/handler-configuration.h" |
10 #include "src/ic/ic-inl.h" | 10 #include "src/ic/ic-inl.h" |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 | 434 |
435 | 435 |
436 // TODO(verwaest): Cleanup. holder() is actually the receiver. | 436 // TODO(verwaest): Cleanup. holder() is actually the receiver. |
437 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( | 437 Handle<Code> NamedStoreHandlerCompiler::CompileStoreTransition( |
438 Handle<Map> transition, Handle<Name> name) { | 438 Handle<Map> transition, Handle<Name> name) { |
439 Label miss; | 439 Label miss; |
440 | 440 |
441 // Ensure that the StoreTransitionStub we are going to call has the same | 441 // Ensure that the StoreTransitionStub we are going to call has the same |
442 // number of stack arguments. This means that we don't have to adapt them | 442 // number of stack arguments. This means that we don't have to adapt them |
443 // if we decide to call the transition or miss stub. | 443 // if we decide to call the transition or miss stub. |
444 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == | 444 STATIC_ASSERT(Descriptor::kStackArgumentsCount == |
445 StoreTransitionDescriptor::kStackArgumentsCount); | 445 StoreTransitionDescriptor::kStackArgumentsCount); |
446 STATIC_ASSERT(StoreWithVectorDescriptor::kStackArgumentsCount == 0 || | 446 STATIC_ASSERT(Descriptor::kStackArgumentsCount == 0 || |
447 StoreWithVectorDescriptor::kStackArgumentsCount == 3); | 447 Descriptor::kStackArgumentsCount == 3); |
448 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - | 448 STATIC_ASSERT(Descriptor::kParameterCount - Descriptor::kValue == |
449 StoreWithVectorDescriptor::kValue == | |
450 StoreTransitionDescriptor::kParameterCount - | 449 StoreTransitionDescriptor::kParameterCount - |
451 StoreTransitionDescriptor::kValue); | 450 StoreTransitionDescriptor::kValue); |
452 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - | 451 STATIC_ASSERT(Descriptor::kParameterCount - Descriptor::kSlot == |
453 StoreWithVectorDescriptor::kSlot == | |
454 StoreTransitionDescriptor::kParameterCount - | 452 StoreTransitionDescriptor::kParameterCount - |
455 StoreTransitionDescriptor::kSlot); | 453 StoreTransitionDescriptor::kSlot); |
456 STATIC_ASSERT(StoreWithVectorDescriptor::kParameterCount - | 454 STATIC_ASSERT(Descriptor::kParameterCount - Descriptor::kVector == |
457 StoreWithVectorDescriptor::kVector == | |
458 StoreTransitionDescriptor::kParameterCount - | 455 StoreTransitionDescriptor::kParameterCount - |
459 StoreTransitionDescriptor::kVector); | 456 StoreTransitionDescriptor::kVector); |
460 | 457 |
| 458 if (Descriptor::kPassLastArgsOnStack) { |
| 459 __ LoadParameterFromStack<Descriptor>(value(), Descriptor::kValue); |
| 460 } |
| 461 |
461 bool need_save_restore = IC::ShouldPushPopSlotAndVector(kind()); | 462 bool need_save_restore = IC::ShouldPushPopSlotAndVector(kind()); |
462 if (need_save_restore) { | 463 if (need_save_restore) { |
463 PushVectorAndSlot(); | 464 PushVectorAndSlot(); |
464 } | 465 } |
465 | 466 |
466 // Check that we are allowed to write this. | 467 // Check that we are allowed to write this. |
467 bool is_nonexistent = holder()->map() == transition->GetBackPointer(); | 468 bool is_nonexistent = holder()->map() == transition->GetBackPointer(); |
468 if (is_nonexistent) { | 469 if (is_nonexistent) { |
469 // Find the top object. | 470 // Find the top object. |
470 Handle<JSObject> last; | 471 Handle<JSObject> last; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
543 | 544 |
544 | 545 |
545 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { | 546 Handle<Code> NamedStoreHandlerCompiler::CompileStoreField(LookupIterator* it) { |
546 Label miss; | 547 Label miss; |
547 DCHECK(it->representation().IsHeapObject()); | 548 DCHECK(it->representation().IsHeapObject()); |
548 | 549 |
549 FieldType* field_type = *it->GetFieldType(); | 550 FieldType* field_type = *it->GetFieldType(); |
550 bool need_save_restore = false; | 551 bool need_save_restore = false; |
551 if (RequiresFieldTypeChecks(field_type)) { | 552 if (RequiresFieldTypeChecks(field_type)) { |
552 need_save_restore = IC::ShouldPushPopSlotAndVector(kind()); | 553 need_save_restore = IC::ShouldPushPopSlotAndVector(kind()); |
| 554 if (Descriptor::kPassLastArgsOnStack) { |
| 555 __ LoadParameterFromStack<Descriptor>(value(), Descriptor::kValue); |
| 556 } |
553 if (need_save_restore) PushVectorAndSlot(); | 557 if (need_save_restore) PushVectorAndSlot(); |
554 GenerateFieldTypeChecks(field_type, value(), &miss); | 558 GenerateFieldTypeChecks(field_type, value(), &miss); |
555 if (need_save_restore) PopVectorAndSlot(); | 559 if (need_save_restore) PopVectorAndSlot(); |
556 } | 560 } |
557 | 561 |
558 StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); | 562 StoreFieldStub stub(isolate(), it->GetFieldIndex(), it->representation()); |
559 GenerateTailCall(masm(), stub.GetCode()); | 563 GenerateTailCall(masm(), stub.GetCode()); |
560 | 564 |
561 __ bind(&miss); | 565 __ bind(&miss); |
562 if (need_save_restore) PopVectorAndSlot(); | 566 if (need_save_restore) PopVectorAndSlot(); |
(...skipping 13 matching lines...) Expand all Loading... |
576 } | 580 } |
577 | 581 |
578 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( | 582 Handle<Code> NamedStoreHandlerCompiler::CompileStoreCallback( |
579 Handle<JSObject> object, Handle<Name> name, | 583 Handle<JSObject> object, Handle<Name> name, |
580 const CallOptimization& call_optimization, int accessor_index, | 584 const CallOptimization& call_optimization, int accessor_index, |
581 Handle<Code> slow_stub) { | 585 Handle<Code> slow_stub) { |
582 if (FLAG_runtime_call_stats) { | 586 if (FLAG_runtime_call_stats) { |
583 GenerateTailCall(masm(), slow_stub); | 587 GenerateTailCall(masm(), slow_stub); |
584 } | 588 } |
585 Register holder = Frontend(name); | 589 Register holder = Frontend(name); |
| 590 if (Descriptor::kPassLastArgsOnStack) { |
| 591 __ LoadParameterFromStack<Descriptor>(value(), Descriptor::kValue); |
| 592 } |
586 GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()), | 593 GenerateApiAccessorCall(masm(), call_optimization, handle(object->map()), |
587 receiver(), scratch2(), true, value(), holder, | 594 receiver(), scratch2(), true, value(), holder, |
588 accessor_index); | 595 accessor_index); |
589 return GetCode(kind(), name); | 596 return GetCode(kind(), name); |
590 } | 597 } |
591 | 598 |
592 | 599 |
593 #undef __ | 600 #undef __ |
594 | 601 |
595 // static | 602 // static |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
649 } | 656 } |
650 | 657 |
651 void ElementHandlerCompiler::CompileElementHandlers( | 658 void ElementHandlerCompiler::CompileElementHandlers( |
652 MapHandleList* receiver_maps, List<Handle<Object>>* handlers) { | 659 MapHandleList* receiver_maps, List<Handle<Object>>* handlers) { |
653 for (int i = 0; i < receiver_maps->length(); ++i) { | 660 for (int i = 0; i < receiver_maps->length(); ++i) { |
654 handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate())); | 661 handlers->Add(GetKeyedLoadHandler(receiver_maps->at(i), isolate())); |
655 } | 662 } |
656 } | 663 } |
657 } // namespace internal | 664 } // namespace internal |
658 } // namespace v8 | 665 } // namespace v8 |
OLD | NEW |