| 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 |