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