OLD | NEW |
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
600 code = Builtins::builtin(Builtins::LoadIC_Miss); | 600 code = Builtins::builtin(Builtins::LoadIC_Miss); |
601 } else { | 601 } else { |
602 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 602 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
603 } | 603 } |
604 | 604 |
605 Handle<Code> ic(code); | 605 Handle<Code> ic(code); |
606 __ jmp(ic, RelocInfo::CODE_TARGET); | 606 __ jmp(ic, RelocInfo::CODE_TARGET); |
607 } | 607 } |
608 | 608 |
609 | 609 |
| 610 // Both name_reg and receiver_reg are preserved on jumps to miss_label, |
| 611 // but may be destroyed if store is successful. |
610 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 612 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
611 Builtins::Name storage_extend, | |
612 JSObject* object, | 613 JSObject* object, |
613 int index, | 614 int index, |
614 Map* transition, | 615 Map* transition, |
615 Register receiver_reg, | 616 Register receiver_reg, |
616 Register name_reg, | 617 Register name_reg, |
617 Register scratch, | 618 Register scratch, |
618 Label* miss_label) { | 619 Label* miss_label) { |
619 // Check that the object isn't a smi. | 620 // Check that the object isn't a smi. |
620 __ test(receiver_reg, Immediate(kSmiTagMask)); | 621 __ test(receiver_reg, Immediate(kSmiTagMask)); |
621 __ j(zero, miss_label, not_taken); | 622 __ j(zero, miss_label, not_taken); |
622 | 623 |
623 // Check that the map of the object hasn't changed. | 624 // Check that the map of the object hasn't changed. |
624 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 625 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
625 Immediate(Handle<Map>(object->map()))); | 626 Immediate(Handle<Map>(object->map()))); |
626 __ j(not_equal, miss_label, not_taken); | 627 __ j(not_equal, miss_label, not_taken); |
627 | 628 |
628 // Perform global security token check if needed. | 629 // Perform global security token check if needed. |
629 if (object->IsJSGlobalProxy()) { | 630 if (object->IsJSGlobalProxy()) { |
630 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); | 631 __ CheckAccessGlobalProxy(receiver_reg, scratch, miss_label); |
631 } | 632 } |
632 | 633 |
633 // Stub never generated for non-global objects that require access | 634 // Stub never generated for non-global objects that require access |
634 // checks. | 635 // checks. |
635 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); | 636 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); |
636 | 637 |
637 // Perform map transition for the receiver if necessary. | 638 // Perform map transition for the receiver if necessary. |
638 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { | 639 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { |
639 // The properties must be extended before we can store the value. | 640 // The properties must be extended before we can store the value. |
640 // We jump to a runtime call that extends the properties array. | 641 // We jump to a runtime call that extends the properties array. |
641 __ mov(ecx, Immediate(Handle<Map>(transition))); | 642 __ pop(scratch); // Return address. |
642 Handle<Code> ic(Builtins::builtin(storage_extend)); | 643 __ push(receiver_reg); |
643 __ jmp(ic, RelocInfo::CODE_TARGET); | 644 __ push(Immediate(Handle<Map>(transition))); |
| 645 __ push(eax); |
| 646 __ push(scratch); |
| 647 __ TailCallRuntime( |
| 648 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage)), 3, 1); |
644 return; | 649 return; |
645 } | 650 } |
646 | 651 |
647 if (transition != NULL) { | 652 if (transition != NULL) { |
648 // Update the map of the object; no write barrier updating is | 653 // Update the map of the object; no write barrier updating is |
649 // needed because the map is never in new space. | 654 // needed because the map is never in new space. |
650 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 655 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
651 Immediate(Handle<Map>(transition))); | 656 Immediate(Handle<Map>(transition))); |
652 } | 657 } |
653 | 658 |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1244 // ----------- S t a t e ------------- | 1249 // ----------- S t a t e ------------- |
1245 // -- eax : value | 1250 // -- eax : value |
1246 // -- ecx : name | 1251 // -- ecx : name |
1247 // -- edx : receiver | 1252 // -- edx : receiver |
1248 // -- esp[0] : return address | 1253 // -- esp[0] : return address |
1249 // ----------------------------------- | 1254 // ----------------------------------- |
1250 Label miss; | 1255 Label miss; |
1251 | 1256 |
1252 // Generate store field code. Trashes the name register. | 1257 // Generate store field code. Trashes the name register. |
1253 GenerateStoreField(masm(), | 1258 GenerateStoreField(masm(), |
1254 Builtins::StoreIC_ExtendStorage, | |
1255 object, | 1259 object, |
1256 index, | 1260 index, |
1257 transition, | 1261 transition, |
1258 edx, ecx, ebx, | 1262 edx, ecx, ebx, |
1259 &miss); | 1263 &miss); |
1260 | 1264 |
1261 // Handle store cache miss. | 1265 // Handle store cache miss. |
1262 __ bind(&miss); | 1266 __ bind(&miss); |
1263 __ mov(ecx, Immediate(Handle<String>(name))); // restore name | 1267 __ mov(ecx, Immediate(Handle<String>(name))); // restore name |
1264 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 1268 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1418 | 1422 |
1419 __ IncrementCounter(&Counters::keyed_store_field, 1); | 1423 __ IncrementCounter(&Counters::keyed_store_field, 1); |
1420 | 1424 |
1421 // Get the name from the stack. | 1425 // Get the name from the stack. |
1422 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 1426 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
1423 // Check that the name has not changed. | 1427 // Check that the name has not changed. |
1424 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 1428 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
1425 __ j(not_equal, &miss, not_taken); | 1429 __ j(not_equal, &miss, not_taken); |
1426 | 1430 |
1427 // Get the object from the stack. | 1431 // Get the object from the stack. |
1428 __ mov(ebx, Operand(esp, 2 * kPointerSize)); | 1432 __ mov(edx, Operand(esp, 2 * kPointerSize)); |
1429 | 1433 |
1430 // Generate store field code. Trashes the name register. | 1434 // Generate store field code. Trashes the name register. |
1431 GenerateStoreField(masm(), | 1435 GenerateStoreField(masm(), |
1432 Builtins::KeyedStoreIC_ExtendStorage, | |
1433 object, | 1436 object, |
1434 index, | 1437 index, |
1435 transition, | 1438 transition, |
1436 ebx, ecx, edx, | 1439 edx, ecx, ebx, |
1437 &miss); | 1440 &miss); |
1438 | 1441 |
1439 // Handle store cache miss. | 1442 // Handle store cache miss. |
1440 __ bind(&miss); | 1443 __ bind(&miss); |
1441 __ DecrementCounter(&Counters::keyed_store_field, 1); | 1444 __ DecrementCounter(&Counters::keyed_store_field, 1); |
1442 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 1445 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
1443 __ jmp(ic, RelocInfo::CODE_TARGET); | 1446 __ jmp(ic, RelocInfo::CODE_TARGET); |
1444 | 1447 |
1445 // Return the generated code. | 1448 // Return the generated code. |
1446 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); | 1449 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); |
(...skipping 497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1944 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); | 1947 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); |
1945 | 1948 |
1946 // Return the generated code. | 1949 // Return the generated code. |
1947 return GetCode(); | 1950 return GetCode(); |
1948 } | 1951 } |
1949 | 1952 |
1950 | 1953 |
1951 #undef __ | 1954 #undef __ |
1952 | 1955 |
1953 } } // namespace v8::internal | 1956 } } // namespace v8::internal |
OLD | NEW |