Commit 775303f4 authored by Igor Sheludko's avatar Igor Sheludko Committed by V8 LUCI CQ

[wasm-gc] Support WasmObject elements loading in runtime

This CL adds WASM_ARRAY_ELEMENTS to distinguish WasmArray maps.

Bug: v8:11804
Change-Id: I243ce24c2f2246efbc223af14361c28506e9a2d2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2922884
Commit-Queue: Igor Sheludko <ishell@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75109}
parent 14fda804
......@@ -902,6 +902,7 @@ uint32_t EstimateElementCount(Isolate* isolate, Handle<JSArray> array) {
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_STRING_WRAPPER_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
case WASM_ARRAY_ELEMENTS:
UNREACHABLE();
}
// As an estimate, we assume that the prototype doesn't contain any
......@@ -1025,6 +1026,10 @@ void CollectElementIndices(Isolate* isolate, Handle<JSObject> object,
}
break;
}
case WASM_ARRAY_ELEMENTS:
// TODO(ishell): implement
UNIMPLEMENTED();
break;
case NO_ELEMENTS:
break;
}
......@@ -1211,6 +1216,10 @@ bool IterateElements(Isolate* isolate, Handle<JSReceiver> receiver,
});
break;
}
case WASM_ARRAY_ELEMENTS:
// TODO(ishell): implement
UNIMPLEMENTED();
break;
case NO_ELEMENTS:
break;
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
......
......@@ -1832,6 +1832,7 @@ void JSObject::IncrementSpillStatistics(Isolate* isolate,
}
case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
case WASM_ARRAY_ELEMENTS:
case NO_ELEMENTS:
break;
}
......
......@@ -529,6 +529,10 @@ void JSObject::PrintElements(std::ostream& os) {
PrintSloppyArgumentElements(os, map().elements_kind(),
SloppyArgumentsElements::cast(elements()));
break;
case WASM_ARRAY_ELEMENTS:
// WasmArrayPrint() should be called intead.
UNREACHABLE();
break;
case NO_ELEMENTS:
break;
}
......
......@@ -31,6 +31,7 @@
#include "src/objects/field-type.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/heap-number-inl.h"
#include "src/objects/instance-type.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/megadom-handler.h"
......@@ -994,6 +995,7 @@ Handle<Object> LoadIC::ComputeHandler(LookupIterator* lookup) {
Handle<Object> getter(accessor_pair->getter(), isolate());
if (!getter->IsJSFunction() && !getter->IsFunctionTemplateInfo()) {
// TODO(jgruber): Update counter name.
TRACE_HANDLER_STATS(isolate(), LoadIC_SlowStub);
return LoadHandler::LoadSlow(isolate());
}
......@@ -1331,6 +1333,13 @@ Handle<Object> KeyedLoadIC::LoadElementHandler(Handle<Map> receiver_map,
if (instance_type == JS_PROXY_TYPE) {
return LoadHandler::LoadProxy(isolate());
}
#if V8_ENABLE_WEBASSEMBLY
if (InstanceTypeChecker::IsWasmObject(instance_type)) {
// TODO(jgruber): Update counter name.
TRACE_HANDLER_STATS(isolate(), KeyedLoadIC_SlowStub);
return LoadHandler::LoadSlow(isolate());
}
#endif // V8_ENABLE_WEBASSEMBLY
ElementsKind elements_kind = receiver_map->elements_kind();
if (IsSloppyArgumentsElementsKind(elements_kind)) {
......
......@@ -58,6 +58,7 @@ int ElementsKindToShiftSize(ElementsKind elements_kind) {
case FAST_STRING_WRAPPER_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
return kTaggedSizeLog2;
case WASM_ARRAY_ELEMENTS:
case NO_ELEMENTS:
UNREACHABLE();
}
......@@ -122,6 +123,8 @@ const char* ElementsKindToString(ElementsKind kind) {
TYPED_ARRAYS(PRINT_NAME);
RAB_GSAB_TYPED_ARRAYS(PRINT_NAME);
#undef PRINT_NAME
case WASM_ARRAY_ELEMENTS:
return "WASM_ARRAY_ELEMENTS";
case NO_ELEMENTS:
return "NO_ELEMENTS";
}
......
......@@ -104,6 +104,10 @@ enum ElementsKind : uint8_t {
RAB_GSAB_TYPED_ARRAYS(TYPED_ARRAY_ELEMENTS_KIND)
#undef TYPED_ARRAY_ELEMENTS_KIND
// WasmObject elements kind. The actual elements type is read from the
// respective WasmTypeInfo.
WASM_ARRAY_ELEMENTS,
// Sentinel ElementsKind for objects with no elements.
NO_ELEMENTS,
......@@ -193,6 +197,10 @@ inline bool IsTypedArrayOrRabGsabTypedArrayElementsKind(ElementsKind kind) {
LAST_RAB_GSAB_FIXED_TYPED_ARRAY_ELEMENTS_KIND);
}
inline bool IsWasmArrayElementsKind(ElementsKind kind) {
return kind == WASM_ARRAY_ELEMENTS;
}
inline bool IsTerminalElementsKind(ElementsKind kind) {
return kind == TERMINAL_FAST_ELEMENTS_KIND ||
IsTypedArrayElementsKind(kind) ||
......
......@@ -2540,6 +2540,7 @@ class FastSmiOrObjectElementsAccessor
TYPED_ARRAYS(TYPED_ARRAY_CASE)
RAB_GSAB_TYPED_ARRAYS(TYPED_ARRAY_CASE)
#undef TYPED_ARRAY_CASE
case WASM_ARRAY_ELEMENTS:
// This function is currently only used for JSArrays with non-zero
// length.
UNREACHABLE();
......@@ -2951,6 +2952,7 @@ class FastDoubleElementsAccessor
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
case FAST_STRING_WRAPPER_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
case WASM_ARRAY_ELEMENTS:
case NO_ELEMENTS:
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
TYPED_ARRAYS(TYPED_ARRAY_CASE)
......
......@@ -5,6 +5,7 @@
#include "src/objects/js-objects.h"
#include "src/api/api-arguments-inl.h"
#include "src/base/logging.h"
#include "src/common/globals.h"
#include "src/date/date.h"
#include "src/execution/arguments.h"
......@@ -4255,6 +4256,9 @@ bool JSObject::HasEnumerableElements() {
return true;
}
return object.elements().length() > 0;
case WASM_ARRAY_ELEMENTS:
UNIMPLEMENTED();
case NO_ELEMENTS:
return false;
}
......@@ -5038,6 +5042,7 @@ int JSObject::GetFastElementsUsage() {
case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
case DICTIONARY_ELEMENTS:
case WASM_ARRAY_ELEMENTS:
case NO_ELEMENTS:
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
......
......@@ -77,7 +77,11 @@ LookupIterator::LookupIterator(Isolate* isolate, Handle<Object> receiver,
// If we're not looking at a TypedArray, we will need the key represented
// as an internalized string.
if (index_ > JSObject::kMaxElementIndex &&
!lookup_start_object->IsJSTypedArray()) {
!lookup_start_object->IsJSTypedArray(isolate_)
#if V8_ENABLE_WEBASSEMBLY
&& !lookup_start_object->IsWasmArray(isolate_)
#endif // V8_ENABLE_WEBASSEMBLY
) {
if (name_.is_null()) {
name_ = isolate->factory()->SizeToString(index_);
}
......@@ -173,7 +177,7 @@ Handle<Name> LookupIterator::GetName() {
bool LookupIterator::IsElement(JSReceiver object) const {
return index_ <= JSObject::kMaxElementIndex ||
(index_ != kInvalidIndex &&
object.map().has_typed_array_or_rab_gsab_typed_array_elements());
object.map().has_any_typed_array_or_wasm_array_elements());
}
bool LookupIterator::is_dictionary_holder() const {
......
......@@ -1158,6 +1158,11 @@ LookupIterator::State LookupIterator::LookupInSpecialHolder(
if (map.IsJSProxyMap()) {
if (is_element || !name_->IsPrivate(isolate_)) return JSPROXY;
}
#if V8_ENABLE_WEBASSEMBLY
if (map.IsWasmObjectMap()) {
return LookupInRegularHolder<is_element>(map, holder);
}
#endif // V8_ENABLE_WEBASSEMBLY
if (map.is_access_check_needed()) {
if (is_element || !name_->IsPrivate(isolate_)) return ACCESS_CHECK;
}
......@@ -1208,20 +1213,38 @@ LookupIterator::State LookupIterator::LookupInRegularHolder(
}
if (is_element && IsElement(holder)) {
JSObject js_object = JSObject::cast(holder);
ElementsAccessor* accessor = js_object.GetElementsAccessor(isolate_);
FixedArrayBase backing_store = js_object.elements(isolate_);
number_ =
accessor->GetEntryForIndex(isolate_, js_object, backing_store, index_);
if (number_.is_not_found()) {
return holder.IsJSTypedArray(isolate_) ? INTEGER_INDEXED_EXOTIC
: NOT_FOUND;
}
property_details_ = accessor->GetDetails(js_object, number_);
if (map.has_frozen_elements()) {
property_details_ = property_details_.CopyAddAttributes(FROZEN);
} else if (map.has_sealed_elements()) {
property_details_ = property_details_.CopyAddAttributes(SEALED);
#if V8_ENABLE_WEBASSEMBLY
if (V8_UNLIKELY(holder.IsWasmObject())) {
// TODO(ishell): consider supporting indexed access to WasmStruct fields.
if (holder.IsWasmArray()) {
WasmArray wasm_array = WasmArray::cast(holder);
number_ = index_ < wasm_array.length() ? InternalIndex(index_)
: InternalIndex::NotFound();
property_details_ =
PropertyDetails(kData, SEALED, PropertyCellType::kNoCell);
} else {
DCHECK(holder.IsWasmStruct());
DCHECK(number_.is_not_found());
}
} else // NOLINT(readability/braces)
#endif // V8_ENABLE_WEBASSEMBLY
{
JSObject js_object = JSObject::cast(holder);
ElementsAccessor* accessor = js_object.GetElementsAccessor(isolate_);
FixedArrayBase backing_store = js_object.elements(isolate_);
number_ = accessor->GetEntryForIndex(isolate_, js_object, backing_store,
index_);
if (number_.is_not_found()) {
return holder.IsJSTypedArray(isolate_) ? INTEGER_INDEXED_EXOTIC
: NOT_FOUND;
}
property_details_ = accessor->GetDetails(js_object, number_);
if (map.has_frozen_elements()) {
property_details_ = property_details_.CopyAddAttributes(FROZEN);
} else if (map.has_sealed_elements()) {
property_details_ = property_details_.CopyAddAttributes(SEALED);
}
}
} else if (!map.is_dictionary_map()) {
DescriptorArray descriptors = map.instance_descriptors(isolate_);
......
......@@ -607,6 +607,15 @@ bool Map::has_typed_array_or_rab_gsab_typed_array_elements() const {
return IsTypedArrayOrRabGsabTypedArrayElementsKind(elements_kind());
}
bool Map::has_any_typed_array_or_wasm_array_elements() const {
ElementsKind kind = elements_kind();
return IsTypedArrayOrRabGsabTypedArrayElementsKind(kind) ||
#if V8_ENABLE_WEBASSEMBLY
IsWasmArrayElementsKind(kind) ||
#endif // V8_ENABLE_WEBASSEMBLY
false;
}
bool Map::has_dictionary_elements() const {
return IsDictionaryElementsKind(elements_kind());
}
......
......@@ -418,6 +418,7 @@ class Map : public HeapObject {
inline bool has_typed_array_elements() const;
inline bool has_rab_gsab_typed_array_elements() const;
inline bool has_typed_array_or_rab_gsab_typed_array_elements() const;
inline bool has_any_typed_array_or_wasm_array_elements() const;
inline bool has_dictionary_elements() const;
inline bool has_any_nonextensible_elements() const;
inline bool has_nonextensible_elements() const;
......
......@@ -215,6 +215,7 @@ MaybeHandle<JSObject> JSObjectWalkVisitor<ContextObject>::StructureWalk(
break;
case FAST_STRING_WRAPPER_ELEMENTS:
case SLOW_STRING_WRAPPER_ELEMENTS:
case WASM_ARRAY_ELEMENTS:
UNREACHABLE();
#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) case TYPE##_ELEMENTS:
......
......@@ -72,14 +72,12 @@ function createArray_i() {
(function TestSimpleArrayInterop() {
function f(o) {
for (let i = 0; i < kIterationsCountForICProgression; i++) {
assertEquals(10, o.length);
for (let i = 0; i < o.length; i++) {
let len = o.length;
assertEquals(10, len);
// Keyed loads are not supported yet
// let v0 = o[0];
// %DebugPrint(v0);
// let v1 = o[1];
// %DebugPrint(v1);
let v = o[i];
assertEquals(i, v);
}
}
......
......@@ -73,6 +73,8 @@ function createStruct_i() {
for (let i = 0; i < kIterationsCountForICProgression; i++) {
let v = o.$field0;
assertEquals(153, v);
v = o[i];
assertEquals(undefined, v);
}
}
......
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