[wasm-gc] Add WasmStruct object definition

Unused so far.

Bug: v8:7748
Change-Id: I8ee905614227c5517fa19088f76f947d2caadc3b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2152843
Commit-Queue: Jakob Kummerow <jkummerow@chromium.org>
Reviewed-by: Tobias Tebbi <tebbi@chromium.org>
Reviewed-by: Ulan Degenbaev <ulan@chromium.org>
Cr-Commit-Position: refs/heads/master@{#67273}
This commit is contained in:
Jakob Kummerow 2020-04-21 12:30:18 +02:00 committed by Commit Bot
parent 268e717643
commit 914204f6f7
15 changed files with 163 additions and 10 deletions

View File

@ -250,6 +250,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case WASM_INSTANCE_OBJECT_TYPE:
case WASM_MEMORY_OBJECT_TYPE:
case WASM_MODULE_OBJECT_TYPE:
case WASM_STRUCT_TYPE:
case WASM_TABLE_OBJECT_TYPE:
case WEAK_CELL_TYPE:
DCHECK(!map.is_callable());

View File

@ -1689,6 +1689,45 @@ void AsmWasmData::AsmWasmDataPrint(std::ostream& os) { // NOLINT
os << "\n";
}
void WasmStruct::WasmStructPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "WasmStruct");
wasm::StructType* struct_type = type();
os << "\n - fields (" << struct_type->field_count() << "):";
for (uint32_t i = 0; i < struct_type->field_count(); i++) {
wasm::ValueType field = struct_type->field(i);
os << "\n - " << field.short_name() << ": ";
uint32_t field_offset = struct_type->field_offset(i);
Address field_address = RawField(field_offset).address();
switch (field.kind()) {
case wasm::ValueType::kI32:
os << base::ReadUnalignedValue<int32_t>(field_address);
break;
case wasm::ValueType::kI64:
os << base::ReadUnalignedValue<int64_t>(field_address);
break;
case wasm::ValueType::kF32:
os << base::ReadUnalignedValue<float>(field_address);
break;
case wasm::ValueType::kF64:
os << base::ReadUnalignedValue<double>(field_address);
break;
case wasm::ValueType::kS128:
case wasm::ValueType::kAnyRef:
case wasm::ValueType::kFuncRef:
case wasm::ValueType::kNullRef:
case wasm::ValueType::kExnRef:
case wasm::ValueType::kRef:
case wasm::ValueType::kOptRef:
case wasm::ValueType::kEqRef:
case wasm::ValueType::kBottom:
case wasm::ValueType::kStmt:
UNIMPLEMENTED(); // TODO(7748): Implement.
break;
}
}
os << "\n";
}
void WasmDebugInfo::WasmDebugInfoPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "WasmDebugInfo");
os << "\n - wasm_instance: " << Brief(wasm_instance());

View File

