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

Unified Diff: src/objects.cc

Issue 1675223002: Mark maps having a hidden prototype rather than maps of hidden prototypes. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comment Created 4 years, 10 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/objects-inl.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 8933e6ce34011bbcd8ac41adf425b55dfa75aa9d..9636024ae9b1d9cf72fcff8dfc98a71d967b5dc4 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1021,9 +1021,10 @@ Object* FunctionTemplateInfo::GetCompatibleReceiver(Isolate* isolate,
if (recv_type->IsUndefined()) return receiver;
FunctionTemplateInfo* signature = FunctionTemplateInfo::cast(recv_type);
// Check the receiver.
- for (PrototypeIterator iter(isolate, receiver,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN); iter.Advance()) {
+ for (PrototypeIterator iter(isolate, JSObject::cast(receiver),
+ PrototypeIterator::START_AT_RECEIVER,
+ PrototypeIterator::END_AT_NON_HIDDEN);
+ !iter.IsAtEnd(); iter.Advance()) {
if (signature->IsTemplateFor(iter.GetCurrent())) return iter.GetCurrent();
}
return isolate->heap()->null_value();
@@ -1098,7 +1099,7 @@ MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
Object);
// 6. If trap is undefined, then return target.[[GetPrototypeOf]]().
if (trap->IsUndefined()) {
- return Object::GetPrototype(isolate, target);
+ return JSReceiver::GetPrototype(isolate, target);
}
// 7. Let handlerProto be ? Call(trap, handler, «target»).
Handle<Object> argv[] = {target};
@@ -1120,7 +1121,7 @@ MaybeHandle<Object> JSProxy::GetPrototype(Handle<JSProxy> proxy) {
// 11. Let targetProto be ? target.[[GetPrototypeOf]]().
Handle<Object> target_proto;
ASSIGN_RETURN_ON_EXCEPTION(isolate, target_proto,
- Object::GetPrototype(isolate, target), Object);
+ JSReceiver::GetPrototype(isolate, target), Object);
// 12. If SameValue(handlerProto, targetProto) is false, throw a TypeError.
if (!handler_proto->SameValue(*target_proto)) {
THROW_NEW_ERROR(
@@ -1436,14 +1437,16 @@ void JSObject::SetNormalizedProperty(Handle<JSObject> object,
}
}
-
-Maybe<bool> Object::HasInPrototypeChain(Isolate* isolate, Handle<Object> object,
- Handle<Object> proto) {
+Maybe<bool> JSReceiver::HasInPrototypeChain(Isolate* isolate,
+ Handle<JSReceiver> object,
+ Handle<Object> proto) {
PrototypeIterator iter(isolate, object, PrototypeIterator::START_AT_RECEIVER);
while (true) {
if (!iter.AdvanceFollowingProxies()) return Nothing<bool>();
if (iter.IsAtEnd()) return Just(false);
- if (iter.IsAtEnd(proto)) return Just(true);
+ if (PrototypeIterator::GetCurrent(iter).is_identical_to(proto)) {
+ return Just(true);
+ }
}
}
@@ -8742,8 +8745,8 @@ static Maybe<bool> GetKeys_Internal(Isolate* isolate,
? PrototypeIterator::END_AT_NON_HIDDEN
: PrototypeIterator::END_AT_NULL;
for (PrototypeIterator iter(isolate, object,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(end); iter.Advance()) {
+ PrototypeIterator::START_AT_RECEIVER, end);
+ !iter.IsAtEnd(); iter.Advance()) {
Handle<JSReceiver> current =
PrototypeIterator::GetCurrent<JSReceiver>(iter);
Maybe<bool> result = Just(false); // Dummy initialization.
@@ -12323,7 +12326,7 @@ bool CheckEquivalent(Map* first, Map* second) {
first->is_extensible() == second->is_extensible() &&
first->is_strong() == second->is_strong() &&
first->new_target_is_base() == second->new_target_is_base() &&
- first->is_hidden_prototype() == second->is_hidden_prototype();
+ first->has_hidden_prototype() == second->has_hidden_prototype();
}
} // namespace
@@ -12886,10 +12889,22 @@ Handle<Cell> Map::GetOrCreatePrototypeChainValidityCell(Handle<Map> map,
// static
void Map::SetPrototype(Handle<Map> map, Handle<Object> prototype,
PrototypeOptimizationMode proto_mode) {
+ bool is_hidden = false;
if (prototype->IsJSObject()) {
Handle<JSObject> prototype_jsobj = Handle<JSObject>::cast(prototype);
JSObject::OptimizeAsPrototype(prototype_jsobj, proto_mode);
+
+ Object* maybe_constructor = prototype_jsobj->map()->GetConstructor();
+ if (maybe_constructor->IsJSFunction()) {
+ JSFunction* constructor = JSFunction::cast(maybe_constructor);
+ Object* data = constructor->shared()->function_data();
+ is_hidden = (data->IsFunctionTemplateInfo() &&
+ FunctionTemplateInfo::cast(data)->hidden_prototype()) ||
+ prototype->IsJSGlobalObject();
+ }
}
+ map->set_has_hidden_prototype(is_hidden);
+
WriteBarrierMode wb_mode =
prototype->IsNull() ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
map->set_prototype(*prototype, wb_mode);
@@ -15651,7 +15666,7 @@ Maybe<bool> JSProxy::SetPrototype(Handle<JSProxy> proxy, Handle<Object> value,
// 11. Let targetProto be ? target.[[GetPrototypeOf]]().
Handle<Object> target_proto;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, target_proto,
- Object::GetPrototype(isolate, target),
+ JSReceiver::GetPrototype(isolate, target),
Nothing<bool>());
// 12. If booleanTrapResult is true and SameValue(V, targetProto) is false,
// throw a TypeError exception.
@@ -15677,7 +15692,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
Handle<Object> old_value;
if (observed) {
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, old_value,
- Object::GetPrototype(isolate, object),
+ JSReceiver::GetPrototype(isolate, object),
Nothing<bool>());
}
@@ -15688,7 +15703,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
if (result.FromJust() && observed) {
Handle<Object> new_value;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, new_value,
- Object::GetPrototype(isolate, object),
+ JSReceiver::GetPrototype(isolate, object),
Nothing<bool>());
if (!new_value->SameValue(*old_value)) {
RETURN_ON_EXCEPTION_VALUE(
@@ -15744,8 +15759,10 @@ Maybe<bool> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
if (from_javascript) {
// Find the first object in the chain whose prototype object is not
// hidden.
- PrototypeIterator iter(isolate, real_receiver);
- while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN)) {
+ PrototypeIterator iter(isolate, real_receiver,
+ PrototypeIterator::START_AT_PROTOTYPE,
+ PrototypeIterator::END_AT_NON_HIDDEN);
+ while (!iter.IsAtEnd()) {
// Casting to JSObject is fine because hidden prototypes are never
// JSProxies.
real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
@@ -15774,13 +15791,15 @@ Maybe<bool> JSObject::SetPrototypeUnobserved(Handle<JSObject> object,
// Before we can set the prototype we need to be sure prototype cycles are
// prevented. It is sufficient to validate that the receiver is not in the
// new prototype chain.
- for (PrototypeIterator iter(isolate, *value,
- PrototypeIterator::START_AT_RECEIVER);
- !iter.IsAtEnd(); iter.Advance()) {
- if (iter.GetCurrent<JSReceiver>() == *object) {
- // Cycle detected.
- RETURN_FAILURE(isolate, should_throw,
- NewTypeError(MessageTemplate::kCyclicProto));
+ if (value->IsJSReceiver()) {
+ for (PrototypeIterator iter(isolate, JSReceiver::cast(*value),
+ PrototypeIterator::START_AT_RECEIVER);
+ !iter.IsAtEnd(); iter.Advance()) {
+ if (iter.GetCurrent<JSReceiver>() == *object) {
+ // Cycle detected.
+ RETURN_FAILURE(isolate, should_throw,
+ NewTypeError(MessageTemplate::kCyclicProto));
+ }
}
}
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698