[turbofan] Brokerize closure creation.

Bug: v8:7790
Change-Id: Iff4f0561901c454fc3facfeb152727d3994b4f98
Reviewed-on: https://chromium-review.googlesource.com/1127947
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: Georg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#54304}
This commit is contained in:
Jaroslav Sevcik 2018-07-06 22:46:41 +02:00 committed by Commit Bot
parent 16de08ea72
commit 289729bb6d
6 changed files with 67 additions and 30 deletions

View File

@ -85,9 +85,9 @@ FieldAccess AccessBuilder::ForJSObjectElements() {
// static
FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map,
FieldAccess AccessBuilder::ForJSObjectInObjectProperty(const MapRef& map,
int index) {
int const offset = map->GetInObjectPropertyOffset(index);
int const offset = map.GetInObjectPropertyOffset(index);
FieldAccess access = {kTaggedBase, offset,
MaybeHandle<Name>(), MaybeHandle<Map>(),
Type::NonInternal(), MachineType::AnyTagged(),

View File

@ -48,7 +48,7 @@ class V8_EXPORT_PRIVATE AccessBuilder final
static FieldAccess ForJSObjectElements();
// Provides access to JSObject inobject property fields.
static FieldAccess ForJSObjectInObjectProperty(Handle<Map> map, int index);
static FieldAccess ForJSObjectInObjectProperty(const MapRef& map, int index);
static FieldAccess ForJSObjectOffset(
int offset, WriteBarrierKind write_barrier_kind = kFullWriteBarrier);

View File

@ -1739,8 +1739,9 @@ Reduction JSCallReducer::ReduceArrayFilter(Node* node,
ab.Store(AccessBuilder::ForJSArrayLength(packed_kind),
jsgraph()->ZeroConstant());
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
ab.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
jsgraph()->UndefinedConstant());
ab.Store(
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
jsgraph()->UndefinedConstant());
}
a = effect = ab.Finish();
}

View File

@ -150,8 +150,9 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
a.Store(AccessBuilder::ForJSObjectElements(),
jsgraph()->EmptyFixedArrayConstant());
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
jsgraph()->UndefinedConstant());
a.Store(
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
jsgraph()->UndefinedConstant());
}
RelaxControls(node);
a.FinishAndChange(node);
@ -475,8 +476,9 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
// Handle in-object properties, too.
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
undefined);
a.Store(
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
undefined);
}
a.FinishAndChange(node);
return Changed(node);
@ -526,7 +528,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
a.Store(AccessBuilder::ForJSArrayLength(initial_map->elements_kind()),
length);
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
jsgraph()->UndefinedConstant());
}
RelaxControls(node);
@ -571,7 +573,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
a.Store(AccessBuilder::ForJSObjectElements(), elements);
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
jsgraph()->UndefinedConstant());
}
RelaxControls(node);
@ -627,7 +629,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node,
a.Store(AccessBuilder::ForJSObjectElements(), elements);
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
jsgraph()->UndefinedConstant());
}
RelaxControls(node);
@ -970,11 +972,12 @@ Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
}
Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
DisallowHandleDereference disallow_dereference;
DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
Handle<SharedFunctionInfo> shared = p.shared_info();
Handle<FeedbackCell> feedback_cell = p.feedback_cell();
Handle<Code> code = p.code();
SharedFunctionInfoRef shared(p.shared_info());
HeapObjectRef feedback_cell(p.feedback_cell());
HeapObjectRef code(p.code());
Node* effect = NodeProperties::GetEffectInput(node);
Node* control = NodeProperties::GetControlInput(node);
Node* context = NodeProperties::GetContextInput(node);
@ -982,18 +985,15 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
// Use inline allocation of closures only for instantiation sites that have
// seen more than one instantiation, this simplifies the generated code and
// also serves as a heuristic of which allocation sites benefit from it.
if (feedback_cell->map() !=
ReadOnlyRoots(isolate()).many_closures_cell_map()) {
// The generic path can only create closures for user functions.
DCHECK_EQ(isolate()->builtins()->builtin(Builtins::kCompileLazy), *code);
if (!feedback_cell.map(js_heap_broker())
.equals(MapRef(factory()->many_closures_cell_map()))) {
return NoChange();
}
Handle<Map> function_map(
Map::cast(native_context()->get(shared->function_map_index())),
isolate());
DCHECK(!function_map->IsInobjectSlackTrackingInProgress());
DCHECK(!function_map->is_dictionary_map());
MapRef function_map = native_context_ref().GetFunctionMapFromIndex(
js_heap_broker(), shared.function_map_index());
DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
DCHECK(!function_map.is_dictionary_map());
// TODO(turbofan): We should use the pretenure flag from {p} here,
// but currently the heuristic in the parser works against us, as
@ -1009,7 +1009,7 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
// Emit code to allocate the JSFunction instance.
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control);
a.Allocate(function_map->instance_size(), pretenure, Type::Function());
a.Allocate(function_map.instance_size(), pretenure, Type::Function());
a.Store(AccessBuilder::ForMap(), function_map);
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
jsgraph()->EmptyFixedArrayConstant());
@ -1020,12 +1020,12 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
a.Store(AccessBuilder::ForJSFunctionCode(), code);
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
if (function_map->has_prototype_slot()) {
if (function_map.has_prototype_slot()) {
a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
jsgraph()->TheHoleConstant());
STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kPointerSize);
}
for (int i = 0; i < function_map->GetInObjectProperties(); i++) {
for (int i = 0; i < function_map.GetInObjectProperties(); i++) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map, i),
jsgraph()->UndefinedConstant());
}
@ -1209,7 +1209,7 @@ Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
a.Store(AccessBuilder::ForJSObjectElements(), elements);
for (int i = 0; i < map->GetInObjectProperties(); i++) {
a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(map), i),
jsgraph()->UndefinedConstant());
}
@ -1712,8 +1712,8 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
int const boilerplate_length = boilerplate_map.GetInObjectProperties();
for (int index = static_cast<int>(inobject_fields.size());
index < boilerplate_length; ++index) {
FieldAccess access = AccessBuilder::ForJSObjectInObjectProperty(
boilerplate_map.object<Map>(), index);
FieldAccess access =
AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
inobject_fields.push_back(std::make_pair(access, value));
}

