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( ...@@ -34,6 +34,7 @@ JSNativeContextSpecialization::JSNativeContextSpecialization(
jsgraph_(jsgraph), jsgraph_(jsgraph),
flags_(flags), flags_(flags),
global_object_(global_object), global_object_(global_object),
native_context_(global_object->native_context(), isolate()),
dependencies_(dependencies), dependencies_(dependencies),
zone_(zone) {} zone_(zone) {}
...@@ -435,8 +436,17 @@ bool JSNativeContextSpecialization::ComputePropertyAccessInfo( ...@@ -435,8 +436,17 @@ bool JSNativeContextSpecialization::ComputePropertyAccessInfo(
// Walk up the prototype chain. // Walk up the prototype chain.
if (!map->prototype()->IsJSObject()) { if (!map->prototype()->IsJSObject()) {
// TODO(bmeurer): Handle the not found case if the prototype is null. // Perform the implicit ToObject for primitives here.
break; // 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()); Handle<JSObject> map_prototype(JSObject::cast(map->prototype()), isolate());
if (map_prototype->map()->is_deprecated()) { if (map_prototype->map()->is_deprecated()) {
...@@ -893,7 +903,14 @@ void JSNativeContextSpecialization::AssumePrototypesStable( ...@@ -893,7 +903,14 @@ void JSNativeContextSpecialization::AssumePrototypesStable(
Type* receiver_type, Handle<JSObject> holder) { Type* receiver_type, Handle<JSObject> holder) {
// Determine actual holder and perform prototype chain checks. // Determine actual holder and perform prototype chain checks.
for (auto i = receiver_type->Classes(); !i.Done(); i.Advance()) { 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()) { for (PrototypeIterator j(map);; j.Advance()) {
// Check that the {prototype} still has the same map. All prototype // Check that the {prototype} still has the same map. All prototype
// maps are guaranteed to be stable, so it's sufficient to add a // maps are guaranteed to be stable, so it's sufficient to add a
......
...@@ -86,12 +86,14 @@ class JSNativeContextSpecialization final : public AdvancedReducer { ...@@ -86,12 +86,14 @@ class JSNativeContextSpecialization final : public AdvancedReducer {
MachineOperatorBuilder* machine() const; MachineOperatorBuilder* machine() const;
Flags flags() const { return flags_; } Flags flags() const { return flags_; }
Handle<GlobalObject> global_object() const { return global_object_; } Handle<GlobalObject> global_object() const { return global_object_; }
Handle<Context> native_context() const { return native_context_; }
CompilationDependencies* dependencies() const { return dependencies_; } CompilationDependencies* dependencies() const { return dependencies_; }
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
JSGraph* const jsgraph_; JSGraph* const jsgraph_;
Flags const flags_; Flags const flags_;
Handle<GlobalObject> global_object_; Handle<GlobalObject> global_object_;
Handle<Context> native_context_;
CompilationDependencies* const dependencies_; CompilationDependencies* const dependencies_;
Zone* const zone_; Zone* const zone_;
......
...@@ -6510,9 +6510,12 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic( ...@@ -6510,9 +6510,12 @@ bool HOptimizedGraphBuilder::PropertyAccessInfo::CanAccessAsMonomorphic(
Handle<Map> HOptimizedGraphBuilder::PropertyAccessInfo::map() { Handle<Map> HOptimizedGraphBuilder::PropertyAccessInfo::map() {
JSFunction* ctor = IC::GetRootConstructor( Handle<JSFunction> ctor;
*map_, current_info()->closure()->context()->native_context()); if (Map::GetConstructorFunction(
if (ctor != NULL) return handle(ctor->initial_map()); map_, handle(current_info()->closure()->context()->native_context()))
.ToHandle(&ctor)) {
return handle(ctor->initial_map());
}
return map_; return map_;
} }
......
...@@ -127,19 +127,6 @@ Code* IC::raw_target() const { ...@@ -127,19 +127,6 @@ Code* IC::raw_target() const {
void IC::UpdateTarget() { target_ = handle(raw_target(), isolate_); } 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, Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder, Isolate* isolate, bool receiver_is_holder, Isolate* isolate,
CacheHolderFlag* flag) { CacheHolderFlag* flag) {
...@@ -147,9 +134,9 @@ Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map, ...@@ -147,9 +134,9 @@ Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
*flag = kCacheOnReceiver; *flag = kCacheOnReceiver;
return receiver_map; return receiver_map;
} }
Context* native_context = *isolate->native_context(); Handle<JSFunction> builtin_ctor;
JSFunction* builtin_ctor = GetRootConstructor(*receiver_map, native_context); if (Map::GetConstructorFunction(receiver_map, isolate->native_context())
if (builtin_ctor != NULL) { .ToHandle(&builtin_ctor)) {
*flag = kCacheOnPrototypeReceiverIsPrimitive; *flag = kCacheOnPrototypeReceiverIsPrimitive;
return handle(HeapObject::cast(builtin_ctor->instance_prototype())->map()); return handle(HeapObject::cast(builtin_ctor->instance_prototype())->map());
} }
...@@ -163,9 +150,9 @@ Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map, ...@@ -163,9 +150,9 @@ Handle<Map> IC::GetHandlerCacheHolder(Handle<Map> receiver_map,
Handle<Map> IC::GetICCacheHolder(Handle<Map> map, Isolate* isolate, Handle<Map> IC::GetICCacheHolder(Handle<Map> map, Isolate* isolate,
CacheHolderFlag* flag) { CacheHolderFlag* flag) {
Context* native_context = *isolate->native_context(); Handle<JSFunction> builtin_ctor;
JSFunction* builtin_ctor = GetRootConstructor(*map, native_context); if (Map::GetConstructorFunction(map, isolate->native_context())
if (builtin_ctor != NULL) { .ToHandle(&builtin_ctor)) {
*flag = kCacheOnPrototype; *flag = kCacheOnPrototype;
return handle(builtin_ctor->initial_map()); return handle(builtin_ctor->initial_map());
} }
......
...@@ -57,8 +57,6 @@ class IC { ...@@ -57,8 +57,6 @@ class IC {
bool IsCallStub() const { return target()->is_call_stub(); } bool IsCallStub() const { return target()->is_call_stub(); }
#endif #endif
static inline JSFunction* GetRootConstructor(Map* receiver_map,
Context* native_context);
static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map, static inline Handle<Map> GetHandlerCacheHolder(Handle<Map> receiver_map,
bool receiver_is_holder, bool receiver_is_holder,
Isolate* isolate, Isolate* isolate,
......
...@@ -1679,6 +1679,20 @@ void JSObject::PrintElementsTransition( ...@@ -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, void Map::PrintReconfiguration(FILE* file, int modify_index, PropertyKind kind,
PropertyAttributes attributes) { PropertyAttributes attributes) {
OFStream os(file); OFStream os(file);
......
...@@ -5518,6 +5518,8 @@ class Map: public HeapObject { ...@@ -5518,6 +5518,8 @@ class Map: public HeapObject {
static const int kNoConstructorFunctionIndex = 0; static const int kNoConstructorFunctionIndex = 0;
inline int GetConstructorFunctionIndex(); inline int GetConstructorFunctionIndex();
inline void SetConstructorFunctionIndex(int value); inline void SetConstructorFunctionIndex(int value);
static MaybeHandle<JSFunction> GetConstructorFunction(
Handle<Map> map, Handle<Context> native_context);
// Instance type. // Instance type.
inline InstanceType 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