Commit 44f4c1d6 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Implement the implicit ToObject for property access.

Drive-by-fix: Move IC::GetRootConstructor to Map::GetConstructorFunction,
so we can use that in the ICs, Crankshaft and Turbofan.

R=jarin@chromium.org
BUG=v8:4470
LOG=n

Review URL: https://codereview.chromium.org/1416493007

Cr-Commit-Position: refs/heads/master@{#31577}
parent 67dc6ce5
......@@ -34,6 +34,7 @@ JSNativeContextSpecialization::JSNativeContextSpecialization(
jsgraph_(jsgraph),
flags_(flags),
global_object_(global_object),
native_context_(global_object->native_context(), isolate()),
dependencies_(dependencies),
zone_(zone) {}
......@@ -435,8 +436,17 @@ bool JSNativeContextSpecialization::ComputePropertyAccessInfo(
// Walk up the prototype chain.
if (!map->prototype()->IsJSObject()) {
// TODO(bmeurer): Handle the not found case if the prototype is null.
break;
// Perform the implicit ToObject for primitives here.
// Implemented according to ES6 section 7.3.2 GetV (V, P).
Handle<JSFunction> constructor;
if (Map::GetConstructorFunction(map, native_context())
.ToHandle(&constructor)) {
map = handle(constructor->initial_map(), isolate());
DCHECK(map->prototype()->IsJSObject());
} else {
// TODO(bmeurer): Handle the not found case if the prototype is null.
break;
}
}
Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate());
if (map_prototype->map()->is_deprecated()) {
......@@ -893,7 +903,14 @@ void JSNativeContextSpecialization::AssumePrototypesStable(
Type* receiver_type, Handle<JSObject> holder) {
// Determine actual holder and perform prototype chain checks.
for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) {
Handle<Map> const map = i.Current();
Handle<Map> map = i.Current();
// Perform the implicit ToObject for primitives here.
// Implemented according to ES6 section 7.3.2 GetV (V, P).
Handle<JSFunction> constructor;
if (Map::GetConstructorFunction(map, native_context())
.ToHandle(&constructor)) {
map = handle(constructor->initial_map(), isolate());
}
for (PrototypeIterator j(map);; j.Advance()) {
// Check that the {prototype} still has the same map. All prototype
// maps are guaranteed to be stable, so it's sufficient to add a
......
......@@ -86,12 +86,14 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
MachineOperatorBuilder* machine() const;
Flags flags() const { return flags_; }
Handle<GlobalObject> global_object() const { return global_object_; }
Handle<Context> native_context() const { return native_context_; }
CompilationDependencies* dependencies() const { return dependencies_; }
Zone* zone() const { return zone_; }
JSGraph* const jsgraph_;
Flags const flags_;
Handle<GlobalObject> global_object_;
Handle<Context> native_context_;
CompilationDependencies* const dependencies_;
Zone* const zone_;
......
......@@ -6510,9 +6510,12 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
Handle<Map> HOptimizedGraphBuilder::PropertyAccessInfo::map() {
JSFunction* ctor = IC::GetRootConstructor(
*map_, current_info()->closure()->context()->native_context());
if (ctor != NULL) return handle(ctor->initial_map());
Handle<JSFunction> ctor;
if (Map::GetConstructorFunction(
map_, handle(current_info()->closure()->context()->native_context()))
.ToHandle(&ctor)) {
return handle(ctor->initial_map());
}
return map_;
}
......
......@@ -127,19 +127,6 @@ Code* IC::raw_target() const {
void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); }
JSFunction* IC::GetRootConstructor(Map* receiver_map, Context* native_context) {
DisallowHeapAllocation no_alloc;
if (receiver_map->IsPrimitiveMap()) {
int constructor_function_index =
receiver_map->GetConstructorFunctionIndex();
if (constructor_function_index != Map::kNoConstructorFunctionIndex) {
return JSFunction::cast(native_context->get(constructor_function_index));
}
}
return nullptr;
}
Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder, Isolate* isolate,
CacheHolderFlag* flag) {
......@@ -147,9 +134,9 @@ Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
*flag = kCacheOnReceiver;
return receiver_map;
}
Context* native_context = *isolate->native_context();
JSFunction* builtin_ctor = GetRootConstructor(*receiver_map, native_context);
if (builtin_ctor != NULL) {
Handle<JSFunction> builtin_ctor;
if (Map::GetConstructorFunction(receiver_map, isolate->native_context())
.ToHandle(&builtin_ctor)) {
*flag = kCacheOnPrototypeReceiverIsPrimitive;
return handle(HeapObject::cast(builtin_ctor->instance_prototype())->map());
}
......@@ -163,9 +150,9 @@ Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
Handle<Map> IC::GetICCacheHolder(Handle<Map> map, Isolate* isolate,
CacheHolderFlag* flag) {
Context* native_context = *isolate->native_context();
JSFunction* builtin_ctor = GetRootConstructor(*map, native_context);
if (builtin_ctor != NULL) {
Handle<JSFunction> builtin_ctor;
if (Map::GetConstructorFunction(map, isolate->native_context())
.ToHandle(&builtin_ctor)) {
*flag = kCacheOnPrototype;
return handle(builtin_ctor->initial_map());
}
......
......@@ -57,8 +57,6 @@ class IC {
bool IsCallStub() const { return target()->is_call_stub(); }
#endif
static inline JSFunction* GetRootConstructor(Map* receiver_map,
Context* native_context);
static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder,
Isolate* isolate,
......
......@@ -1679,6 +1679,20 @@ void JSObject::PrintElementsTransition(
}
// static
MaybeHandle<JSFunction> Map::GetConstructorFunction(
Handle<Map> map, Handle<Context> native_context) {
if (map->IsPrimitiveMap()) {
int const constructor_function_index = map->GetConstructorFunctionIndex();
if (constructor_function_index != kNoConstructorFunctionIndex) {
return handle(
JSFunction::cast(native_context->get(constructor_function_index)));
}
}
return MaybeHandle<JSFunction>();
}
void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
PropertyAttributes attributes) {
OFStream os(file);
......
......@@ -5518,6 +5518,8 @@ class Map: public HeapObject {
static const int kNoConstructorFunctionIndex = 0;
inline int GetConstructorFunctionIndex();
inline void SetConstructorFunctionIndex(int value);
static MaybeHandle<JSFunction> GetConstructorFunction(
Handle<Map> map, Handle<Context> native_context);
// Instance type.
inline InstanceType instance_type();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment