Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(170)

Unified Diff: src/objects.cc

Issue 150813004: In-heap small typed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Patch for review Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index d2ad0b7f5e866db7b3abc6b6e7b8d601db2989cd..9b4c7cbc4268da619d6b162a672d66ec3d78f7cf 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -3260,24 +3260,30 @@ Handle<Map> Map::FindTransitionedMap(MapHandleList* candidates) {
static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
Map* current_map = map;
- int index = GetSequenceIndexFromFastElementsKind(map->elements_kind());
- int to_index = IsFastElementsKind(to_kind)
- ? GetSequenceIndexFromFastElementsKind(to_kind)
- : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
+ int target_kind =
+ IsFastElementsKind(to_kind) || IsExternalArrayElementsKind(to_kind)
+ ? to_kind
+ : TERMINAL_FAST_ELEMENTS_KIND;
- ASSERT(index <= to_index);
+ // Support for legacy API.
+ if (IsExternalArrayElementsKind(to_kind) &&
+ !IsFixedTypedArrayElementsKind(map->elements_kind())) {
+ return map;
+ }
- for (; index < to_index; ++index) {
+ ElementsKind kind = map->elements_kind();
+ while (kind != target_kind) {
+ kind = GetNextTransitionElementsKind(kind);
if (!current_map->HasElementsTransition()) return current_map;
current_map = current_map->elements_transition_map();
}
- if (!IsFastElementsKind(to_kind) && current_map->HasElementsTransition()) {
+
+ if (to_kind != kind && current_map->HasElementsTransition()) {
Map* next_map = current_map->elements_transition_map();
if (next_map->elements_kind() == to_kind) return next_map;
}
- ASSERT(IsFastElementsKind(to_kind)
- ? current_map->elements_kind() == to_kind
- : current_map->elements_kind() == TERMINAL_FAST_ELEMENTS_KIND);
+
+ ASSERT(current_map->elements_kind() == target_kind);
return current_map;
}
@@ -3305,26 +3311,21 @@ bool Map::IsMapInArrayPrototypeChain() {
static MaybeObject* AddMissingElementsTransitions(Map* map,
ElementsKind to_kind) {
- ASSERT(IsFastElementsKind(map->elements_kind()));
- int index = GetSequenceIndexFromFastElementsKind(map->elements_kind());
- int to_index = IsFastElementsKind(to_kind)
- ? GetSequenceIndexFromFastElementsKind(to_kind)
- : GetSequenceIndexFromFastElementsKind(TERMINAL_FAST_ELEMENTS_KIND);
-
- ASSERT(index <= to_index);
+ ASSERT(IsTransitionElementsKind(map->elements_kind()));
Map* current_map = map;
- for (; index < to_index; ++index) {
- ElementsKind next_kind = GetFastElementsKindFromSequenceIndex(index + 1);
+ ElementsKind kind = map->elements_kind();
+ while (kind != to_kind && !IsTerminalElementsKind(kind)) {
+ kind = GetNextTransitionElementsKind(kind);
MaybeObject* maybe_next_map =
- current_map->CopyAsElementsKind(next_kind, INSERT_TRANSITION);
+ current_map->CopyAsElementsKind(kind, INSERT_TRANSITION);
if (!maybe_next_map->To(&current_map)) return maybe_next_map;
}
// In case we are exiting the fast elements kind system, just add the map in
// the end.
- if (!IsFastElementsKind(to_kind)) {
+ if (kind != to_kind) {
MaybeObject* maybe_next_map =
current_map->CopyAsElementsKind(to_kind, INSERT_TRANSITION);
if (!maybe_next_map->To(&current_map)) return maybe_next_map;
@@ -3356,7 +3357,7 @@ MaybeObject* JSObject::GetElementsTransitionMapSlow(ElementsKind to_kind) {
// Only remember the map transition if there is not an already existing
// non-matching element transition.
!start_map->IsUndefined() && !start_map->is_shared() &&
- IsFastElementsKind(from_kind);
+ IsTransitionElementsKind(from_kind);
// Only store fast element maps in ascending generality.
if (IsFastElementsKind(to_kind)) {
@@ -3384,6 +3385,11 @@ MaybeObject* Map::AsElementsKind(ElementsKind kind) {
}
+Handle<Map> Map::AsElementsKind(Handle<Map> map, ElementsKind kind) {
+ CALL_HEAP_FUNCTION(map->GetIsolate(), map->AsElementsKind(kind), Map);
+}
+
+
void JSObject::LocalLookupRealNamedProperty(Name* name, LookupResult* result) {
if (IsJSGlobalProxy()) {
Object* proto = GetPrototype();
@@ -4734,7 +4740,7 @@ Handle<SeededNumberDictionary> JSObject::NormalizeElements(
MaybeObject* JSObject::NormalizeElements() {
- ASSERT(!HasExternalArrayElements());
+ ASSERT(!HasExternalArrayElements() && !HasFixedTypedArrayElements());
// Find the backing store.
FixedArrayBase* array = FixedArrayBase::cast(elements());
@@ -5475,7 +5481,8 @@ Handle<Object> JSObject::PreventExtensions(Handle<JSObject> object) {
}
// It's not possible to seal objects with external array elements
- if (object->HasExternalArrayElements()) {
+ if (object->HasExternalArrayElements() ||
+ object->HasFixedTypedArrayElements()) {
Handle<Object> error =
isolate->factory()->NewTypeError(
"cant_prevent_ext_external_array_elements",
@@ -5555,7 +5562,8 @@ Handle<Object> JSObject::Freeze(Handle<JSObject> object) {
}
// It's not possible to freeze objects with external array elements
- if (object->HasExternalArrayElements()) {
+ if (object->HasExternalArrayElements() ||
+ object->HasFixedTypedArrayElements()) {
Handle<Object> error =
isolate->factory()->NewTypeError(
"cant_prevent_ext_external_array_elements",
@@ -12535,7 +12543,9 @@ Handle<Object> JSObject::SetElement(Handle<JSObject> object,
}
// Don't allow element properties to be redefined for external arrays.
- if (object->HasExternalArrayElements() && set_mode == DEFINE_PROPERTY) {
+ if ((object->HasExternalArrayElements() ||
+ object->HasFixedTypedArrayElements()) &&
+ set_mode == DEFINE_PROPERTY) {
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
Handle<Object> args[] = { object, number };
Handle<Object> error = isolate->factory()->NewTypeError(
@@ -14456,10 +14466,11 @@ Handle<Object> JSObject::PrepareElementsForSort(Handle<JSObject> object,
object->ValidateElements();
object->set_map_and_elements(*new_map, *fast_elements);
- } else if (object->HasExternalArrayElements()) {
- // External arrays cannot have holes or undefined elements.
+ } else if (object->HasExternalArrayElements() ||
+ object->HasFixedTypedArrayElements()) {
+ // Typed arrays cannot have holes or undefined elements.
return handle(Smi::FromInt(
- ExternalArray::cast(object->elements())->length()), isolate);
+ FixedArrayBase::cast(object->elements())->length()), isolate);
} else if (!object->HasFastDoubleElements()) {
EnsureWritableFastElements(object);
}
@@ -14560,12 +14571,14 @@ ExternalArrayType JSTypedArray::type() {
switch (elements()->map()->instance_type()) {
#define INSTANCE_TYPE_TO_ARRAY_TYPE(Type, type, TYPE, ctype, size) \
case EXTERNAL_##TYPE##_ARRAY_TYPE: \
+ case FIXED_##TYPE##_ARRAY_TYPE: \
return kExternal##Type##Array;
TYPED_ARRAYS(INSTANCE_TYPE_TO_ARRAY_TYPE)
#undef INSTANCE_TYPE_TO_ARRAY_TYPE
default:
+ UNREACHABLE();
return static_cast<ExternalArrayType>(-1);
}
}
@@ -16423,6 +16436,67 @@ void JSTypedArray::Neuter() {
}
+static ElementsKind FixedToExternalElementsKind(ElementsKind elements_kind) {
+ switch (elements_kind) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
+ case TYPE##_ELEMENTS: return EXTERNAL_##TYPE##_ELEMENTS;
+
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+#undef TYPED_ARRAY_CASE
+
+ default:
+ UNREACHABLE();
+ return FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND;
+ }
+}
+
+
+Handle<JSArrayBuffer> JSTypedArray::MaterializeArrayBuffer(
+ Handle<JSTypedArray> typed_array) {
+
+ printf("Materializing buffer!\n");
mvstanton 2014/03/03 10:37:49 Remove this printf().
Dmitry Lomov (no reviews) 2014/03/10 09:20:35 Done.
+ Handle<Map> map(typed_array->map());
+ Isolate* isolate = typed_array->GetIsolate();
+
+ ASSERT(IsFixedTypedArrayElementsKind(map->elements_kind()));
+
+ Handle<JSArrayBuffer> buffer = isolate->factory()->NewJSArrayBuffer();
+ Handle<FixedTypedArrayBase> fixed_typed_array(
+ FixedTypedArrayBase::cast(typed_array->elements()));
+ Runtime::SetupArrayBufferAllocatingData(isolate, buffer,
+ fixed_typed_array->DataSize(), false);
+ memcpy(buffer->backing_store(),
+ fixed_typed_array->DataPtr(),
+ fixed_typed_array->DataSize());
+ Handle<ExternalArray> new_elements =
+ isolate->factory()->NewExternalArray(
+ fixed_typed_array->length(), typed_array->type(),
+ static_cast<uint8_t*>(buffer->backing_store()));
+ Handle<Map> new_map =
+ isolate->factory()->GetElementsTransitionMap(
+ typed_array,
+ FixedToExternalElementsKind(map->elements_kind()));
+
+ buffer->set_weak_first_view(*typed_array);
+ ASSERT(typed_array->weak_next() == isolate->heap()->undefined_value());
+ typed_array->set_buffer(*buffer);
+ typed_array->set_map_and_elements(*new_map, *new_elements);
+
+ return buffer;
+}
+
+
+Handle<JSArrayBuffer> JSTypedArray::GetBuffer() {
+ Handle<Object> result(buffer(), GetIsolate());
+ if (*result != Smi::FromInt(0)) {
+ ASSERT(IsExternalArrayElementsKind(map()->elements_kind()));
+ return Handle<JSArrayBuffer>::cast(result);
+ }
+ Handle<JSTypedArray> self(this);
+ return MaterializeArrayBuffer(self);
+}
+
+
HeapType* PropertyCell::type() {
return static_cast<HeapType*>(type_raw());
}

Powered by Google App Engine
This is Rietveld 408576698