Commit 2ff3e2e0 authored by dslomov@chromium.org's avatar dslomov@chromium.org

Preallocate transitioned maps for TypedArrays.

R=hpayer@chromium.org

Review URL: https://codereview.chromium.org/15172003

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14693 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 31b8fc19
......@@ -5053,7 +5053,7 @@ class Internals {
static const int kNullValueRootIndex = 7;
static const int kTrueValueRootIndex = 8;
static const int kFalseValueRootIndex = 9;
static const int kEmptyStringRootIndex = 118;
static const int kEmptyStringRootIndex = 127;
static const int kNodeClassIdOffset = 1 * kApiPointerSize;
static const int kNodeFlagsOffset = 1 * kApiPointerSize + 3;
......
......@@ -5953,10 +5953,6 @@ i::Handle<i::JSTypedArray> NewTypedArray(
isolate->factory()->NewExternalArray(
static_cast<int>(length), array_type,
static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
i::Handle<i::Map> map =
isolate->factory()->GetElementsTransitionMap(
obj, elements_kind);
obj->set_map(*map);
obj->set_elements(*elements);
return obj;
}
......
This diff is collapsed.
......@@ -2501,6 +2501,54 @@ bool Heap::CreateInitialMaps() {
}
set_external_double_array_map(Map::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalByteArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_byte_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj =
AllocateEmptyExternalArray(kExternalUnsignedByteArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_unsigned_byte_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalShortArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_short_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(
kExternalUnsignedShortArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_unsigned_short_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalIntArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_int_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj =
AllocateEmptyExternalArray(kExternalUnsignedIntArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_unsigned_int_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalFloatArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_float_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalDoubleArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_double_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateEmptyExternalArray(kExternalPixelArray);
if (!maybe_obj->ToObject(&obj)) return false;
}
set_empty_external_pixel_array(ExternalArray::cast(obj));
{ MaybeObject* maybe_obj = AllocateMap(CODE_TYPE, kVariableSizeSentinel);
if (!maybe_obj->ToObject(&obj)) return false;
}
......@@ -3232,6 +3280,40 @@ Heap::RootListIndex Heap::RootIndexForExternalArrayType(
}
}
Heap::RootListIndex Heap::RootIndexForEmptyExternalArray(
ElementsKind elementsKind) {
switch (elementsKind) {
case EXTERNAL_BYTE_ELEMENTS:
return kEmptyExternalByteArrayRootIndex;
case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
return kEmptyExternalUnsignedByteArrayRootIndex;
case EXTERNAL_SHORT_ELEMENTS:
return kEmptyExternalShortArrayRootIndex;
case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
return kEmptyExternalUnsignedShortArrayRootIndex;
case EXTERNAL_INT_ELEMENTS:
return kEmptyExternalIntArrayRootIndex;
case EXTERNAL_UNSIGNED_INT_ELEMENTS:
return kEmptyExternalUnsignedIntArrayRootIndex;
case EXTERNAL_FLOAT_ELEMENTS:
return kEmptyExternalFloatArrayRootIndex;
case EXTERNAL_DOUBLE_ELEMENTS:
return kEmptyExternalDoubleArrayRootIndex;
case EXTERNAL_PIXEL_ELEMENTS:
return kEmptyExternalPixelArrayRootIndex;
default:
UNREACHABLE();
return kUndefinedValueRootIndex;
}
}
ExternalArray* Heap::EmptyExternalArrayForMap(Map* map) {
return ExternalArray::cast(
roots_[RootIndexForEmptyExternalArray(map->elements_kind())]);
}
MaybeObject* Heap::NumberFromDouble(double value, PretenureFlag pretenure) {
// We need to distinguish the minus zero value and this cannot be
......@@ -4236,7 +4318,8 @@ MaybeObject* Heap::AllocateJSObjectFromMap(Map* map, PretenureFlag pretenure) {
InitializeJSObjectFromMap(JSObject::cast(obj),
FixedArray::cast(properties),
map);
ASSERT(JSObject::cast(obj)->HasFastElements());
ASSERT(JSObject::cast(obj)->HasFastElements() ||
JSObject::cast(obj)->HasExternalArrayElements());
return obj;
}
......@@ -5200,6 +5283,10 @@ MaybeObject* Heap::AllocateEmptyFixedArray() {
return result;
}
MaybeObject* Heap::AllocateEmptyExternalArray(ExternalArrayType array_type) {
return AllocateExternalArray(0, array_type, NULL, TENURED);
}
MaybeObject* Heap::AllocateRawFixedArray(int length) {
if (length < 0 || length > FixedArray::kMaxLength) {
......
......@@ -128,7 +128,6 @@ namespace internal {
V(Map, short_external_ascii_string_map, ShortExternalAsciiStringMap) \
V(Map, undetectable_string_map, UndetectableStringMap) \
V(Map, undetectable_ascii_string_map, UndetectableAsciiStringMap) \
V(Map, external_pixel_array_map, ExternalPixelArrayMap) \
V(Map, external_byte_array_map, ExternalByteArrayMap) \
V(Map, external_unsigned_byte_array_map, ExternalUnsignedByteArrayMap) \
V(Map, external_short_array_map, ExternalShortArrayMap) \
......@@ -137,6 +136,21 @@ namespace internal {
V(Map, external_unsigned_int_array_map, ExternalUnsignedIntArrayMap) \
V(Map, external_float_array_map, ExternalFloatArrayMap) \
V(Map, external_double_array_map, ExternalDoubleArrayMap) \
V(Map, external_pixel_array_map, ExternalPixelArrayMap) \
V(ExternalArray, empty_external_byte_array, \
EmptyExternalByteArray) \
V(ExternalArray, empty_external_unsigned_byte_array, \
EmptyExternalUnsignedByteArray) \
V(ExternalArray, empty_external_short_array, EmptyExternalShortArray) \
V(ExternalArray, empty_external_unsigned_short_array, \
EmptyExternalUnsignedShortArray) \
V(ExternalArray, empty_external_int_array, EmptyExternalIntArray) \
V(ExternalArray, empty_external_unsigned_int_array, \
EmptyExternalUnsignedIntArray) \
V(ExternalArray, empty_external_float_array, EmptyExternalFloatArray) \
V(ExternalArray, empty_external_double_array, EmptyExternalDoubleArray) \
V(ExternalArray, empty_external_pixel_array, \
EmptyExternalPixelArray) \
V(Map, non_strict_arguments_elements_map, NonStrictArgumentsElementsMap) \
V(Map, function_context_map, FunctionContextMap) \
V(Map, catch_context_map, CatchContextMap) \
......@@ -1628,6 +1642,9 @@ class Heap {
RootListIndex RootIndexForExternalArrayType(
ExternalArrayType array_type);
RootListIndex RootIndexForEmptyExternalArray(ElementsKind kind);
ExternalArray* EmptyExternalArrayForMap(Map* map);
void RecordStats(HeapStats* stats, bool take_snapshot = false);
// Copy block of memory from src to dst. Size of block should be aligned
......@@ -2138,6 +2155,10 @@ class Heap {
// Allocate empty fixed array.
MUST_USE_RESULT MaybeObject* AllocateEmptyFixedArray();
// Allocate empty external array of given type.
MUST_USE_RESULT MaybeObject* AllocateEmptyExternalArray(
ExternalArrayType array_type);
// Allocate empty fixed double array.
MUST_USE_RESULT MaybeObject* AllocateEmptyFixedDoubleArray();
......
......@@ -1484,10 +1484,17 @@ void JSObject::initialize_properties() {
void JSObject::initialize_elements() {
ASSERT(map()->has_fast_smi_or_object_elements() ||
map()->has_fast_double_elements());
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
if (map()->has_fast_smi_or_object_elements() ||
map()->has_fast_double_elements()) {
ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
} else if (map()->has_external_array_elements()) {
ExternalArray* empty_array = GetHeap()->EmptyExternalArrayForMap(map());
ASSERT(!GetHeap()->InNewSpace(empty_array));
WRITE_FIELD(this, kElementsOffset, empty_array);
} else {
UNREACHABLE();
}
}
......
......@@ -795,51 +795,41 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
CONVERT_ARG_HANDLE_CHECKED(Object, byte_length_object, 4);
ExternalArrayType arrayType;
ElementsKind elementsKind;
size_t elementSize;
switch (arrayId) {
case ARRAY_ID_UINT8:
elementsKind = EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
arrayType = kExternalUnsignedByteArray;
elementSize = 1;
break;
case ARRAY_ID_INT8:
elementsKind = EXTERNAL_BYTE_ELEMENTS;
arrayType = kExternalByteArray;
elementSize = 1;
break;
case ARRAY_ID_UINT16:
elementsKind = EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
arrayType = kExternalUnsignedShortArray;
elementSize = 2;
break;
case ARRAY_ID_INT16:
elementsKind = EXTERNAL_SHORT_ELEMENTS;
arrayType = kExternalShortArray;
elementSize = 2;
break;
case ARRAY_ID_UINT32:
elementsKind = EXTERNAL_UNSIGNED_INT_ELEMENTS;
arrayType = kExternalUnsignedIntArray;
elementSize = 4;
break;
case ARRAY_ID_INT32:
elementsKind = EXTERNAL_INT_ELEMENTS;
arrayType = kExternalIntArray;
elementSize = 4;
break;
case ARRAY_ID_FLOAT32:
elementsKind = EXTERNAL_FLOAT_ELEMENTS;
arrayType = kExternalFloatArray;
elementSize = 4;
break;
case ARRAY_ID_FLOAT64:
elementsKind = EXTERNAL_DOUBLE_ELEMENTS;
arrayType = kExternalDoubleArray;
elementSize = 8;
break;
case ARRAY_ID_UINT8C:
elementsKind = EXTERNAL_PIXEL_ELEMENTS;
arrayType = kExternalPixelArray;
elementSize = 1;
break;
......@@ -864,9 +854,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayInitialize) {
isolate->factory()->NewExternalArray(
static_cast<int>(length), arrayType,
static_cast<uint8_t*>(buffer->backing_store()) + byte_offset);
Handle<Map> map =
isolate->factory()->GetElementsTransitionMap(holder, elementsKind);
holder->set_map(*map);
holder->set_elements(*elements);
return isolate->heap()->undefined_value();
}
......
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