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

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

Issue 12603003: MIPS: Refactoring Store ICs. A first step towards polymorphic store ICs. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: 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/mips/code-stubs-mips.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 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
300 // Get the global function with the given index. 300 // Get the global function with the given index.
301 Handle<JSFunction> function( 301 Handle<JSFunction> function(
302 JSFunction::cast(isolate->native_context()->get(index))); 302 JSFunction::cast(isolate->native_context()->get(index)));
303 // Load its initial map. The global functions all have initial maps. 303 // Load its initial map. The global functions all have initial maps.
304 __ li(prototype, Handle<Map>(function->initial_map())); 304 __ li(prototype, Handle<Map>(function->initial_map()));
305 // Load the prototype from the initial map. 305 // Load the prototype from the initial map.
306 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 306 __ lw(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
307 } 307 }
308 308
309 309
310 // Load a fast property out of a holder object (src). In-object properties
311 // are loaded directly otherwise the property is loaded from the properties
312 // fixed array.
313 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
314 Register dst,
315 Register src,
316 Handle<JSObject> holder,
317 PropertyIndex index) {
318 DoGenerateFastPropertyLoad(
319 masm, dst, src, index.is_inobject(holder), index.translate(holder));
320 }
321
322
323 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm, 310 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
324 Register dst, 311 Register dst,
325 Register src, 312 Register src,
326 bool inobject, 313 bool inobject,
327 int index) { 314 int index) {
328 int offset = index * kPointerSize; 315 int offset = index * kPointerSize;
329 if (!inobject) { 316 if (!inobject) {
330 // Calculate the offset into the properties array. 317 // Calculate the offset into the properties array.
331 offset = offset + FixedArray::kHeaderSize; 318 offset = offset + FixedArray::kHeaderSize;
332 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 319 __ lw(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
426 // Generate StoreField code, value is passed in a0 register. 413 // Generate StoreField code, value is passed in a0 register.
427 // After executing generated code, the receiver_reg and name_reg 414 // After executing generated code, the receiver_reg and name_reg
428 // may be clobbered. 415 // may be clobbered.
429 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 416 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
430 Handle<JSObject> object, 417 Handle<JSObject> object,
431 int index, 418 int index,
432 Handle<Map> transition, 419 Handle<Map> transition,
433 Handle<Name> name, 420 Handle<Name> name,
434 Register receiver_reg, 421 Register receiver_reg,
435 Register name_reg, 422 Register name_reg,
423 Register value_reg,
436 Register scratch1, 424 Register scratch1,
437 Register scratch2, 425 Register scratch2,
438 Label* miss_label) { 426 Label* miss_label,
427 Label* miss_restore_name) {
439 // a0 : value. 428 // a0 : value.
440 Label exit; 429 Label exit;
441 430
442 LookupResult lookup(masm->isolate()); 431 LookupResult lookup(masm->isolate());
443 object->Lookup(*name, &lookup); 432 object->Lookup(*name, &lookup);
444 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { 433 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
445 // In sloppy mode, we could just return the value and be done. However, we 434 // In sloppy mode, we could just return the value and be done. However, we
446 // might be in strict mode, where we have to throw. Since we cannot tell, 435 // might be in strict mode, where we have to throw. Since we cannot tell,
447 // go into slow case unconditionally. 436 // go into slow case unconditionally.
448 __ jmp(miss_label); 437 __ jmp(miss_label);
(...skipping 16 matching lines...) Expand all
465 JSObject* holder; 454 JSObject* holder;
466 if (lookup.IsFound()) { 455 if (lookup.IsFound()) {
467 holder = lookup.holder(); 456 holder = lookup.holder();
468 } else { 457 } else {
469 // Find the top object. 458 // Find the top object.
470 holder = *object; 459 holder = *object;
471 do { 460 do {
472 holder = JSObject::cast(holder->GetPrototype()); 461 holder = JSObject::cast(holder->GetPrototype());
473 } while (holder->GetPrototype()->IsJSObject()); 462 } while (holder->GetPrototype()->IsJSObject());
474 } 463 }
475 // We need an extra register, push
476 __ push(name_reg);
477 Label miss_pop, done_check;
478 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, 464 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
479 scratch1, scratch2, name, &miss_pop); 465 scratch1, scratch2, name, miss_restore_name);
480 __ jmp(&done_check);
481 __ bind(&miss_pop);
482 __ pop(name_reg);
483 __ jmp(miss_label);
484 __ bind(&done_check);
485 __ pop(name_reg);
486 } 466 }
487 467
488 // Stub never generated for non-global objects that require access 468 // Stub never generated for non-global objects that require access
489 // checks. 469 // checks.
490 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 470 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
491 471
492 // Perform map transition for the receiver if necessary. 472 // Perform map transition for the receiver if necessary.
493 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 473 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
494 // The properties must be extended before we can store the value. 474 // The properties must be extended before we can store the value.
495 // We jump to a runtime call that extends the properties array. 475 // We jump to a runtime call that extends the properties array.
(...skipping 25 matching lines...) Expand all
521 } 501 }
522 502
523 // Adjust for the number of properties stored in the object. Even in the 503 // Adjust for the number of properties stored in the object. Even in the
524 // face of a transition we can use the old map here because the size of the 504 // face of a transition we can use the old map here because the size of the
525 // object and the number of in-object properties is not going to change. 505 // object and the number of in-object properties is not going to change.
526 index -= object->map()->inobject_properties(); 506 index -= object->map()->inobject_properties();
527 507
528 if (index < 0) { 508 if (index < 0) {
529 // Set the property straight into the object. 509 // Set the property straight into the object.
530 int offset = object->map()->instance_size() + (index * kPointerSize); 510 int offset = object->map()->instance_size() + (index * kPointerSize);
531 __ sw(a0, FieldMemOperand(receiver_reg, offset)); 511 __ sw(value_reg, FieldMemOperand(receiver_reg, offset));
532 512
533 // Skip updating write barrier if storing a smi. 513 // Skip updating write barrier if storing a smi.
534 __ JumpIfSmi(a0, &exit, scratch1); 514 __ JumpIfSmi(value_reg, &exit);
535 515
536 // Update the write barrier for the array address. 516 // Update the write barrier for the array address.
537 // Pass the now unused name_reg as a scratch register. 517 // Pass the now unused name_reg as a scratch register.
538 __ mov(name_reg, a0); 518 __ mov(name_reg, value_reg);
539 __ RecordWriteField(receiver_reg, 519 __ RecordWriteField(receiver_reg,
540 offset, 520 offset,
541 name_reg, 521 name_reg,
542 scratch1, 522 scratch1,
543 kRAHasNotBeenSaved, 523 kRAHasNotBeenSaved,
544 kDontSaveFPRegs); 524 kDontSaveFPRegs);
545 } else { 525 } else {
546 // Write to the properties array. 526 // Write to the properties array.
547 int offset = index * kPointerSize + FixedArray::kHeaderSize; 527 int offset = index * kPointerSize + FixedArray::kHeaderSize;
548 // Get the properties array. 528 // Get the properties array.
549 __ lw(scratch1, 529 __ lw(scratch1,
550 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 530 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
551 __ sw(a0, FieldMemOperand(scratch1, offset)); 531 __ sw(value_reg, FieldMemOperand(scratch1, offset));
552 532
553 // Skip updating write barrier if storing a smi. 533 // Skip updating write barrier if storing a smi.
554 __ JumpIfSmi(a0, &exit); 534 __ JumpIfSmi(value_reg, &exit);
555 535
556 // Update the write barrier for the array address. 536 // Update the write barrier for the array address.
557 // Ok to clobber receiver_reg and name_reg, since we return. 537 // Ok to clobber receiver_reg and name_reg, since we return.
558 __ mov(name_reg, a0); 538 __ mov(name_reg, value_reg);
559 __ RecordWriteField(scratch1, 539 __ RecordWriteField(scratch1,
560 offset, 540 offset,
561 name_reg, 541 name_reg,
562 receiver_reg, 542 receiver_reg,
563 kRAHasNotBeenSaved, 543 kRAHasNotBeenSaved,
564 kDontSaveFPRegs); 544 kDontSaveFPRegs);
565 } 545 }
566 546
567 // Return the value (register v0). 547 // Return the value (register v0).
548 ASSERT(value_reg.is(a0));
568 __ bind(&exit); 549 __ bind(&exit);
569 __ mov(v0, a0); 550 __ mov(v0, a0);
570 __ Ret(); 551 __ Ret();
571 } 552 }
572 553
573 554
574 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 555 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
575 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 556 Label* label,
576 Handle<Code> code = (kind == Code::LOAD_IC) 557 Handle<Name> name) {
577 ? masm->isolate()->builtins()->LoadIC_Miss() 558 if (!label->is_unused()) {
578 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); 559 __ bind(label);
579 __ Jump(code, RelocInfo::CODE_TARGET); 560 __ li(this->name(), Operand(name));
561 }
580 } 562 }
581 563
582 564
583 void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
584 ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
585 Handle<Code> code = (kind == Code::STORE_IC)
586 ? masm->isolate()->builtins()->StoreIC_Miss()
587 : masm->isolate()->builtins()->KeyedStoreIC_Miss();
588 __ Jump(code, RelocInfo::CODE_TARGET);
589 }
590
591
592 static void GenerateCallFunction(MacroAssembler* masm, 565 static void GenerateCallFunction(MacroAssembler* masm,
593 Handle<Object> object, 566 Handle<Object> object,
594 const ParameterCount& arguments, 567 const ParameterCount& arguments,
595 Label* miss, 568 Label* miss,
596 Code::ExtraICState extra_ic_state) { 569 Code::ExtraICState extra_ic_state) {
597 // ----------- S t a t e ------------- 570 // ----------- S t a t e -------------
598 // -- a0: receiver 571 // -- a0: receiver
599 // -- a1: function to call 572 // -- a1: function to call
600 // ----------------------------------- 573 // -----------------------------------
601 // Check that the function really is a function. 574 // Check that the function really is a function.
(...skipping 455 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 1030
1058 __ bind(&done); 1031 __ bind(&done);
1059 1032
1060 __ sll(scratch1, wordoffset, 2); 1033 __ sll(scratch1, wordoffset, 2);
1061 __ addu(scratch1, dst, scratch1); 1034 __ addu(scratch1, dst, scratch1);
1062 __ sw(fval, MemOperand(scratch1, 0)); 1035 __ sw(fval, MemOperand(scratch1, 0));
1063 } 1036 }
1064 } 1037 }
1065 1038
1066 1039
1040 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1041 __ Jump(code, RelocInfo::CODE_TARGET);
1042 }
1043
1044
1067 #undef __ 1045 #undef __
1068 #define __ ACCESS_MASM(masm()) 1046 #define __ ACCESS_MASM(masm())
1069 1047
1070 1048
1071 void StubCompiler::GenerateTailCall(Handle<Code> code) {
1072 __ Jump(code, RelocInfo::CODE_TARGET);
1073 }
1074
1075
1076 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1049 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1077 Register object_reg, 1050 Register object_reg,
1078 Handle<JSObject> holder, 1051 Handle<JSObject> holder,
1079 Register holder_reg, 1052 Register holder_reg,
1080 Register scratch1, 1053 Register scratch1,
1081 Register scratch2, 1054 Register scratch2,
1082 Handle<Name> name, 1055 Handle<Name> name,
1083 int save_at_depth, 1056 int save_at_depth,
1084 Label* miss, 1057 Label* miss,
1085 PrototypeCheckType check) { 1058 PrototypeCheckType check) {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1183 // Return the register containing the holder. 1156 // Return the register containing the holder.
1184 return reg; 1157 return reg;
1185 } 1158 }
1186 1159
1187 1160
1188 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success, 1161 void BaseLoadStubCompiler::HandlerFrontendFooter(Label* success,
1189 Label* miss) { 1162 Label* miss) {
1190 if (!miss->is_unused()) { 1163 if (!miss->is_unused()) {
1191 __ Branch(success); 1164 __ Branch(success);
1192 __ bind(miss); 1165 __ bind(miss);
1193 GenerateLoadMiss(masm(), kind()); 1166 TailCallBuiltin(masm(), MissBuiltin(kind()));
1194 } 1167 }
1195 } 1168 }
1196 1169
1197 1170
1198 Register BaseLoadStubCompiler::CallbackHandlerFrontend( 1171 Register BaseLoadStubCompiler::CallbackHandlerFrontend(
1199 Handle<JSObject> object, 1172 Handle<JSObject> object,
1200 Register object_reg, 1173 Register object_reg,
1201 Handle<JSObject> holder, 1174 Handle<JSObject> holder,
1202 Handle<Name> name, 1175 Handle<Name> name,
1203 Label* success, 1176 Label* success,
(...skipping 1418 matching lines...) Expand 10 before | Expand all | Expand 10 after
2622 // Handle call cache miss. 2595 // Handle call cache miss.
2623 __ bind(&miss); 2596 __ bind(&miss);
2624 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3); 2597 __ IncrementCounter(counters->call_global_inline_miss(), 1, a1, a3);
2625 GenerateMissBranch(); 2598 GenerateMissBranch();
2626 2599
2627 // Return the generated code. 2600 // Return the generated code.
2628 return GetCode(Code::NORMAL, name); 2601 return GetCode(Code::NORMAL, name);
2629 } 2602 }
2630 2603
2631 2604
2632 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2633 int index,
2634 Handle<Map> transition,
2635 Handle<Name> name) {
2636 // ----------- S t a t e -------------
2637 // -- a0 : value
2638 // -- a1 : receiver
2639 // -- a2 : name
2640 // -- ra : return address
2641 // -----------------------------------
2642 Label miss;
2643
2644 // Name register might be clobbered.
2645 GenerateStoreField(masm(),
2646 object,
2647 index,
2648 transition,
2649 name,
2650 a1, a2, a3, t0,
2651 &miss);
2652 __ bind(&miss);
2653 __ li(a2, Operand(Handle<Name>(name))); // Restore name.
2654 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss();
2655 __ Jump(ic, RelocInfo::CODE_TARGET);
2656
2657 // Return the generated code.
2658 return GetCode(transition.is_null()
2659 ? Code::FIELD
2660 : Code::MAP_TRANSITION, name);
2661 }
2662
2663
2664 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2605 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2665 Handle<Name> name, 2606 Handle<Name> name,
2666 Handle<JSObject> receiver, 2607 Handle<JSObject> receiver,
2667 Handle<JSObject> holder, 2608 Handle<JSObject> holder,
2668 Handle<ExecutableAccessorInfo> callback) { 2609 Handle<ExecutableAccessorInfo> callback) {
2669 // ----------- S t a t e ------------- 2610 // ----------- S t a t e -------------
2670 // -- a0 : value 2611 // -- a0 : value
2671 // -- a1 : receiver 2612 // -- a1 : receiver
2672 // -- a2 : name 2613 // -- a2 : name
2673 // -- ra : return address 2614 // -- ra : return address
(...skipping 12 matching lines...) Expand all
2686 __ Push(a3, a2, a0); 2627 __ Push(a3, a2, a0);
2687 2628
2688 // Do tail-call to the runtime system. 2629 // Do tail-call to the runtime system.
2689 ExternalReference store_callback_property = 2630 ExternalReference store_callback_property =
2690 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), 2631 ExternalReference(IC_Utility(IC::kStoreCallbackProperty),
2691 masm()->isolate()); 2632 masm()->isolate());
2692 __ TailCallExternalReference(store_callback_property, 4, 1); 2633 __ TailCallExternalReference(store_callback_property, 4, 1);
2693 2634
2694 // Handle store cache miss. 2635 // Handle store cache miss.
2695 __ bind(&miss); 2636 __ bind(&miss);
2696 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2637 TailCallBuiltin(masm(), MissBuiltin(kind()));
2697 __ Jump(ic, RelocInfo::CODE_TARGET);
2698 2638
2699 // Return the generated code. 2639 // Return the generated code.
2700 return GetCode(Code::CALLBACKS, name); 2640 return GetICCode(kind(), Code::CALLBACKS, name);
2701 } 2641 }
2702 2642
2703 2643
2704 #undef __ 2644 #undef __
2705 #define __ ACCESS_MASM(masm) 2645 #define __ ACCESS_MASM(masm)
2706 2646
2707 2647
2708 void StoreStubCompiler::GenerateStoreViaSetter( 2648 void StoreStubCompiler::GenerateStoreViaSetter(
2709 MacroAssembler* masm, 2649 MacroAssembler* masm,
2710 Handle<JSFunction> setter) { 2650 Handle<JSFunction> setter) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
2760 // ----------------------------------- 2700 // -----------------------------------
2761 Label miss; 2701 Label miss;
2762 2702
2763 // Check that the maps haven't changed. 2703 // Check that the maps haven't changed.
2764 __ JumpIfSmi(a1, &miss); 2704 __ JumpIfSmi(a1, &miss);
2765 CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss); 2705 CheckPrototypes(receiver, a1, holder, a3, t0, t1, name, &miss);
2766 2706
2767 GenerateStoreViaSetter(masm(), setter); 2707 GenerateStoreViaSetter(masm(), setter);
2768 2708
2769 __ bind(&miss); 2709 __ bind(&miss);
2770 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2710 TailCallBuiltin(masm(), MissBuiltin(kind()));
2771 __ Jump(ic, RelocInfo::CODE_TARGET);
2772 2711
2773 // Return the generated code. 2712 // Return the generated code.
2774 return GetCode(Code::CALLBACKS, name); 2713 return GetICCode(kind(), Code::CALLBACKS, name);
2775 } 2714 }
2776 2715
2777 2716
2778 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 2717 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2779 Handle<JSObject> receiver, 2718 Handle<JSObject> receiver,
2780 Handle<Name> name) { 2719 Handle<Name> name) {
2781 // ----------- S t a t e ------------- 2720 // ----------- S t a t e -------------
2782 // -- a0 : value 2721 // -- a0 : value
2783 // -- a1 : receiver 2722 // -- a1 : receiver
2784 // -- a2 : name 2723 // -- a2 : name
2785 // -- ra : return address 2724 // -- ra : return address
2786 // ----------------------------------- 2725 // -----------------------------------
2787 Label miss; 2726 Label miss;
2788 2727
2789 // Check that the map of the object hasn't changed. 2728 // Check that the map of the object hasn't changed.
2790 __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss, 2729 __ CheckMap(a1, a3, Handle<Map>(receiver->map()), &miss,
2791 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); 2730 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
2792 2731
2793 // Perform global security token check if needed. 2732 // Perform global security token check if needed.
2794 if (receiver->IsJSGlobalProxy()) { 2733 if (receiver->IsJSGlobalProxy()) {
2795 __ CheckAccessGlobalProxy(a1, a3, &miss); 2734 __ CheckAccessGlobalProxy(a1, a3, &miss);
2796 } 2735 }
2797 2736
2798 // Stub is never generated for non-global objects that require access 2737 // Stub is never generated for non-global objects that require access
2799 // checks. 2738 // checks.
2800 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); 2739 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
2801 2740
2802 __ Push(a1, a2, a0); // Receiver, name, value. 2741 __ Push(a1, a2, a0); // Receiver, name, value.
2803 2742
2804 __ li(a0, Operand(Smi::FromInt(strict_mode_))); 2743 __ li(a0, Operand(Smi::FromInt(strict_mode())));
2805 __ push(a0); // Strict mode. 2744 __ push(a0); // Strict mode.
2806 2745
2807 // Do tail-call to the runtime system. 2746 // Do tail-call to the runtime system.
2808 ExternalReference store_ic_property = 2747 ExternalReference store_ic_property =
2809 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), 2748 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty),
2810 masm()->isolate()); 2749 masm()->isolate());
2811 __ TailCallExternalReference(store_ic_property, 4, 1); 2750 __ TailCallExternalReference(store_ic_property, 4, 1);
2812 2751
2813 // Handle store cache miss. 2752 // Handle store cache miss.
2814 __ bind(&miss); 2753 __ bind(&miss);
2815 Handle<Code> ic = masm()->isolate()->builtins()->Builtins::StoreIC_Miss(); 2754 TailCallBuiltin(masm(), MissBuiltin(kind()));
2816 __ Jump(ic, RelocInfo::CODE_TARGET);
2817 2755
2818 // Return the generated code. 2756 // Return the generated code.
2819 return GetCode(Code::INTERCEPTOR, name); 2757 return GetICCode(kind(), Code::INTERCEPTOR, name);
2820 } 2758 }
2821 2759
2822 2760
2823 Handle<Code> StoreStubCompiler::CompileStoreGlobal( 2761 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2824 Handle<GlobalObject> object, 2762 Handle<GlobalObject> object,
2825 Handle<JSGlobalPropertyCell> cell, 2763 Handle<JSGlobalPropertyCell> cell,
2826 Handle<Name> name) { 2764 Handle<Name> name) {
2827 // ----------- S t a t e ------------- 2765 // ----------- S t a t e -------------
2828 // -- a0 : value 2766 // -- a0 : value
2829 // -- a1 : receiver 2767 // -- a1 : receiver
(...skipping 20 matching lines...) Expand all
2850 __ mov(v0, a0); // Stored value must be returned in v0. 2788 __ mov(v0, a0); // Stored value must be returned in v0.
2851 // Cells are always rescanned, so no write barrier here. 2789 // Cells are always rescanned, so no write barrier here.
2852 2790
2853 Counters* counters = masm()->isolate()->counters(); 2791 Counters* counters = masm()->isolate()->counters();
2854 __ IncrementCounter(counters->named_store_global_inline(), 1, a1, a3); 2792 __ IncrementCounter(counters->named_store_global_inline(), 1, a1, a3);
2855 __ Ret(); 2793 __ Ret();
2856 2794
2857 // Handle store cache miss. 2795 // Handle store cache miss.
2858 __ bind(&miss); 2796 __ bind(&miss);
2859 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3); 2797 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, a1, a3);
2860 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2798 TailCallBuiltin(masm(), MissBuiltin(kind()));
2861 __ Jump(ic, RelocInfo::CODE_TARGET);
2862 2799
2863 // Return the generated code. 2800 // Return the generated code.
2864 return GetCode(Code::NORMAL, name); 2801 return GetICCode(kind(), Code::NORMAL, name);
2865 } 2802 }
2866 2803
2867 2804
2868 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2805 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2869 Handle<JSObject> object, 2806 Handle<JSObject> object,
2870 Handle<JSObject> last, 2807 Handle<JSObject> last,
2871 Handle<Name> name, 2808 Handle<Name> name,
2872 Handle<GlobalObject> global) { 2809 Handle<GlobalObject> global) {
2873 Label success; 2810 Label success;
2874 2811
(...skipping 16 matching lines...) Expand all
2891 } 2828 }
2892 2829
2893 2830
2894 Register* KeyedLoadStubCompiler::registers() { 2831 Register* KeyedLoadStubCompiler::registers() {
2895 // receiver, name, scratch1, scratch2, scratch3, scratch4. 2832 // receiver, name, scratch1, scratch2, scratch3, scratch4.
2896 static Register registers[] = { a1, a0, a2, a3, t0, t1 }; 2833 static Register registers[] = { a1, a0, a2, a3, t0, t1 };
2897 return registers; 2834 return registers;
2898 } 2835 }
2899 2836
2900 2837
2838 Register* StoreStubCompiler::registers() {
2839 // receiver, name, value, scratch1, scratch2, scratch3.
2840 static Register registers[] = { a1, a2, a0, a3, t0, t1 };
2841 return registers;
2842 }
2843
2844
2845 Register* KeyedStoreStubCompiler::registers() {
2846 // receiver, name, value, scratch1, scratch2, scratch3.
2847 static Register registers[] = { a2, a1, a0, a3, t0, t1 };
2848 return registers;
2849 }
2850
2851
2901 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, 2852 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2902 Register name_reg, 2853 Register name_reg,
2903 Label* miss) { 2854 Label* miss) {
2904 __ Branch(miss, ne, name_reg, Operand(name)); 2855 __ Branch(miss, ne, name_reg, Operand(name));
2905 } 2856 }
2906 2857
2907 2858
2859 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2860 Register name_reg,
2861 Label* miss) {
2862 __ Branch(miss, ne, name_reg, Operand(name));
2863 }
2864
2865
2908 #undef __ 2866 #undef __
2909 #define __ ACCESS_MASM(masm) 2867 #define __ ACCESS_MASM(masm)
2910 2868
2911 2869
2912 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 2870 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2913 Handle<JSFunction> getter) { 2871 Handle<JSFunction> getter) {
2914 // ----------- S t a t e ------------- 2872 // ----------- S t a t e -------------
2915 // -- a0 : receiver 2873 // -- a0 : receiver
2916 // -- a2 : name 2874 // -- a2 : name
2917 // -- ra : return address 2875 // -- ra : return address
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
2991 Handle<Code> stub = KeyedLoadFastElementStub( 2949 Handle<Code> stub = KeyedLoadFastElementStub(
2992 receiver_map->instance_type() == JS_ARRAY_TYPE, 2950 receiver_map->instance_type() == JS_ARRAY_TYPE,
2993 elements_kind).GetCode(isolate()); 2951 elements_kind).GetCode(isolate());
2994 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); 2952 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
2995 } else { 2953 } else {
2996 Handle<Code> stub = 2954 Handle<Code> stub =
2997 KeyedLoadDictionaryElementStub().GetCode(isolate()); 2955 KeyedLoadDictionaryElementStub().GetCode(isolate());
2998 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK); 2956 __ DispatchMap(a1, a2, receiver_map, stub, DO_SMI_CHECK);
2999 } 2957 }
3000 2958
3001 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 2959 TailCallBuiltin(masm(), MissBuiltin(kind()));
3002 __ Jump(ic, RelocInfo::CODE_TARGET);
3003 2960
3004 // Return the generated code. 2961 // Return the generated code.
3005 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 2962 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
3006 } 2963 }
3007 2964
3008 2965
3009 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 2966 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
3010 MapHandleList* receiver_maps, 2967 MapHandleList* receiver_maps,
3011 CodeHandleList* handlers, 2968 CodeHandleList* handlers,
3012 Handle<Name> name, 2969 Handle<Name> name,
3013 Code::StubType type, 2970 Code::StubType type,
3014 IcCheckType check) { 2971 IcCheckType check) {
3015 Label miss; 2972 Label miss;
3016 2973
3017 if (check == PROPERTY) { 2974 if (check == PROPERTY) {
3018 GenerateNameCheck(name, this->name(), &miss); 2975 GenerateNameCheck(name, this->name(), &miss);
3019 } 2976 }
3020 2977
3021 __ JumpIfSmi(receiver(), &miss); 2978 __ JumpIfSmi(receiver(), &miss);
3022 Register map_reg = scratch1(); 2979 Register map_reg = scratch1();
3023 2980
3024 int receiver_count = receiver_maps->length(); 2981 int receiver_count = receiver_maps->length();
3025 __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 2982 __ lw(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
3026 for (int current = 0; current < receiver_count; ++current) { 2983 for (int current = 0; current < receiver_count; ++current) {
3027 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, 2984 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET,
3028 eq, map_reg, Operand(receiver_maps->at(current))); 2985 eq, map_reg, Operand(receiver_maps->at(current)));
3029 } 2986 }
3030 2987
3031 __ bind(&miss); 2988 __ bind(&miss);
3032 GenerateLoadMiss(masm(), kind()); 2989 TailCallBuiltin(masm(), MissBuiltin(kind()));
3033 2990
3034 // Return the generated code. 2991 // Return the generated code.
3035 InlineCacheState state = 2992 InlineCacheState state =
3036 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 2993 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
3037 return GetICCode(kind(), type, name, state); 2994 return GetICCode(kind(), type, name, state);
3038 } 2995 }
3039 2996
3040 2997
3041 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
3042 int index,
3043 Handle<Map> transition,
3044 Handle<Name> name) {
3045 // ----------- S t a t e -------------
3046 // -- a0 : value
3047 // -- a1 : key
3048 // -- a2 : receiver
3049 // -- ra : return address
3050 // -----------------------------------
3051
3052 Label miss;
3053
3054 Counters* counters = masm()->isolate()->counters();
3055 __ IncrementCounter(counters->keyed_store_field(), 1, a3, t0);
3056
3057 // Check that the name has not changed.
3058 __ Branch(&miss, ne, a1, Operand(name));
3059
3060 // a3 is used as scratch register. a1 and a2 keep their values if a jump to
3061 // the miss label is generated.
3062 GenerateStoreField(masm(),
3063 object,
3064 index,
3065 transition,
3066 name,
3067 a2, a1, a3, t0,
3068 &miss);
3069 __ bind(&miss);
3070
3071 __ DecrementCounter(counters->keyed_store_field(), 1, a3, t0);
3072 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
3073 __ Jump(ic, RelocInfo::CODE_TARGET);
3074
3075 // Return the generated code.
3076 return GetCode(transition.is_null()
3077 ? Code::FIELD
3078 : Code::MAP_TRANSITION, name);
3079 }
3080
3081
3082 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( 2998 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
3083 Handle<Map> receiver_map) { 2999 Handle<Map> receiver_map) {
3084 // ----------- S t a t e ------------- 3000 // ----------- S t a t e -------------
3085 // -- a0 : value 3001 // -- a0 : value
3086 // -- a1 : key 3002 // -- a1 : key
3087 // -- a2 : receiver 3003 // -- a2 : receiver
3088 // -- ra : return address 3004 // -- ra : return address
3089 // -- a3 : scratch 3005 // -- a3 : scratch
3090 // ----------------------------------- 3006 // -----------------------------------
3091 ElementsKind elements_kind = receiver_map->elements_kind(); 3007 ElementsKind elements_kind = receiver_map->elements_kind();
3092 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 3008 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
3093 Handle<Code> stub = 3009 Handle<Code> stub =
3094 KeyedStoreElementStub(is_js_array, 3010 KeyedStoreElementStub(is_js_array,
3095 elements_kind, 3011 elements_kind,
3096 store_mode_).GetCode(isolate()); 3012 store_mode_).GetCode(isolate());
3097 3013
3098 __ DispatchMap(a2, a3, receiver_map, stub, DO_SMI_CHECK); 3014 __ DispatchMap(a2, a3, receiver_map, stub, DO_SMI_CHECK);
3099 3015
3100 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3016 TailCallBuiltin(masm(), MissBuiltin(kind()));
3101 __ Jump(ic, RelocInfo::CODE_TARGET);
3102 3017
3103 // Return the generated code. 3018 // Return the generated code.
3104 return GetCode(Code::NORMAL, factory()->empty_string()); 3019 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
3105 } 3020 }
3106 3021
3107 3022
3108 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 3023 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
3109 MapHandleList* receiver_maps, 3024 MapHandleList* receiver_maps,
3110 CodeHandleList* handler_stubs, 3025 CodeHandleList* handler_stubs,
3111 MapHandleList* transitioned_maps) { 3026 MapHandleList* transitioned_maps) {
3112 // ----------- S t a t e ------------- 3027 // ----------- S t a t e -------------
3113 // -- a0 : value 3028 // -- a0 : value
3114 // -- a1 : key 3029 // -- a1 : key
(...skipping 13 matching lines...) Expand all
3128 } else { 3043 } else {
3129 Label next_map; 3044 Label next_map;
3130 __ Branch(&next_map, ne, a3, Operand(receiver_maps->at(i))); 3045 __ Branch(&next_map, ne, a3, Operand(receiver_maps->at(i)));
3131 __ li(a3, Operand(transitioned_maps->at(i))); 3046 __ li(a3, Operand(transitioned_maps->at(i)));
3132 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET); 3047 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET);
3133 __ bind(&next_map); 3048 __ bind(&next_map);
3134 } 3049 }
3135 } 3050 }
3136 3051
3137 __ bind(&miss); 3052 __ bind(&miss);
3138 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3053 TailCallBuiltin(masm(), MissBuiltin(kind()));
3139 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3140 3054
3141 // Return the generated code. 3055 // Return the generated code.
3142 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3056 return GetICCode(
3057 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3143 } 3058 }
3144 3059
3145 3060
3146 Handle<Code> ConstructStubCompiler::CompileConstructStub( 3061 Handle<Code> ConstructStubCompiler::CompileConstructStub(
3147 Handle<JSFunction> function) { 3062 Handle<JSFunction> function) {
3148 // a0 : argc 3063 // a0 : argc
3149 // a1 : constructor 3064 // a1 : constructor
3150 // ra : return address 3065 // ra : return address
3151 // [sp] : last argument 3066 // [sp] : last argument
3152 Label generic_stub_call; 3067 Label generic_stub_call;
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after
3320 __ bind(&slow); 3235 __ bind(&slow);
3321 __ IncrementCounter( 3236 __ IncrementCounter(
3322 masm->isolate()->counters()->keyed_load_external_array_slow(), 3237 masm->isolate()->counters()->keyed_load_external_array_slow(),
3323 1, a2, a3); 3238 1, a2, a3);
3324 // Entry registers are intact. 3239 // Entry registers are intact.
3325 // ---------- S t a t e -------------- 3240 // ---------- S t a t e --------------
3326 // -- ra : return address 3241 // -- ra : return address
3327 // -- a0 : key 3242 // -- a0 : key
3328 // -- a1 : receiver 3243 // -- a1 : receiver
3329 // ----------------------------------- 3244 // -----------------------------------
3330 Handle<Code> slow_ic = 3245 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
3331 masm->isolate()->builtins()->KeyedLoadIC_Slow();
3332 __ Jump(slow_ic, RelocInfo::CODE_TARGET);
3333 3246
3334 // Miss case, call the runtime. 3247 // Miss case, call the runtime.
3335 __ bind(&miss_force_generic); 3248 __ bind(&miss_force_generic);
3336 3249
3337 // ---------- S t a t e -------------- 3250 // ---------- S t a t e --------------
3338 // -- ra : return address 3251 // -- ra : return address
3339 // -- a0 : key 3252 // -- a0 : key
3340 // -- a1 : receiver 3253 // -- a1 : receiver
3341 // ----------------------------------- 3254 // -----------------------------------
3342 3255 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3343 Handle<Code> miss_ic =
3344 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3345 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3346 } 3256 }
3347 3257
3348 3258
3349 static bool IsElementTypeSigned(ElementsKind elements_kind) { 3259 static bool IsElementTypeSigned(ElementsKind elements_kind) {
3350 switch (elements_kind) { 3260 switch (elements_kind) {
3351 case EXTERNAL_BYTE_ELEMENTS: 3261 case EXTERNAL_BYTE_ELEMENTS:
3352 case EXTERNAL_SHORT_ELEMENTS: 3262 case EXTERNAL_SHORT_ELEMENTS:
3353 case EXTERNAL_INT_ELEMENTS: 3263 case EXTERNAL_INT_ELEMENTS:
3354 return true; 3264 return true;
3355 3265
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after
3789 __ bind(&slow); 3699 __ bind(&slow);
3790 __ IncrementCounter( 3700 __ IncrementCounter(
3791 masm->isolate()->counters()->keyed_load_external_array_slow(), 3701 masm->isolate()->counters()->keyed_load_external_array_slow(),
3792 1, a2, a3); 3702 1, a2, a3);
3793 // Entry registers are intact. 3703 // Entry registers are intact.
3794 // ---------- S t a t e -------------- 3704 // ---------- S t a t e --------------
3795 // -- ra : return address 3705 // -- ra : return address
3796 // -- a0 : key 3706 // -- a0 : key
3797 // -- a1 : receiver 3707 // -- a1 : receiver
3798 // ----------------------------------- 3708 // -----------------------------------
3799 Handle<Code> slow_ic = 3709 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3800 masm->isolate()->builtins()->KeyedStoreIC_Slow();
3801 __ Jump(slow_ic, RelocInfo::CODE_TARGET);
3802 3710
3803 // Miss case, call the runtime. 3711 // Miss case, call the runtime.
3804 __ bind(&miss_force_generic); 3712 __ bind(&miss_force_generic);
3805 3713
3806 // ---------- S t a t e -------------- 3714 // ---------- S t a t e --------------
3807 // -- ra : return address 3715 // -- ra : return address
3808 // -- a0 : key 3716 // -- a0 : key
3809 // -- a1 : receiver 3717 // -- a1 : receiver
3810 // ----------------------------------- 3718 // -----------------------------------
3811 3719 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3812 Handle<Code> miss_ic =
3813 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3814 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3815 } 3720 }
3816 3721
3817 3722
3818 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3723 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3819 MacroAssembler* masm, 3724 MacroAssembler* masm,
3820 bool is_js_array, 3725 bool is_js_array,
3821 ElementsKind elements_kind, 3726 ElementsKind elements_kind,
3822 KeyedAccessStoreMode store_mode) { 3727 KeyedAccessStoreMode store_mode) {
3823 // ----------- S t a t e ------------- 3728 // ----------- S t a t e -------------
3824 // -- a0 : value 3729 // -- a0 : value
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
3895 scratch, // Address. 3800 scratch, // Address.
3896 receiver_reg, // Value. 3801 receiver_reg, // Value.
3897 kRAHasNotBeenSaved, 3802 kRAHasNotBeenSaved,
3898 kDontSaveFPRegs); 3803 kDontSaveFPRegs);
3899 } 3804 }
3900 // value_reg (a0) is preserved. 3805 // value_reg (a0) is preserved.
3901 // Done. 3806 // Done.
3902 __ Ret(); 3807 __ Ret();
3903 3808
3904 __ bind(&miss_force_generic); 3809 __ bind(&miss_force_generic);
3905 Handle<Code> ic = 3810 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3906 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3907 __ Jump(ic, RelocInfo::CODE_TARGET);
3908 3811
3909 __ bind(&transition_elements_kind); 3812 __ bind(&transition_elements_kind);
3910 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3813 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3911 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
3912 3814
3913 if (is_js_array && IsGrowStoreMode(store_mode)) { 3815 if (is_js_array && IsGrowStoreMode(store_mode)) {
3914 // Grow the array by a single element if possible. 3816 // Grow the array by a single element if possible.
3915 __ bind(&grow); 3817 __ bind(&grow);
3916 3818
3917 // Make sure the array is only growing by a single element, anything else 3819 // Make sure the array is only growing by a single element, anything else
3918 // must be handled by the runtime. 3820 // must be handled by the runtime.
3919 __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch)); 3821 __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch));
3920 3822
3921 // Check for the empty array, and preallocate a small backing store if 3823 // Check for the empty array, and preallocate a small backing store if
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3965 3867
3966 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); 3868 __ lw(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
3967 __ Branch(&slow, hs, length_reg, Operand(scratch)); 3869 __ Branch(&slow, hs, length_reg, Operand(scratch));
3968 3870
3969 // Grow the array and finish the store. 3871 // Grow the array and finish the store.
3970 __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1))); 3872 __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1)));
3971 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); 3873 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3972 __ jmp(&finish_store); 3874 __ jmp(&finish_store);
3973 3875
3974 __ bind(&slow); 3876 __ bind(&slow);
3975 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3877 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3976 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
3977 } 3878 }
3978 } 3879 }
3979 3880
3980 3881
3981 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( 3882 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3982 MacroAssembler* masm, 3883 MacroAssembler* masm,
3983 bool is_js_array, 3884 bool is_js_array,
3984 KeyedAccessStoreMode store_mode) { 3885 KeyedAccessStoreMode store_mode) {
3985 // ----------- S t a t e ------------- 3886 // ----------- S t a t e -------------
3986 // -- a0 : value 3887 // -- a0 : value
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
4042 scratch2, 3943 scratch2,
4043 scratch3, 3944 scratch3,
4044 scratch4, 3945 scratch4,
4045 &transition_elements_kind); 3946 &transition_elements_kind);
4046 3947
4047 __ Ret(USE_DELAY_SLOT); 3948 __ Ret(USE_DELAY_SLOT);
4048 __ mov(v0, value_reg); // In delay slot. 3949 __ mov(v0, value_reg); // In delay slot.
4049 3950
4050 // Handle store cache miss, replacing the ic with the generic stub. 3951 // Handle store cache miss, replacing the ic with the generic stub.
4051 __ bind(&miss_force_generic); 3952 __ bind(&miss_force_generic);
4052 Handle<Code> ic = 3953 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
4053 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
4054 __ Jump(ic, RelocInfo::CODE_TARGET);
4055 3954
4056 __ bind(&transition_elements_kind); 3955 __ bind(&transition_elements_kind);
4057 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3956 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
4058 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
4059 3957
4060 if (is_js_array && IsGrowStoreMode(store_mode)) { 3958 if (is_js_array && IsGrowStoreMode(store_mode)) {
4061 // Grow the array by a single element if possible. 3959 // Grow the array by a single element if possible.
4062 __ bind(&grow); 3960 __ bind(&grow);
4063 3961
4064 // Make sure the array is only growing by a single element, anything else 3962 // Make sure the array is only growing by a single element, anything else
4065 // must be handled by the runtime. 3963 // must be handled by the runtime.
4066 __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch1)); 3964 __ Branch(&miss_force_generic, ne, key_reg, Operand(scratch1));
4067 3965
4068 // Transition on values that can't be stored in a FixedDoubleArray. 3966 // Transition on values that can't be stored in a FixedDoubleArray.
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
4131 __ lw(scratch1, 4029 __ lw(scratch1,
4132 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); 4030 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset));
4133 __ Branch(&slow, hs, length_reg, Operand(scratch1)); 4031 __ Branch(&slow, hs, length_reg, Operand(scratch1));
4134 4032
4135 // Grow the array and finish the store. 4033 // Grow the array and finish the store.
4136 __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1))); 4034 __ Addu(length_reg, length_reg, Operand(Smi::FromInt(1)));
4137 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); 4035 __ sw(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
4138 __ jmp(&finish_store); 4036 __ jmp(&finish_store);
4139 4037
4140 __ bind(&slow); 4038 __ bind(&slow);
4141 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 4039 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
4142 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4143 } 4040 }
4144 } 4041 }
4145 4042
4146 4043
4147 #undef __ 4044 #undef __
4148 4045
4149 } } // namespace v8::internal 4046 } } // namespace v8::internal
4150 4047
4151 #endif // V8_TARGET_ARCH_MIPS 4048 #endif // V8_TARGET_ARCH_MIPS
OLDNEW
« no previous file with comments | « src/mips/code-stubs-mips.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698