@ -2439,6 +2439,13 @@ Handle<JSGeneratorObject> Factory::NewJSGeneratorObject(
return Handle<JSGeneratorObject>::cast(NewJSObjectFromMap(map));
}
Handle<WasmStruct> Factory::NewWasmStruct(Handle<Map> map) {
int size = map->instance_size();
HeapObject result = AllocateRaw(size, AllocationType::kYoung);
result.set_map_after_allocation(*map);
return handle(WasmStruct::cast(result), isolate());
}
Handle<SourceTextModule> Factory::NewSourceTextModule(
Handle<SharedFunctionInfo> code) {
Handle<SourceTextModuleInfo> module_info(

View File

@ -546,6 +546,8 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<JSModuleNamespace> NewJSModuleNamespace();
Handle<WasmStruct> NewWasmStruct(Handle<Map> map);
Handle<SourceTextModule> NewSourceTextModule(Handle<SharedFunctionInfo> code);
Handle<SyntheticModule> NewSyntheticModule(
Handle<String> module_name, Handle<FixedArray> export_names,

View File

@ -64,7 +64,8 @@ namespace internal {
V(UncompiledDataWithPreparseData) \
V(WasmCapiFunctionData) \
V(WasmIndirectFunctionTable) \
V(WasmInstanceObject)
V(WasmInstanceObject) \
V(WasmStruct)
#define FORWARD_DECLARE(TypeName) class TypeName;
TYPED_VISITOR_ID_LIST(FORWARD_DECLARE)

View File

@ -747,6 +747,9 @@ ACCESSORS_CHECKED2(Map, constructor_or_backpointer, Object,
ACCESSORS_CHECKED(Map, native_context, NativeContext,
kConstructorOrBackPointerOrNativeContextOffset,
IsContextMap())
ACCESSORS_CHECKED(Map, wasm_type_info, Foreign,
kConstructorOrBackPointerOrNativeContextOffset,
IsWasmStructMap())
bool Map::IsPrototypeValidityCellValid() const {
Object validity_cell = prototype_validity_cell();

View File

@ -367,6 +367,9 @@ VisitorId Map::GetVisitorId(Map map) {
case SYNTHETIC_MODULE_TYPE:
return kVisitSyntheticModule;
case WASM_STRUCT_TYPE:
return kVisitWasmStruct; // TODO(7748): Other Wasm object types.
#define MAKE_TQ_CASE(TYPE, Name) \
case TYPE: \
return kVisit##Name;

View File

@ -81,6 +81,7 @@ enum InstanceType : uint16_t;
V(WasmCapiFunctionData) \
V(WasmIndirectFunctionTable) \
V(WasmInstanceObject) \
V(WasmStruct) \
V(WeakArray) \
V(WeakCell)
@ -573,9 +574,11 @@ class Map : public HeapObject {
// back pointer chain until they find the map holding their constructor.
// Returns null_value if there's neither a constructor function nor a
// FunctionTemplateInfo available.
// The field also overlaps with the native context pointer for context maps.
// The field also overlaps with the native context pointer for context maps,
// and with the Wasm type info for WebAssembly object maps.
DECL_ACCESSORS(constructor_or_backpointer, Object)
DECL_ACCESSORS(native_context, NativeContext)
DECL_ACCESSORS(wasm_type_info, Foreign)
DECL_GETTER(GetConstructor, Object)
DECL_GETTER(GetFunctionTemplateInfo, FunctionTemplateInfo)
inline void SetConstructor(Object constructor,

View File

@ -232,6 +232,7 @@ class ZoneForwardList;
V(WasmInstanceObject) \
V(WasmMemoryObject) \
V(WasmModuleObject) \
V(WasmStruct) \
V(WasmTableObject) \
V(WeakFixedArray) \
V(WeakArrayList) \

View File

@ -825,6 +825,33 @@ class CodeDataContainer::BodyDescriptor final : public BodyDescriptorBase {
}
};
class WasmStruct::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
// Fields in WasmStructs never change their types in place, so
// there should never be a need to call this function.
UNREACHABLE();
return false;
}
template <typename ObjectVisitor>
static inline void IterateBody(Map map, HeapObject obj, int object_size,
ObjectVisitor* v) {
WasmStruct wasm_struct = WasmStruct::cast(obj);
wasm::StructType* type = WasmStruct::type(map);
for (uint32_t i = 0; i < type->field_count(); i++) {
if (!type->field(i).IsReferenceType()) continue;
int offset =
WasmStruct::kHeaderSize + static_cast<int>(type->field_offset(i));
v->VisitPointer(wasm_struct, wasm_struct.RawField(offset));
}
}
static inline int SizeOf(Map map, HeapObject object) {
return map.instance_size();
}
};
class EmbedderDataArray::BodyDescriptor final : public BodyDescriptorBase {
public:
static bool IsValidSlot(Map map, HeapObject obj, int offset) {
@ -949,6 +976,8 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3, T4 p4) {
return Op::template apply<FeedbackVector::BodyDescriptor>(p1, p2, p3, p4);
case COVERAGE_INFO_TYPE:
return Op::template apply<CoverageInfo::BodyDescriptor>(p1, p2, p3, p4);
case WASM_STRUCT_TYPE:
return Op::template apply<WasmStruct::BodyDescriptor>(p1, p2, p3, p4);
case JS_OBJECT_TYPE:
case JS_ERROR_TYPE:
case JS_ARGUMENTS_OBJECT_TYPE:

View File

@ -37,6 +37,7 @@ OBJECT_CONSTRUCTORS_IMPL(WasmMemoryObject, JSObject)
OBJECT_CONSTRUCTORS_IMPL(WasmModuleObject, JSObject)
OBJECT_CONSTRUCTORS_IMPL(WasmTableObject, JSObject)
OBJECT_CONSTRUCTORS_IMPL(AsmWasmData, Struct)
TQ_OBJECT_CONSTRUCTORS_IMPL(WasmStruct)
NEVER_READ_ONLY_SPACE_IMPL(WasmDebugInfo)
@ -49,6 +50,7 @@ CAST_ACCESSOR(WasmMemoryObject)
CAST_ACCESSOR(WasmModuleObject)
CAST_ACCESSOR(WasmTableObject)
CAST_ACCESSOR(AsmWasmData)
CAST_ACCESSOR(WasmStruct)
#define OPTIONAL_ACCESSORS(holder, name, type, offset) \
DEF_GETTER(holder, has_##name, bool) { \
@ -412,6 +414,19 @@ ACCESSORS(AsmWasmData, managed_native_module, Managed<wasm::NativeModule>,
ACCESSORS(AsmWasmData, export_wrappers, FixedArray, kExportWrappersOffset)
ACCESSORS(AsmWasmData, uses_bitset, HeapNumber, kUsesBitsetOffset)
wasm::StructType* WasmStruct::type(Map map) {
DCHECK_EQ(WASM_STRUCT_TYPE, map.instance_type());
Foreign foreign = Foreign::cast(map.constructor_or_backpointer());
return reinterpret_cast<wasm::StructType*>(foreign.foreign_address());
}
wasm::StructType* WasmStruct::type() const { return type(map()); }
ObjectSlot WasmStruct::RawField(int raw_offset) {
int offset = WasmStruct::kHeaderSize + raw_offset;
return ObjectSlot(FIELD_ADDR(*this, offset));
}
#include "src/objects/object-macros-undef.h"
} // namespace internal

View File

@ -1414,6 +1414,29 @@ WasmInstanceObject::GetOrCreateWasmExternalFunction(
return result;
}
Handle<Map> WasmInstanceObject::GetOrCreateStructMap(
Isolate* isolate, Handle<WasmInstanceObject> instance, int struct_index) {
Handle<WasmModuleObject> module_object(instance->module_object(), isolate);
const WasmModule* module = module_object->module();
const wasm::StructType* type = module->struct_type(struct_index);
int inobject_properties = 0;
DCHECK_LE(kMaxInt - WasmStruct::kHeaderSize, type->total_fields_size());
int instance_size =
WasmStruct::kHeaderSize + static_cast<int>(type->total_fields_size());
InstanceType instance_type = WASM_STRUCT_TYPE;
// TODO(jkummerow): If NO_ELEMENTS were supported, we could use that here.
ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
Handle<Foreign> type_info =
isolate->factory()->NewForeign(reinterpret_cast<Address>(type));
Handle<Map> map = isolate->factory()->NewMap(
instance_type, instance_size, elements_kind, inobject_properties);
map->set_constructor_or_backpointer(*type_info);
// TODO(7748): Cache the map somewhere on the instance.
return map;
}
void WasmInstanceObject::SetWasmExternalFunction(
Isolate* isolate, Handle<WasmInstanceObject> instance, int index,
Handle<WasmExternalFunction> val) {

View File

@ -13,7 +13,9 @@
#include "src/debug/debug.h"
#include "src/heap/heap.h"
#include "src/objects/objects.h"
#include "src/wasm/struct-types.h"
#include "src/wasm/value-type.h"
#include "torque-generated/class-definitions-tq.h"
// Has to be the last include (doesn't have include guards)
#include "src/objects/object-macros.h"
@ -573,6 +575,10 @@ class WasmInstanceObject : public JSObject {
Handle<WasmInstanceObject>,
uint32_t memory_index);
static Handle<Map> GetOrCreateStructMap(Isolate* isolate,
Handle<WasmInstanceObject> instance,
int struct_index);
OBJECT_CONSTRUCTORS(WasmInstanceObject, JSObject);
private:
@ -992,6 +998,21 @@ class AsmWasmData : public Struct {
OBJECT_CONSTRUCTORS(AsmWasmData, Struct);
};
class WasmStruct : public TorqueGeneratedWasmStruct<WasmStruct, HeapObject> {
public:
static inline wasm::StructType* type(Map map);
inline wasm::StructType* type() const;
inline ObjectSlot RawField(int raw_offset);
DECL_CAST(WasmStruct)
DECL_PRINTER(WasmStruct)
class BodyDescriptor;
TQ_OBJECT_CONSTRUCTORS(WasmStruct)
};
#undef DECL_OPTIONAL_ACCESSORS
} // namespace internal

View File

@ -102,3 +102,7 @@ extern class AsmWasmData extends Struct {
export_wrappers: FixedArray;
uses_bitset: HeapNumber;
}
@generateCppClass
extern class WasmStruct extends HeapObject {
}

View File

@ -136,13 +136,14 @@ INSTANCE_TYPES = {
172: "SMI_BOX_TYPE",
173: "SMI_PAIR_TYPE",
174: "SORT_STATE_TYPE",
175: "WEAK_ARRAY_LIST_TYPE",
176: "WEAK_CELL_TYPE",
177: "JS_PROXY_TYPE",
175: "WASM_STRUCT_TYPE",
176: "WEAK_ARRAY_LIST_TYPE",
177: "WEAK_CELL_TYPE",
178: "JS_PROXY_TYPE",
1057: "JS_OBJECT_TYPE",
178: "JS_GLOBAL_OBJECT_TYPE",
179: "JS_GLOBAL_PROXY_TYPE",
180: "JS_MODULE_NAMESPACE_TYPE",
179: "JS_GLOBAL_OBJECT_TYPE",
180: "JS_GLOBAL_PROXY_TYPE",
181: "JS_MODULE_NAMESPACE_TYPE",
1040: "JS_SPECIAL_API_OBJECT_TYPE",
1041: "JS_PRIMITIVE_WRAPPER_TYPE",
1042: "JS_MAP_KEY_ITERATOR_TYPE",
@ -267,10 +268,10 @@ KNOWN_MAPS = {
("read_only_space", 0x00dd5): (150, "SyntheticModuleMap"),
("read_only_space", 0x00dfd): (152, "UncompiledDataWithoutPreparseDataMap"),
("read_only_space", 0x00e25): (151, "UncompiledDataWithPreparseDataMap"),
("read_only_space", 0x00e4d): (175, "WeakArrayListMap"),
("read_only_space", 0x00e4d): (176, "WeakArrayListMap"),
("read_only_space", 0x00e75): (119, "EphemeronHashTableMap"),
("read_only_space", 0x00e9d): (160, "EmbedderDataArrayMap"),
("read_only_space", 0x00ec5): (176, "WeakCellMap"),
("read_only_space", 0x00ec5): (177, "WeakCellMap"),
("read_only_space", 0x00eed): (32, "StringMap"),
("read_only_space", 0x00f15): (41, "ConsOneByteStringMap"),
("read_only_space", 0x00f3d): (33, "ConsStringMap"),