| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 28a7ce623bfb35d8eae2c880c01ed033858e05a5..931ef0a0a9896ff80c2df17410d9ea471ad9c233 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -9905,7 +9905,8 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
|
| JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, 0,
|
| "NormalizeAsPrototype");
|
| }
|
| - Handle<Map> previous_map(object->map());
|
| + Isolate* isolate = object->GetIsolate();
|
| + Handle<Map> previous_map(object->map(), isolate);
|
| if (!object->HasFastProperties()) {
|
| JSObject::MigrateSlowToFast(object, 0, "OptimizeAsPrototype");
|
| }
|
| @@ -9921,8 +9922,7 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
|
| // from the same context if undetectable from JS. This is to avoid keeping
|
| // memory alive unnecessarily.
|
| if (!constructor->shared()->IsApiFunction() &&
|
| - object->class_name() ==
|
| - object->GetIsolate()->heap()->Object_string()) {
|
| + object->class_name() == isolate->heap()->Object_string()) {
|
| Context* context = constructor->context()->native_context();
|
| JSFunction* object_function = context->object_function();
|
| object->map()->SetConstructor(object_function);
|
| @@ -9930,6 +9930,8 @@ void JSObject::OptimizeAsPrototype(Handle<JSObject> object,
|
| }
|
| object->map()->set_is_prototype_map(true);
|
| }
|
| + Handle<Map> new_map(object->map(), isolate);
|
| + Map::SetPrototypeObject(new_map, object, isolate);
|
| }
|
|
|
|
|
| @@ -9948,14 +9950,10 @@ void JSObject::RegisterPrototypeUser(Handle<JSObject> prototype,
|
| if (prototype->IsJSGlobalProxy()) {
|
| prototype = handle(JSObject::cast(prototype->map()->prototype()), isolate);
|
| }
|
| - Handle<PrototypeInfo> proto_info;
|
| - Object* maybe_proto_info = prototype->map()->prototype_info();
|
| - if (maybe_proto_info->IsPrototypeInfo()) {
|
| - proto_info = handle(PrototypeInfo::cast(maybe_proto_info), isolate);
|
| - } else {
|
| - proto_info = isolate->factory()->NewPrototypeInfo(prototype);
|
| - prototype->map()->set_prototype_info(*proto_info);
|
| - }
|
| + Handle<Map> proto_map(prototype->map(), isolate);
|
| + Handle<PrototypeInfo> proto_info =
|
| + Map::GetOrCreatePrototypeInfo(proto_map, isolate);
|
| + proto_info->set_prototype_object(*prototype);
|
| Handle<Object> maybe_registry(proto_info->prototype_users(), isolate);
|
| Handle<WeakFixedArray> new_array = WeakFixedArray::Add(maybe_registry, user);
|
| if (!maybe_registry.is_identical_to(new_array)) {
|
| @@ -9983,6 +9981,45 @@ void JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype,
|
|
|
|
|
| // static
|
| +Handle<PrototypeInfo> Map::GetOrCreatePrototypeInfo(Handle<Map> map,
|
| + Isolate* isolate) {
|
| + Object* maybe_proto_info = map->prototype_info();
|
| + if (maybe_proto_info->IsPrototypeInfo()) {
|
| + return handle(PrototypeInfo::cast(maybe_proto_info), isolate);
|
| + }
|
| + Handle<PrototypeInfo> proto_info = isolate->factory()->NewPrototypeInfo();
|
| + map->set_prototype_info(*proto_info);
|
| + return proto_info;
|
| +}
|
| +
|
| +
|
| +// static
|
| +void Map::SetPrototypeObject(Handle<Map> map, Handle<JSObject> prototype_obj,
|
| + Isolate* isolate) {
|
| + if (!FLAG_track_prototype_users) return;
|
| + Handle<PrototypeInfo> proto_info = GetOrCreatePrototypeInfo(map, isolate);
|
| + proto_info->set_prototype_object(*prototype_obj);
|
| +}
|
| +
|
| +
|
| +Object* Map::GetPrototypeObject() {
|
| + DisallowHeapAllocation no_handlification_required;
|
| + if (!is_prototype_map()) return Smi::FromInt(0);
|
| + Object* maybe_prototype_info = prototype_info();
|
| + if (!maybe_prototype_info->IsPrototypeInfo()) return Smi::FromInt(0);
|
| + PrototypeInfo* proto_info = PrototypeInfo::cast(maybe_prototype_info);
|
| + Object* maybe_obj = proto_info->prototype_object();
|
| + if (maybe_obj->IsSmi()) return maybe_obj;
|
| + JSObject* object = JSObject::cast(maybe_obj);
|
| + if (object->map() != this) {
|
| + proto_info->set_prototype_object(Smi::FromInt(0));
|
| + return Smi::FromInt(0);
|
| + }
|
| + return object;
|
| +}
|
| +
|
| +
|
| +// static
|
| void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
|
| PrototypeOptimizationMode proto_mode) {
|
| if (map->prototype()->IsJSObject() && FLAG_track_prototype_users) {
|
|
|