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) {
// Force completion of inobject slack tracking before
// generating code to finalize the instance size.
int const instance_size =
original_constructor.GetInstanceSizeWithFinishedSlackTracking();
SlackTrackingResult slack_tracking_result =
original_constructor.FinishSlackTracking();
// Emit code to allocate the JSObject instance for the
// {original_constructor}.
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::ForJSObjectPropertiesOrHash(),
jsgraph()->EmptyFixedArrayConstant());
a.Store(AccessBuilder::ForJSObjectElements(),
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),
jsgraph()->UndefinedConstant());
}
......@@ -418,6 +418,7 @@ Reduction JSCreateLowering::ReduceJSCreateArguments(Node* node) {
}
Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
DisallowHeapAccess no_heap_access;
DCHECK_EQ(IrOpcode::kJSCreateGeneratorObject, node->opcode());
Node* const closure = NodeProperties::GetValueInput(node, 0);
Node* const receiver = NodeProperties::GetValueInput(node, 1);
......@@ -426,29 +427,29 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
Node* effect = NodeProperties::GetEffectInput(node);
Node* const control = NodeProperties::GetControlInput(node);
if (closure_type.IsHeapConstant()) {
DCHECK(closure_type.AsHeapConstant()->Value()->IsJSFunction());
Handle<JSFunction> js_function =
Handle<JSFunction>::cast(closure_type.AsHeapConstant()->Value());
JSFunction::EnsureHasInitialMap(js_function);
DCHECK(closure_type.AsHeapConstant()->Ref().IsJSFunction());
JSFunctionRef js_function =
closure_type.AsHeapConstant()->Ref().AsJSFunction();
js_function.EnsureHasInitialMap();
// Force completion of inobject slack tracking before
// 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
// deoptimized whenever the {initial_map} changes.
Handle<Map> initial_map = dependencies()->DependOnInitialMap(js_function);
DCHECK(initial_map->instance_type() == JS_GENERATOR_OBJECT_TYPE ||
initial_map->instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
MapRef initial_map(
js_function.DependOnInitialMap(js_heap_broker(), dependencies()));
DCHECK(initial_map.instance_type() == JS_GENERATOR_OBJECT_TYPE ||
initial_map.instance_type() == JS_ASYNC_GENERATOR_OBJECT_TYPE);
// Allocate a register file.
DCHECK(js_function->shared()->HasBytecodeArray());
Handle<BytecodeArray> bytecode_array(
js_function->shared()->GetBytecodeArray(), isolate());
int parameter_count_no_receiver = bytecode_array->parameter_count() - 1;
DCHECK_EQ(parameter_count_no_receiver,
js_function->shared()->internal_formal_parameter_count());
int size = parameter_count_no_receiver + bytecode_array->register_count();
SharedFunctionInfoRef shared(js_function.shared(js_heap_broker()));
DCHECK(shared.HasBytecodeArray());
int parameter_count_no_receiver = shared.internal_formal_parameter_count();
int size =
parameter_count_no_receiver + shared.GetBytecodeArrayRegisterCount();
AllocationBuilder ab(jsgraph(), js_heap_broker(), effect, control);
ab.AllocateArray(size, factory()->fixed_array_map());
for (int i = 0; i < size; ++i) {
......@@ -459,7 +460,7 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
// Emit code to allocate the JS[Async]GeneratorObject instance.
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* undefined = jsgraph()->UndefinedConstant();
a.Store(AccessBuilder::ForMap(), initial_map);
......@@ -476,17 +477,16 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
a.Store(AccessBuilder::ForJSGeneratorObjectParametersAndRegisters(),
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::ForJSAsyncGeneratorObjectIsAwaiting(),
jsgraph()->ZeroConstant());
}
// Handle in-object properties, too.
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
a.Store(
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
undefined);
for (int i = 0; i < slack_tracking_result.inobject_property_count; ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
undefined);
}
a.FinishAndChange(node);
return Changed(node);
......
......@@ -165,6 +165,16 @@ MapRef JSFunctionRef::DependOnInitialMap(
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,
CompilationDependencies* dependencies) const {
AllowHandleAllocation handle_allocation;
......@@ -172,11 +182,14 @@ void MapRef::DependOnStableMap(const JSHeapBroker* broker,
dependencies->DependOnStableMap(object<Map>());
}
int JSFunctionRef::GetInstanceSizeWithFinishedSlackTracking() const {
AllowHandleAllocation handle_allocation;
SlackTrackingResult JSFunctionRef::FinishSlackTracking() const {
AllowHandleDereference allow_handle_dereference;
AllowHandleAllocation handle_allocation;
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 {
......@@ -622,6 +635,16 @@ bool SharedFunctionInfoRef::construct_as_builtin() const {
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(
const JSHeapBroker* broker) const {
AllowHandleAllocation handle_allocation;
......
......@@ -150,6 +150,14 @@ class JSObjectRef : public HeapObjectRef {
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 {
public:
using JSObjectRef::JSObjectRef;
......@@ -162,9 +170,12 @@ class JSFunctionRef : public JSObjectRef {
MapRef DependOnInitialMap(const JSHeapBroker* broker,
CompilationDependencies* dependencies) const;
int GetInstanceSizeWithFinishedSlackTracking() const;
SharedFunctionInfoRef shared(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 {
......@@ -333,6 +344,8 @@ class SharedFunctionInfoRef : public HeapObjectRef {
bool HasBuiltinId() const;
int builtin_id() const;
bool construct_as_builtin() const;
bool HasBytecodeArray() const;
int GetBytecodeArrayRegisterCount() const;
};
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