View File

@ -63,6 +63,10 @@ bool ObjectRef::IsSmi() const {
int ObjectRef::AsSmi() const { return object<Smi>()->value(); }
bool ObjectRef::equals(const ObjectRef& other) const {
return object<Object>().equals(other.object<Object>());
}
base::Optional<ContextRef> ContextRef::previous(
const JSHeapBroker* broker) const {
AllowHandleAllocation handle_allocation;
@ -411,6 +415,16 @@ bool MapRef::IsFixedCowArrayMap(const JSHeapBroker* broker) const {
ReadOnlyRoots(broker->isolate()).fixed_cow_array_map();
}
int MapRef::GetInObjectPropertyOffset(int index) const {
AllowHandleDereference allow_handle_dereference;
return object<Map>()->GetInObjectPropertyOffset(index);
}
bool MapRef::has_prototype_slot() const {
AllowHandleDereference allow_handle_dereference;
return object<Map>()->has_prototype_slot();
}
ElementsKind JSArrayRef::GetElementsKind() const {
AllowHandleDereference allow_handle_dereference;
return object<JSArray>()->GetElementsKind();
@ -483,6 +497,11 @@ int SharedFunctionInfoRef::internal_formal_parameter_count() const {
return object<SharedFunctionInfo>()->internal_formal_parameter_count();
}
int SharedFunctionInfoRef::function_map_index() const {
AllowHandleDereference allow_handle_dereference;
return object<SharedFunctionInfo>()->function_map_index();
}
bool SharedFunctionInfoRef::has_duplicate_parameters() const {
AllowHandleDereference allow_handle_dereference;
return object<SharedFunctionInfo>()->has_duplicate_parameters();
@ -558,6 +577,14 @@ MapRef NativeContextRef::map_key_value_iterator_map(
broker->isolate()));
}
MapRef NativeContextRef::GetFunctionMapFromIndex(const JSHeapBroker* broker,
int index) const {
AllowHandleDereference allow_handle_dereference;
DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX);
return get(broker, index).AsMap();
}
} // namespace compiler
} // namespace internal
} // namespace v8

View File

@ -100,6 +100,8 @@ class ObjectRef {
bool IsSmi() const;
int AsSmi() const;
bool equals(const ObjectRef& other) const;
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
HEAP_BROKER_KIND_LIST(HEAP_IS_METHOD_DECL)
#undef HEAP_IS_METHOD_DECL
@ -211,6 +213,8 @@ class NativeContextRef : public ContextRef {
MapRef map_key_iterator_map(const JSHeapBroker* broker) const;
MapRef map_value_iterator_map(const JSHeapBroker* broker) const;
MapRef map_key_value_iterator_map(const JSHeapBroker* broker) const;
MapRef GetFunctionMapFromIndex(const JSHeapBroker* broker, int index) const;
};
class NameRef : public HeapObjectRef {
@ -260,10 +264,14 @@ class MapRef : public HeapObjectRef {
NameRef GetPropertyKey(const JSHeapBroker* broker, int i) const;
FieldIndex GetFieldIndexFor(int i) const;
int GetInObjectPropertyOffset(int index) const;
bool IsJSArrayMap() const;
bool IsFixedCowArrayMap(const JSHeapBroker* broker) const;
bool is_dictionary_map() const;
bool has_prototype_slot() const;
bool IsInobjectSlackTrackingInProgress() const;
};
@ -315,6 +323,7 @@ class SharedFunctionInfoRef : public HeapObjectRef {
int internal_formal_parameter_count() const;
bool has_duplicate_parameters() const;
int function_map_index() const;
};
} // namespace compiler