Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(802)

Unified Diff: src/objects.cc

Issue 450303003: Tag all prototypes as proto, except those set using __proto__ (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 645bb4a74e39f81272c0c9e3c4c4d913976224fc..1ac755f28626219593a437787fb043c39cdd0683 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -6979,7 +6979,8 @@ Handle<Map> Map::Normalize(Handle<Map> fast_map,
isolate->context()->native_context()->normalized_map_cache());
Handle<Map> new_map;
- if (cache->Get(fast_map, mode).ToHandle(&new_map)) {
+ if (!fast_map->is_prototype_map() &&
+ cache->Get(fast_map, mode).ToHandle(&new_map)) {
#ifdef VERIFY_HEAP
if (FLAG_verify_heap) {
new_map->SharedMapVerify();
@@ -7006,8 +7007,10 @@ Handle<Map> Map::Normalize(Handle<Map> fast_map,
#endif
} else {
new_map = Map::CopyNormalized(fast_map, mode, SHARED_NORMALIZED_MAP);
- cache->Set(fast_map, new_map);
- isolate->counters()->normalized_maps()->Increment();
+ if (!fast_map->is_prototype_map()) {
+ cache->Set(fast_map, new_map);
+ isolate->counters()->normalized_maps()->Increment();
+ }
}
fast_map->NotifyLeafMapLayoutChange();
return new_map;
@@ -9876,21 +9879,30 @@ void JSFunction::SetInstancePrototype(Handle<JSFunction> function,
if (function->IsInobjectSlackTrackingInProgress()) {
function->CompleteInobjectSlackTracking();
}
+
Handle<Map> initial_map(function->initial_map(), isolate);
- Handle<Map> new_map = Map::Copy(initial_map);
- new_map->set_prototype(*value);
- // If the function is used as the global Array function, cache the
- // initial map (and transitioned versions) in the native context.
- Context* native_context = function->context()->native_context();
- Object* array_function = native_context->get(Context::ARRAY_FUNCTION_INDEX);
- if (array_function->IsJSFunction() &&
- *function == JSFunction::cast(array_function)) {
- CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
+ if (!initial_map->GetIsolate()->bootstrapper()->IsActive() &&
+ initial_map->instance_type() == JS_OBJECT_TYPE) {
+ // Put the value in the initial map field until an initial map is needed.
+ // At that point, a new initial map is created and the prototype is put
+ // into the initial map where it belongs.
+ function->set_prototype_or_initial_map(*value);
+ } else {
+ Handle<Map> new_map = Map::Copy(initial_map);
+ JSFunction::SetInitialMap(function, new_map, value);
+
+ // If the function is used as the global Array function, cache the
+ // initial map (and transitioned versions) in the native context.
+ Context* native_context = function->context()->native_context();
+ Object* array_function =
+ native_context->get(Context::ARRAY_FUNCTION_INDEX);
+ if (array_function->IsJSFunction() &&
+ *function == JSFunction::cast(array_function)) {
+ CacheInitialJSArrayMaps(handle(native_context, isolate), new_map);
+ }
}
- JSFunction::SetInitialMap(function, new_map);
-
// Deoptimize all code that embeds the previous initial map.
initial_map->dependent_code()->DeoptimizeDependentCodeGroup(
isolate, DependentCode::kInitialMapChangedGroup);
@@ -9956,9 +9968,10 @@ bool JSFunction::RemovePrototype() {
}
-void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map) {
- if (map->prototype()->IsJSObject()) {
- Handle<JSObject> js_proto = handle(JSObject::cast(map->prototype()));
+void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map,
+ Handle<Object> prototype) {
+ if (prototype->IsJSObject()) {
+ Handle<JSObject> js_proto = Handle<JSObject>::cast(prototype);
if (!js_proto->map()->is_prototype_map() &&
!js_proto->map()->IsGlobalObjectMap() &&
!js_proto->map()->IsJSGlobalProxyMap()) {
@@ -9977,6 +9990,7 @@ void JSFunction::SetInitialMap(Handle<JSFunction> function, Handle<Map> map) {
}
}
}
+ map->set_prototype(*prototype);
function->set_prototype_or_initial_map(*map);
map->set_constructor(*function);
}
@@ -10011,11 +10025,10 @@ void JSFunction::EnsureHasInitialMap(Handle<JSFunction> function) {
}
map->set_inobject_properties(in_object_properties);
map->set_unused_property_fields(in_object_properties);
- map->set_prototype(*prototype);
DCHECK(map->has_fast_object_elements());
// Finally link initial map and constructor function.
- JSFunction::SetInitialMap(function, map);
+ JSFunction::SetInitialMap(function, map, Handle<JSReceiver>::cast(prototype));
if (!function->shared()->is_generator()) {
function->StartInobjectSlackTracking();
@@ -12100,7 +12113,7 @@ Handle<Map> Map::TransitionToPrototype(Handle<Map> map,
MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
Handle<Object> value,
- bool skip_hidden_prototypes) {
+ bool from_javascript) {
#ifdef DEBUG
int size = object->Size();
#endif
@@ -12145,7 +12158,7 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
object->map()->DictionaryElementsInPrototypeChainOnly();
Handle<JSObject> real_receiver = object;
- if (skip_hidden_prototypes) {
+ if (from_javascript) {
// Find the first object in the chain whose prototype object is not
// hidden and set the new prototype on that object.
PrototypeIterator iter(isolate, real_receiver);
@@ -12163,7 +12176,19 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
if (map->prototype() == *value) return value;
if (value->IsJSObject()) {
- JSObject::OptimizeAsPrototype(Handle<JSObject>::cast(value));
+ Handle<JSObject> js_proto = Handle<JSObject>::cast(value);
+ if (!from_javascript && !js_proto->IsJSGlobalProxy() &&
+ !js_proto->IsGlobalObject() && !js_proto->map()->is_prototype_map()) {
+ JSObject::NormalizeProperties(js_proto, KEEP_INOBJECT_PROPERTIES, 0);
+ JSObject::MigrateSlowToFast(js_proto, 0);
+ if (js_proto->HasFastProperties()) {
+ Handle<Map> new_map = Map::Copy(handle(js_proto->map()));
+ JSObject::MigrateToMap(js_proto, new_map);
+ js_proto->map()->set_is_prototype_map(true);
+ }
Igor Sheludko 2014/08/11 07:42:13 The "make-prototype-super-fast" piece of code look
+ } else {
+ JSObject::OptimizeAsPrototype(js_proto);
+ }
}
Handle<Map> new_map = Map::TransitionToPrototype(map, value);
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698