| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 362b363cc80174caf85d440d881f4c392974a3f2..bddc5d7221c8af79d32180bea6012f2fb9baabfd 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -4479,18 +4479,19 @@ void NormalizedMapCache::Clear() {
|
| }
|
|
|
|
|
| -void JSObject::UpdateMapCodeCache(Handle<JSObject> object,
|
| - Handle<Name> name,
|
| - Handle<Code> code) {
|
| +void HeapObject::UpdateMapCodeCache(Handle<HeapObject> object,
|
| + Handle<Name> name,
|
| + Handle<Code> code) {
|
| Handle<Map> map(object->map());
|
| if (map->is_shared()) {
|
| + Handle<JSObject> receiver = Handle<JSObject>::cast(object);
|
| // Fast case maps are never marked as shared.
|
| - ASSERT(!object->HasFastProperties());
|
| + ASSERT(!receiver->HasFastProperties());
|
| // Replace the map with an identical copy that can be safely modified.
|
| map = Map::CopyNormalized(map, KEEP_INOBJECT_PROPERTIES,
|
| UNIQUE_NORMALIZED_MAP);
|
| - object->GetIsolate()->counters()->normalized_maps()->Increment();
|
| - object->set_map(*map);
|
| + receiver->GetIsolate()->counters()->normalized_maps()->Increment();
|
| + receiver->set_map(*map);
|
| }
|
| Map::UpdateCodeCache(map, name, code);
|
| }
|
| @@ -5634,71 +5635,78 @@ MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) {
|
| }
|
|
|
|
|
| -MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
|
| - StackLimitCheck check(isolate);
|
| - if (check.HasOverflowed()) return isolate->StackOverflow();
|
| +// TODO(mstarzinger): Temporary wrapper until handlified.
|
| +static Handle<Object> NewStorageFor(Isolate* isolate,
|
| + Handle<Object> object,
|
| + Representation representation) {
|
| + Heap* heap = isolate->heap();
|
| + CALL_HEAP_FUNCTION(isolate,
|
| + object->AllocateNewStorageFor(heap, representation),
|
| + Object);
|
| +}
|
|
|
| - if (map()->is_deprecated()) {
|
| - MaybeObject* maybe_failure = MigrateInstance();
|
| - if (maybe_failure->IsFailure()) return maybe_failure;
|
| +
|
| +Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
|
| + Isolate* isolate = object->GetIsolate();
|
| + CALL_HEAP_FUNCTION(isolate,
|
| + isolate->heap()->CopyJSObject(*object), JSObject);
|
| +}
|
| +
|
| +
|
| +Handle<JSObject> JSObject::DeepCopy(Handle<JSObject> object) {
|
| + Isolate* isolate = object->GetIsolate();
|
| + StackLimitCheck check(isolate);
|
| + if (check.HasOverflowed()) {
|
| + isolate->StackOverflow();
|
| + return Handle<JSObject>::null();
|
| }
|
|
|
| - Heap* heap = isolate->heap();
|
| - Object* result;
|
| - { MaybeObject* maybe_result = heap->CopyJSObject(this);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| + if (object->map()->is_deprecated()) {
|
| + MigrateInstance(object);
|
| }
|
| - JSObject* copy = JSObject::cast(result);
|
| +
|
| + Handle<JSObject> copy = Copy(object);
|
|
|
| // Deep copy local properties.
|
| if (copy->HasFastProperties()) {
|
| - DescriptorArray* descriptors = copy->map()->instance_descriptors();
|
| + Handle<DescriptorArray> descriptors(copy->map()->instance_descriptors());
|
| int limit = copy->map()->NumberOfOwnDescriptors();
|
| for (int i = 0; i < limit; i++) {
|
| PropertyDetails details = descriptors->GetDetails(i);
|
| if (details.type() != FIELD) continue;
|
| int index = descriptors->GetFieldIndex(i);
|
| - Object* value = RawFastPropertyAt(index);
|
| + Handle<Object> value(object->RawFastPropertyAt(index), isolate);
|
| if (value->IsJSObject()) {
|
| - JSObject* js_object = JSObject::cast(value);
|
| - MaybeObject* maybe_copy = js_object->DeepCopy(isolate);
|
| - if (!maybe_copy->To(&value)) return maybe_copy;
|
| + value = DeepCopy(Handle<JSObject>::cast(value));
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<JSObject>());
|
| } else {
|
| Representation representation = details.representation();
|
| - MaybeObject* maybe_storage =
|
| - value->AllocateNewStorageFor(heap, representation);
|
| - if (!maybe_storage->To(&value)) return maybe_storage;
|
| + value = NewStorageFor(isolate, value, representation);
|
| }
|
| - copy->FastPropertyAtPut(index, value);
|
| + copy->FastPropertyAtPut(index, *value);
|
| }
|
| } else {
|
| - { MaybeObject* maybe_result =
|
| - heap->AllocateFixedArray(copy->NumberOfLocalProperties());
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| - }
|
| - FixedArray* names = FixedArray::cast(result);
|
| - copy->GetLocalPropertyNames(names, 0);
|
| + Handle<FixedArray> names =
|
| + isolate->factory()->NewFixedArray(copy->NumberOfLocalProperties());
|
| + copy->GetLocalPropertyNames(*names, 0);
|
| for (int i = 0; i < names->length(); i++) {
|
| ASSERT(names->get(i)->IsString());
|
| - String* key_string = String::cast(names->get(i));
|
| + Handle<String> key_string(String::cast(names->get(i)));
|
| PropertyAttributes attributes =
|
| - copy->GetLocalPropertyAttribute(key_string);
|
| + copy->GetLocalPropertyAttribute(*key_string);
|
| // Only deep copy fields from the object literal expression.
|
| // In particular, don't try to copy the length attribute of
|
| // an array.
|
| if (attributes != NONE) continue;
|
| - Object* value =
|
| - copy->GetProperty(key_string, &attributes)->ToObjectUnchecked();
|
| + Handle<Object> value(
|
| + copy->GetProperty(*key_string, &attributes)->ToObjectUnchecked(),
|
| + isolate);
|
| if (value->IsJSObject()) {
|
| - JSObject* js_object = JSObject::cast(value);
|
| - { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| - }
|
| - { MaybeObject* maybe_result =
|
| - // Creating object copy for literals. No strict mode needed.
|
| - copy->SetProperty(key_string, result, NONE, kNonStrictMode);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| - }
|
| + Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
|
| + // Creating object copy for literals. No strict mode needed.
|
| + CHECK_NOT_EMPTY_HANDLE(isolate, SetProperty(
|
| + copy, key_string, result, NONE, kNonStrictMode));
|
| }
|
| }
|
| }
|
| @@ -5711,8 +5719,8 @@ MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
|
| case FAST_ELEMENTS:
|
| case FAST_HOLEY_SMI_ELEMENTS:
|
| case FAST_HOLEY_ELEMENTS: {
|
| - FixedArray* elements = FixedArray::cast(copy->elements());
|
| - if (elements->map() == heap->fixed_cow_array_map()) {
|
| + Handle<FixedArray> elements(FixedArray::cast(copy->elements()));
|
| + if (elements->map() == isolate->heap()->fixed_cow_array_map()) {
|
| isolate->counters()->cow_arrays_created_runtime()->Increment();
|
| #ifdef DEBUG
|
| for (int i = 0; i < elements->length(); i++) {
|
| @@ -5721,34 +5729,31 @@ MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
|
| #endif
|
| } else {
|
| for (int i = 0; i < elements->length(); i++) {
|
| - Object* value = elements->get(i);
|
| + Handle<Object> value(elements->get(i), isolate);
|
| ASSERT(value->IsSmi() ||
|
| value->IsTheHole() ||
|
| (IsFastObjectElementsKind(copy->GetElementsKind())));
|
| if (value->IsJSObject()) {
|
| - JSObject* js_object = JSObject::cast(value);
|
| - { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| - }
|
| - elements->set(i, result);
|
| + Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
|
| + elements->set(i, *result);
|
| }
|
| }
|
| }
|
| break;
|
| }
|
| case DICTIONARY_ELEMENTS: {
|
| - SeededNumberDictionary* element_dictionary = copy->element_dictionary();
|
| + Handle<SeededNumberDictionary> element_dictionary(
|
| + copy->element_dictionary());
|
| int capacity = element_dictionary->Capacity();
|
| for (int i = 0; i < capacity; i++) {
|
| Object* k = element_dictionary->KeyAt(i);
|
| if (element_dictionary->IsKey(k)) {
|
| - Object* value = element_dictionary->ValueAt(i);
|
| + Handle<Object> value(element_dictionary->ValueAt(i), isolate);
|
| if (value->IsJSObject()) {
|
| - JSObject* js_object = JSObject::cast(value);
|
| - { MaybeObject* maybe_result = js_object->DeepCopy(isolate);
|
| - if (!maybe_result->ToObject(&result)) return maybe_result;
|
| - }
|
| - element_dictionary->ValueAtPut(i, result);
|
| + Handle<Object> result = DeepCopy(Handle<JSObject>::cast(value));
|
| + RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>());
|
| + element_dictionary->ValueAtPut(i, *result);
|
| }
|
| }
|
| }
|
| @@ -9011,8 +9016,7 @@ AllocationMemento* AllocationMemento::FindForJSObject(JSObject* object) {
|
| // involves carefully checking the object immediately after the JSArray
|
| // (if there is one) to see if it's an AllocationMemento.
|
| if (FLAG_track_allocation_sites && object->GetHeap()->InNewSpace(object)) {
|
| - // TODO(mvstanton): CHECK to diagnose chromium bug 284577, remove after.
|
| - CHECK(object->GetHeap()->InToSpace(object));
|
| + ASSERT(object->GetHeap()->InToSpace(object));
|
| Address ptr_end = (reinterpret_cast<Address>(object) - kHeapObjectTag) +
|
| object->Size();
|
| if ((ptr_end + AllocationMemento::kSize) <=
|
| @@ -9022,15 +9026,20 @@ AllocationMemento* AllocationMemento::FindForJSObject(JSObject* object) {
|
| reinterpret_cast<Map**>(ptr_end);
|
| if (*possible_allocation_memento_map ==
|
| object->GetHeap()->allocation_memento_map()) {
|
| - Address ptr_object = reinterpret_cast<Address>(object);
|
| - // TODO(mvstanton): CHECK to diagnose chromium bug 284577, remove after.
|
| - // If this check fails it points to the very unlikely case that we've
|
| - // misinterpreted a page header as an allocation memento. Follow up
|
| - // with a real fix.
|
| - CHECK(Page::FromAddress(ptr_object) == Page::FromAddress(ptr_end));
|
| AllocationMemento* memento = AllocationMemento::cast(
|
| reinterpret_cast<Object*>(ptr_end + kHeapObjectTag));
|
| - return memento;
|
| +
|
| + // TODO(mvstanton): because of chromium bug 284577, put extra care
|
| + // into validating that the memento points to a valid AllocationSite.
|
| + // This check is expensive so remove it asap. Also, this check
|
| + // HIDES bug 284577, so it must be disabled to debug/diagnose.
|
| + Object* site = memento->allocation_site();
|
| + Heap* heap = object->GetHeap();
|
| + if (heap->InOldPointerSpace(site) &&
|
| + site->IsHeapObject() &&
|
| + HeapObject::cast(site)->map() == heap->allocation_site_map()) {
|
| + return memento;
|
| + }
|
| }
|
| }
|
| }
|
| @@ -9321,18 +9330,6 @@ void JSFunction::MarkForConcurrentRecompilation() {
|
| }
|
|
|
|
|
| -void JSFunction::MarkForInstallingRecompiledCode() {
|
| - // The debugger could have switched the builtin to lazy compile.
|
| - // In that case, simply carry on. It will be dealt with later.
|
| - ASSERT(!IsOptimized());
|
| - ASSERT(shared()->allows_lazy_compilation() || code()->optimizable());
|
| - ASSERT(FLAG_concurrent_recompilation);
|
| - set_code_no_write_barrier(
|
| - GetIsolate()->builtins()->builtin(Builtins::kInstallRecompiledCode));
|
| - // No write barrier required, since the builtin is part of the root set.
|
| -}
|
| -
|
| -
|
| void JSFunction::MarkInRecompileQueue() {
|
| // We can only arrive here via the concurrent-recompilation builtin. If
|
| // break points were set, the code would point to the lazy-compile builtin.
|
| @@ -10443,8 +10440,8 @@ bool Code::allowed_in_shared_map_code_cache() {
|
| }
|
|
|
|
|
| -void Code::MakeCodeAgeSequenceYoung(byte* sequence) {
|
| - PatchPlatformCodeAge(sequence, kNoAge, NO_MARKING_PARITY);
|
| +void Code::MakeCodeAgeSequenceYoung(byte* sequence, Isolate* isolate) {
|
| + PatchPlatformCodeAge(isolate, sequence, kNoAge, NO_MARKING_PARITY);
|
| }
|
|
|
|
|
| @@ -10455,7 +10452,9 @@ void Code::MakeOlder(MarkingParity current_parity) {
|
| MarkingParity code_parity;
|
| GetCodeAgeAndParity(sequence, &age, &code_parity);
|
| if (age != kLastCodeAge && code_parity != current_parity) {
|
| - PatchPlatformCodeAge(sequence, static_cast<Age>(age + 1),
|
| + PatchPlatformCodeAge(GetIsolate(),
|
| + sequence,
|
| + static_cast<Age>(age + 1),
|
| current_parity);
|
| }
|
| }
|
| @@ -10518,8 +10517,7 @@ void Code::GetCodeAgeAndParity(Code* code, Age* age,
|
| }
|
|
|
|
|
| -Code* Code::GetCodeAgeStub(Age age, MarkingParity parity) {
|
| - Isolate* isolate = Isolate::Current();
|
| +Code* Code::GetCodeAgeStub(Isolate* isolate, Age age, MarkingParity parity) {
|
| Builtins* builtins = isolate->builtins();
|
| switch (age) {
|
| #define HANDLE_CODE_AGE(AGE) \
|
| @@ -10790,7 +10788,7 @@ const char* Code::StubType2String(StubType type) {
|
| case CONSTANT: return "CONSTANT";
|
| case CALLBACKS: return "CALLBACKS";
|
| case INTERCEPTOR: return "INTERCEPTOR";
|
| - case MAP_TRANSITION: return "MAP_TRANSITION";
|
| + case TRANSITION: return "TRANSITION";
|
| case NONEXISTENT: return "NONEXISTENT";
|
| }
|
| UNREACHABLE(); // keep the compiler happy
|
|
|