OLD | NEW |
1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 388 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
399 } else { | 399 } else { |
400 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); | 400 code = Builtins::builtin(Builtins::KeyedLoadIC_Miss); |
401 } | 401 } |
402 | 402 |
403 Handle<Code> ic(code); | 403 Handle<Code> ic(code); |
404 __ jmp(ic, RelocInfo::CODE_TARGET); | 404 __ jmp(ic, RelocInfo::CODE_TARGET); |
405 } | 405 } |
406 | 406 |
407 | 407 |
408 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 408 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| 409 Builtins::Name storage_extend, |
409 JSObject* object, | 410 JSObject* object, |
410 int index, | 411 int index, |
411 Map* transition, | 412 Map* transition, |
412 Register receiver_reg, | 413 Register receiver_reg, |
413 Register name_reg, | 414 Register name_reg, |
414 Register scratch, | 415 Register scratch, |
415 Label* miss_label) { | 416 Label* miss_label) { |
416 // Check that the object isn't a smi. | 417 // Check that the object isn't a smi. |
417 __ test(receiver_reg, Immediate(kSmiTagMask)); | 418 __ test(receiver_reg, Immediate(kSmiTagMask)); |
418 __ j(zero, miss_label, not_taken); | 419 __ j(zero, miss_label, not_taken); |
419 | 420 |
420 // Check that the map of the object hasn't changed. | 421 // Check that the map of the object hasn't changed. |
421 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), | 422 __ cmp(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
422 Immediate(Handle<Map>(object->map()))); | 423 Immediate(Handle<Map>(object->map()))); |
423 __ j(not_equal, miss_label, not_taken); | 424 __ j(not_equal, miss_label, not_taken); |
424 | 425 |
425 // Perform global security token check if needed. | 426 // Perform global security token check if needed. |
426 if (object->IsJSGlobalObject()) { | 427 if (object->IsJSGlobalObject()) { |
427 __ CheckAccessGlobal(receiver_reg, scratch, miss_label); | 428 __ CheckAccessGlobal(receiver_reg, scratch, miss_label); |
428 } | 429 } |
429 | 430 |
430 // Stub never generated for non-global objects that require access | 431 // Stub never generated for non-global objects that require access |
431 // checks. | 432 // checks. |
432 ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded()); | 433 ASSERT(object->IsJSGlobalObject() || !object->IsAccessCheckNeeded()); |
433 | 434 |
| 435 // Perform map transition for the receiver if necessary. |
| 436 if ((transition != NULL) && (object->map()->unused_property_fields() == 0)) { |
| 437 // The properties must be extended before we can store the value. |
| 438 // We jump to a runtime call that extends the propeties array. |
| 439 __ mov(Operand(ecx), Immediate(Handle<Map>(transition))); |
| 440 Handle<Code> ic(Builtins::builtin(storage_extend)); |
| 441 __ jmp(ic, RelocInfo::CODE_TARGET); |
| 442 return; |
| 443 } |
| 444 |
434 // Get the properties array (optimistically). | 445 // Get the properties array (optimistically). |
435 __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); | 446 __ mov(scratch, FieldOperand(receiver_reg, JSObject::kPropertiesOffset)); |
436 | |
437 // Perform map transition for the receiver if necessary. | |
438 if (transition != NULL) { | 447 if (transition != NULL) { |
439 if (object->map()->unused_property_fields() == 0) { | 448 // Update the map of the object; no write barrier updating is |
440 // The properties must be extended before we can store the value. | 449 // needed because the map is never in new space. |
441 // We jump to a runtime call that extends the propeties array. | 450 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), |
442 __ mov(Operand(ecx), Immediate(Handle<Map>(transition))); | 451 Immediate(Handle<Map>(transition))); |
443 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_ExtendStorage)); | |
444 __ jmp(ic, RelocInfo::CODE_TARGET); | |
445 } else { | |
446 // Update the map of the object; no write barrier updating is | |
447 // needed because the map is never in new space. | |
448 __ mov(FieldOperand(receiver_reg, HeapObject::kMapOffset), | |
449 Immediate(Handle<Map>(transition))); | |
450 } | |
451 } | 452 } |
452 | 453 |
453 // Write to the properties array. | 454 // Write to the properties array. |
454 int offset = index * kPointerSize + Array::kHeaderSize; | 455 int offset = index * kPointerSize + Array::kHeaderSize; |
455 __ mov(FieldOperand(scratch, offset), eax); | 456 __ mov(FieldOperand(scratch, offset), eax); |
456 | 457 |
457 // Update the write barrier for the array address. | 458 // Update the write barrier for the array address. |
458 // Pass the value being stored in the now unused name_reg. | 459 // Pass the value being stored in the now unused name_reg. |
459 __ mov(name_reg, Operand(eax)); | 460 __ mov(name_reg, Operand(eax)); |
460 __ RecordWrite(scratch, offset, name_reg, receiver_reg); | 461 __ RecordWrite(scratch, offset, name_reg, receiver_reg); |
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
730 // -- esp[4] : receiver | 731 // -- esp[4] : receiver |
731 // ----------------------------------- | 732 // ----------------------------------- |
732 | 733 |
733 HandleScope scope; | 734 HandleScope scope; |
734 Label miss; | 735 Label miss; |
735 | 736 |
736 // Get the object from the stack. | 737 // Get the object from the stack. |
737 __ mov(ebx, Operand(esp, 1 * kPointerSize)); | 738 __ mov(ebx, Operand(esp, 1 * kPointerSize)); |
738 | 739 |
739 // Generate store field code. Trashes the name register. | 740 // Generate store field code. Trashes the name register. |
740 GenerateStoreField(masm(), object, index, transition, ebx, ecx, edx, &miss); | 741 GenerateStoreField(masm(), |
| 742 Builtins::StoreIC_ExtendStorage, |
| 743 object, |
| 744 index, |
| 745 transition, |
| 746 ebx, ecx, edx, |
| 747 &miss); |
741 | 748 |
742 // Handle store cache miss. | 749 // Handle store cache miss. |
743 __ bind(&miss); | 750 __ bind(&miss); |
744 __ mov(Operand(ecx), Immediate(Handle<String>(name))); // restore name | 751 __ mov(Operand(ecx), Immediate(Handle<String>(name))); // restore name |
745 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); | 752 Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Miss)); |
746 __ jmp(ic, RelocInfo::CODE_TARGET); | 753 __ jmp(ic, RelocInfo::CODE_TARGET); |
747 | 754 |
748 // Return the generated code. | 755 // Return the generated code. |
749 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION); | 756 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION); |
750 } | 757 } |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 // Get the name from the stack. | 887 // Get the name from the stack. |
881 __ mov(ecx, Operand(esp, 1 * kPointerSize)); | 888 __ mov(ecx, Operand(esp, 1 * kPointerSize)); |
882 // Check that the name has not changed. | 889 // Check that the name has not changed. |
883 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); | 890 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); |
884 __ j(not_equal, &miss, not_taken); | 891 __ j(not_equal, &miss, not_taken); |
885 | 892 |
886 // Get the object from the stack. | 893 // Get the object from the stack. |
887 __ mov(ebx, Operand(esp, 2 * kPointerSize)); | 894 __ mov(ebx, Operand(esp, 2 * kPointerSize)); |
888 | 895 |
889 // Generate store field code. Trashes the name register. | 896 // Generate store field code. Trashes the name register. |
890 GenerateStoreField(masm(), object, index, transition, ebx, ecx, edx, &miss); | 897 GenerateStoreField(masm(), |
| 898 Builtins::KeyedStoreIC_ExtendStorage, |
| 899 object, |
| 900 index, |
| 901 transition, |
| 902 ebx, ecx, edx, |
| 903 &miss); |
891 | 904 |
892 // Handle store cache miss. | 905 // Handle store cache miss. |
893 __ bind(&miss); | 906 __ bind(&miss); |
894 __ DecrementCounter(&Counters::keyed_store_field, 1); | 907 __ DecrementCounter(&Counters::keyed_store_field, 1); |
895 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); | 908 Handle<Code> ic(Builtins::builtin(Builtins::KeyedStoreIC_Miss)); |
896 __ jmp(ic, RelocInfo::CODE_TARGET); | 909 __ jmp(ic, RelocInfo::CODE_TARGET); |
897 | 910 |
898 // Return the generated code. | 911 // Return the generated code. |
899 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION); | 912 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION); |
900 } | 913 } |
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1241 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); | 1254 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); |
1242 | 1255 |
1243 // Return the generated code. | 1256 // Return the generated code. |
1244 return GetCode(CALLBACKS); | 1257 return GetCode(CALLBACKS); |
1245 } | 1258 } |
1246 | 1259 |
1247 | 1260 |
1248 #undef __ | 1261 #undef __ |
1249 | 1262 |
1250 } } // namespace v8::internal | 1263 } } // namespace v8::internal |
OLD | NEW |