| 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 405 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 416 __ Ret(); | 416 __ Ret(); |
| 417 } | 417 } |
| 418 | 418 |
| 419 | 419 |
| 420 // Generate StoreField code, value is passed in r0 register. | 420 // Generate StoreField code, value is passed in r0 register. |
| 421 // When leaving generated code after success, the receiver_reg and name_reg | 421 // When leaving generated code after success, the receiver_reg and name_reg |
| 422 // may be clobbered. Upon branch to miss_label, the receiver and name | 422 // may be clobbered. Upon branch to miss_label, the receiver and name |
| 423 // registers have their original values. | 423 // registers have their original values. |
| 424 void StubCompiler::GenerateStoreField(MacroAssembler* masm, | 424 void StubCompiler::GenerateStoreField(MacroAssembler* masm, |
| 425 Handle<JSObject> object, | 425 Handle<JSObject> object, |
| 426 int index, | 426 LookupResult* lookup, |
| 427 Handle<Map> transition, | 427 Handle<Map> transition, |
| 428 Handle<Name> name, | 428 Handle<Name> name, |
| 429 Register receiver_reg, | 429 Register receiver_reg, |
| 430 Register name_reg, | 430 Register name_reg, |
| 431 Register value_reg, | 431 Register value_reg, |
| 432 Register scratch1, | 432 Register scratch1, |
| 433 Register scratch2, | 433 Register scratch2, |
| 434 Label* miss_label, | 434 Label* miss_label, |
| 435 Label* miss_restore_name) { | 435 Label* miss_restore_name) { |
| 436 // r0 : value | 436 // r0 : value |
| 437 Label exit; | 437 Label exit; |
| 438 | 438 |
| 439 LookupResult lookup(masm->isolate()); | |
| 440 object->Lookup(*name, &lookup); | |
| 441 if (lookup.IsFound() && (lookup.IsReadOnly() || !lookup.IsCacheable())) { | |
| 442 // In sloppy mode, we could just return the value and be done. However, we | |
| 443 // might be in strict mode, where we have to throw. Since we cannot tell, | |
| 444 // go into slow case unconditionally. | |
| 445 __ jmp(miss_label); | |
| 446 return; | |
| 447 } | |
| 448 | |
| 449 // Check that the map of the object hasn't changed. | 439 // Check that the map of the object hasn't changed. |
| 450 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS | 440 CompareMapMode mode = transition.is_null() ? ALLOW_ELEMENT_TRANSITION_MAPS |
| 451 : REQUIRE_EXACT_MAP; | 441 : REQUIRE_EXACT_MAP; |
| 452 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, | 442 __ CheckMap(receiver_reg, scratch1, Handle<Map>(object->map()), miss_label, |
| 453 DO_SMI_CHECK, mode); | 443 DO_SMI_CHECK, mode); |
| 454 | 444 |
| 455 // Perform global security token check if needed. | 445 // Perform global security token check if needed. |
| 456 if (object->IsJSGlobalProxy()) { | 446 if (object->IsJSGlobalProxy()) { |
| 457 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); | 447 __ CheckAccessGlobalProxy(receiver_reg, scratch1, miss_label); |
| 458 } | 448 } |
| 459 | 449 |
| 460 // Check that we are allowed to write this. | 450 // Check that we are allowed to write this. |
| 461 if (!transition.is_null() && object->GetPrototype()->IsJSObject()) { | 451 if (!transition.is_null() && object->GetPrototype()->IsJSObject()) { |
| 462 JSObject* holder; | 452 JSObject* holder; |
| 463 if (lookup.IsFound()) { | 453 if (lookup->IsFound()) { |
| 464 holder = lookup.holder(); | 454 holder = lookup->holder(); |
| 465 } else { | 455 } else { |
| 466 // Find the top object. | 456 // Find the top object. |
| 467 holder = *object; | 457 holder = *object; |
| 468 do { | 458 do { |
| 469 holder = JSObject::cast(holder->GetPrototype()); | 459 holder = JSObject::cast(holder->GetPrototype()); |
| 470 } while (holder->GetPrototype()->IsJSObject()); | 460 } while (holder->GetPrototype()->IsJSObject()); |
| 471 } | 461 } |
| 472 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, | 462 CheckPrototypes(object, receiver_reg, Handle<JSObject>(holder), name_reg, |
| 473 scratch1, scratch2, name, miss_restore_name); | 463 scratch1, scratch2, name, miss_restore_name); |
| 474 } | 464 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 485 __ mov(r2, Operand(transition)); | 475 __ mov(r2, Operand(transition)); |
| 486 __ Push(r2, r0); | 476 __ Push(r2, r0); |
| 487 __ TailCallExternalReference( | 477 __ TailCallExternalReference( |
| 488 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), | 478 ExternalReference(IC_Utility(IC::kSharedStoreIC_ExtendStorage), |
| 489 masm->isolate()), | 479 masm->isolate()), |
| 490 3, | 480 3, |
| 491 1); | 481 1); |
| 492 return; | 482 return; |
| 493 } | 483 } |
| 494 | 484 |
| 485 int index; |
| 495 if (!transition.is_null()) { | 486 if (!transition.is_null()) { |
| 496 // Update the map of the object. | 487 // Update the map of the object. |
| 497 __ mov(scratch1, Operand(transition)); | 488 __ mov(scratch1, Operand(transition)); |
| 498 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); | 489 __ str(scratch1, FieldMemOperand(receiver_reg, HeapObject::kMapOffset)); |
| 499 | 490 |
| 500 // Update the write barrier for the map field and pass the now unused | 491 // Update the write barrier for the map field and pass the now unused |
| 501 // name_reg as scratch register. | 492 // name_reg as scratch register. |
| 502 __ RecordWriteField(receiver_reg, | 493 __ RecordWriteField(receiver_reg, |
| 503 HeapObject::kMapOffset, | 494 HeapObject::kMapOffset, |
| 504 scratch1, | 495 scratch1, |
| 505 name_reg, | 496 name_reg, |
| 506 kLRHasNotBeenSaved, | 497 kLRHasNotBeenSaved, |
| 507 kDontSaveFPRegs, | 498 kDontSaveFPRegs, |
| 508 OMIT_REMEMBERED_SET, | 499 OMIT_REMEMBERED_SET, |
| 509 OMIT_SMI_CHECK); | 500 OMIT_SMI_CHECK); |
| 501 index = transition->instance_descriptors()->GetFieldIndex( |
| 502 transition->LastAdded()); |
| 503 } else { |
| 504 index = lookup->GetFieldIndex().field_index(); |
| 510 } | 505 } |
| 511 | 506 |
| 512 // Adjust for the number of properties stored in the object. Even in the | 507 // Adjust for the number of properties stored in the object. Even in the |
| 513 // face of a transition we can use the old map here because the size of the | 508 // face of a transition we can use the old map here because the size of the |
| 514 // object and the number of in-object properties is not going to change. | 509 // object and the number of in-object properties is not going to change. |
| 515 index -= object->map()->inobject_properties(); | 510 index -= object->map()->inobject_properties(); |
| 516 | 511 |
| 517 if (index < 0) { | 512 if (index < 0) { |
| 518 // Set the property straight into the object. | 513 // Set the property straight into the object. |
| 519 int offset = object->map()->instance_size() + (index * kPointerSize); | 514 int offset = object->map()->instance_size() + (index * kPointerSize); |
| (...skipping 3322 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3842 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); | 3837 TailCallBuiltin(masm, Builtins::kKeyedStoreIC_Slow); |
| 3843 } | 3838 } |
| 3844 } | 3839 } |
| 3845 | 3840 |
| 3846 | 3841 |
| 3847 #undef __ | 3842 #undef __ |
| 3848 | 3843 |
| 3849 } } // namespace v8::internal | 3844 } } // namespace v8::internal |
| 3850 | 3845 |
| 3851 #endif // V8_TARGET_ARCH_ARM | 3846 #endif // V8_TARGET_ARCH_ARM |
| OLD | NEW |