Commit 045fdaf4 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Serialize for "prototype" access on functions

Bug: v8:7790
Change-Id: I44c722357434a32ae9400a0e44dbc522dafe873a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1547849
Auto-Submit: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#60567}
parent d4266e30
...@@ -325,6 +325,7 @@ class JSFunctionData : public JSObjectData { ...@@ -325,6 +325,7 @@ class JSFunctionData : public JSObjectData {
} }
void Serialize(JSHeapBroker* broker); void Serialize(JSHeapBroker* broker);
bool serialized() const { return serialized_; }
ContextData* context() const { return context_; } ContextData* context() const { return context_; }
NativeContextData* native_context() const { return native_context_; } NativeContextData* native_context() const { return native_context_; }
...@@ -2864,6 +2865,11 @@ void JSFunctionRef::Serialize() { ...@@ -2864,6 +2865,11 @@ void JSFunctionRef::Serialize() {
data()->AsJSFunction()->Serialize(broker()); data()->AsJSFunction()->Serialize(broker());
} }
bool JSFunctionRef::serialized() const {
CHECK_NE(broker()->mode(), JSHeapBroker::kDisabled);
return data()->AsJSFunction()->serialized();
}
bool JSFunctionRef::IsSerializedForCompilation() const { bool JSFunctionRef::IsSerializedForCompilation() const {
return shared().IsSerializedForCompilation(feedback_vector()); return shared().IsSerializedForCompilation(feedback_vector());
} }
......
...@@ -243,7 +243,7 @@ class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef { ...@@ -243,7 +243,7 @@ class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef {
bool PrototypeRequiresRuntimeLookup() const; bool PrototypeRequiresRuntimeLookup() const;
void Serialize(); void Serialize();
bool IsSerializedForCompilation() const; bool serialized() const;
// The following are available only after calling Serialize(). // The following are available only after calling Serialize().
ObjectRef prototype() const; ObjectRef prototype() const;
...@@ -253,6 +253,8 @@ class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef { ...@@ -253,6 +253,8 @@ class V8_EXPORT_PRIVATE JSFunctionRef : public JSObjectRef {
SharedFunctionInfoRef shared() const; SharedFunctionInfoRef shared() const;
FeedbackVectorRef feedback_vector() const; FeedbackVectorRef feedback_vector() const;
int InitialMapInstanceSizeWithMinSlack() const; int InitialMapInstanceSizeWithMinSlack() const;
bool IsSerializedForCompilation() const;
}; };
class JSRegExpRef : public JSObjectRef { class JSRegExpRef : public JSObjectRef {
......
...@@ -1384,9 +1384,13 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) { ...@@ -1384,9 +1384,13 @@ Reduction JSNativeContextSpecialization::ReduceJSLoadNamed(Node* node) {
name.equals(ObjectRef(broker(), factory()->prototype_string()))) { name.equals(ObjectRef(broker(), factory()->prototype_string()))) {
// Optimize "prototype" property of functions. // Optimize "prototype" property of functions.
JSFunctionRef function = object.AsJSFunction(); JSFunctionRef function = object.AsJSFunction();
// TODO(neis): This is a temporary hack needed because the copy reducer if (!FLAG_concurrent_inlining) {
// runs only after this pass.
function.Serialize(); function.Serialize();
} else if (!function.serialized()) {
TRACE_BROKER(broker(), "ReduceJSLoadNamed: missing data for function "
<< function.object().address() << "\n");
return NoChange();
}
// TODO(neis): Remove the has_prototype_slot condition once the broker is // TODO(neis): Remove the has_prototype_slot condition once the broker is
// always enabled. // always enabled.
if (!function.map().has_prototype_slot() || !function.has_prototype() || if (!function.map().has_prototype_slot() || !function.has_prototype() ||
......
...@@ -856,7 +856,8 @@ void SerializerForBackgroundCompilation::VisitLdaKeyedProperty( ...@@ -856,7 +856,8 @@ void SerializerForBackgroundCompilation::VisitLdaKeyedProperty(
} }
void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess( void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
Hints const& receiver, NameRef const& name, FeedbackSlot slot) { Hints const& receiver, NameRef const& name, FeedbackSlot slot,
AccessMode mode) {
if (!slot.IsInvalid()) ProcessFeedbackForNamedPropertyAccess(slot, name); if (!slot.IsInvalid()) ProcessFeedbackForNamedPropertyAccess(slot, name);
for (Handle<Map> map : for (Handle<Map> map :
...@@ -866,29 +867,42 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess( ...@@ -866,29 +867,42 @@ void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
JSGlobalProxyRef global_proxy = JSGlobalProxyRef global_proxy =
broker()->native_context().global_proxy_object(); broker()->native_context().global_proxy_object();
for (Handle<Object> object : receiver.constants()) {
for (Handle<Object> hint : receiver.constants()) {
ObjectRef object(broker(), hint);
// For JSNativeContextSpecialization::ReduceNamedAccessFromNexus. // For JSNativeContextSpecialization::ReduceNamedAccessFromNexus.
if (object.equals(global_proxy.object())) { if (object.equals(global_proxy)) {
global_proxy.GetPropertyCell(name, true); global_proxy.GetPropertyCell(name, true);
} }
// For JSNativeContextSpecialization::ReduceJSLoadNamed.
if (mode == AccessMode::kLoad && object.IsJSFunction() &&
name.equals(ObjectRef(
broker(), broker()->isolate()->factory()->prototype_string()))) {
object.AsJSFunction().Serialize();
}
} }
environment()->accumulator_hints().Clear(); environment()->accumulator_hints().Clear();
} }
void SerializerForBackgroundCompilation::VisitLdaNamedProperty( void SerializerForBackgroundCompilation::ProcessNamedPropertyAccess(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator, AccessMode mode) {
Hints const& receiver = Hints const& receiver =
environment()->register_hints(iterator->GetRegisterOperand(0)); environment()->register_hints(iterator->GetRegisterOperand(0));
Handle<Name> name(Name::cast(iterator->GetConstantForIndexOperand(1)), Handle<Name> name(Name::cast(iterator->GetConstantForIndexOperand(1)),
broker()->isolate()); broker()->isolate());
FeedbackSlot slot = iterator->GetSlotOperand(2); FeedbackSlot slot = iterator->GetSlotOperand(2);
ProcessNamedPropertyAccess(receiver, NameRef(broker(), name), slot); ProcessNamedPropertyAccess(receiver, NameRef(broker(), name), slot, mode);
}
void SerializerForBackgroundCompilation::VisitLdaNamedProperty(
BytecodeArrayIterator* iterator) {
ProcessNamedPropertyAccess(iterator, AccessMode::kLoad);
} }
void SerializerForBackgroundCompilation::VisitStaNamedProperty( void SerializerForBackgroundCompilation::VisitStaNamedProperty(
BytecodeArrayIterator* iterator) { BytecodeArrayIterator* iterator) {
VisitLdaNamedProperty(iterator); ProcessNamedPropertyAccess(iterator, AccessMode::kStore);
} }
void SerializerForBackgroundCompilation::VisitTestIn( void SerializerForBackgroundCompilation::VisitTestIn(
......
...@@ -247,14 +247,14 @@ class SerializerForBackgroundCompilation { ...@@ -247,14 +247,14 @@ class SerializerForBackgroundCompilation {
void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator, void ProcessCallVarArgs(interpreter::BytecodeArrayIterator* iterator,
ConvertReceiverMode receiver_mode, ConvertReceiverMode receiver_mode,
bool with_spread = false); bool with_spread = false);
void ProcessJump(interpreter::BytecodeArrayIterator* iterator); void ProcessJump(interpreter::BytecodeArrayIterator* iterator);
void MergeAfterJump(interpreter::BytecodeArrayIterator* iterator); void MergeAfterJump(interpreter::BytecodeArrayIterator* iterator);
void ProcessNamedPropertyAccess(Hints const& receiver, NameRef const& name,
FeedbackSlot slot);
Hints RunChildSerializer(CompilationSubject function, void ProcessNamedPropertyAccess(interpreter::BytecodeArrayIterator* iterator,
base::Optional<Hints> new_target, AccessMode mode);
const HintsVector& arguments, bool with_spread); void ProcessNamedPropertyAccess(Hints const& receiver, NameRef const& name,
FeedbackSlot slot, AccessMode mode);
GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(FeedbackSlot slot); GlobalAccessFeedback const* ProcessFeedbackForGlobalAccess(FeedbackSlot slot);
void ProcessFeedbackForKeyedPropertyAccess(FeedbackSlot slot, void ProcessFeedbackForKeyedPropertyAccess(FeedbackSlot slot,
...@@ -263,6 +263,10 @@ class SerializerForBackgroundCompilation { ...@@ -263,6 +263,10 @@ class SerializerForBackgroundCompilation {
NameRef const& name); NameRef const& name);
void ProcessMapForNamedPropertyAccess(MapRef const& map, NameRef const& name); void ProcessMapForNamedPropertyAccess(MapRef const& map, NameRef const& name);
Hints RunChildSerializer(CompilationSubject function,
base::Optional<Hints> new_target,
const HintsVector& arguments, bool with_spread);
JSHeapBroker* broker() const { return broker_; } JSHeapBroker* broker() const { return broker_; }
Zone* zone() const { return zone_; } Zone* zone() const { return zone_; }
Environment* environment() const { return environment_; } Environment* environment() const { return environment_; }
......
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