OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 5617 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5628 MaybeObject* maybe_copy = map()->Copy(); | 5628 MaybeObject* maybe_copy = map()->Copy(); |
5629 if (!maybe_copy->To(&new_map)) return maybe_copy; | 5629 if (!maybe_copy->To(&new_map)) return maybe_copy; |
5630 new_map->set_is_observed(true); | 5630 new_map->set_is_observed(true); |
5631 } | 5631 } |
5632 set_map(new_map); | 5632 set_map(new_map); |
5633 | 5633 |
5634 return heap->undefined_value(); | 5634 return heap->undefined_value(); |
5635 } | 5635 } |
5636 | 5636 |
5637 | 5637 |
5638 // TODO(mstarzinger): Temporary wrapper until handlified. | 5638 MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) { |
5639 static Handle<Object> NewStorageFor(Isolate* isolate, | 5639 StackLimitCheck check(isolate); |
5640 Handle<Object> object, | 5640 if (check.HasOverflowed()) return isolate->StackOverflow(); |
5641 Representation representation) { | |
5642 Heap* heap = isolate->heap(); | |
5643 CALL_HEAP_FUNCTION(isolate, | |
5644 object->AllocateNewStorageFor(heap, representation), | |
5645 Object); | |
5646 } | |
5647 | 5641 |
5648 | 5642 if (map()->is_deprecated()) { |
5649 Handle<JSObject> JSObject::Copy(Handle<JSObject> object) { | 5643 MaybeObject* maybe_failure = MigrateInstance(); |
5650 Isolate* isolate = object->GetIsolate(); | 5644 if (maybe_failure->IsFailure()) return maybe_failure; |
5651 CALL_HEAP_FUNCTION(isolate, | |
5652 isolate->heap()->CopyJSObject(*object), JSObject); | |
5653 } | |
5654 | |
5655 | |
5656 Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) { | |
5657 Isolate* isolate = object->GetIsolate(); | |
5658 StackLimitCheck check(isolate); | |
5659 if (check.HasOverflowed()) { | |
5660 isolate->StackOverflow(); | |
5661 return Handle<JSObject>::null(); | |
5662 } | 5645 } |
5663 | 5646 |
5664 if (object->map()->is_deprecated()) { | 5647 Heap* heap = isolate->heap(); |
5665 MigrateInstance(object); | 5648 Object* result; |
| 5649 { MaybeObject* maybe_result = heap->CopyJSObject(this); |
| 5650 if (!maybe_result->ToObject(&result)) return maybe_result; |
5666 } | 5651 } |
5667 | 5652 JSObject* copy = JSObject::cast(result); |
5668 Handle<JSObject> copy = Copy(object); | |
5669 | 5653 |
5670 // Deep copy local properties. | 5654 // Deep copy local properties. |
5671 if (copy->HasFastProperties()) { | 5655 if (copy->HasFastProperties()) { |
5672 Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors()); | 5656 DescriptorArray* descriptors = copy->map()->instance_descriptors(); |
5673 int limit = copy->map()->NumberOfOwnDescriptors(); | 5657 int limit = copy->map()->NumberOfOwnDescriptors(); |
5674 for (int i = 0; i < limit; i++) { | 5658 for (int i = 0; i < limit; i++) { |
5675 PropertyDetails details = descriptors->GetDetails(i); | 5659 PropertyDetails details = descriptors->GetDetails(i); |
5676 if (details.type() != FIELD) continue; | 5660 if (details.type() != FIELD) continue; |
5677 int index = descriptors->GetFieldIndex(i); | 5661 int index = descriptors->GetFieldIndex(i); |
5678 Handle<Object> value(object->RawFastPropertyAt(index), isolate); | 5662 Object* value = RawFastPropertyAt(index); |
5679 if (value->IsJSObject()) { | 5663 if (value->IsJSObject()) { |
5680 value = DeepCopy(Handle<JSObject>::cast(value)); | 5664 JSObject* js_object = JSObject::cast(value); |
5681 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>()); | 5665 MaybeObject* maybe_copy = js_object->DeepCopy(isolate); |
| 5666 if (!maybe_copy->To(&value)) return maybe_copy; |
5682 } else { | 5667 } else { |
5683 Representation representation = details.representation(); | 5668 Representation representation = details.representation(); |
5684 value = NewStorageFor(isolate, value, representation); | 5669 MaybeObject* maybe_storage = |
| 5670 value->AllocateNewStorageFor(heap, representation); |
| 5671 if (!maybe_storage->To(&value)) return maybe_storage; |
5685 } | 5672 } |
5686 copy->FastPropertyAtPut(index, *value); | 5673 copy->FastPropertyAtPut(index, value); |
5687 } | 5674 } |
5688 } else { | 5675 } else { |
5689 Handle<FixedArray> names = | 5676 { MaybeObject* maybe_result = |
5690 isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties()); | 5677 heap->AllocateFixedArray(copy->NumberOfLocalProperties()); |
5691 copy->GetLocalPropertyNames(*names, 0); | 5678 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5679 } |
| 5680 FixedArray* names = FixedArray::cast(result); |
| 5681 copy->GetLocalPropertyNames(names, 0); |
5692 for (int i = 0; i < names->length(); i++) { | 5682 for (int i = 0; i < names->length(); i++) { |
5693 ASSERT(names->get(i)->IsString()); | 5683 ASSERT(names->get(i)->IsString()); |
5694 Handle<String> key_string(String::cast(names->get(i))); | 5684 String* key_string = String::cast(names->get(i)); |
5695 PropertyAttributes attributes = | 5685 PropertyAttributes attributes = |
5696 copy->GetLocalPropertyAttribute(*key_string); | 5686 copy->GetLocalPropertyAttribute(key_string); |
5697 // Only deep copy fields from the object literal expression. | 5687 // Only deep copy fields from the object literal expression. |
5698 // In particular, don't try to copy the length attribute of | 5688 // In particular, don't try to copy the length attribute of |
5699 // an array. | 5689 // an array. |
5700 if (attributes != NONE) continue; | 5690 if (attributes != NONE) continue; |
5701 Handle<Object> value( | 5691 Object* value = |
5702 copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(), | 5692 copy->GetProperty(key_string, &attributes)->ToObjectUnchecked(); |
5703 isolate); | |
5704 if (value->IsJSObject()) { | 5693 if (value->IsJSObject()) { |
5705 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); | 5694 JSObject* js_object = JSObject::cast(value); |
5706 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5695 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); |
5707 // Creating object copy for literals. No strict mode needed. | 5696 if (!maybe_result->ToObject(&result)) return maybe_result; |
5708 CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty( | 5697 } |
5709 copy, key_string, result, NONE, kNonStrictMode)); | 5698 { MaybeObject* maybe_result = |
| 5699 // Creating object copy for literals. No strict mode needed. |
| 5700 copy->SetProperty(key_string, result, NONE, kNonStrictMode); |
| 5701 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5702 } |
5710 } | 5703 } |
5711 } | 5704 } |
5712 } | 5705 } |
5713 | 5706 |
5714 // Deep copy local elements. | 5707 // Deep copy local elements. |
5715 // Pixel elements cannot be created using an object literal. | 5708 // Pixel elements cannot be created using an object literal. |
5716 ASSERT(!copy->HasExternalArrayElements()); | 5709 ASSERT(!copy->HasExternalArrayElements()); |
5717 switch (copy->GetElementsKind()) { | 5710 switch (copy->GetElementsKind()) { |
5718 case FAST_SMI_ELEMENTS: | 5711 case FAST_SMI_ELEMENTS: |
5719 case FAST_ELEMENTS: | 5712 case FAST_ELEMENTS: |
5720 case FAST_HOLEY_SMI_ELEMENTS: | 5713 case FAST_HOLEY_SMI_ELEMENTS: |
5721 case FAST_HOLEY_ELEMENTS: { | 5714 case FAST_HOLEY_ELEMENTS: { |
5722 Handle<FixedArray> elements(FixedArray::cast(copy->elements())); | 5715 FixedArray* elements = FixedArray::cast(copy->elements()); |
5723 if (elements->map() == isolate->heap()->fixed_cow_array_map()) { | 5716 if (elements->map() == heap->fixed_cow_array_map()) { |
5724 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 5717 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
5725 #ifdef DEBUG | 5718 #ifdef DEBUG |
5726 for (int i = 0; i < elements->length(); i++) { | 5719 for (int i = 0; i < elements->length(); i++) { |
5727 ASSERT(!elements->get(i)->IsJSObject()); | 5720 ASSERT(!elements->get(i)->IsJSObject()); |
5728 } | 5721 } |
5729 #endif | 5722 #endif |
5730 } else { | 5723 } else { |
5731 for (int i = 0; i < elements->length(); i++) { | 5724 for (int i = 0; i < elements->length(); i++) { |
5732 Handle<Object> value(elements->get(i), isolate); | 5725 Object* value = elements->get(i); |
5733 ASSERT(value->IsSmi() || | 5726 ASSERT(value->IsSmi() || |
5734 value->IsTheHole() || | 5727 value->IsTheHole() || |
5735 (IsFastObjectElementsKind(copy->GetElementsKind()))); | 5728 (IsFastObjectElementsKind(copy->GetElementsKind()))); |
5736 if (value->IsJSObject()) { | 5729 if (value->IsJSObject()) { |
5737 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); | 5730 JSObject* js_object = JSObject::cast(value); |
5738 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5731 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); |
5739 elements->set(i, *result); | 5732 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5733 } |
| 5734 elements->set(i, result); |
5740 } | 5735 } |
5741 } | 5736 } |
5742 } | 5737 } |
5743 break; | 5738 break; |
5744 } | 5739 } |
5745 case DICTIONARY_ELEMENTS: { | 5740 case DICTIONARY_ELEMENTS: { |
5746 Handle<SeededNumberDictionary> element_dictionary( | 5741 SeededNumberDictionary* element_dictionary = copy->element_dictionary(); |
5747 copy->element_dictionary()); | |
5748 int capacity = element_dictionary->Capacity(); | 5742 int capacity = element_dictionary->Capacity(); |
5749 for (int i = 0; i < capacity; i++) { | 5743 for (int i = 0; i < capacity; i++) { |
5750 Object* k = element_dictionary->KeyAt(i); | 5744 Object* k = element_dictionary->KeyAt(i); |
5751 if (element_dictionary->IsKey(k)) { | 5745 if (element_dictionary->IsKey(k)) { |
5752 Handle<Object> value(element_dictionary->ValueAt(i), isolate); | 5746 Object* value = element_dictionary->ValueAt(i); |
5753 if (value->IsJSObject()) { | 5747 if (value->IsJSObject()) { |
5754 Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value)); | 5748 JSObject* js_object = JSObject::cast(value); |
5755 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5749 { MaybeObject* maybe_result = js_object->DeepCopy(isolate); |
5756 element_dictionary->ValueAtPut(i, *result); | 5750 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 5751 } |
| 5752 element_dictionary->ValueAtPut(i, result); |
5757 } | 5753 } |
5758 } | 5754 } |
5759 } | 5755 } |
5760 break; | 5756 break; |
5761 } | 5757 } |
5762 case NON_STRICT_ARGUMENTS_ELEMENTS: | 5758 case NON_STRICT_ARGUMENTS_ELEMENTS: |
5763 UNIMPLEMENTED(); | 5759 UNIMPLEMENTED(); |
5764 break; | 5760 break; |
5765 case EXTERNAL_PIXEL_ELEMENTS: | 5761 case EXTERNAL_PIXEL_ELEMENTS: |
5766 case EXTERNAL_BYTE_ELEMENTS: | 5762 case EXTERNAL_BYTE_ELEMENTS: |
(...skipping 4662 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10429 } | 10425 } |
10430 | 10426 |
10431 | 10427 |
10432 bool Code::allowed_in_shared_map_code_cache() { | 10428 bool Code::allowed_in_shared_map_code_cache() { |
10433 return is_keyed_load_stub() || is_keyed_store_stub() || | 10429 return is_keyed_load_stub() || is_keyed_store_stub() || |
10434 (is_compare_ic_stub() && | 10430 (is_compare_ic_stub() && |
10435 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); | 10431 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); |
10436 } | 10432 } |
10437 | 10433 |
10438 | 10434 |
10439 void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) { | 10435 void Code::MakeCodeAgeSequenceYoung(byte* sequence) { |
10440 PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY); | 10436 PatchPlatformCodeAge(sequence, kNoAge, NO_MARKING_PARITY); |
10441 } | 10437 } |
10442 | 10438 |
10443 | 10439 |
10444 void Code::MakeOlder(MarkingParity current_parity) { | 10440 void Code::MakeOlder(MarkingParity current_parity) { |
10445 byte* sequence = FindCodeAgeSequence(); | 10441 byte* sequence = FindCodeAgeSequence(); |
10446 if (sequence != NULL) { | 10442 if (sequence != NULL) { |
10447 Age age; | 10443 Age age; |
10448 MarkingParity code_parity; | 10444 MarkingParity code_parity; |
10449 GetCodeAgeAndParity(sequence, &age, &code_parity); | 10445 GetCodeAgeAndParity(sequence, &age, &code_parity); |
10450 if (age != kLastCodeAge && code_parity != current_parity) { | 10446 if (age != kLastCodeAge && code_parity != current_parity) { |
10451 PatchPlatformCodeAge(GetIsolate(), | 10447 PatchPlatformCodeAge(sequence, static_cast<Age>(age + 1), |
10452 sequence, | |
10453 static_cast<Age>(age + 1), | |
10454 current_parity); | 10448 current_parity); |
10455 } | 10449 } |
10456 } | 10450 } |
10457 } | 10451 } |
10458 | 10452 |
10459 | 10453 |
10460 bool Code::IsOld() { | 10454 bool Code::IsOld() { |
10461 byte* sequence = FindCodeAgeSequence(); | 10455 byte* sequence = FindCodeAgeSequence(); |
10462 if (sequence == NULL) return false; | 10456 if (sequence == NULL) return false; |
10463 Age age; | 10457 Age age; |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10506 *age = k##AGE##CodeAge; \ | 10500 *age = k##AGE##CodeAge; \ |
10507 *parity = ODD_MARKING_PARITY; \ | 10501 *parity = ODD_MARKING_PARITY; \ |
10508 return; \ | 10502 return; \ |
10509 } | 10503 } |
10510 CODE_AGE_LIST(HANDLE_CODE_AGE) | 10504 CODE_AGE_LIST(HANDLE_CODE_AGE) |
10511 #undef HANDLE_CODE_AGE | 10505 #undef HANDLE_CODE_AGE |
10512 UNREACHABLE(); | 10506 UNREACHABLE(); |
10513 } | 10507 } |
10514 | 10508 |
10515 | 10509 |
10516 Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) { | 10510 Code* Code::GetCodeAgeStub(Age age, MarkingParity parity) { |
| 10511 Isolate* isolate = Isolate::Current(); |
10517 Builtins* builtins = isolate->builtins(); | 10512 Builtins* builtins = isolate->builtins(); |
10518 switch (age) { | 10513 switch (age) { |
10519 #define HANDLE_CODE_AGE(AGE) \ | 10514 #define HANDLE_CODE_AGE(AGE) \ |
10520 case k##AGE##CodeAge: { \ | 10515 case k##AGE##CodeAge: { \ |
10521 Code* stub = parity == EVEN_MARKING_PARITY \ | 10516 Code* stub = parity == EVEN_MARKING_PARITY \ |
10522 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ | 10517 ? *builtins->Make##AGE##CodeYoungAgainEvenMarking() \ |
10523 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ | 10518 : *builtins->Make##AGE##CodeYoungAgainOddMarking(); \ |
10524 return stub; \ | 10519 return stub; \ |
10525 } | 10520 } |
10526 CODE_AGE_LIST(HANDLE_CODE_AGE) | 10521 CODE_AGE_LIST(HANDLE_CODE_AGE) |
(...skipping 5623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16150 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16145 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16151 static const char* error_messages_[] = { | 16146 static const char* error_messages_[] = { |
16152 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16147 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16153 }; | 16148 }; |
16154 #undef ERROR_MESSAGES_TEXTS | 16149 #undef ERROR_MESSAGES_TEXTS |
16155 return error_messages_[reason]; | 16150 return error_messages_[reason]; |
16156 } | 16151 } |
16157 | 16152 |
16158 | 16153 |
16159 } } // namespace v8::internal | 16154 } } // namespace v8::internal |
OLD | NEW |