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

Side by Side Diff: src/arm/stub-cache-arm.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/arm/code-stubs-arm.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | 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 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
313 // Get the global function with the given index. 313 // Get the global function with the given index.
314 Handle<JSFunction> function( 314 Handle<JSFunction> function(
315 JSFunction::cast(isolate->native_context()->get(index))); 315 JSFunction::cast(isolate->native_context()->get(index)));
316 // Load its initial map. The global functions all have initial maps. 316 // Load its initial map. The global functions all have initial maps.
317 __ Move(prototype, Handle<Map>(function->initial_map())); 317 __ Move(prototype, Handle<Map>(function->initial_map()));
318 // Load the prototype from the initial map. 318 // Load the prototype from the initial map.
319 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset)); 319 __ ldr(prototype, FieldMemOperand(prototype, Map::kPrototypeOffset));
320 } 320 }
321 321
322 322
323 // Load a fast property out of a holder object (src). In-object properties
324 // are loaded directly otherwise the property is loaded from the properties
325 // fixed array.
326 void StubCompiler::GenerateFastPropertyLoad(MacroAssembler* masm,
327 Register dst,
328 Register src,
329 Handle<JSObject> holder,
330 PropertyIndex index) {
331 DoGenerateFastPropertyLoad(
332 masm, dst, src, index.is_inobject(holder), index.translate(holder));
333 }
334
335
336 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm, 323 void StubCompiler::DoGenerateFastPropertyLoad(MacroAssembler* masm,
337 Register dst, 324 Register dst,
338 Register src, 325 Register src,
339 bool inobject, 326 bool inobject,
340 int index) { 327 int index) {
341 int offset = index * kPointerSize; 328 int offset = index * kPointerSize;
342 if (!inobject) { 329 if (!inobject) {
343 // Calculate the offset into the properties array. 330 // Calculate the offset into the properties array.
344 offset = offset + FixedArray::kHeaderSize; 331 offset = offset + FixedArray::kHeaderSize;
345 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset)); 332 __ ldr(dst, FieldMemOperand(src, JSObject::kPropertiesOffset));
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 // When leaving generated code after success, the receiver_reg and name_reg 426 // When leaving generated code after success, the receiver_reg and name_reg
440 // may be clobbered. Upon branch to miss_label, the receiver and name 427 // may be clobbered. Upon branch to miss_label, the receiver and name
441 // registers have their original values. 428 // registers have their original values.
442 void StubCompiler::GenerateStoreField(MacroAssembler* masm, 429 void StubCompiler::GenerateStoreField(MacroAssembler* masm,
443 Handle<JSObject> object, 430 Handle<JSObject> object,
444 int index, 431 int index,
445 Handle<Map> transition, 432 Handle<Map> transition,
446 Handle<Name> name, 433 Handle<Name> name,
447 Register receiver_reg, 434 Register receiver_reg,
448 Register name_reg, 435 Register name_reg,
436 Register value_reg,
449 Register scratch1, 437 Register scratch1,
450 Register scratch2, 438 Register scratch2,
451 Label* miss_label) { 439 Label* miss_label,
440 Label* miss_restore_name) {
452 // r0 : value 441 // r0 : value
453 Label exit; 442 Label exit;
454 443
455 LookupResult lookup(masm->isolate()); 444 LookupResult lookup(masm->isolate());
456 object->Lookup(*name, &lookup); 445 object->Lookup(*name, &lookup);
457 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { 446 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) {
458 // In sloppy mode, we could just return the value and be done. However, we 447 // In sloppy mode, we could just return the value and be done. However, we
459 // might be in strict mode, where we have to throw. Since we cannot tell, 448 // might be in strict mode, where we have to throw. Since we cannot tell,
460 // go into slow case unconditionally. 449 // go into slow case unconditionally.
461 __ jmp(miss_label); 450 __ jmp(miss_label);
(...skipping 16 matching lines...) Expand all
478 JSObject* holder; 467 JSObject* holder;
479 if (lookup.IsFound()) { 468 if (lookup.IsFound()) {
480 holder = lookup.holder(); 469 holder = lookup.holder();
481 } else { 470 } else {
482 // Find the top object. 471 // Find the top object.
483 holder = *object; 472 holder = *object;
484 do { 473 do {
485 holder = JSObject::cast(holder->GetPrototype()); 474 holder = JSObject::cast(holder->GetPrototype());
486 } while (holder->GetPrototype()->IsJSObject()); 475 } while (holder->GetPrototype()->IsJSObject());
487 } 476 }
488 // We need an extra register, push
489 __ push(name_reg);
490 Label miss_pop, done_check;
491 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, 477 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg,
492 scratch1, scratch2, name, &miss_pop); 478 scratch1, scratch2, name, miss_restore_name);
493 __ jmp(&done_check);
494 __ bind(&miss_pop);
495 __ pop(name_reg);
496 __ jmp(miss_label);
497 __ bind(&done_check);
498 __ pop(name_reg);
499 } 479 }
500 480
501 // Stub never generated for non-global objects that require access 481 // Stub never generated for non-global objects that require access
502 // checks. 482 // checks.
503 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 483 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
504 484
505 // Perform map transition for the receiver if necessary. 485 // Perform map transition for the receiver if necessary.
506 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) { 486 if (!transition.is_null() && (object->map()->unused_property_fields() == 0)) {
507 // The properties must be extended before we can store the value. 487 // The properties must be extended before we can store the value.
508 // We jump to a runtime call that extends the properties array. 488 // We jump to a runtime call that extends the properties array.
(...skipping 26 matching lines...) Expand all
535 } 515 }
536 516
537 // Adjust for the number of properties stored in the object. Even in the 517 // Adjust for the number of properties stored in the object. Even in the
538 // face of a transition we can use the old map here because the size of the 518 // face of a transition we can use the old map here because the size of the
539 // object and the number of in-object properties is not going to change. 519 // object and the number of in-object properties is not going to change.
540 index -= object->map()->inobject_properties(); 520 index -= object->map()->inobject_properties();
541 521
542 if (index < 0) { 522 if (index < 0) {
543 // Set the property straight into the object. 523 // Set the property straight into the object.
544 int offset = object->map()->instance_size() + (index * kPointerSize); 524 int offset = object->map()->instance_size() + (index * kPointerSize);
545 __ str(r0, FieldMemOperand(receiver_reg, offset)); 525 __ str(value_reg, FieldMemOperand(receiver_reg, offset));
546 526
547 // Skip updating write barrier if storing a smi. 527 // Skip updating write barrier if storing a smi.
548 __ JumpIfSmi(r0, &exit); 528 __ JumpIfSmi(value_reg, &exit);
549 529
550 // Update the write barrier for the array address. 530 // Update the write barrier for the array address.
551 // Pass the now unused name_reg as a scratch register. 531 // Pass the now unused name_reg as a scratch register.
552 __ mov(name_reg, r0); 532 __ mov(name_reg, value_reg);
553 __ RecordWriteField(receiver_reg, 533 __ RecordWriteField(receiver_reg,
554 offset, 534 offset,
555 name_reg, 535 name_reg,
556 scratch1, 536 scratch1,
557 kLRHasNotBeenSaved, 537 kLRHasNotBeenSaved,
558 kDontSaveFPRegs); 538 kDontSaveFPRegs);
559 } else { 539 } else {
560 // Write to the properties array. 540 // Write to the properties array.
561 int offset = index * kPointerSize + FixedArray::kHeaderSize; 541 int offset = index * kPointerSize + FixedArray::kHeaderSize;
562 // Get the properties array 542 // Get the properties array
563 __ ldr(scratch1, 543 __ ldr(scratch1,
564 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset)); 544 FieldMemOperand(receiver_reg, JSObject::kPropertiesOffset));
565 __ str(r0, FieldMemOperand(scratch1, offset)); 545 __ str(value_reg, FieldMemOperand(scratch1, offset));
566 546
567 // Skip updating write barrier if storing a smi. 547 // Skip updating write barrier if storing a smi.
568 __ JumpIfSmi(r0, &exit); 548 __ JumpIfSmi(value_reg, &exit);
569 549
570 // Update the write barrier for the array address. 550 // Update the write barrier for the array address.
571 // Ok to clobber receiver_reg and name_reg, since we return. 551 // Ok to clobber receiver_reg and name_reg, since we return.
572 __ mov(name_reg, r0); 552 __ mov(name_reg, value_reg);
573 __ RecordWriteField(scratch1, 553 __ RecordWriteField(scratch1,
574 offset, 554 offset,
575 name_reg, 555 name_reg,
576 receiver_reg, 556 receiver_reg,
577 kLRHasNotBeenSaved, 557 kLRHasNotBeenSaved,
578 kDontSaveFPRegs); 558 kDontSaveFPRegs);
579 } 559 }
580 560
581 // Return the value (register r0). 561 // Return the value (register r0).
562 ASSERT(value_reg.is(r0));
582 __ bind(&exit); 563 __ bind(&exit);
583 __ Ret(); 564 __ Ret();
584 } 565 }
585 566
586 567
587 void StubCompiler::GenerateLoadMiss(MacroAssembler* masm, Code::Kind kind) { 568 void BaseStoreStubCompiler::GenerateRestoreName(MacroAssembler* masm,
588 ASSERT(kind == Code::LOAD_IC || kind == Code::KEYED_LOAD_IC); 569 Label* label,
589 Handle<Code> code = (kind == Code::LOAD_IC) 570 Handle<Name> name) {
590 ? masm->isolate()->builtins()->LoadIC_Miss() 571 if (!label->is_unused()) {
591 : masm->isolate()->builtins()->KeyedLoadIC_Miss(); 572 __ bind(label);
592 __ Jump(code, RelocInfo::CODE_TARGET); 573 __ mov(this->name(), Operand(name));
574 }
593 } 575 }
594 576
595 577
596 void StubCompiler::GenerateStoreMiss(MacroAssembler* masm, Code::Kind kind) {
597 ASSERT(kind == Code::STORE_IC || kind == Code::KEYED_STORE_IC);
598 Handle<Code> code = (kind == Code::STORE_IC)
599 ? masm->isolate()->builtins()->StoreIC_Miss()
600 : masm->isolate()->builtins()->KeyedStoreIC_Miss();
601 __ Jump(code, RelocInfo::CODE_TARGET);
602 }
603
604
605 static void GenerateCallFunction(MacroAssembler* masm, 578 static void GenerateCallFunction(MacroAssembler* masm,
606 Handle<Object> object, 579 Handle<Object> object,
607 const ParameterCount& arguments, 580 const ParameterCount& arguments,
608 Label* miss, 581 Label* miss,
609 Code::ExtraICState extra_ic_state) { 582 Code::ExtraICState extra_ic_state) {
610 // ----------- S t a t e ------------- 583 // ----------- S t a t e -------------
611 // -- r0: receiver 584 // -- r0: receiver
612 // -- r1: function to call 585 // -- r1: function to call
613 // ----------------------------------- 586 // -----------------------------------
614 587
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1056 __ orr(fval, 1029 __ orr(fval,
1057 fval, 1030 fval,
1058 Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits)); 1031 Operand(ival, LSR, kBitsPerInt - kBinary32MantissaBits));
1059 1032
1060 __ bind(&done); 1033 __ bind(&done);
1061 __ str(fval, MemOperand(dst, wordoffset, LSL, 2)); 1034 __ str(fval, MemOperand(dst, wordoffset, LSL, 2));
1062 } 1035 }
1063 } 1036 }
1064 1037
1065 1038
1039 void StubCompiler::GenerateTailCall(MacroAssembler* masm, Handle<Code> code) {
1040 __ Jump(code, RelocInfo::CODE_TARGET);
1041 }
1042
1043
1066 #undef __ 1044 #undef __
1067 #define __ ACCESS_MASM(masm()) 1045 #define __ ACCESS_MASM(masm())
1068 1046
1069 1047
1070 void StubCompiler::GenerateTailCall(Handle<Code> code) {
1071 __ Jump(code, RelocInfo::CODE_TARGET);
1072 }
1073
1074
1075 Register StubCompiler::CheckPrototypes(Handle<JSObject> object, 1048 Register StubCompiler::CheckPrototypes(Handle<JSObject> object,
1076 Register object_reg, 1049 Register object_reg,
1077 Handle<JSObject> holder, 1050 Handle<JSObject> holder,
1078 Register holder_reg, 1051 Register holder_reg,
1079 Register scratch1, 1052 Register scratch1,
1080 Register scratch2, 1053 Register scratch2,
1081 Handle<Name> name, 1054 Handle<Name> name,
1082 int save_at_depth, 1055 int save_at_depth,
1083 Label* miss, 1056 Label* miss,
1084 PrototypeCheckType check) { 1057 PrototypeCheckType check) {
(...skipping 98 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 __ b(success); 1164 __ b(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 1388 matching lines...) Expand 10 before | Expand all | Expand 10 after
2592 // Handle call cache miss. 2565 // Handle call cache miss.
2593 __ bind(&miss); 2566 __ bind(&miss);
2594 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3); 2567 __ IncrementCounter(counters->call_global_inline_miss(), 1, r1, r3);
2595 GenerateMissBranch(); 2568 GenerateMissBranch();
2596 2569
2597 // Return the generated code. 2570 // Return the generated code.
2598 return GetCode(Code::NORMAL, name); 2571 return GetCode(Code::NORMAL, name);
2599 } 2572 }
2600 2573
2601 2574
2602 Handle<Code> StoreStubCompiler::CompileStoreField(Handle<JSObject> object,
2603 int index,
2604 Handle<Map> transition,
2605 Handle<Name> name) {
2606 // ----------- S t a t e -------------
2607 // -- r0 : value
2608 // -- r1 : receiver
2609 // -- r2 : name
2610 // -- lr : return address
2611 // -----------------------------------
2612 Label miss;
2613
2614 GenerateStoreField(masm(),
2615 object,
2616 index,
2617 transition,
2618 name,
2619 r1, r2, r3, r4,
2620 &miss);
2621 __ bind(&miss);
2622 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss();
2623 __ Jump(ic, RelocInfo::CODE_TARGET);
2624
2625 // Return the generated code.
2626 return GetCode(transition.is_null()
2627 ? Code::FIELD
2628 : Code::MAP_TRANSITION, name);
2629 }
2630
2631
2632 Handle<Code> StoreStubCompiler::CompileStoreCallback( 2575 Handle<Code> StoreStubCompiler::CompileStoreCallback(
2633 Handle<Name> name, 2576 Handle<Name> name,
2634 Handle<JSObject> receiver, 2577 Handle<JSObject> receiver,
2635 Handle<JSObject> holder, 2578 Handle<JSObject> holder,
2636 Handle<ExecutableAccessorInfo> callback) { 2579 Handle<ExecutableAccessorInfo> callback) {
2637 // ----------- S t a t e ------------- 2580 // ----------- S t a t e -------------
2638 // -- r0 : value 2581 // -- r0 : value
2639 // -- r1 : receiver 2582 // -- r1 : receiver
2640 // -- r2 : name 2583 // -- r2 : name
2641 // -- lr : return address 2584 // -- lr : return address
(...skipping 11 matching lines...) Expand all
2653 __ Push(ip, r2, r0); 2596 __ Push(ip, r2, r0);
2654 2597
2655 // Do tail-call to the runtime system. 2598 // Do tail-call to the runtime system.
2656 ExternalReference store_callback_property = 2599 ExternalReference store_callback_property =
2657 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), 2600 ExternalReference(IC_Utility(IC::kStoreCallbackProperty),
2658 masm()->isolate()); 2601 masm()->isolate());
2659 __ TailCallExternalReference(store_callback_property, 4, 1); 2602 __ TailCallExternalReference(store_callback_property, 4, 1);
2660 2603
2661 // Handle store cache miss. 2604 // Handle store cache miss.
2662 __ bind(&miss); 2605 __ bind(&miss);
2663 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2606 TailCallBuiltin(masm(), MissBuiltin(kind()));
2664 __ Jump(ic, RelocInfo::CODE_TARGET);
2665 2607
2666 // Return the generated code. 2608 // Return the generated code.
2667 return GetCode(Code::CALLBACKS, name); 2609 return GetICCode(kind(), Code::CALLBACKS, name);
2668 } 2610 }
2669 2611
2670 2612
2671 #undef __ 2613 #undef __
2672 #define __ ACCESS_MASM(masm) 2614 #define __ ACCESS_MASM(masm)
2673 2615
2674 2616
2675 void StoreStubCompiler::GenerateStoreViaSetter( 2617 void StoreStubCompiler::GenerateStoreViaSetter(
2676 MacroAssembler* masm, 2618 MacroAssembler* masm,
2677 Handle<JSFunction> setter) { 2619 Handle<JSFunction> setter) {
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
2726 // ----------------------------------- 2668 // -----------------------------------
2727 Label miss; 2669 Label miss;
2728 2670
2729 // Check that the maps haven't changed. 2671 // Check that the maps haven't changed.
2730 __ JumpIfSmi(r1, &miss); 2672 __ JumpIfSmi(r1, &miss);
2731 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss); 2673 CheckPrototypes(receiver, r1, holder, r3, r4, r5, name, &miss);
2732 2674
2733 GenerateStoreViaSetter(masm(), setter); 2675 GenerateStoreViaSetter(masm(), setter);
2734 2676
2735 __ bind(&miss); 2677 __ bind(&miss);
2736 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2678 TailCallBuiltin(masm(), MissBuiltin(kind()));
2737 __ Jump(ic, RelocInfo::CODE_TARGET);
2738 2679
2739 // Return the generated code. 2680 // Return the generated code.
2740 return GetCode(Code::CALLBACKS, name); 2681 return GetICCode(kind(), Code::CALLBACKS, name);
2741 } 2682 }
2742 2683
2743 2684
2744 Handle<Code> StoreStubCompiler::CompileStoreInterceptor( 2685 Handle<Code> StoreStubCompiler::CompileStoreInterceptor(
2745 Handle<JSObject> receiver, 2686 Handle<JSObject> receiver,
2746 Handle<Name> name) { 2687 Handle<Name> name) {
2747 // ----------- S t a t e ------------- 2688 // ----------- S t a t e -------------
2748 // -- r0 : value 2689 // -- r0 : value
2749 // -- r1 : receiver 2690 // -- r1 : receiver
2750 // -- r2 : name 2691 // -- r2 : name
2751 // -- lr : return address 2692 // -- lr : return address
2752 // ----------------------------------- 2693 // -----------------------------------
2753 Label miss; 2694 Label miss;
2754 2695
2755 // Check that the map of the object hasn't changed. 2696 // Check that the map of the object hasn't changed.
2756 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss, 2697 __ CheckMap(r1, r3, Handle<Map>(receiver->map()), &miss,
2757 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS); 2698 DO_SMI_CHECK, ALLOW_ELEMENT_TRANSITION_MAPS);
2758 2699
2759 // Perform global security token check if needed. 2700 // Perform global security token check if needed.
2760 if (receiver->IsJSGlobalProxy()) { 2701 if (receiver->IsJSGlobalProxy()) {
2761 __ CheckAccessGlobalProxy(r1, r3, &miss); 2702 __ CheckAccessGlobalProxy(r1, r3, &miss);
2762 } 2703 }
2763 2704
2764 // Stub is never generated for non-global objects that require access 2705 // Stub is never generated for non-global objects that require access
2765 // checks. 2706 // checks.
2766 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); 2707 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
2767 2708
2768 __ Push(r1, r2, r0); // Receiver, name, value. 2709 __ Push(r1, r2, r0); // Receiver, name, value.
2769 2710
2770 __ mov(r0, Operand(Smi::FromInt(strict_mode_))); 2711 __ mov(r0, Operand(Smi::FromInt(strict_mode())));
2771 __ push(r0); // strict mode 2712 __ push(r0); // strict mode
2772 2713
2773 // Do tail-call to the runtime system. 2714 // Do tail-call to the runtime system.
2774 ExternalReference store_ic_property = 2715 ExternalReference store_ic_property =
2775 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), 2716 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty),
2776 masm()->isolate()); 2717 masm()->isolate());
2777 __ TailCallExternalReference(store_ic_property, 4, 1); 2718 __ TailCallExternalReference(store_ic_property, 4, 1);
2778 2719
2779 // Handle store cache miss. 2720 // Handle store cache miss.
2780 __ bind(&miss); 2721 __ bind(&miss);
2781 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2722 TailCallBuiltin(masm(), MissBuiltin(kind()));
2782 __ Jump(ic, RelocInfo::CODE_TARGET);
2783 2723
2784 // Return the generated code. 2724 // Return the generated code.
2785 return GetCode(Code::INTERCEPTOR, name); 2725 return GetICCode(kind(), Code::INTERCEPTOR, name);
2786 } 2726 }
2787 2727
2788 2728
2789 Handle<Code> StoreStubCompiler::CompileStoreGlobal( 2729 Handle<Code> StoreStubCompiler::CompileStoreGlobal(
2790 Handle<GlobalObject> object, 2730 Handle<GlobalObject> object,
2791 Handle<JSGlobalPropertyCell> cell, 2731 Handle<JSGlobalPropertyCell> cell,
2792 Handle<Name> name) { 2732 Handle<Name> name) {
2793 // ----------- S t a t e ------------- 2733 // ----------- S t a t e -------------
2794 // -- r0 : value 2734 // -- r0 : value
2795 // -- r1 : receiver 2735 // -- r1 : receiver
(...skipping 21 matching lines...) Expand all
2817 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset)); 2757 __ str(r0, FieldMemOperand(r4, JSGlobalPropertyCell::kValueOffset));
2818 // Cells are always rescanned, so no write barrier here. 2758 // Cells are always rescanned, so no write barrier here.
2819 2759
2820 Counters* counters = masm()->isolate()->counters(); 2760 Counters* counters = masm()->isolate()->counters();
2821 __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3); 2761 __ IncrementCounter(counters->named_store_global_inline(), 1, r4, r3);
2822 __ Ret(); 2762 __ Ret();
2823 2763
2824 // Handle store cache miss. 2764 // Handle store cache miss.
2825 __ bind(&miss); 2765 __ bind(&miss);
2826 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3); 2766 __ IncrementCounter(counters->named_store_global_inline_miss(), 1, r4, r3);
2827 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2767 TailCallBuiltin(masm(), MissBuiltin(kind()));
2828 __ Jump(ic, RelocInfo::CODE_TARGET);
2829 2768
2830 // Return the generated code. 2769 // Return the generated code.
2831 return GetCode(Code::NORMAL, name); 2770 return GetICCode(kind(), Code::NORMAL, name);
2832 } 2771 }
2833 2772
2834 2773
2835 Handle<Code> LoadStubCompiler::CompileLoadNonexistent( 2774 Handle<Code> LoadStubCompiler::CompileLoadNonexistent(
2836 Handle<JSObject> object, 2775 Handle<JSObject> object,
2837 Handle<JSObject> last, 2776 Handle<JSObject> last,
2838 Handle<Name> name, 2777 Handle<Name> name,
2839 Handle<GlobalObject> global) { 2778 Handle<GlobalObject> global) {
2840 Label success; 2779 Label success;
2841 2780
(...skipping 17 matching lines...) Expand all
2859 } 2798 }
2860 2799
2861 2800
2862 Register* KeyedLoadStubCompiler::registers() { 2801 Register* KeyedLoadStubCompiler::registers() {
2863 // receiver, name, scratch1, scratch2, scratch3, scratch4. 2802 // receiver, name, scratch1, scratch2, scratch3, scratch4.
2864 static Register registers[] = { r1, r0, r2, r3, r4, r5 }; 2803 static Register registers[] = { r1, r0, r2, r3, r4, r5 };
2865 return registers; 2804 return registers;
2866 } 2805 }
2867 2806
2868 2807
2808 Register* StoreStubCompiler::registers() {
2809 // receiver, name, value, scratch1, scratch2, scratch3.
2810 static Register registers[] = { r1, r2, r0, r3, r4, r5 };
2811 return registers;
2812 }
2813
2814
2815 Register* KeyedStoreStubCompiler::registers() {
2816 // receiver, name, value, scratch1, scratch2, scratch3.
2817 static Register registers[] = { r2, r1, r0, r3, r4, r5 };
2818 return registers;
2819 }
2820
2821
2869 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name, 2822 void KeyedLoadStubCompiler::GenerateNameCheck(Handle<Name> name,
2870 Register name_reg, 2823 Register name_reg,
2871 Label* miss) { 2824 Label* miss) {
2872 __ cmp(name_reg, Operand(name)); 2825 __ cmp(name_reg, Operand(name));
2873 __ b(ne, miss); 2826 __ b(ne, miss);
2874 } 2827 }
2875 2828
2876 2829
2830 void KeyedStoreStubCompiler::GenerateNameCheck(Handle<Name> name,
2831 Register name_reg,
2832 Label* miss) {
2833 __ cmp(name_reg, Operand(name));
2834 __ b(ne, miss);
2835 }
2836
2837
2877 #undef __ 2838 #undef __
2878 #define __ ACCESS_MASM(masm) 2839 #define __ ACCESS_MASM(masm)
2879 2840
2880 2841
2881 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm, 2842 void LoadStubCompiler::GenerateLoadViaGetter(MacroAssembler* masm,
2882 Handle<JSFunction> getter) { 2843 Handle<JSFunction> getter) {
2883 // ----------- S t a t e ------------- 2844 // ----------- S t a t e -------------
2884 // -- r0 : receiver 2845 // -- r0 : receiver
2885 // -- r2 : name 2846 // -- r2 : name
2886 // -- lr : return address 2847 // -- lr : return address
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2961 Handle<Code> stub = KeyedLoadFastElementStub( 2922 Handle<Code> stub = KeyedLoadFastElementStub(
2962 receiver_map->instance_type() == JS_ARRAY_TYPE, 2923 receiver_map->instance_type() == JS_ARRAY_TYPE,
2963 elements_kind).GetCode(isolate()); 2924 elements_kind).GetCode(isolate());
2964 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK); 2925 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK);
2965 } else { 2926 } else {
2966 Handle<Code> stub = 2927 Handle<Code> stub =
2967 KeyedLoadDictionaryElementStub().GetCode(isolate()); 2928 KeyedLoadDictionaryElementStub().GetCode(isolate());
2968 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK); 2929 __ DispatchMap(r1, r2, receiver_map, stub, DO_SMI_CHECK);
2969 } 2930 }
2970 2931
2971 Handle<Code> ic = isolate()->builtins()->KeyedLoadIC_Miss(); 2932 TailCallBuiltin(masm(), MissBuiltin(kind()));
2972 __ Jump(ic, RelocInfo::CODE_TARGET);
2973 2933
2974 // Return the generated code. 2934 // Return the generated code.
2975 return GetICCode(kind(), Code::NORMAL, factory()->empty_string()); 2935 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
2976 } 2936 }
2977 2937
2978 2938
2979 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC( 2939 Handle<Code> BaseLoadStubCompiler::CompilePolymorphicIC(
2980 MapHandleList* receiver_maps, 2940 MapHandleList* receiver_maps,
2981 CodeHandleList* handlers, 2941 CodeHandleList* handlers,
2982 Handle<Name> name, 2942 Handle<Name> name,
(...skipping 10 matching lines...) Expand all
2993 2953
2994 int receiver_count = receiver_maps->length(); 2954 int receiver_count = receiver_maps->length();
2995 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset)); 2955 __ ldr(map_reg, FieldMemOperand(receiver(), HeapObject::kMapOffset));
2996 for (int current = 0; current < receiver_count; ++current) { 2956 for (int current = 0; current < receiver_count; ++current) {
2997 __ mov(ip, Operand(receiver_maps->at(current))); 2957 __ mov(ip, Operand(receiver_maps->at(current)));
2998 __ cmp(map_reg, ip); 2958 __ cmp(map_reg, ip);
2999 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq); 2959 __ Jump(handlers->at(current), RelocInfo::CODE_TARGET, eq);
3000 } 2960 }
3001 2961
3002 __ bind(&miss); 2962 __ bind(&miss);
3003 GenerateLoadMiss(masm(), kind()); 2963 TailCallBuiltin(masm(), MissBuiltin(kind()));
3004 2964
3005 // Return the generated code. 2965 // Return the generated code.
3006 InlineCacheState state = 2966 InlineCacheState state =
3007 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC; 2967 receiver_maps->length() > 1 ? POLYMORPHIC : MONOMORPHIC;
3008 return GetICCode(kind(), type, name, state); 2968 return GetICCode(kind(), type, name, state);
3009 } 2969 }
3010 2970
3011 2971
3012 Handle<Code> KeyedStoreStubCompiler::CompileStoreField(Handle<JSObject> object,
3013 int index,
3014 Handle<Map> transition,
3015 Handle<Name> name) {
3016 // ----------- S t a t e -------------
3017 // -- r0 : value
3018 // -- r1 : name
3019 // -- r2 : receiver
3020 // -- lr : return address
3021 // -----------------------------------
3022 Label miss;
3023
3024 Counters* counters = masm()->isolate()->counters();
3025 __ IncrementCounter(counters->keyed_store_field(), 1, r3, r4);
3026
3027 // Check that the name has not changed.
3028 __ cmp(r1, Operand(name));
3029 __ b(ne, &miss);
3030
3031 // r3 is used as scratch register. r1 and r2 keep their values if a jump to
3032 // the miss label is generated.
3033 GenerateStoreField(masm(),
3034 object,
3035 index,
3036 transition,
3037 name,
3038 r2, r1, r3, r4,
3039 &miss);
3040 __ bind(&miss);
3041
3042 __ DecrementCounter(counters->keyed_store_field(), 1, r3, r4);
3043 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss();
3044 __ Jump(ic, RelocInfo::CODE_TARGET);
3045
3046 // Return the generated code.
3047 return GetCode(transition.is_null()
3048 ? Code::FIELD
3049 : Code::MAP_TRANSITION, name);
3050 }
3051
3052
3053 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement( 2972 Handle<Code> KeyedStoreStubCompiler::CompileStoreElement(
3054 Handle<Map> receiver_map) { 2973 Handle<Map> receiver_map) {
3055 // ----------- S t a t e ------------- 2974 // ----------- S t a t e -------------
3056 // -- r0 : value 2975 // -- r0 : value
3057 // -- r1 : key 2976 // -- r1 : key
3058 // -- r2 : receiver 2977 // -- r2 : receiver
3059 // -- lr : return address 2978 // -- lr : return address
3060 // -- r3 : scratch 2979 // -- r3 : scratch
3061 // ----------------------------------- 2980 // -----------------------------------
3062 ElementsKind elements_kind = receiver_map->elements_kind(); 2981 ElementsKind elements_kind = receiver_map->elements_kind();
3063 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; 2982 bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
3064 Handle<Code> stub = 2983 Handle<Code> stub =
3065 KeyedStoreElementStub(is_js_array, 2984 KeyedStoreElementStub(is_js_array,
3066 elements_kind, 2985 elements_kind,
3067 store_mode_).GetCode(isolate()); 2986 store_mode_).GetCode(isolate());
3068 2987
3069 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK); 2988 __ DispatchMap(r2, r3, receiver_map, stub, DO_SMI_CHECK);
3070 2989
3071 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss(); 2990 TailCallBuiltin(masm(), MissBuiltin(kind()));
3072 __ Jump(ic, RelocInfo::CODE_TARGET);
3073 2991
3074 // Return the generated code. 2992 // Return the generated code.
3075 return GetCode(Code::NORMAL, factory()->empty_string()); 2993 return GetICCode(kind(), Code::NORMAL, factory()->empty_string());
3076 } 2994 }
3077 2995
3078 2996
3079 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic( 2997 Handle<Code> KeyedStoreStubCompiler::CompileStorePolymorphic(
3080 MapHandleList* receiver_maps, 2998 MapHandleList* receiver_maps,
3081 CodeHandleList* handler_stubs, 2999 CodeHandleList* handler_stubs,
3082 MapHandleList* transitioned_maps) { 3000 MapHandleList* transitioned_maps) {
3083 // ----------- S t a t e ------------- 3001 // ----------- S t a t e -------------
3084 // -- r0 : value 3002 // -- r0 : value
3085 // -- r1 : key 3003 // -- r1 : key
(...skipping 14 matching lines...) Expand all
3100 } else { 3018 } else {
3101 Label next_map; 3019 Label next_map;
3102 __ b(ne, &next_map); 3020 __ b(ne, &next_map);
3103 __ mov(r3, Operand(transitioned_maps->at(i))); 3021 __ mov(r3, Operand(transitioned_maps->at(i)));
3104 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al); 3022 __ Jump(handler_stubs->at(i), RelocInfo::CODE_TARGET, al);
3105 __ bind(&next_map); 3023 __ bind(&next_map);
3106 } 3024 }
3107 } 3025 }
3108 3026
3109 __ bind(&miss); 3027 __ bind(&miss);
3110 Handle<Code> miss_ic = isolate()->builtins()->KeyedStoreIC_Miss(); 3028 TailCallBuiltin(masm(), MissBuiltin(kind()));
3111 __ Jump(miss_ic, RelocInfo::CODE_TARGET, al);
3112 3029
3113 // Return the generated code. 3030 // Return the generated code.
3114 return GetCode(Code::NORMAL, factory()->empty_string(), POLYMORPHIC); 3031 return GetICCode(
3032 kind(), Code::NORMAL, factory()->empty_string(), POLYMORPHIC);
3115 } 3033 }
3116 3034
3117 3035
3118 Handle<Code> ConstructStubCompiler::CompileConstructStub( 3036 Handle<Code> ConstructStubCompiler::CompileConstructStub(
3119 Handle<JSFunction> function) { 3037 Handle<JSFunction> function) {
3120 // ----------- S t a t e ------------- 3038 // ----------- S t a t e -------------
3121 // -- r0 : argc 3039 // -- r0 : argc
3122 // -- r1 : constructor 3040 // -- r1 : constructor
3123 // -- lr : return address 3041 // -- lr : return address
3124 // -- [sp] : last argument 3042 // -- [sp] : last argument
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
3285 __ bind(&slow); 3203 __ bind(&slow);
3286 __ IncrementCounter( 3204 __ IncrementCounter(
3287 masm->isolate()->counters()->keyed_load_external_array_slow(), 3205 masm->isolate()->counters()->keyed_load_external_array_slow(),
3288 1, r2, r3); 3206 1, r2, r3);
3289 3207
3290 // ---------- S t a t e -------------- 3208 // ---------- S t a t e --------------
3291 // -- lr : return address 3209 // -- lr : return address
3292 // -- r0 : key 3210 // -- r0 : key
3293 // -- r1 : receiver 3211 // -- r1 : receiver
3294 // ----------------------------------- 3212 // -----------------------------------
3295 Handle<Code> slow_ic = 3213 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Slow);
3296 masm->isolate()->builtins()->KeyedLoadIC_Slow();
3297 __ Jump(slow_ic, RelocInfo::CODE_TARGET);
3298 3214
3299 // Miss case, call the runtime. 3215 // Miss case, call the runtime.
3300 __ bind(&miss_force_generic); 3216 __ bind(&miss_force_generic);
3301 3217
3302 // ---------- S t a t e -------------- 3218 // ---------- S t a t e --------------
3303 // -- lr : return address 3219 // -- lr : return address
3304 // -- r0 : key 3220 // -- r0 : key
3305 // -- r1 : receiver 3221 // -- r1 : receiver
3306 // ----------------------------------- 3222 // -----------------------------------
3307 3223 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_MissForceGeneric);
3308 Handle<Code> miss_ic =
3309 masm->isolate()->builtins()->KeyedLoadIC_MissForceGeneric();
3310 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3311 } 3224 }
3312 3225
3313 3226
3314 static bool IsElementTypeSigned(ElementsKind elements_kind) { 3227 static bool IsElementTypeSigned(ElementsKind elements_kind) {
3315 switch (elements_kind) { 3228 switch (elements_kind) {
3316 case EXTERNAL_BYTE_ELEMENTS: 3229 case EXTERNAL_BYTE_ELEMENTS:
3317 case EXTERNAL_SHORT_ELEMENTS: 3230 case EXTERNAL_SHORT_ELEMENTS:
3318 case EXTERNAL_INT_ELEMENTS: 3231 case EXTERNAL_INT_ELEMENTS:
3319 return true; 3232 return true;
3320 3233
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after
3692 __ bind(&slow); 3605 __ bind(&slow);
3693 __ IncrementCounter( 3606 __ IncrementCounter(
3694 masm->isolate()->counters()->keyed_load_external_array_slow(), 3607 masm->isolate()->counters()->keyed_load_external_array_slow(),
3695 1, r2, r3); 3608 1, r2, r3);
3696 3609
3697 // ---------- S t a t e -------------- 3610 // ---------- S t a t e --------------
3698 // -- lr : return address 3611 // -- lr : return address
3699 // -- r0 : key 3612 // -- r0 : key
3700 // -- r1 : receiver 3613 // -- r1 : receiver
3701 // ----------------------------------- 3614 // -----------------------------------
3702 Handle<Code> slow_ic = 3615 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3703 masm->isolate()->builtins()->KeyedStoreIC_Slow();
3704 __ Jump(slow_ic, RelocInfo::CODE_TARGET);
3705 3616
3706 // Miss case, call the runtime. 3617 // Miss case, call the runtime.
3707 __ bind(&miss_force_generic); 3618 __ bind(&miss_force_generic);
3708 3619
3709 // ---------- S t a t e -------------- 3620 // ---------- S t a t e --------------
3710 // -- lr : return address 3621 // -- lr : return address
3711 // -- r0 : key 3622 // -- r0 : key
3712 // -- r1 : receiver 3623 // -- r1 : receiver
3713 // ----------------------------------- 3624 // -----------------------------------
3714 3625 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3715 Handle<Code> miss_ic =
3716 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3717 __ Jump(miss_ic, RelocInfo::CODE_TARGET);
3718 } 3626 }
3719 3627
3720 3628
3721 void KeyedStoreStubCompiler::GenerateStoreFastElement( 3629 void KeyedStoreStubCompiler::GenerateStoreFastElement(
3722 MacroAssembler* masm, 3630 MacroAssembler* masm,
3723 bool is_js_array, 3631 bool is_js_array,
3724 ElementsKind elements_kind, 3632 ElementsKind elements_kind,
3725 KeyedAccessStoreMode store_mode) { 3633 KeyedAccessStoreMode store_mode) {
3726 // ----------- S t a t e ------------- 3634 // ----------- S t a t e -------------
3727 // -- r0 : value 3635 // -- r0 : value
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
3800 scratch, // Address. 3708 scratch, // Address.
3801 receiver_reg, // Value. 3709 receiver_reg, // Value.
3802 kLRHasNotBeenSaved, 3710 kLRHasNotBeenSaved,
3803 kDontSaveFPRegs); 3711 kDontSaveFPRegs);
3804 } 3712 }
3805 // value_reg (r0) is preserved. 3713 // value_reg (r0) is preserved.
3806 // Done. 3714 // Done.
3807 __ Ret(); 3715 __ Ret();
3808 3716
3809 __ bind(&miss_force_generic); 3717 __ bind(&miss_force_generic);
3810 Handle<Code> ic = 3718 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3811 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3812 __ Jump(ic, RelocInfo::CODE_TARGET);
3813 3719
3814 __ bind(&transition_elements_kind); 3720 __ bind(&transition_elements_kind);
3815 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3721 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3816 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
3817 3722
3818 if (is_js_array && IsGrowStoreMode(store_mode)) { 3723 if (is_js_array && IsGrowStoreMode(store_mode)) {
3819 // Grow the array by a single element if possible. 3724 // Grow the array by a single element if possible.
3820 __ bind(&grow); 3725 __ bind(&grow);
3821 3726
3822 // Make sure the array is only growing by a single element, anything else 3727 // Make sure the array is only growing by a single element, anything else
3823 // must be handled by the runtime. Flags already set by previous compare. 3728 // must be handled by the runtime. Flags already set by previous compare.
3824 __ b(ne, &miss_force_generic); 3729 __ b(ne, &miss_force_generic);
3825 3730
3826 // Check for the empty array, and preallocate a small backing store if 3731 // Check for the empty array, and preallocate a small backing store if
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3871 __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset)); 3776 __ ldr(scratch, FieldMemOperand(elements_reg, FixedArray::kLengthOffset));
3872 __ cmp(length_reg, scratch); 3777 __ cmp(length_reg, scratch);
3873 __ b(hs, &slow); 3778 __ b(hs, &slow);
3874 3779
3875 // Grow the array and finish the store. 3780 // Grow the array and finish the store.
3876 __ add(length_reg, length_reg, Operand(Smi::FromInt(1))); 3781 __ add(length_reg, length_reg, Operand(Smi::FromInt(1)));
3877 __ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); 3782 __ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
3878 __ jmp(&finish_store); 3783 __ jmp(&finish_store);
3879 3784
3880 __ bind(&slow); 3785 __ bind(&slow);
3881 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3786 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
3882 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
3883 } 3787 }
3884 } 3788 }
3885 3789
3886 3790
3887 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement( 3791 void KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(
3888 MacroAssembler* masm, 3792 MacroAssembler* masm,
3889 bool is_js_array, 3793 bool is_js_array,
3890 KeyedAccessStoreMode store_mode) { 3794 KeyedAccessStoreMode store_mode) {
3891 // ----------- S t a t e ------------- 3795 // ----------- S t a t e -------------
3892 // -- r0 : value 3796 // -- r0 : value
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3946 elements_reg, 3850 elements_reg,
3947 scratch1, 3851 scratch1,
3948 scratch2, 3852 scratch2,
3949 scratch3, 3853 scratch3,
3950 scratch4, 3854 scratch4,
3951 &transition_elements_kind); 3855 &transition_elements_kind);
3952 __ Ret(); 3856 __ Ret();
3953 3857
3954 // Handle store cache miss, replacing the ic with the generic stub. 3858 // Handle store cache miss, replacing the ic with the generic stub.
3955 __ bind(&miss_force_generic); 3859 __ bind(&miss_force_generic);
3956 Handle<Code> ic = 3860 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_MissForceGeneric);
3957 masm->isolate()->builtins()->KeyedStoreIC_MissForceGeneric();
3958 __ Jump(ic, RelocInfo::CODE_TARGET);
3959 3861
3960 __ bind(&transition_elements_kind); 3862 __ bind(&transition_elements_kind);
3961 Handle<Code> ic_miss = masm->isolate()->builtins()->KeyedStoreIC_Miss(); 3863 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Miss);
3962 __ Jump(ic_miss, RelocInfo::CODE_TARGET);
3963 3864
3964 if (is_js_array && IsGrowStoreMode(store_mode)) { 3865 if (is_js_array && IsGrowStoreMode(store_mode)) {
3965 // Grow the array by a single element if possible. 3866 // Grow the array by a single element if possible.
3966 __ bind(&grow); 3867 __ bind(&grow);
3967 3868
3968 // Make sure the array is only growing by a single element, anything else 3869 // Make sure the array is only growing by a single element, anything else
3969 // must be handled by the runtime. Flags already set by previous compare. 3870 // must be handled by the runtime. Flags already set by previous compare.
3970 __ b(ne, &miss_force_generic); 3871 __ b(ne, &miss_force_generic);
3971 3872
3972 // Transition on values that can't be stored in a FixedDoubleArray. 3873 // Transition on values that can't be stored in a FixedDoubleArray.
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
4037 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset)); 3938 FieldMemOperand(elements_reg, FixedDoubleArray::kLengthOffset));
4038 __ cmp(length_reg, scratch1); 3939 __ cmp(length_reg, scratch1);
4039 __ b(hs, &slow); 3940 __ b(hs, &slow);
4040 3941
4041 // Grow the array and finish the store. 3942 // Grow the array and finish the store.
4042 __ add(length_reg, length_reg, Operand(Smi::FromInt(1))); 3943 __ add(length_reg, length_reg, Operand(Smi::FromInt(1)));
4043 __ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset)); 3944 __ str(length_reg, FieldMemOperand(receiver_reg, JSArray::kLengthOffset));
4044 __ jmp(&finish_store); 3945 __ jmp(&finish_store);
4045 3946
4046 __ bind(&slow); 3947 __ bind(&slow);
4047 Handle<Code> ic_slow = masm->isolate()->builtins()->KeyedStoreIC_Slow(); 3948 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow);
4048 __ Jump(ic_slow, RelocInfo::CODE_TARGET);
4049 } 3949 }
4050 } 3950 }
4051 3951
4052 3952
4053 #undef __ 3953 #undef __
4054 3954
4055 } } // namespace v8::internal 3955 } } // namespace v8::internal
4056 3956
4057 #endif // V8_TARGET_ARCH_ARM 3957 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.cc ('k') | src/ia32/code-stubs-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698