Commit 7c554080 authored by Camillo Bruni's avatar Camillo Bruni Committed by Commit Bot

[factory] Make FactoryBase::NewStructInternal inlineable

Move NewStructInternal to header and templatize it to unroll
initialisation loop.

Bug: v8:11263
Change-Id: Iaaf2929c9a17b9195177b6afa7087b9b4ed6f0b4
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2821706Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarAnton Bikineev <bikineev@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/master@{#74088}
parent ba6ba5cd
......@@ -6,9 +6,10 @@
#define V8_HEAP_FACTORY_BASE_INL_H_
#include "src/heap/factory-base.h"
#include "src/numbers/conversions.h"
#include "src/objects/heap-number.h"
#include "src/objects/map.h"
#include "src/objects/slots-inl.h"
#include "src/objects/smi.h"
#include "src/roots/roots.h"
......@@ -93,6 +94,29 @@ Handle<HeapNumber> FactoryBase<Impl>::NewHeapNumberWithHoleNaN() {
return NewHeapNumberFromBits<allocation>(kHoleNanInt64);
}
template <typename Impl>
template <typename StructType>
StructType FactoryBase<Impl>::NewStructInternal(InstanceType type,
AllocationType allocation) {
ReadOnlyRoots roots = read_only_roots();
Map map = Map::GetInstanceTypeMap(roots, type);
int size = StructType::kSize;
return StructType::cast(NewStructInternal(roots, map, size, allocation));
}
template <typename Impl>
Struct FactoryBase<Impl>::NewStructInternal(ReadOnlyRoots roots, Map map,
int size,
AllocationType allocation) {
DCHECK_EQ(size, map.instance_size());
HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
Struct str = Struct::cast(result);
Object value = roots.undefined_value();
int length = (size >> kTaggedSizeLog2) - 1;
MemsetTagged(str.RawField(Struct::kHeaderSize), value, length);
return str;
}
} // namespace internal
} // namespace v8
......
......@@ -53,29 +53,20 @@ FactoryBase<LocalFactory>::NewHeapNumber<AllocationType::kOld>();
template <typename Impl>
Handle<Struct> FactoryBase<Impl>::NewStruct(InstanceType type,
AllocationType allocation) {
return handle(NewStructInternal(type, allocation), isolate());
}
template <typename Impl>
Struct FactoryBase<Impl>::NewStructInternal(InstanceType type,
AllocationType allocation) {
Map map = Map::GetInstanceTypeMap(read_only_roots(), type);
ReadOnlyRoots roots = read_only_roots();
Map map = Map::GetInstanceTypeMap(roots, type);
int size = map.instance_size();
HeapObject result = AllocateRawWithImmortalMap(size, allocation, map);
Struct str = Struct::cast(result);
str.InitializeBody(size);
return str;
return handle(NewStructInternal(roots, map, size, allocation), isolate());
}
template <typename Impl>
Handle<AccessorPair> FactoryBase<Impl>::NewAccessorPair() {
Handle<AccessorPair> accessors = Handle<AccessorPair>::cast(
NewStruct(ACCESSOR_PAIR_TYPE, AllocationType::kOld));
AccessorPair raw = *accessors;
auto accessors =
NewStructInternal<AccessorPair>(ACCESSOR_PAIR_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
raw.set_getter(read_only_roots().null_value(), SKIP_WRITE_BARRIER);
raw.set_setter(read_only_roots().null_value(), SKIP_WRITE_BARRIER);
return accessors;
accessors.set_getter(read_only_roots().null_value(), SKIP_WRITE_BARRIER);
accessors.set_setter(read_only_roots().null_value(), SKIP_WRITE_BARRIER);
return handle(accessors, isolate());
}
template <typename Impl>
......@@ -233,8 +224,8 @@ Handle<Script> FactoryBase<Impl>::NewScriptWithId(
DCHECK(source->IsString() || source->IsUndefined());
// Create and initialize script object.
ReadOnlyRoots roots = read_only_roots();
Handle<Script> script =
Handle<Script>::cast(NewStruct(SCRIPT_TYPE, AllocationType::kOld));
Handle<Script> script = handle(
NewStructInternal<Script>(SCRIPT_TYPE, AllocationType::kOld), isolate());
{
DisallowGarbageCollection no_gc;
Script raw = *script;
......@@ -397,14 +388,12 @@ template <typename Impl>
Handle<ArrayBoilerplateDescription>
FactoryBase<Impl>::NewArrayBoilerplateDescription(
ElementsKind elements_kind, Handle<FixedArrayBase> constant_values) {
Handle<ArrayBoilerplateDescription> result =
Handle<ArrayBoilerplateDescription>::cast(
NewStruct(ARRAY_BOILERPLATE_DESCRIPTION_TYPE, AllocationType::kOld));
auto result = NewStructInternal<ArrayBoilerplateDescription>(
ARRAY_BOILERPLATE_DESCRIPTION_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
ArrayBoilerplateDescription raw = *result;
raw.set_elements_kind(elements_kind);
raw.set_constant_elements(*constant_values);
return result;
result.set_elements_kind(elements_kind);
result.set_constant_elements(*constant_values);
return handle(result, isolate());
}
template <typename Impl>
......@@ -412,15 +401,13 @@ Handle<RegExpBoilerplateDescription>
FactoryBase<Impl>::NewRegExpBoilerplateDescription(Handle<FixedArray> data,
Handle<String> source,
Smi flags) {
Handle<RegExpBoilerplateDescription> result =
Handle<RegExpBoilerplateDescription>::cast(NewStruct(
REG_EXP_BOILERPLATE_DESCRIPTION_TYPE, AllocationType::kOld));
auto result = NewStructInternal<RegExpBoilerplateDescription>(
REG_EXP_BOILERPLATE_DESCRIPTION_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
RegExpBoilerplateDescription raw = *result;
raw.set_data(*data);
raw.set_source(*source);
raw.set_flags(flags.value());
return result;
result.set_data(*data);
result.set_source(*source);
result.set_flags(flags.value());
return handle(result, isolate());
}
template <typename Impl>
......@@ -429,14 +416,12 @@ FactoryBase<Impl>::NewTemplateObjectDescription(
Handle<FixedArray> raw_strings, Handle<FixedArray> cooked_strings) {
DCHECK_EQ(raw_strings->length(), cooked_strings->length());
DCHECK_LT(0, raw_strings->length());
Handle<TemplateObjectDescription> result =
Handle<TemplateObjectDescription>::cast(
NewStruct(TEMPLATE_OBJECT_DESCRIPTION_TYPE, AllocationType::kOld));
auto result = NewStructInternal<TemplateObjectDescription>(
TEMPLATE_OBJECT_DESCRIPTION_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
TemplateObjectDescription raw = *result;
raw.set_raw_strings(*raw_strings);
raw.set_cooked_strings(*cooked_strings);
return result;
result.set_raw_strings(*raw_strings);
result.set_cooked_strings(*cooked_strings);
return handle(result, isolate());
}
template <typename Impl>
......@@ -764,11 +749,11 @@ Handle<DescriptorArray> FactoryBase<Impl>::NewDescriptorArray(
template <typename Impl>
Handle<ClassPositions> FactoryBase<Impl>::NewClassPositions(int start,
int end) {
Handle<ClassPositions> class_positions = Handle<ClassPositions>::cast(
NewStruct(CLASS_POSITIONS_TYPE, AllocationType::kOld));
class_positions->set_start(start);
class_positions->set_end(end);
return class_positions;
auto result = NewStructInternal<ClassPositions>(CLASS_POSITIONS_TYPE,
AllocationType::kOld);
result.set_start(start);
result.set_end(end);
return handle(result, isolate());
}
template <typename Impl>
......
......@@ -234,8 +234,11 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) FactoryBase
HeapObject AllocateRawFixedArray(int length, AllocationType allocation);
HeapObject AllocateRawWeakArrayList(int length, AllocationType allocation);
Struct NewStructInternal(InstanceType type,
AllocationType allocation = AllocationType::kYoung);
template <typename StructType>
inline StructType NewStructInternal(InstanceType type,
AllocationType allocation);
Struct NewStructInternal(ReadOnlyRoots roots, Map map, int size,
AllocationType allocation);
HeapObject AllocateRawWithImmortalMap(
int size, AllocationType allocation, Map map,
......
......@@ -315,8 +315,8 @@ Handle<HeapObject> Factory::NewFillerObject(int size, bool double_align,
}
Handle<PrototypeInfo> Factory::NewPrototypeInfo() {
PrototypeInfo result = PrototypeInfo::cast(
NewStructInternal(PROTOTYPE_INFO_TYPE, AllocationType::kOld));
auto result = NewStructInternal<PrototypeInfo>(PROTOTYPE_INFO_TYPE,
AllocationType::kOld);
DisallowGarbageCollection no_gc;
result.set_prototype_users(Smi::zero());
result.set_registry_slot(PrototypeInfo::UNREGISTERED);
......@@ -327,8 +327,8 @@ Handle<PrototypeInfo> Factory::NewPrototypeInfo() {
Handle<EnumCache> Factory::NewEnumCache(Handle<FixedArray> keys,
Handle<FixedArray> indices) {
EnumCache result =
EnumCache::cast(NewStructInternal(ENUM_CACHE_TYPE, AllocationType::kOld));
auto result =
NewStructInternal<EnumCache>(ENUM_CACHE_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
result.set_keys(*keys);
result.set_indices(*indices);
......@@ -337,7 +337,7 @@ Handle<EnumCache> Factory::NewEnumCache(Handle<FixedArray> keys,
Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1, Handle<Object> value2,
AllocationType allocation) {
Tuple2 result = Tuple2::cast(NewStructInternal(TUPLE2_TYPE, allocation));
auto result = NewStructInternal<Tuple2>(TUPLE2_TYPE, allocation);
DisallowGarbageCollection no_gc;
result.set_value1(*value1);
result.set_value2(*value2);
......@@ -346,8 +346,8 @@ Handle<Tuple2> Factory::NewTuple2(Handle<Object> value1, Handle<Object> value2,
Handle<BaselineData> Factory::NewBaselineData(
Handle<Code> code, Handle<HeapObject> function_data) {
BaselineData baseline_data = BaselineData::cast(
NewStructInternal(BASELINE_DATA_TYPE, AllocationType::kOld));
auto baseline_data =
NewStructInternal<BaselineData>(BASELINE_DATA_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
baseline_data.set_baseline_code(*code);
baseline_data.set_data(*function_data);
......@@ -559,9 +559,8 @@ Handle<NameDictionary> Factory::NewNameDictionary(int at_least_space_for) {
}
Handle<PropertyDescriptorObject> Factory::NewPropertyDescriptorObject() {
PropertyDescriptorObject object =
PropertyDescriptorObject::cast(NewStructInternal(
PROPERTY_DESCRIPTOR_OBJECT_TYPE, AllocationType::kYoung));
auto object = NewStructInternal<PropertyDescriptorObject>(
PROPERTY_DESCRIPTOR_OBJECT_TYPE, AllocationType::kYoung);
DisallowGarbageCollection no_gc;
object.set_flags(0);
Oddball the_hole = read_only_roots().the_hole_value();
......@@ -1267,15 +1266,15 @@ Handle<Context> Factory::NewBuiltinContext(Handle<NativeContext> native_context,
Handle<AliasedArgumentsEntry> Factory::NewAliasedArgumentsEntry(
int aliased_context_slot) {
AliasedArgumentsEntry entry = AliasedArgumentsEntry::cast(
NewStructInternal(ALIASED_ARGUMENTS_ENTRY_TYPE, AllocationType::kYoung));
auto entry = NewStructInternal<AliasedArgumentsEntry>(
ALIASED_ARGUMENTS_ENTRY_TYPE, AllocationType::kYoung);
entry.set_aliased_context_slot(aliased_context_slot);
return handle(entry, isolate());
}
Handle<AccessorInfo> Factory::NewAccessorInfo() {
AccessorInfo info = AccessorInfo::cast(
NewStructInternal(ACCESSOR_INFO_TYPE, AllocationType::kOld));
auto info =
NewStructInternal<AccessorInfo>(ACCESSOR_INFO_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
info.set_name(*empty_string(), SKIP_WRITE_BARRIER);
info.set_flags(0); // Must clear the flags, it was initialized as undefined.
......@@ -1332,8 +1331,8 @@ Handle<Script> Factory::CloneScript(Handle<Script> script) {
Handle<CallableTask> Factory::NewCallableTask(Handle<JSReceiver> callable,
Handle<Context> context) {
DCHECK(callable->IsCallable());
CallableTask microtask = CallableTask::cast(
NewStructInternal(CALLABLE_TASK_TYPE, AllocationType::kYoung));
auto microtask = NewStructInternal<CallableTask>(CALLABLE_TASK_TYPE,
AllocationType::kYoung);
DisallowGarbageCollection no_gc;
microtask.set_callable(*callable, SKIP_WRITE_BARRIER);
microtask.set_context(*context, SKIP_WRITE_BARRIER);
......@@ -1342,8 +1341,8 @@ Handle<CallableTask> Factory::NewCallableTask(Handle<JSReceiver> callable,
Handle<CallbackTask> Factory::NewCallbackTask(Handle<Foreign> callback,
Handle<Foreign> data) {
CallbackTask microtask = CallbackTask::cast(
NewStructInternal(CALLBACK_TASK_TYPE, AllocationType::kYoung));
auto microtask = NewStructInternal<CallbackTask>(CALLBACK_TASK_TYPE,
AllocationType::kYoung);
DisallowGarbageCollection no_gc;
microtask.set_callback(*callback, SKIP_WRITE_BARRIER);
microtask.set_data(*data, SKIP_WRITE_BARRIER);
......@@ -1354,9 +1353,8 @@ Handle<PromiseResolveThenableJobTask> Factory::NewPromiseResolveThenableJobTask(
Handle<JSPromise> promise_to_resolve, Handle<JSReceiver> thenable,
Handle<JSReceiver> then, Handle<Context> context) {
DCHECK(then->IsCallable());
PromiseResolveThenableJobTask microtask =
PromiseResolveThenableJobTask::cast(NewStructInternal(
PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, AllocationType::kYoung));
auto microtask = NewStructInternal<PromiseResolveThenableJobTask>(
PROMISE_RESOLVE_THENABLE_JOB_TASK_TYPE, AllocationType::kYoung);
DisallowGarbageCollection no_gc;
microtask.set_promise_to_resolve(*promise_to_resolve, SKIP_WRITE_BARRIER);
microtask.set_thenable(*thenable, SKIP_WRITE_BARRIER);
......@@ -3018,8 +3016,8 @@ Handle<String> Factory::SizeToString(size_t value, bool check_cache) {
Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
DCHECK(!shared->HasDebugInfo());
DebugInfo debug_info =
DebugInfo::cast(NewStructInternal(DEBUG_INFO_TYPE, AllocationType::kOld));
auto debug_info =
NewStructInternal<DebugInfo>(DEBUG_INFO_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
SharedFunctionInfo raw_shared = *shared;
debug_info.set_flags(DebugInfo::kNone);
......@@ -3041,8 +3039,8 @@ Handle<DebugInfo> Factory::NewDebugInfo(Handle<SharedFunctionInfo> shared) {
}
Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
BreakPointInfo new_break_point_info = BreakPointInfo::cast(
NewStructInternal(BREAK_POINT_INFO_TYPE, AllocationType::kOld));
auto new_break_point_info = NewStructInternal<BreakPointInfo>(
BREAK_POINT_INFO_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
new_break_point_info.set_source_position(source_position);
new_break_point_info.set_break_points(*undefined_value(), SKIP_WRITE_BARRIER);
......@@ -3050,8 +3048,8 @@ Handle<BreakPointInfo> Factory::NewBreakPointInfo(int source_position) {
}
Handle<BreakPoint> Factory::NewBreakPoint(int id, Handle<String> condition) {
BreakPoint new_break_point = BreakPoint::cast(
NewStructInternal(BREAK_POINT_TYPE, AllocationType::kOld));
auto new_break_point =
NewStructInternal<BreakPoint>(BREAK_POINT_TYPE, AllocationType::kOld);
DisallowGarbageCollection no_gc;
new_break_point.set_id(id);
new_break_point.set_condition(*condition);
......@@ -3062,8 +3060,8 @@ Handle<StackFrameInfo> Factory::NewStackFrameInfo(
Handle<Object> receiver_or_instance, Handle<Object> function,
Handle<HeapObject> code_object, int code_offset_or_source_position,
int flags, Handle<FixedArray> parameters) {
StackFrameInfo info = StackFrameInfo::cast(
NewStructInternal(STACK_FRAME_INFO_TYPE, AllocationType::kYoung));
auto info = NewStructInternal<StackFrameInfo>(STACK_FRAME_INFO_TYPE,
AllocationType::kYoung);
DisallowGarbageCollection no_gc;
info.set_receiver_or_instance(*receiver_or_instance, SKIP_WRITE_BARRIER);
info.set_function(*function, SKIP_WRITE_BARRIER);
......
......@@ -28,13 +28,6 @@ NEVER_READ_ONLY_SPACE_IMPL(AccessorPair)
TQ_OBJECT_CONSTRUCTORS_IMPL(ClassPositions)
void Struct::InitializeBody(int object_size) {
Object value = GetReadOnlyRoots().undefined_value();
for (int offset = kHeaderSize; offset < object_size; offset += kTaggedSize) {
WRITE_FIELD(*this, offset, value);
}
}
Object AccessorPair::get(AccessorComponent component) {
return component == ACCESSOR_GETTER ? getter() : setter();
}
......
......@@ -21,7 +21,6 @@ namespace internal {
// identified in the type system.
class Struct : public TorqueGeneratedStruct<Struct, HeapObject> {
public:
inline void InitializeBody(int object_size);
void BriefPrintDetails(std::ostream& os);
STATIC_ASSERT(kHeaderSize == HeapObject::kHeaderSize);
......
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