case kExternal##Type##Array: \
return size;
TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+#undef TYPED_ARRAY_CASE
+}
+
+
+size_t GetFixedTypedArraysElementSize(ElementsKind kind) {
+ switch (kind) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return size;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+ return 0;
+ }
+#undef TYPED_ARRAY_CASE
+}
+
+
+ExternalArrayType GetArrayTypeFromElementsKind(ElementsKind kind) {
+ switch (kind) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return kExternal##Type##Array;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+ return kExternalInt8Array;
}
- UNREACHABLE();
- return 0;
#undef TYPED_ARRAY_CASE
}
}
+JSFunction* GetTypedArrayFun(ElementsKind elements_kind, Isolate* isolate) {
+ Context* native_context = isolate->context()->native_context();
+ switch (elements_kind) {
+#define TYPED_ARRAY_FUN(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: \
+ return native_context->type##_array_fun();
+
+ TYPED_ARRAYS(TYPED_ARRAY_FUN)
+#undef TYPED_ARRAY_FUN
+
+ default:
+ UNREACHABLE();
+ return NULL;
+ }
+}
+
+
void SetupArrayBufferView(i::Isolate* isolate,
i::Handle<i::JSArrayBufferView> obj,
i::Handle<i::JSArrayBuffer> buffer,
}
+Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind) {
+ Handle<JSFunction> typed_array_fun_handle(
+ GetTypedArrayFun(elements_kind, isolate()));
+
+ CALL_HEAP_FUNCTION(
+ isolate(), isolate()->heap()->AllocateJSObject(*typed_array_fun_handle),
+ JSTypedArray);
+}
+
+
Handle<JSTypedArray> Factory::NewJSTypedArray(ExternalArrayType type,
Handle<JSArrayBuffer> buffer,
size_t byte_offset,
}
+Handle<JSTypedArray> Factory::NewJSTypedArray(ElementsKind elements_kind,
+ size_t number_of_elements) {
+ Handle<JSTypedArray> obj = NewJSTypedArray(elements_kind);
+
+ size_t element_size = GetFixedTypedArraysElementSize(elements_kind);
+ ExternalArrayType array_type = GetArrayTypeFromElementsKind(elements_kind);
+
+ CHECK(number_of_elements <=
+ (std::numeric_limits<size_t>::max() / element_size));
+ CHECK(number_of_elements <= static_cast<size_t>(Smi::kMaxValue));
+ size_t byte_length = number_of_elements * element_size;
+
+ obj->set_byte_offset(Smi::FromInt(0));
+ i::Handle<i::Object> byte_length_object =
+ isolate()->factory()->NewNumberFromSize(byte_length);
+ obj->set_byte_length(*byte_length_object);
+ Handle<Object> length_object = NewNumberFromSize(number_of_elements);
+ obj->set_length(*length_object);
+
+ obj->set_buffer(Smi::FromInt(0));
+ obj->set_weak_next(isolate()->heap()->undefined_value());
+ Handle<FixedTypedArrayBase> elements =
+ isolate()->factory()->NewFixedTypedArray(
+ static_cast<int>(number_of_elements), array_type);
+ obj->set_elements(*elements);
+ return obj;
+}
+
+
Handle<JSDataView> Factory::NewJSDataView(Handle<JSArrayBuffer> buffer,
size_t byte_offset,
size_t byte_length) {
Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type);
+ Handle<JSTypedArray> NewJSTypedArray(ElementsKind elements_kind);
+
// Creates a new JSTypedArray with the specified buffer.
Handle<JSTypedArray> NewJSTypedArray(ExternalArrayType type,
Handle<JSArrayBuffer> buffer,
size_t byte_offset, size_t length);
+ // Creates a new on-heap JSTypedArray.
+ Handle<JSTypedArray> NewJSTypedArray(ElementsKind elements_kind,
+ size_t number_of_elements);
+
Handle<JSDataView> NewJSDataView();
Handle<JSDataView> NewJSDataView(Handle<JSArrayBuffer> buffer,
size_t byte_offset, size_t byte_length);
}
length = GetSlowModeBackingStoreLength(length);
return Handle<LayoutDescriptor>::cast(
- isolate->factory()->NewFixedTypedArray(length, kExternalUint32Array));
+ isolate->factory()->NewJSTypedArray(UINT32_ELEMENTS, length));
}
}
*layout_word_index = field_index / kNumberOfBits;
- CHECK((!IsSmi() && (*layout_word_index < length())) ||
+ CHECK((!IsSmi() && (*layout_word_index < Smi::cast(length())->value())) ||
(IsSmi() && (*layout_word_index < 1)));
*layout_bit_index = field_index % kNumberOfBits;
int LayoutDescriptor::capacity() {
- return IsSlowLayout() ? (length() * kNumberOfBits) : kSmiValueSize;
+ return IsSlowLayout() ? (Smi::cast(length())->value() * kNumberOfBits)
+ : kSmiValueSize;
+}
+
+
+uint32_t LayoutDescriptor::get_scalar(int index) {
+ DCHECK(IsSlowLayout());
+ return FixedTypedArray<Uint32ArrayTraits>::cast(elements())
+ ->get_scalar(index);
+}
+
+
+void LayoutDescriptor::set(int index, uint32_t value) {
+ DCHECK(IsSlowLayout());
+ FixedTypedArray<Uint32ArrayTraits>::cast(elements())->set(index, value);
}
DCHECK(new_layout_descriptor->IsSlowLayout());
if (layout_descriptor->IsSlowLayout()) {
- memcpy(new_layout_descriptor->DataPtr(), layout_descriptor->DataPtr(),
- layout_descriptor->DataSize());
+ DisallowHeapAllocation no_gc;
+ Handle<FixedTypedArrayBase> elements(
+ FixedTypedArrayBase::cast(layout_descriptor->elements()));
+ Handle<FixedTypedArrayBase> new_elements(
+ FixedTypedArrayBase::cast(new_layout_descriptor->elements()));
+ memcpy(new_elements->DataPtr(), elements->DataPtr(), elements->DataSize());
return new_layout_descriptor;
} else {
// Fast layout.
// This is a contiguous sequence till the end of current word, proceed
// counting in the subsequent words.
if (IsSlowLayout()) {
- int len = length();
+ int len = Smi::cast(length())->value();
++layout_word_index;
for (; layout_word_index < len; layout_word_index++) {
value = get_scalar(layout_word_index);
// Trim, clean and reinitialize this slow-mode layout descriptor.
int array_length = GetSlowModeBackingStoreLength(layout_descriptor_length);
- int current_length = length();
+ int current_length = Smi::cast(length())->value();
if (current_length != array_length) {
DCHECK_LT(array_length, current_length);
int delta = current_length - array_length;
- heap->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(this, delta);
+ heap->RightTrimFixedArray<Heap::SEQUENTIAL_TO_SWEEPER>(elements(), delta);
+ set_byte_length(Smi::FromInt(array_length * 4));
+ set_length(Smi::FromInt(array_length));
+ }
+ {
+ DisallowHeapAllocation no_gc;
+ Handle<FixedTypedArrayBase> fixed_array(
+ FixedTypedArrayBase::cast(elements()));
+ memset(fixed_array->DataPtr(), 0, fixed_array->DataSize());
}
- memset(DataPtr(), 0, DataSize());
LayoutDescriptor* layout_descriptor =
Initialize(this, map, descriptors, num_descriptors);
DCHECK_EQ(this, layout_descriptor);
// of the descriptor then the field is also considered tagged.
// Once a layout descriptor is created it is allowed only to append properties
// to it.
-class LayoutDescriptor : public FixedTypedArray<Uint32ArrayTraits> {
+class LayoutDescriptor : public JSTypedArray {
public:
V8_INLINE bool IsTagged(int field_index);
// Capacity of layout descriptors in bits.
V8_INLINE int capacity();
+ V8_INLINE uint32_t get_scalar(int index);
+ V8_INLINE void set(int index, uint32_t value);
+
static Handle<LayoutDescriptor> NewForTesting(Isolate* isolate, int length);
LayoutDescriptor* SetTaggedForTesting(int field_index, bool tagged);
bool Object::IsArrayList() const { return IsFixedArray(); }
-bool Object::IsLayoutDescriptor() const {
- return IsSmi() || IsFixedTypedArrayBase();
-}
+bool Object::IsLayoutDescriptor() const { return IsSmi() || IsJSTypedArray(); }
bool Object::IsTransitionArray() const {
PrintBitMask(os, static_cast<uint32_t>(Smi::cast(this)->value()));
} else {
os << "slow";
- int len = length();
+ int len = Smi::cast(length())->value();
for (int i = 0; i < len; i++) {
if (i > 0) os << " |";
PrintBitMask(os, get_scalar(i));
LayoutDescriptor* layout_desc = *layout_descriptor;
CHECK_EQ(layout_desc, LayoutDescriptor::cast(layout_desc));
CHECK_EQ(layout_desc, LayoutDescriptor::cast_gc_safe(layout_desc));
- CHECK(layout_descriptor->IsFixedTypedArrayBase());
+ CHECK(layout_descriptor->IsJSTypedArray());
// Now make it look like a forwarding pointer to layout_descriptor_copy.
MapWord map_word = layout_desc->map_word();
CHECK(!map_word.IsForwardingAddress());
CHECK(map->layout_descriptor()->IsConsistentWithMap(*map, true));
CHECK(map->layout_descriptor()->IsSlowLayout());
CHECK(map->owns_descriptors());
- CHECK_EQ(2, map->layout_descriptor()->length());
+ CHECK_EQ(2, Smi::cast(map->layout_descriptor()->length())->value());
{
// Add transitions to double fields.
CHECK_EQ(map->layout_descriptor(), tmp_map->layout_descriptor());
}
CHECK(map->layout_descriptor()->IsSlowLayout());
- CHECK_EQ(4, map->layout_descriptor()->length());
+ CHECK_EQ(4, Smi::cast(map->layout_descriptor()->length())->value());
// The unused tail of the layout descriptor is now "durty" because of sharing.
CHECK(map->layout_descriptor()->IsConsistentWithMap(*map));
CHECK_EQ(map->NumberOfOwnDescriptors(),
map->instance_descriptors()->number_of_descriptors());
CHECK(map->layout_descriptor()->IsSlowLayout());
- CHECK_EQ(2, map->layout_descriptor()->length());
+ CHECK_EQ(2, Smi::cast(map->layout_descriptor()->length())->value());
{
// Add transitions to tagged fields.