OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |