| 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 |