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

Side by Side Diff: src/x64/stub-cache-x64.cc

Issue 12781004: Refactoring Store ICs. A first step towards polymorphic store ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: space nits Created 7 years, 9 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 325 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 Register receiver, 336 Register receiver,
337 Register result, 337 Register result,
338 Register scratch, 338 Register scratch,
339 Label* miss_label) { 339 Label* miss_label) {
340 __ TryGetFunctionPrototype(receiver, result, miss_label); 340 __ TryGetFunctionPrototype(receiver, result, miss_label);
341 if (!result.is(rax)) __ movq(rax, result); 341 if (!result.is(rax)) __ movq(rax, result);
342 __ ret(0); 342 __ ret(0);
343 } 343 }
344 344
345 345
346 // Load a fast property out of a holder object (src). In-object properties
347 // are loaded directly otherwise the property is loaded from the properties
348 // fixed array.
349 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
350 Register dst,
351 Register src,
352 Handle<JSObject> holder,
353 PropertyIndex index) {
354 DoGenerateFastPropertyLoad(
355 masm, dst, src, index.is_inobject(holder), index.translate(holder));
356 }
357
358
359 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm, 346 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
360 Register dst, 347 Register dst,
361 Register src, 348 Register src,
362 bool inobject, 349 bool inobject,
363 int index) { 350 int index) {
364 int offset = index * kPointerSize; 351 int offset = index * kPointerSize;
365 if (!inobject) { 352 if (!inobject) {
366 // Calculate the offset into the properties array. 353 // Calculate the offset into the properties array.
367 offset = offset + FixedArray::kHeaderSize; 354 offset = offset + FixedArray::kHeaderSize;
368 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset)); 355 __ movq(dst, FieldOperand(src, JSObject::kPropertiesOffset));
(...skipping 339 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 __ j(not_equal, interceptor_succeeded); 695 __ j(not_equal, interceptor_succeeded);
709 } 696 }
710 697
711 StubCompiler* stub_compiler_; 698 StubCompiler* stub_compiler_;
712 const ParameterCount& arguments_; 699 const ParameterCount& arguments_;
713 Register name_; 700 Register name_;
714 Code::ExtraICState extra_ic_state_; 701 Code::ExtraICState extra_ic_state_;
715 }; 702 };
716 703
717 704
718 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 705 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
719 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 706 Label* label,
720 Handle<Code> code = (kind == Code::LOAD_IC) 707 Handle<Name> name) {
721 ? masm->isolate()->builtins()->LoadIC_Miss() 708 if (!label->is_unused()) {
722 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); 709 __ bind(label);
723 __ Jump(code, RelocInfo::CODE_TARGET); 710 __ Move(this->name(), name);
711 }
724 } 712 }
725 713
726 714
727 void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
728 ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
729 Handle<Code> code = (kind == Code::STORE_IC)
730 ? masm->isolate()->builtins()->StoreIC_Miss()
731 : masm->isolate()->builtins()->KeyedStoreIC_Miss();
732 __ Jump(code, RelocInfo::CODE_TARGET);
733 }
734
735
736 void StubCompiler::GenerateKeyedLoadMissForceGeneric(MacroAssembler* masm) {
737 Handle<Code> code =
738 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
739 __ Jump(code, RelocInfo::CODE_TARGET);
740 }
741
742
743 // Both name_reg and receiver_reg are preserved on jumps to miss_label, 715 // Both name_reg and receiver_reg are preserved on jumps to miss_label,
744 // but may be destroyed if store is successful. 716 // but may be destroyed if store is successful.
745 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 717 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
746 Handle<JSObject> object, 718 Handle<JSObject> object,
747 int index, 719 int index,
748 Handle<Map> transition, 720 Handle<Map> transition,
749 Handle<Name> name, 721 Handle<Name> name,
750 Register receiver_reg, 722 Register receiver_reg,
751 Register name_reg, 723 Register name_reg,
724 Register value_reg,
752 Register scratch1, 725 Register scratch1,
753 Register scratch2, 726 Register scratch2,
754 Label* miss_label) { 727 Label* miss_label,
728 Label* miss_restore_name) {
755 LookupResult lookup(masm->isolate()); 729 LookupResult lookup(masm->isolate());
756 object->Lookup(*name, &lookup); 730 object->Lookup(*name, &lookup);
757 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { 731 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
758 // In sloppy mode, we could just return the value and be done. However, we 732 // In sloppy mode, we could just return the value and be done. However, we
759 // might be in strict mode, where we have to throw. Since we cannot tell, 733 // might be in strict mode, where we have to throw. Since we cannot tell,
760 // go into slow case unconditionally. 734 // go into slow case unconditionally.
761 __ jmp(miss_label); 735 __ jmp(miss_label);
762 return; 736 return;
763 } 737 }
764 738
(...skipping 13 matching lines...) Expand all
778 JSObject* holder; 752 JSObject* holder;
779 if (lookup.IsFound()) { 753 if (lookup.IsFound()) {
780 holder = lookup.holder(); 754 holder = lookup.holder();
781 } else { 755 } else {
782 // Find the top object. 756 // Find the top object.
783 holder = *object; 757 holder = *object;
784 do { 758 do {
785 holder = JSObject::cast(holder->GetPrototype()); 759 holder = JSObject::cast(holder->GetPrototype());
786 } while (holder->GetPrototype()->IsJSObject()); 760 } while (holder->GetPrototype()->IsJSObject());
787 } 761 }
788 // We need an extra register, push
789 __ push(name_reg);
790 Label miss_pop, done_check;
791 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, 762 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
792 scratch1, scratch2, name, &miss_pop); 763 scratch1, scratch2, name, miss_restore_name);
793 __ jmp(&done_check);
794 __ bind(&miss_pop);
795 __ pop(name_reg);
796 __ jmp(miss_label);
797 __ bind(&done_check);
798 __ pop(name_reg);
799 } 764 }
800 765
801 // Stub never generated for non-global objects that require access 766 // Stub never generated for non-global objects that require access
802 // checks. 767 // checks.
803 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 768 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
804 769
805 // Perform map transition for the receiver if necessary. 770 // Perform map transition for the receiver if necessary.
806 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 771 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
807 // The properties must be extended before we can store the value. 772 // The properties must be extended before we can store the value.
808 // We jump to a runtime call that extends the properties array. 773 // We jump to a runtime call that extends the properties array.
809 __ pop(scratch1); // Return address. 774 __ pop(scratch1); // Return address.
810 __ push(receiver_reg); 775 __ push(receiver_reg);
811 __ Push(transition); 776 __ Push(transition);
812 __ push(rax); 777 __ push(value_reg);
813 __ push(scratch1); 778 __ push(scratch1);
814 __ TailCallExternalReference( 779 __ TailCallExternalReference(
815 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), 780 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage),
816 masm->isolate()), 781 masm->isolate()),
817 3, 782 3,
818 1); 783 1);
819 return; 784 return;
820 } 785 }
821 786
822 if (!transition.is_null()) { 787 if (!transition.is_null()) {
(...skipping 13 matching lines...) Expand all
836 } 801 }
837 802
838 // Adjust for the number of properties stored in the object. Even in the 803 // Adjust for the number of properties stored in the object. Even in the
839 // face of a transition we can use the old map here because the size of the 804 // face of a transition we can use the old map here because the size of the
840 // object and the number of in-object properties is not going to change. 805 // object and the number of in-object properties is not going to change.
841 index -= object->map()->inobject_properties(); 806 index -= object->map()->inobject_properties();
842 807
843 if (index < 0) { 808 if (index < 0) {
844 // Set the property straight into the object. 809 // Set the property straight into the object.
845 int offset = object->map()->instance_size() + (index * kPointerSize); 810 int offset = object->map()->instance_size() + (index * kPointerSize);
846 __ movq(FieldOperand(receiver_reg, offset), rax); 811 __ movq(FieldOperand(receiver_reg, offset), value_reg);
847 812
848 // Update the write barrier for the array address. 813 // Update the write barrier for the array address.
849 // Pass the value being stored in the now unused name_reg. 814 // Pass the value being stored in the now unused name_reg.
850 __ movq(name_reg, rax); 815 __ movq(name_reg, value_reg);
851 __ RecordWriteField( 816 __ RecordWriteField(
852 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs); 817 receiver_reg, offset, name_reg, scratch1, kDontSaveFPRegs);
853 } else { 818 } else {
854 // Write to the properties array. 819 // Write to the properties array.
855 int offset = index * kPointerSize + FixedArray::kHeaderSize; 820 int offset = index * kPointerSize + FixedArray::kHeaderSize;
856 // Get the properties array (optimistically). 821 // Get the properties array (optimistically).
857 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); 822 __ movq(scratch1, FieldOperand(receiver_reg, JSObject::kPropertiesOffset));
858 __ movq(FieldOperand(scratch1, offset), rax); 823 __ movq(FieldOperand(scratch1, offset), value_reg);
859 824
860 // Update the write barrier for the array address. 825 // Update the write barrier for the array address.
861 // Pass the value being stored in the now unused name_reg. 826 // Pass the value being stored in the now unused name_reg.
862 __ movq(name_reg, rax); 827 __ movq(name_reg, value_reg);
863 __ RecordWriteField( 828 __ RecordWriteField(
864 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs); 829 scratch1, offset, name_reg, receiver_reg, kDontSaveFPRegs);
865 } 830 }
866 831
867 // Return the value (register rax). 832 // Return the value (register rax).
833 ASSERT(value_reg.is(rax));
868 __ ret(0); 834 __ ret(0);
869 } 835 }
870 836
871 837
872 // Generate code to check that a global property cell is empty. Create 838 // Generate code to check that a global property cell is empty. Create
873 // the property cell at compilation time if no cell exists for the 839 // the property cell at compilation time if no cell exists for the
874 // property. 840 // property.
875 static void GenerateCheckPropertyCell(MacroAssembler* masm, 841 static void GenerateCheckPropertyCell(MacroAssembler* masm,
876 Handle<GlobalObject> global, 842 Handle<GlobalObject> global,
877 Handle<Name> name, 843 Handle<Name> name,
(...skipping 23 matching lines...) Expand all
901 GenerateCheckPropertyCell(masm, 867 GenerateCheckPropertyCell(masm,
902 Handle<GlobalObject>::cast(current), 868 Handle<GlobalObject>::cast(current),
903 name, 869 name,
904 scratch, 870 scratch,
905 miss); 871 miss);
906 } 872 }
907 current = Handle<JSObject>(JSObject::cast(current->GetPrototype())); 873 current = Handle<JSObject>(JSObject::cast(current->GetPrototype()));
908 } 874 }
909 } 875 }
910 876
877
878 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
879 __ jmp(code, RelocInfo::CODE_TARGET);
880 }
881
882
911 #undef __ 883 #undef __
912 #define __ ACCESS_MASM((masm())) 884 #define __ ACCESS_MASM((masm()))
913 885
914 886
915 void StubCompiler::GenerateTailCall(Handle<Code> code) {
916 __ jmp(code, RelocInfo::CODE_TARGET);
917 }
918
919
920 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 887 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
921 Register object_reg, 888 Register object_reg,
922 Handle<JSObject> holder, 889 Handle<JSObject> holder,
923 Register holder_reg, 890 Register holder_reg,
924 Register scratch1, 891 Register scratch1,
925 Register scratch2, 892 Register scratch2,
926 Handle<Name> name, 893 Handle<Name> name,
927 int save_at_depth, 894 int save_at_depth,
928 Label* miss, 895 Label* miss,
929 PrototypeCheckType check) { 896 PrototypeCheckType check) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1032 // Return the register containing the holder. 999 // Return the register containing the holder.
1033 return reg; 1000 return reg;
1034 } 1001 }
1035 1002
1036 1003
1037 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1004 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success,
1038 Label* miss) { 1005 Label* miss) {
1039 if (!miss->is_unused()) { 1006 if (!miss->is_unused()) {
1040 __ jmp(success); 1007 __ jmp(success);
1041 __ bind(miss); 1008 __ bind(miss);
1042 GenerateLoadMiss(masm(), kind()); 1009 TailCallBuiltin(masm(), MissBuiltin(kind()));
1043 } 1010 }
1044 } 1011 }
1045 1012
1046 1013
1047 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1014 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1048 Handle<JSObject> object, 1015 Handle<JSObject> object,
1049 Register object_reg, 1016 Register object_reg,
1050 Handle<JSObject> holder, 1017 Handle<JSObject> holder,
1051 Handle<Name> name, 1018 Handle<Name> name,
1052 Label* success, 1019 Label* success,
(...skipping 1348 matching lines...) Expand 10 before | Expand all | Expand 10 after
2401 // Handle call cache miss. 2368 // Handle call cache miss.
2402 __ bind(&miss); 2369 __ bind(&miss);
2403 __ IncrementCounter(counters->call_global_inline_miss(), 1); 2370 __ IncrementCounter(counters->call_global_inline_miss(), 1);
2404 GenerateMissBranch(); 2371 GenerateMissBranch();
2405 2372
2406 // Return the generated code. 2373 // Return the generated code.
2407 return GetCode(Code::NORMAL, name); 2374 return GetCode(Code::NORMAL, name);
2408 } 2375 }
2409 2376
2410 2377
2411 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2412 int index,
2413 Handle<Map> transition,
2414 Handle<Name> name) {
2415 // ----------- S t a t e -------------
2416 // -- rax : value
2417 // -- rcx : name
2418 // -- rdx : receiver
2419 // -- rsp[0] : return address
2420 // -----------------------------------
2421 Label miss;
2422
2423 // Generate store field code. Preserves receiver and name on jump to miss.
2424 GenerateStoreField(masm(),
2425 object,
2426 index,
2427 transition,
2428 name,
2429 rdx, rcx, rbx, rdi,
2430 &miss);
2431
2432 // Handle store cache miss.
2433 __ bind(&miss);
2434 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2435 __ Jump(ic, RelocInfo::CODE_TARGET);
2436
2437 // Return the generated code.
2438 return GetCode(transition.is_null()
2439 ? Code::FIELD
2440 : Code::MAP_TRANSITION, name);
2441 }
2442
2443
2444 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2378 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2445 Handle<Name> name, 2379 Handle<Name> name,
2446 Handle<JSObject> receiver, 2380 Handle<JSObject> receiver,
2447 Handle<JSObject> holder, 2381 Handle<JSObject> holder,
2448 Handle<ExecutableAccessorInfo> callback) { 2382 Handle<ExecutableAccessorInfo> callback) {
2449 // ----------- S t a t e ------------- 2383 // ----------- S t a t e -------------
2450 // -- rax : value 2384 // -- rax : value
2451 // -- rcx : name 2385 // -- rcx : name
2452 // -- rdx : receiver 2386 // -- rdx : receiver
2453 // -- rsp[0] : return address 2387 // -- rsp[0] : return address
(...skipping 13 matching lines...) Expand all
2467 __ push(rax); // value 2401 __ push(rax); // value
2468 __ push(rbx); // restore return address 2402 __ push(rbx); // restore return address
2469 2403
2470 // Do tail-call to the runtime system. 2404 // Do tail-call to the runtime system.
2471 ExternalReference store_callback_property = 2405 ExternalReference store_callback_property =
2472 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate()); 2406 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2473 __ TailCallExternalReference(store_callback_property, 4, 1); 2407 __ TailCallExternalReference(store_callback_property, 4, 1);
2474 2408
2475 // Handle store cache miss. 2409 // Handle store cache miss.
2476 __ bind(&miss); 2410 __ bind(&miss);
2477 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2411 TailCallBuiltin(masm(), MissBuiltin(kind()));
2478 __ Jump(ic, RelocInfo::CODE_TARGET);
2479 2412
2480 // Return the generated code. 2413 // Return the generated code.
2481 return GetCode(Code::CALLBACKS, name); 2414 return GetICCode(kind(), Code::CALLBACKS, name);
2482 } 2415 }
2483 2416
2484 2417
2485 #undef __ 2418 #undef __
2486 #define __ ACCESS_MASM(masm) 2419 #define __ ACCESS_MASM(masm)
2487 2420
2488 2421
2489 void StoreStubCompiler::GenerateStoreViaSetter( 2422 void StoreStubCompiler::GenerateStoreViaSetter(
2490 MacroAssembler* masm, 2423 MacroAssembler* masm,
2491 Handle<JSFunction> setter) { 2424 Handle<JSFunction> setter) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2541 // ----------------------------------- 2474 // -----------------------------------
2542 Label miss; 2475 Label miss;
2543 2476
2544 // Check that the maps haven't changed. 2477 // Check that the maps haven't changed.
2545 __ JumpIfSmi(rdx, &miss); 2478 __ JumpIfSmi(rdx, &miss);
2546 CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss); 2479 CheckPrototypes(receiver, rdx, holder, rbx, r8, rdi, name, &miss);
2547 2480
2548 GenerateStoreViaSetter(masm(), setter); 2481 GenerateStoreViaSetter(masm(), setter);
2549 2482
2550 __ bind(&miss); 2483 __ bind(&miss);
2551 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2484 TailCallBuiltin(masm(), MissBuiltin(kind()));
2552 __ Jump(ic, RelocInfo::CODE_TARGET);
2553 2485
2554 // Return the generated code. 2486 // Return the generated code.
2555 return GetCode(Code::CALLBACKS, name); 2487 return GetICCode(kind(), Code::CALLBACKS, name);
2556 } 2488 }
2557 2489
2558 2490
2559 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 2491 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2560 Handle<JSObject> receiver, 2492 Handle<JSObject> receiver,
2561 Handle<Name> name) { 2493 Handle<Name> name) {
2562 // ----------- S t a t e ------------- 2494 // ----------- S t a t e -------------
2563 // -- rax : value 2495 // -- rax : value
2564 // -- rcx : name 2496 // -- rcx : name
2565 // -- rdx : receiver 2497 // -- rdx : receiver
(...skipping 11 matching lines...) Expand all
2577 } 2509 }
2578 2510
2579 // Stub never generated for non-global objects that require access 2511 // Stub never generated for non-global objects that require access
2580 // checks. 2512 // checks.
2581 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); 2513 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
2582 2514
2583 __ pop(rbx); // remove the return address 2515 __ pop(rbx); // remove the return address
2584 __ push(rdx); // receiver 2516 __ push(rdx); // receiver
2585 __ push(rcx); // name 2517 __ push(rcx); // name
2586 __ push(rax); // value 2518 __ push(rax); // value
2587 __ Push(Smi::FromInt(strict_mode_)); 2519 __ Push(Smi::FromInt(strict_mode()));
2588 __ push(rbx); // restore return address 2520 __ push(rbx); // restore return address
2589 2521
2590 // Do tail-call to the runtime system. 2522 // Do tail-call to the runtime system.
2591 ExternalReference store_ic_property = 2523 ExternalReference store_ic_property =
2592 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate()); 2524 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2593 __ TailCallExternalReference(store_ic_property, 4, 1); 2525 __ TailCallExternalReference(store_ic_property, 4, 1);
2594 2526
2595 // Handle store cache miss. 2527 // Handle store cache miss.
2596 __ bind(&miss); 2528 __ bind(&miss);
2597 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2529 TailCallBuiltin(masm(), MissBuiltin(kind()));
2598 __ Jump(ic, RelocInfo::CODE_TARGET);
2599 2530
2600 // Return the generated code. 2531 // Return the generated code.
2601 return GetCode(Code::INTERCEPTOR, name); 2532 return GetICCode(kind(), Code::INTERCEPTOR, name);
2602 } 2533 }
2603 2534
2604 2535
2605 Handle<Code> StoreStubCompiler::CompileStoreGlobal( 2536 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2606 Handle<GlobalObject> object, 2537 Handle<GlobalObject> object,
2607 Handle<JSGlobalPropertyCell> cell, 2538 Handle<JSGlobalPropertyCell> cell,
2608 Handle<Name> name) { 2539 Handle<Name> name) {
2609 // ----------- S t a t e ------------- 2540 // ----------- S t a t e -------------
2610 // -- rax : value 2541 // -- rax : value
2611 // -- rcx : name 2542 // -- rcx : name
(...skipping 23 matching lines...) Expand all
2635 // Cells are always rescanned, so no write barrier here. 2566 // Cells are always rescanned, so no write barrier here.
2636 2567
2637 // Return the value (register rax). 2568 // Return the value (register rax).
2638 Counters* counters = isolate()->counters(); 2569 Counters* counters = isolate()->counters();
2639 __ IncrementCounter(counters->named_store_global_inline(), 1); 2570 __ IncrementCounter(counters->named_store_global_inline(), 1);
2640 __ ret(0); 2571 __ ret(0);
2641 2572
2642 // Handle store cache miss. 2573 // Handle store cache miss.
2643 __ bind(&miss); 2574 __ bind(&miss);
2644 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2575 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2645 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss(); 2576 TailCallBuiltin(masm(), MissBuiltin(kind()));
2646 __ Jump(ic, RelocInfo::CODE_TARGET);
2647 2577
2648 // Return the generated code. 2578 // Return the generated code.
2649 return GetCode(Code::NORMAL, name); 2579 return GetICCode(kind(), Code::NORMAL, name);
2650 } 2580 }
2651 2581
2652 2582
2653 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2654 int index,
2655 Handle<Map> transition,
2656 Handle<Name> name) {
2657 // ----------- S t a t e -------------
2658 // -- rax : value
2659 // -- rcx : key
2660 // -- rdx : receiver
2661 // -- rsp[0] : return address
2662 // -----------------------------------
2663 Label miss;
2664
2665 Counters* counters = isolate()->counters();
2666 __ IncrementCounter(counters->keyed_store_field(), 1);
2667
2668 // Check that the name has not changed.
2669 __ Cmp(rcx, name);
2670 __ j(not_equal, &miss);
2671
2672 // Generate store field code. Preserves receiver and name on jump to miss.
2673 GenerateStoreField(masm(),
2674 object,
2675 index,
2676 transition,
2677 name,
2678 rdx, rcx, rbx, rdi,
2679 &miss);
2680
2681 // Handle store cache miss.
2682 __ bind(&miss);
2683 __ DecrementCounter(counters->keyed_store_field(), 1);
2684 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2685 __ Jump(ic, RelocInfo::CODE_TARGET);
2686
2687 // Return the generated code.
2688 return GetCode(transition.is_null()
2689 ? Code::FIELD
2690 : Code::MAP_TRANSITION, name);
2691 }
2692
2693
2694 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( 2583 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
2695 Handle<Map> receiver_map) { 2584 Handle<Map> receiver_map) {
2696 // ----------- S t a t e ------------- 2585 // ----------- S t a t e -------------
2697 // -- rax : value 2586 // -- rax : value
2698 // -- rcx : key 2587 // -- rcx : key
2699 // -- rdx : receiver 2588 // -- rdx : receiver
2700 // -- rsp[0] : return address 2589 // -- rsp[0] : return address
2701 // ----------------------------------- 2590 // -----------------------------------
2702 2591
2703 ElementsKind elements_kind = receiver_map->elements_kind(); 2592 ElementsKind elements_kind = receiver_map->elements_kind();
2704 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2593 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
2705 Handle<Code> stub = 2594 Handle<Code> stub =
2706 KeyedStoreElementStub(is_js_array, 2595 KeyedStoreElementStub(is_js_array,
2707 elements_kind, 2596 elements_kind,
2708 store_mode_).GetCode(isolate()); 2597 store_mode_).GetCode(isolate());
2709 2598
2710 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); 2599 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
2711 2600
2712 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2601 TailCallBuiltin(masm(), MissBuiltin(kind()));
2713 __ jmp(ic, RelocInfo::CODE_TARGET);
2714 2602
2715 // Return the generated code. 2603 // Return the generated code.
2716 return GetCode(Code::NORMAL, factory()->empty_string()); 2604 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
2717 } 2605 }
2718 2606
2719 2607
2720 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2608 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
2721 MapHandleList* receiver_maps, 2609 MapHandleList* receiver_maps,
2722 CodeHandleList* handler_stubs, 2610 CodeHandleList* handler_stubs,
2723 MapHandleList* transitioned_maps) { 2611 MapHandleList* transitioned_maps) {
2724 // ----------- S t a t e ------------- 2612 // ----------- S t a t e -------------
2725 // -- rax : value 2613 // -- rax : value
2726 // -- rcx : key 2614 // -- rcx : key
(...skipping 13 matching lines...) Expand all
2740 } else { 2628 } else {
2741 Label next_map; 2629 Label next_map;
2742 __ j(not_equal, &next_map, Label::kNear); 2630 __ j(not_equal, &next_map, Label::kNear);
2743 __ movq(rbx, transitioned_maps->at(i), RelocInfo::EMBEDDED_OBJECT); 2631 __ movq(rbx, transitioned_maps->at(i), RelocInfo::EMBEDDED_OBJECT);
2744 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET); 2632 __ jmp(handler_stubs->at(i), RelocInfo::CODE_TARGET);
2745 __ bind(&next_map); 2633 __ bind(&next_map);
2746 } 2634 }
2747 } 2635 }
2748 2636
2749 __ bind(&miss); 2637 __ bind(&miss);
2750 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2638
2751 __ jmp(ic, RelocInfo::CODE_TARGET); 2639 TailCallBuiltin(masm(), MissBuiltin(kind()));
2752 2640
2753 // Return the generated code. 2641 // Return the generated code.
2754 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 2642 return GetICCode(
2643 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
2755 } 2644 }
2756 2645
2757 2646
2758 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2647 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2759 Handle<JSObject> object, 2648 Handle<JSObject> object,
2760 Handle<JSObject> last, 2649 Handle<JSObject> last,
2761 Handle<Name> name, 2650 Handle<Name> name,
2762 Handle<GlobalObject> global) { 2651 Handle<GlobalObject> global) {
2763 Label success; 2652 Label success;
2764 2653
(...skipping 17 matching lines...) Expand all
2782 } 2671 }
2783 2672
2784 2673
2785 Register* KeyedLoadStubCompiler::registers() { 2674 Register* KeyedLoadStubCompiler::registers() {
2786 // receiver, name, scratch1, scratch2, scratch3, scratch4. 2675 // receiver, name, scratch1, scratch2, scratch3, scratch4.
2787 static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 }; 2676 static Register registers[] = { rdx, rax, rbx, rcx, rdi, r8 };
2788 return registers; 2677 return registers;
2789 } 2678 }
2790 2679
2791 2680
2681 Register* StoreStubCompiler::registers() {
2682 // receiver, name, value, scratch1, scratch2, scratch3.
2683 static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
2684 return registers;
2685 }
2686
2687
2688 Register* KeyedStoreStubCompiler::registers() {
2689 // receiver, name, value, scratch1, scratch2, scratch3.
2690 static Register registers[] = { rdx, rcx, rax, rbx, rdi, r8 };
2691 return registers;
2692 }
2693
2694
2792 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, 2695 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2793 Register name_reg, 2696 Register name_reg,
2794 Label* miss) { 2697 Label* miss) {
2795 __ Cmp(name_reg, name); 2698 __ Cmp(name_reg, name);
2796 __ j(not_equal, miss); 2699 __ j(not_equal, miss);
2797 } 2700 }
2798 2701
2799 2702
2703 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2704 Register name_reg,
2705 Label* miss) {
2706 __ Cmp(name_reg, name);
2707 __ j(not_equal, miss);
2708 }
2709
2710
2800 #undef __ 2711 #undef __
2801 #define __ ACCESS_MASM(masm) 2712 #define __ ACCESS_MASM(masm)
2802 2713
2803 2714
2804 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 2715 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2805 Handle<JSFunction> getter) { 2716 Handle<JSFunction> getter) {
2806 // ----------- S t a t e ------------- 2717 // ----------- S t a t e -------------
2807 // -- rax : receiver 2718 // -- rax : receiver
2808 // -- rcx : name 2719 // -- rcx : name
2809 // -- rsp[0] : return address 2720 // -- rsp[0] : return address
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2888 Handle<Code> stub = KeyedLoadFastElementStub( 2799 Handle<Code> stub = KeyedLoadFastElementStub(
2889 receiver_map->instance_type() == JS_ARRAY_TYPE, 2800 receiver_map->instance_type() == JS_ARRAY_TYPE,
2890 elements_kind).GetCode(isolate()); 2801 elements_kind).GetCode(isolate());
2891 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); 2802 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
2892 } else { 2803 } else {
2893 Handle<Code> stub = 2804 Handle<Code> stub =
2894 KeyedLoadDictionaryElementStub().GetCode(isolate()); 2805 KeyedLoadDictionaryElementStub().GetCode(isolate());
2895 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK); 2806 __ DispatchMap(rdx, receiver_map, stub, DO_SMI_CHECK);
2896 } 2807 }
2897 2808
2898 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2809 TailCallBuiltin(masm(), Builtins::kKeyedLoadIC_Miss);
2899 2810
2900 // Return the generated code. 2811 // Return the generated code.
2901 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 2812 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
2902 } 2813 }
2903 2814
2904 2815
2905 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 2816 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
2906 MapHandleList* receiver_maps, 2817 MapHandleList* receiver_maps,
2907 CodeHandleList* handlers, 2818 CodeHandleList* handlers,
2908 Handle<Name> name, 2819 Handle<Name> name,
2909 Code::StubType type, 2820 Code::StubType type,
2910 IcCheckType check) { 2821 IcCheckType check) {
2911 Label miss; 2822 Label miss;
2912 2823
2913 if (check == PROPERTY) { 2824 if (check == PROPERTY) {
2914 GenerateNameCheck(name, this->name(), &miss); 2825 GenerateNameCheck(name, this->name(), &miss);
2915 } 2826 }
2916 2827
2917 __ JumpIfSmi(receiver(), &miss); 2828 __ JumpIfSmi(receiver(), &miss);
2918 Register map_reg = scratch1(); 2829 Register map_reg = scratch1();
2919 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset)); 2830 __ movq(map_reg, FieldOperand(receiver(), HeapObject::kMapOffset));
2920 int receiver_count = receiver_maps->length(); 2831 int receiver_count = receiver_maps->length();
2921 for (int current = 0; current < receiver_count; ++current) { 2832 for (int current = 0; current < receiver_count; ++current) {
2922 // Check map and tail call if there's a match 2833 // Check map and tail call if there's a match
2923 __ Cmp(map_reg, receiver_maps->at(current)); 2834 __ Cmp(map_reg, receiver_maps->at(current));
2924 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET); 2835 __ j(equal, handlers->at(current), RelocInfo::CODE_TARGET);
2925 } 2836 }
2926 2837
2927 __ bind(&miss); 2838 __ bind(&miss);
2928 GenerateLoadMiss(masm(), kind()); 2839 TailCallBuiltin(masm(), MissBuiltin(kind()));
2929 2840
2930 // Return the generated code. 2841 // Return the generated code.
2931 InlineCacheState state = 2842 InlineCacheState state =
2932 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 2843 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
2933 return GetICCode(kind(), type, name, state); 2844 return GetICCode(kind(), type, name, state);
2934 } 2845 }
2935 2846
2936 2847
2937 // Specialized stub for constructing objects from functions which only have only 2848 // Specialized stub for constructing objects from functions which only have only
2938 // simple assignments of the form this.x = ...; in their body. 2849 // simple assignments of the form this.x = ...; in their body.
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
3094 // rcx: elements 3005 // rcx: elements
3095 __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax); 3006 __ LoadFromNumberDictionary(&slow, rcx, rax, rbx, r9, rdi, rax);
3096 __ ret(0); 3007 __ ret(0);
3097 3008
3098 __ bind(&slow); 3009 __ bind(&slow);
3099 // ----------- S t a t e ------------- 3010 // ----------- S t a t e -------------
3100 // -- rax : key 3011 // -- rax : key
3101 // -- rdx : receiver 3012 // -- rdx : receiver
3102 // -- rsp[0] : return address 3013 // -- rsp[0] : return address
3103 // ----------------------------------- 3014 // -----------------------------------
3104 Handle<Code> slow_ic = 3015 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
3105 masm->isolate()->builtins()->KeyedLoadIC_Slow();
3106 __ jmp(slow_ic, RelocInfo::CODE_TARGET);
3107 3016
3108 __ bind(&miss_force_generic); 3017 __ bind(&miss_force_generic);
3109 // ----------- S t a t e ------------- 3018 // ----------- S t a t e -------------
3110 // -- rax : key 3019 // -- rax : key
3111 // -- rdx : receiver 3020 // -- rdx : receiver
3112 // -- rsp[0] : return address 3021 // -- rsp[0] : return address
3113 // ----------------------------------- 3022 // -----------------------------------
3114 Handle<Code> miss_ic = 3023 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3115 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3116 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3117 } 3024 }
3118 3025
3119 3026
3120 static void GenerateSmiKeyCheck(MacroAssembler* masm, 3027 static void GenerateSmiKeyCheck(MacroAssembler* masm,
3121 Register key, 3028 Register key,
3122 Register scratch, 3029 Register scratch,
3123 XMMRegister xmm_scratch0, 3030 XMMRegister xmm_scratch0,
3124 XMMRegister xmm_scratch1, 3031 XMMRegister xmm_scratch1,
3125 Label* fail) { 3032 Label* fail) {
3126 // Check that key is a smi or a heap number containing a smi and branch 3033 // Check that key is a smi or a heap number containing a smi and branch
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
3304 3211
3305 // Slow case: call runtime. 3212 // Slow case: call runtime.
3306 __ bind(&slow); 3213 __ bind(&slow);
3307 3214
3308 // ----------- S t a t e ------------- 3215 // ----------- S t a t e -------------
3309 // -- rax : value 3216 // -- rax : value
3310 // -- rcx : key 3217 // -- rcx : key
3311 // -- rdx : receiver 3218 // -- rdx : receiver
3312 // -- rsp[0] : return address 3219 // -- rsp[0] : return address
3313 // ----------------------------------- 3220 // -----------------------------------
3314 3221 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3315 Handle<Code> ic = masm->isolate()->builtins()->KeyedStoreIC_Slow();
3316 __ jmp(ic, RelocInfo::CODE_TARGET);
3317 3222
3318 // Miss case: call runtime. 3223 // Miss case: call runtime.
3319 __ bind(&miss_force_generic); 3224 __ bind(&miss_force_generic);
3320 3225
3321 // ----------- S t a t e ------------- 3226 // ----------- S t a t e -------------
3322 // -- rax : value 3227 // -- rax : value
3323 // -- rcx : key 3228 // -- rcx : key
3324 // -- rdx : receiver 3229 // -- rdx : receiver
3325 // -- rsp[0] : return address 3230 // -- rsp[0] : return address
3326 // ----------------------------------- 3231 // -----------------------------------
3327 3232 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3328 Handle<Code> miss_ic =
3329 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3330 __ jmp(miss_ic, RelocInfo::CODE_TARGET);
3331 } 3233 }
3332 3234
3333 3235
3334 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3236 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3335 MacroAssembler* masm, 3237 MacroAssembler* masm,
3336 bool is_js_array, 3238 bool is_js_array,
3337 ElementsKind elements_kind, 3239 ElementsKind elements_kind,
3338 KeyedAccessStoreMode store_mode) { 3240 KeyedAccessStoreMode store_mode) {
3339 // ----------- S t a t e ------------- 3241 // ----------- S t a t e -------------
3340 // -- rax : value 3242 // -- rax : value
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3389 // Make sure to preserve the value in register rax. 3291 // Make sure to preserve the value in register rax.
3390 __ movq(rbx, rax); 3292 __ movq(rbx, rax);
3391 __ RecordWrite(rdi, rcx, rbx, kDontSaveFPRegs); 3293 __ RecordWrite(rdi, rcx, rbx, kDontSaveFPRegs);
3392 } 3294 }
3393 3295
3394 // Done. 3296 // Done.
3395 __ ret(0); 3297 __ ret(0);
3396 3298
3397 // Handle store cache miss. 3299 // Handle store cache miss.
3398 __ bind(&miss_force_generic); 3300 __ bind(&miss_force_generic);
3399 Handle<Code> ic_force_generic = 3301 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3400 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3401 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3402 3302
3403 __ bind(&transition_elements_kind); 3303 __ bind(&transition_elements_kind);
3404 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3304 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3405 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3406 3305
3407 if (is_js_array && IsGrowStoreMode(store_mode)) { 3306 if (is_js_array && IsGrowStoreMode(store_mode)) {
3408 // Grow the array by a single element if possible. 3307 // Grow the array by a single element if possible.
3409 __ bind(&grow); 3308 __ bind(&grow);
3410 3309
3411 // Make sure the array is only growing by a single element, anything else 3310 // Make sure the array is only growing by a single element, anything else
3412 // must be handled by the runtime. Flags are already set by previous 3311 // must be handled by the runtime. Flags are already set by previous
3413 // compare. 3312 // compare.
3414 __ j(not_equal, &miss_force_generic); 3313 __ j(not_equal, &miss_force_generic);
3415 3314
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
3461 // Make sure that the backing store can hold additional elements. 3360 // Make sure that the backing store can hold additional elements.
3462 __ cmpq(rcx, FieldOperand(rdi, FixedArray::kLengthOffset)); 3361 __ cmpq(rcx, FieldOperand(rdi, FixedArray::kLengthOffset));
3463 __ j(above_equal, &slow); 3362 __ j(above_equal, &slow);
3464 3363
3465 // Grow the array and finish the store. 3364 // Grow the array and finish the store.
3466 __ SmiAddConstant(FieldOperand(rdx, JSArray::kLengthOffset), 3365 __ SmiAddConstant(FieldOperand(rdx, JSArray::kLengthOffset),
3467 Smi::FromInt(1)); 3366 Smi::FromInt(1));
3468 __ jmp(&finish_store); 3367 __ jmp(&finish_store);
3469 3368
3470 __ bind(&slow); 3369 __ bind(&slow);
3471 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3370 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3472 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3473 } 3371 }
3474 } 3372 }
3475 3373
3476 3374
3477 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( 3375 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3478 MacroAssembler* masm, 3376 MacroAssembler* masm,
3479 bool is_js_array, 3377 bool is_js_array,
3480 KeyedAccessStoreMode store_mode) { 3378 KeyedAccessStoreMode store_mode) {
3481 // ----------- S t a t e ------------- 3379 // ----------- S t a t e -------------
3482 // -- rax : value 3380 // -- rax : value
(...skipping 29 matching lines...) Expand all
3512 3410
3513 // Handle smi values specially 3411 // Handle smi values specially
3514 __ bind(&finish_store); 3412 __ bind(&finish_store);
3515 __ SmiToInteger32(rcx, rcx); 3413 __ SmiToInteger32(rcx, rcx);
3516 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0, 3414 __ StoreNumberToDoubleElements(rax, rdi, rcx, xmm0,
3517 &restore_key_transition_elements_kind); 3415 &restore_key_transition_elements_kind);
3518 __ ret(0); 3416 __ ret(0);
3519 3417
3520 // Handle store cache miss, replacing the ic with the generic stub. 3418 // Handle store cache miss, replacing the ic with the generic stub.
3521 __ bind(&miss_force_generic); 3419 __ bind(&miss_force_generic);
3522 Handle<Code> ic_force_generic = 3420 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3523 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3524 __ jmp(ic_force_generic, RelocInfo::CODE_TARGET);
3525 3421
3526 __ bind(&restore_key_transition_elements_kind); 3422 __ bind(&restore_key_transition_elements_kind);
3527 // Restore smi-tagging of rcx. 3423 // Restore smi-tagging of rcx.
3528 __ Integer32ToSmi(rcx, rcx); 3424 __ Integer32ToSmi(rcx, rcx);
3529 __ bind(&transition_elements_kind); 3425 __ bind(&transition_elements_kind);
3530 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3426 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3531 __ jmp(ic_miss, RelocInfo::CODE_TARGET);
3532 3427
3533 if (is_js_array && IsGrowStoreMode(store_mode)) { 3428 if (is_js_array && IsGrowStoreMode(store_mode)) {
3534 // Grow the array by a single element if possible. 3429 // Grow the array by a single element if possible.
3535 __ bind(&grow); 3430 __ bind(&grow);
3536 3431
3537 // Make sure the array is only growing by a single element, anything else 3432 // Make sure the array is only growing by a single element, anything else
3538 // must be handled by the runtime. Flags are already set by previous 3433 // must be handled by the runtime. Flags are already set by previous
3539 // compare. 3434 // compare.
3540 __ j(not_equal, &miss_force_generic); 3435 __ j(not_equal, &miss_force_generic);
3541 3436
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3595 // Make sure that the backing store can hold additional elements. 3490 // Make sure that the backing store can hold additional elements.
3596 __ cmpq(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset)); 3491 __ cmpq(rcx, FieldOperand(rdi, FixedDoubleArray::kLengthOffset));
3597 __ j(above_equal, &slow); 3492 __ j(above_equal, &slow);
3598 3493
3599 // Grow the array and finish the store. 3494 // Grow the array and finish the store.
3600 __ SmiAddConstant(FieldOperand(rdx, JSArray::kLengthOffset), 3495 __ SmiAddConstant(FieldOperand(rdx, JSArray::kLengthOffset),
3601 Smi::FromInt(1)); 3496 Smi::FromInt(1));
3602 __ jmp(&finish_store); 3497 __ jmp(&finish_store);
3603 3498
3604 __ bind(&slow); 3499 __ bind(&slow);
3605 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3500 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3606 __ jmp(ic_slow, RelocInfo::CODE_TARGET);
3607 } 3501 }
3608 } 3502 }
3609 3503
3610 3504
3611 #undef __ 3505 #undef __
3612 3506
3613 } } // namespace v8::internal 3507 } } // namespace v8::internal
3614 3508
3615 #endif // V8_TARGET_ARCH_X64 3509 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/ic-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698