[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/+/2821706 Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Anton Bikineev <bikineev@chromium.org> Commit-Queue: Camillo Bruni <cbruni@chromium.org> Cr-Commit-Position: refs/heads/master@{#74088}
This commit is contained in:
parent
ba6ba5cd84
commit
7c554080d9
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user