Commit 46a93c9e authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

[turbofan] Brokerize JSCreateLowering::ReduceJSCreateGeneratorObject.

This also fixes JSCreateLowering::ReduceJSCreate to use in-object
property count after slack tracking. This would still deserve some
more bullet-proof treatment; in particular, we should make it
somehow hard to access the pre-slack-tracking instance_size and
inobject_property_count (and possibly other things that might be
derived from the stale instance_size).

Bug: v8:7790
Change-Id: Ie374e5a030ec2fe000647e94d848ca0f9ee346f4
Reviewed-on: https://chromium-review.googlesource.com/1138235
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54471}
parent 70aacc2e
...@@ -148,19 +148,19 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) { ...@@ -148,19 +148,19 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
// Force completion of inobject slack tracking before // Force completion of inobject slack tracking before
// generating code to finalize the instance size. // generating code to finalize the instance size.
int const instance_size = SlackTrackingResult slack_tracking_result =
original_constructor.GetInstanceSizeWithFinishedSlackTracking(); original_constructor.FinishSlackTracking();
// Emit code to allocate the JSObject instance for the // Emit code to allocate the JSObject instance for the
// {original_constructor}. // {original_constructor}.
AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control); AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control);
a.Allocate(instance_size); a.Allocate(slack_tracking_result.instance_size);
a.Store(AccessBuilder::ForMap(), initial_map); a.Store(AccessBuilder::ForMap(), initial_map);
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
jsgraph()->EmptyFixedArrayConstant()); jsgraph()->EmptyFixedArrayConstant());
a.Store(AccessBuilder::ForJSObjectElements(), a.Store(AccessBuilder::ForJSObjectElements(),
jsgraph()->EmptyFixedArrayConstant()); jsgraph()->EmptyFixedArrayConstant());
for (int i = 0; i < initial_map.GetInObjectProperties(); ++i) { for (int i = 0; i < slack_tracking_result.inobject_property_count; ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i), a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
jsgraph()->UndefinedConstant()); jsgraph()->UndefinedConstant());
} }
...@@ -418,6 +418,7 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) { ...@@ -418,6 +418,7 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
} }
Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) { Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
DisallowHeapAccess no_heap_access;
DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode()); DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
Node* const closure = NodeProperties::GetValueInput(node, 0); Node* const closure = NodeProperties::GetValueInput(node, 0);
Node* const receiver = NodeProperties::GetValueInput(node, 1); Node* const receiver = NodeProperties::GetValueInput(node, 1);
...@@ -426,29 +427,29 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) { ...@@ -426,29 +427,29 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node); Node* effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node); Node* const control = NodeProperties::GetControlInput(node);
if (closure_type.IsHeapConstant()) { if (closure_type.IsHeapConstant()) {
DCHECK(closure_type.AsHeapConstant()->Value()->IsJSFunction()); DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
Handle<JSFunction> js_function = JSFunctionRef js_function =
Handle<JSFunction>::cast(closure_type.AsHeapConstant()->Value()); closure_type.AsHeapConstant()->Ref().AsJSFunction();
JSFunction::EnsureHasInitialMap(js_function); js_function.EnsureHasInitialMap();
// Force completion of inobject slack tracking before // Force completion of inobject slack tracking before
// generating code to finalize the instance size. // generating code to finalize the instance size.
js_function->CompleteInobjectSlackTrackingIfActive(); SlackTrackingResult slack_tracking_result =
js_function.FinishSlackTracking();
// Add a dependency on the {initial_map} to make sure that this code is // Add a dependency on the {initial_map} to make sure that this code is
// deoptimized whenever the {initial_map} changes. // deoptimized whenever the {initial_map} changes.
Handle<Map> initial_map = dependencies()->DependOnInitialMap(js_function); MapRef initial_map(
DCHECK(initial_map->instance_type() == JS_GENERATOR_OBJECT_TYPE || js_function.DependOnInitialMap(js_heap_broker(), dependencies()));
initial_map->instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE); DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
// Allocate a register file. // Allocate a register file.
DCHECK(js_function->shared()->HasBytecodeArray()); SharedFunctionInfoRef shared(js_function.shared(js_heap_broker()));
Handle<BytecodeArray> bytecode_array( DCHECK(shared.HasBytecodeArray());
js_function->shared()->GetBytecodeArray(), isolate()); int parameter_count_no_receiver = shared.internal_formal_parameter_count();
int parameter_count_no_receiver = bytecode_array->parameter_count() - 1; int size =
DCHECK_EQ(parameter_count_no_receiver, parameter_count_no_receiver + shared.GetBytecodeArrayRegisterCount();
js_function->shared()->internal_formal_parameter_count());
int size = parameter_count_no_receiver + bytecode_array->register_count();
AllocationBuilder ab(jsgraph(), js_heap_broker(), effect, control); AllocationBuilder ab(jsgraph(), js_heap_broker(), effect, control);
ab.AllocateArray(size, factory()->fixed_array_map()); ab.AllocateArray(size, factory()->fixed_array_map());
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
...@@ -459,7 +460,7 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) { ...@@ -459,7 +460,7 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
// Emit code to allocate the JS[Async]GeneratorObject instance. // Emit code to allocate the JS[Async]GeneratorObject instance.
AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control); AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control);
a.Allocate(initial_map->instance_size()); a.Allocate(slack_tracking_result.instance_size);
Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant(); Node* empty_fixed_array = jsgraph()->EmptyFixedArrayConstant();
Node* undefined = jsgraph()->UndefinedConstant(); Node* undefined = jsgraph()->UndefinedConstant();
a.Store(AccessBuilder::ForMap(), initial_map); a.Store(AccessBuilder::ForMap(), initial_map);
...@@ -476,17 +477,16 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) { ...@@ -476,17 +477,16 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(), a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
parameters_and_registers); parameters_and_registers);
if (initial_map->instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE) { if (initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE) {
a.Store(AccessBuilder::ForJSAsyncGeneratorObjectQueue(), undefined); a.Store(AccessBuilder::ForJSAsyncGeneratorObjectQueue(), undefined);
a.Store(AccessBuilder::ForJSAsyncGeneratorObjectIsAwaiting(), a.Store(AccessBuilder::ForJSAsyncGeneratorObjectIsAwaiting(),
jsgraph()->ZeroConstant()); jsgraph()->ZeroConstant());
} }
// Handle in-object properties, too. // Handle in-object properties, too.
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) { for (int i = 0; i < slack_tracking_result.inobject_property_count; ++i) {
a.Store( a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i), undefined);
undefined);
} }
a.FinishAndChange(node); a.FinishAndChange(node);
return Changed(node); return Changed(node);
......
...@@ -165,6 +165,16 @@ MapRef JSFunctionRef::DependOnInitialMap( ...@@ -165,6 +165,16 @@ MapRef JSFunctionRef::DependOnInitialMap(
return MapRef(initial_map); return MapRef(initial_map);
} }
void JSFunctionRef::EnsureHasInitialMap() const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference;
AllowHeapAllocation heap_allocation;
// TODO(jarin) Eventually, we will prepare initial maps for resumable
// functions (i.e., generators).
DCHECK(IsResumableFunction(object<JSFunction>()->shared()->kind()));
JSFunction::EnsureHasInitialMap(object<JSFunction>());
}
void MapRef::DependOnStableMap(const JSHeapBroker* broker, void MapRef::DependOnStableMap(const JSHeapBroker* broker,
CompilationDependencies* dependencies) const { CompilationDependencies* dependencies) const {
AllowHandleAllocation handle_allocation; AllowHandleAllocation handle_allocation;
...@@ -172,11 +182,14 @@ void MapRef::DependOnStableMap(const JSHeapBroker* broker, ...@@ -172,11 +182,14 @@ void MapRef::DependOnStableMap(const JSHeapBroker* broker,
dependencies->DependOnStableMap(object<Map>()); dependencies->DependOnStableMap(object<Map>());
} }
int JSFunctionRef::GetInstanceSizeWithFinishedSlackTracking() const { SlackTrackingResult JSFunctionRef::FinishSlackTracking() const {
AllowHandleAllocation handle_allocation;
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
AllowHandleAllocation handle_allocation;
object<JSFunction>()->CompleteInobjectSlackTrackingIfActive(); object<JSFunction>()->CompleteInobjectSlackTrackingIfActive();
return object<JSFunction>()->initial_map()->instance_size(); int instance_size = object<JSFunction>()->initial_map()->instance_size();
int inobject_property_count =
object<JSFunction>()->initial_map()->GetInObjectProperties();
return SlackTrackingResult(instance_size, inobject_property_count);
} }
bool JSFunctionRef::has_initial_map() const { bool JSFunctionRef::has_initial_map() const {
...@@ -622,6 +635,16 @@ bool SharedFunctionInfoRef::construct_as_builtin() const { ...@@ -622,6 +635,16 @@ bool SharedFunctionInfoRef::construct_as_builtin() const {
return object<SharedFunctionInfo>()->construct_as_builtin(); return object<SharedFunctionInfo>()->construct_as_builtin();
} }
bool SharedFunctionInfoRef::HasBytecodeArray() const {
AllowHandleDereference allow_handle_dereference;
return object<SharedFunctionInfo>()->HasBytecodeArray();
}
int SharedFunctionInfoRef::GetBytecodeArrayRegisterCount() const {
AllowHandleDereference allow_handle_dereference;
return object<SharedFunctionInfo>()->GetBytecodeArray()->register_count();
}
MapRef NativeContextRef::fast_aliased_arguments_map( MapRef NativeContextRef::fast_aliased_arguments_map(
const JSHeapBroker* broker) const { const JSHeapBroker* broker) const {
AllowHandleAllocation handle_allocation; AllowHandleAllocation handle_allocation;
......
...@@ -150,6 +150,14 @@ class JSObjectRef : public HeapObjectRef { ...@@ -150,6 +150,14 @@ class JSObjectRef : public HeapObjectRef {
void EnsureElementsTenured(const JSHeapBroker* broker); void EnsureElementsTenured(const JSHeapBroker* broker);
}; };
struct SlackTrackingResult {
SlackTrackingResult(int instance_sizex, int inobject_property_countx)
: instance_size(instance_sizex),
inobject_property_count(inobject_property_countx) {}
int instance_size;
int inobject_property_count;
};
class JSFunctionRef : public JSObjectRef { class JSFunctionRef : public JSObjectRef {
public: public:
using JSObjectRef::JSObjectRef; using JSObjectRef::JSObjectRef;
...@@ -162,9 +170,12 @@ class JSFunctionRef : public JSObjectRef { ...@@ -162,9 +170,12 @@ class JSFunctionRef : public JSObjectRef {
MapRef DependOnInitialMap(const JSHeapBroker* broker, MapRef DependOnInitialMap(const JSHeapBroker* broker,
CompilationDependencies* dependencies) const; CompilationDependencies* dependencies) const;
int GetInstanceSizeWithFinishedSlackTracking() const;
SharedFunctionInfoRef shared(const JSHeapBroker* broker) const;
JSGlobalProxyRef global_proxy(const JSHeapBroker* broker) const; JSGlobalProxyRef global_proxy(const JSHeapBroker* broker) const;
SlackTrackingResult FinishSlackTracking() const;
SharedFunctionInfoRef shared(const JSHeapBroker* broker) const;
void EnsureHasInitialMap() const;
}; };
class JSRegExpRef : public JSObjectRef { class JSRegExpRef : public JSObjectRef {
...@@ -333,6 +344,8 @@ class SharedFunctionInfoRef : public HeapObjectRef { ...@@ -333,6 +344,8 @@ class SharedFunctionInfoRef : public HeapObjectRef {
bool HasBuiltinId() const; bool HasBuiltinId() const;
int builtin_id() const; int builtin_id() const;
bool construct_as_builtin() const; bool construct_as_builtin() const;
bool HasBytecodeArray() const;
int GetBytecodeArrayRegisterCount() const;
}; };
class StringRef : public NameRef { class StringRef : public NameRef {
......
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