Reviewers: Toon Verwaest,
Message:
PTAL. This is split out from https://codereview.chromium.org/908213002/.
Description:
Handlify Map::SetPrototype()
Please review this at https://codereview.chromium.org/1005393004/
Base URL: https://chromium.googlesource.com/v8/v8.git@master
Affected files (+56, -42 lines):
M src/bootstrapper.cc
M src/factory.cc
M src/objects.h
M src/objects.cc
M src/runtime/runtime-classes.cc
M src/runtime/runtime-debug.cc
M test/cctest/test-heap.cc
Index: src/bootstrapper.cc
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index
963336a79ca68a9036e3c11b9b0d3e5eff39b0b1..814009118d545c8ad0d62a09d281da54a90b36c9
100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -329,7 +329,7 @@ static void SetObjectPrototype(Handle<JSObject> object,
Handle<Object> proto) {
// object.__proto__ = proto;
Handle<Map> old_map = Handle<Map>(object->map());
Handle<Map> new_map = Map::Copy(old_map, "SetObjectPrototype");
- new_map->SetPrototype(proto, FAST_PROTOTYPE);
+ Map::SetPrototype(new_map, proto, FAST_PROTOTYPE);
JSObject::MigrateToMap(object, new_map);
}
@@ -509,7 +509,7 @@ Handle<JSFunction>
Genesis::CreateEmptyFunction(Isolate* isolate) {
Handle<Map> empty_function_map =
CreateSloppyFunctionMap(FUNCTION_WITHOUT_PROTOTYPE);
DCHECK(!empty_function_map->is_dictionary_map());
- empty_function_map->SetPrototype(object_function_prototype);
+ Map::SetPrototype(empty_function_map, object_function_prototype);
empty_function_map->set_is_prototype_map(true);
empty_function->set_map(*empty_function_map);
@@ -523,10 +523,13 @@ Handle<JSFunction>
Genesis::CreateEmptyFunction(Isolate* isolate) {
empty_function->shared()->DontAdaptArguments();
// Set prototypes for the function maps.
- native_context()->sloppy_function_map()->SetPrototype(empty_function);
- native_context()->sloppy_function_without_prototype_map()->SetPrototype(
- empty_function);
- sloppy_function_map_writable_prototype_->SetPrototype(empty_function);
+ Handle<Map> sloppy_function_map(native_context()->sloppy_function_map(),
+ isolate);
+ Handle<Map> sloppy_function_without_prototype_map(
+ native_context()->sloppy_function_without_prototype_map(), isolate);
+ Map::SetPrototype(sloppy_function_map, empty_function);
+ Map::SetPrototype(sloppy_function_without_prototype_map, empty_function);
+ Map::SetPrototype(sloppy_function_map_writable_prototype_,
empty_function);
return empty_function;
}
@@ -654,7 +657,7 @@ Handle<Map> Genesis::CreateStrictFunctionMap(
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetStrictFunctionInstanceDescriptor(map, function_mode);
map->set_function_with_prototype(IsFunctionModeWithPrototype(function_mode));
- map->SetPrototype(empty_function);
+ Map::SetPrototype(map, empty_function);
return map;
}
@@ -664,7 +667,7 @@ Handle<Map> Genesis::CreateStrongFunctionMap(
Handle<Map> map = factory()->NewMap(JS_FUNCTION_TYPE, JSFunction::kSize);
SetStrongFunctionInstanceDescriptor(map);
map->set_function_with_prototype(is_constructor);
- map->SetPrototype(empty_function);
+ Map::SetPrototype(map, empty_function);
map->set_is_extensible(is_constructor);
// TODO(rossberg): mark strong
return map;
@@ -1124,7 +1127,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject>
global_object,
Smi::FromInt(0),
SKIP_WRITE_BARRIER); // It's a Smi.
proto_map->set_is_prototype_map(true);
- initial_map->SetPrototype(proto);
+ Map::SetPrototype(initial_map, proto);
factory->SetRegExpIrregexpData(Handle<JSRegExp>::cast(proto),
JSRegExp::IRREGEXP,
factory->empty_string(),
JSRegExp::Flags(0), 0);
@@ -1313,7 +1316,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject>
global_object,
map->set_function_with_prototype(true);
DCHECK_EQ(native_context()->object_function()->prototype(),
*isolate->initial_object_prototype());
- map->SetPrototype(isolate->initial_object_prototype());
+ Map::SetPrototype(map, isolate->initial_object_prototype());
map->set_pre_allocated_property_fields(1);
map->set_inobject_properties(1);
@@ -2035,7 +2038,7 @@ bool Genesis::InstallNatives() {
// maps in the native context.
Handle<Map> generator_function_map =
Map::Copy(sloppy_function_map_writable_prototype_, "GeneratorFunction");
- generator_function_map->SetPrototype(generator_function_prototype);
+ Map::SetPrototype(generator_function_map,
generator_function_prototype);
native_context()->set_sloppy_generator_function_map(
*generator_function_map);
@@ -2068,20 +2071,23 @@ bool Genesis::InstallNatives() {
Handle<Map> strict_generator_function_map =
Map::Copy(strict_function_map, "StrictGeneratorFunction");
// "arguments" and "caller" already poisoned.
-
strict_generator_function_map->SetPrototype(generator_function_prototype);
+ Map::SetPrototype(strict_generator_function_map,
+ generator_function_prototype);
native_context()->set_strict_generator_function_map(
*strict_generator_function_map);
Handle<Map>
strong_function_map(native_context()->strong_function_map());
Handle<Map> strong_generator_function_map =
Map::Copy(strong_function_map, "StrongGeneratorFunction");
-
strong_generator_function_map->SetPrototype(generator_function_prototype);
+ Map::SetPrototype(strong_generator_function_map,
+ generator_function_prototype);
native_context()->set_strong_generator_function_map(
*strong_generator_function_map);
Handle<JSFunction>
object_function(native_context()->object_function());
Handle<Map> generator_object_prototype_map = Map::Create(isolate(), 0);
-
generator_object_prototype_map->SetPrototype(generator_object_prototype);
+ Map::SetPrototype(generator_object_prototype_map,
+ generator_object_prototype);
native_context()->set_generator_object_prototype_map(
*generator_object_prototype_map);
}
@@ -2183,7 +2189,7 @@ bool Genesis::InstallNatives() {
// Set prototype on map.
initial_map->set_non_instance_prototype(false);
- initial_map->SetPrototype(array_prototype);
+ Map::SetPrototype(initial_map, array_prototype);
// Update map with length accessor from Array and add "index"
and "input".
Map::EnsureDescriptorSlack(initial_map, 3);
Index: src/factory.cc
diff --git a/src/factory.cc b/src/factory.cc
index
59f9d68727b8d0bb84adf1f0ca429b85e99a84fe..b940f80531c9f424f43afc4ecb250d339a7fdff3
100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1869,7 +1869,7 @@ Handle<JSProxy> Factory::NewJSProxy(Handle<Object>
handler,
// TODO(rossberg): Once we optimize proxies, think about a scheme to
share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_PROXY_TYPE, JSProxy::kSize);
- map->SetPrototype(prototype);
+ Map::SetPrototype(map, prototype);
// Allocate the proxy object.
Handle<JSProxy> result = New<JSProxy>(map, NEW_SPACE);
@@ -1888,7 +1888,7 @@ Handle<JSProxy>
Factory::NewJSFunctionProxy(Handle<Object> handler,
// TODO(rossberg): Once we optimize proxies, think about a scheme to
share
// maps. Will probably depend on the identity of the handler object, too.
Handle<Map> map = NewMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
- map->SetPrototype(prototype);
+ Map::SetPrototype(map, prototype);
// Allocate the proxy object.
Handle<JSFunctionProxy> result = New<JSFunctionProxy>(map, NEW_SPACE);
@@ -1913,7 +1913,8 @@ void Factory::ReinitializeJSProxy(Handle<JSProxy>
proxy, InstanceType type,
int size_difference = proxy->map()->instance_size() -
map->instance_size();
DCHECK(size_difference >= 0);
- map->SetPrototype(handle(proxy->map()->prototype(),
proxy->GetIsolate()));
+ Handle<Object> prototype(proxy->map()->prototype(), isolate());
+ Map::SetPrototype(map, prototype);
// Allocate the backing storage for the properties.
int prop_size = map->InitialPropertiesLength();
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index
b885a17b239e6234036a7a3bc33697e5f48d337a..359cf60c761033194a9ed852f73adea33eafd432
100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6799,9 +6799,11 @@ Object* JSObject::SlowReverseLookup(Object* value) {
Handle<Map> Map::RawCopy(Handle<Map> map, int instance_size) {
- Handle<Map> result = map->GetIsolate()->factory()->NewMap(
- map->instance_type(), instance_size);
- result->SetPrototype(handle(map->prototype(), map->GetIsolate()));
+ Isolate* isolate = map->GetIsolate();
+ Handle<Map> result =
+ isolate->factory()->NewMap(map->instance_type(), instance_size);
+ Handle<Object> prototype(map->prototype(), isolate);
+ Map::SetPrototype(result, prototype);
result->set_constructor_or_backpointer(map->GetConstructor());
result->set_bit_field(map->bit_field());
result->set_bit_field2(map->bit_field2());
@@ -6996,7 +6998,7 @@ void Map::ConnectTransition(Handle<Map> parent,
Handle<Map> child,
TransitionArray::Insert(parent, name, child, flag);
if (child->prototype()->IsJSObject()) {
Handle<JSObject> proto(JSObject::cast(child->prototype()));
- if (!child->ShouldRegisterAsPrototypeUser(proto)) {
+ if (!ShouldRegisterAsPrototypeUser(child, proto)) {
JSObject::UnregisterPrototypeUser(proto, child);
}
}
@@ -9958,29 +9960,32 @@ void
JSObject::UnregisterPrototypeUser(Handle<JSObject> prototype,
}
-void Map::SetPrototype(Handle<Object> prototype,
+// static
+void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
PrototypeOptimizationMode proto_mode) {
- if (this->prototype()->IsJSObject() && FLAG_track_prototype_users) {
- Handle<JSObject> old_prototype(JSObject::cast(this->prototype()));
- JSObject::UnregisterPrototypeUser(old_prototype, handle(this));
+ if (map->prototype()->IsJSObject() && FLAG_track_prototype_users) {
+ Handle<JSObject> old_prototype(JSObject::cast(map->prototype()));
+ JSObject::UnregisterPrototypeUser(old_prototype, map);
}
if (prototype->IsJSObject()) {
Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
- if (ShouldRegisterAsPrototypeUser(prototype_jsobj)) {
- JSObject::RegisterPrototypeUser(prototype_jsobj, handle(this));
+ if (ShouldRegisterAsPrototypeUser(map, prototype_jsobj)) {
+ JSObject::RegisterPrototypeUser(prototype_jsobj, map);
}
JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode);
}
WriteBarrierMode wb_mode =
prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
- set_prototype(*prototype, wb_mode);
+ map->set_prototype(*prototype, wb_mode);
}
-bool Map::ShouldRegisterAsPrototypeUser(Handle<JSObject> prototype) {
+// static
+bool Map::ShouldRegisterAsPrototypeUser(Handle<Map> map,
+ Handle<JSObject> prototype) {
if (!FLAG_track_prototype_users) return false;
- if (this->is_prototype_map()) return true;
- Object* back = GetBackPointer();
+ if (map->is_prototype_map()) return true;
+ Object* back = map->GetBackPointer();
if (!back->IsMap()) return true;
if (Map::cast(back)->prototype() != *prototype) return true;
return false;
@@ -10133,7 +10138,7 @@ bool JSFunction::RemovePrototype() {
void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map>
map,
Handle<Object> prototype) {
if (map->prototype() != *prototype) {
- map->SetPrototype(prototype, FAST_PROTOTYPE);
+ Map::SetPrototype(map, prototype, FAST_PROTOTYPE);
}
function->set_prototype_or_initial_map(*map);
map->SetConstructor(*function);
@@ -12244,7 +12249,7 @@ Handle<Map> Map::TransitionToPrototype(Handle<Map>
map,
if (new_map.is_null()) {
new_map = Copy(map, "TransitionToPrototype");
TransitionArray::PutPrototypeTransition(map, prototype, new_map);
- new_map->SetPrototype(prototype, mode);
+ Map::SetPrototype(new_map, prototype, mode);
}
return new_map;
}
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index
2fe600d5236e0cc0c898649e8ce520096db431b0..ed0bda149c98a8af9908294f9b3dfbfaa08d88e1
100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -6042,9 +6042,11 @@ class Map: public HeapObject {
// [prototype]: implicit prototype object.
DECL_ACCESSORS(prototype, Object)
// TODO(jkummerow): make set_prototype private.
- void SetPrototype(Handle<Object> prototype,
- PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
- bool ShouldRegisterAsPrototypeUser(Handle<JSObject> prototype);
+ static void SetPrototype(
+ Handle<Map> map, Handle<Object> prototype,
+ PrototypeOptimizationMode proto_mode = FAST_PROTOTYPE);
+ static bool ShouldRegisterAsPrototypeUser(Handle<Map> map,
+ Handle<JSObject> prototype);
bool CanUseOptimizationsBasedOnPrototypeRegistry();
// [constructor]: points back to the function responsible for this map.
@@ -6338,8 +6340,8 @@ class Map: public HeapObject {
kPrototypeOffset + kPointerSize;
// When there is only one transition, it is stored directly in this
field;
// otherwise a transition array is used.
- // For prototype maps, this slot is used to store a pointer to the
prototype
- // object using this map.
+ // For prototype maps, this slot is used to store this map's
PrototypeInfo
+ // struct.
static const int kTransitionsOrPrototypeInfoOffset =
kConstructorOrBackPointerOffset + kPointerSize;
static const int kDescriptorsOffset =
Index: src/runtime/runtime-classes.cc
diff --git a/src/runtime/runtime-classes.cc b/src/runtime/runtime-classes.cc
index
67d7e6939a634213440744b054796355d6e3bd44..9059870c7ab344544952d61fd953982af96e1313
100644
--- a/src/runtime/runtime-classes.cc
+++ b/src/runtime/runtime-classes.cc
@@ -140,7 +140,7 @@ RUNTIME_FUNCTION(Runtime_DefineClass) {
Handle<Map> map =
isolate->factory()->NewMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
- map->SetPrototype(prototype_parent);
+ Map::SetPrototype(map, prototype_parent);
map->SetConstructor(*constructor);
Handle<JSObject> prototype = isolate->factory()->NewJSObjectFromMap(map);
Index: src/runtime/runtime-debug.cc
diff --git a/src/runtime/runtime-debug.cc b/src/runtime/runtime-debug.cc
index
a7bca97a964553977010b2211b4cb71fd531dcf4..5cd65e00faffaf25570700c674b354b3f6e284b1
100644
--- a/src/runtime/runtime-debug.cc
+++ b/src/runtime/runtime-debug.cc
@@ -2171,7 +2171,7 @@ static Handle<JSObject>
NewJSObjectWithNullProto(Isolate* isolate) {
isolate->factory()->NewJSObject(isolate->object_function());
Handle<Map> new_map =
Map::Copy(Handle<Map>(result->map()), "ObjectWithNullProto");
- new_map->SetPrototype(isolate->factory()->null_value());
+ Map::SetPrototype(new_map, isolate->factory()->null_value());
JSObject::MigrateToMap(result, new_map);
return result;
}
Index: test/cctest/test-heap.cc
diff --git a/test/cctest/test-heap.cc b/test/cctest/test-heap.cc
index
ca3ec7b07ab416f3385702ed480b4f08add3de0f..fff65eba0ac1054e2db5b9b2320b73db3825d19f
100644
--- a/test/cctest/test-heap.cc
+++ b/test/cctest/test-heap.cc
@@ -5072,7 +5072,7 @@ void CheckMapRetainingFor(int n) {
CompileRun("(function () { return {x : 10}; })();");
Handle<JSObject> proto =
v8::Utils::OpenHandle(*v8::Handle<v8::Object>::Cast(result));
- map->set_prototype(*proto);
+ Map::SetPrototype(map, proto);
heap->AddRetainedMap(map);
weak_cell = inner_scope.CloseAndEscape(Map::WeakCellForMap(map));
}
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.