Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 25fc74973a8a721c0c3afdffbd76722d6026c5bc..a9d98a5da5cdc82c0d8fd22e0e2081af99bd1605 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -6469,7 +6469,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
access = AddInstruction(BuildKeyedGeneric(access_type, object, key, val)); |
} else { |
ASSERT(IsFastElementsKind(elements_kind) || |
- IsExternalArrayElementsKind(elements_kind)); |
+ IsExternalArrayElementsKind(elements_kind) || |
+ IsFixedTypedArrayElementsKind(elements_kind)); |
LoadKeyedHoleMode load_mode = BuildKeyedHoleMode(map); |
// Happily, mapcompare is a checked object. |
access = BuildUncheckedMonomorphicElementAccess( |
@@ -8409,9 +8410,6 @@ void HGraphBuilder::BuildArrayBufferViewInitialization( |
Add<HStoreNamedField>( |
obj, |
- HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); |
- Add<HStoreNamedField>( |
- obj, |
HObjectAccess::ForJSArrayBufferViewByteOffset(), |
byte_offset); |
Add<HStoreNamedField>( |
@@ -8419,14 +8417,27 @@ void HGraphBuilder::BuildArrayBufferViewInitialization( |
HObjectAccess::ForJSArrayBufferViewByteLength(), |
byte_length); |
- HObjectAccess weak_first_view_access = |
- HObjectAccess::ForJSArrayBufferWeakFirstView(); |
- Add<HStoreNamedField>(obj, |
- HObjectAccess::ForJSArrayBufferViewWeakNext(), |
- Add<HLoadNamedField>(buffer, static_cast<HValue*>(NULL), |
- weak_first_view_access)); |
- Add<HStoreNamedField>( |
- buffer, weak_first_view_access, obj); |
+ if (buffer != NULL) { |
+ Add<HStoreNamedField>( |
+ obj, |
+ HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); |
+ HObjectAccess weak_first_view_access = |
+ HObjectAccess::ForJSArrayBufferWeakFirstView(); |
+ Add<HStoreNamedField>(obj, |
+ HObjectAccess::ForJSArrayBufferViewWeakNext(), |
+ Add<HLoadNamedField>(buffer, |
+ static_cast<HValue*>(NULL), |
+ weak_first_view_access)); |
+ Add<HStoreNamedField>(buffer, weak_first_view_access, obj); |
+ } else { |
+ Add<HStoreNamedField>( |
+ obj, |
+ HObjectAccess::ForJSArrayBufferViewBuffer(), |
+ Add<HConstant>(static_cast<int32_t>(0))); |
+ Add<HStoreNamedField>(obj, |
+ HObjectAccess::ForJSArrayBufferViewWeakNext(), |
+ graph()->GetConstantUndefined()); |
+ } |
} |
@@ -8452,9 +8463,26 @@ void HOptimizedGraphBuilder::VisitDataViewInitialize( |
obj, buffer, byte_offset, byte_length); |
} |
+static Handle<Map> TypedArrayMap(Isolate* isolate, |
mvstanton
2014/03/11 10:43:51
nit: add another space above this method.
Dmitry Lomov (no reviews)
2014/03/24 08:31:22
Done.
|
+ ExternalArrayType array_type, |
+ ElementsKind target_kind) { |
+ Handle<Context> native_context = isolate->native_context(); |
+ Handle<JSFunction> fun; |
+ switch (array_type) { |
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
+ case kExternal##Type##Array: \ |
+ fun = Handle<JSFunction>(native_context->type##_array_fun()); \ |
+ break; |
+ |
+ TYPED_ARRAYS(TYPED_ARRAY_CASE) |
+#undef TYPED_ARRAY_CASE |
+ } |
+ Handle<Map> map(fun->initial_map()); |
+ return Map::AsElementsKind(map, target_kind); |
+} |
+ |
-void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
- CallRuntime* expr) { |
+void HOptimizedGraphBuilder::VisitTypedArrayInitialize(CallRuntime* expr) { |
ZoneList<Expression*>* arguments = expr->arguments(); |
NoObservableSideEffectsScope scope(this); |
@@ -8476,8 +8504,13 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
ASSERT(value->IsSmi()); |
int array_id = Smi::cast(*value)->value(); |
- CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); |
- HValue* buffer = Pop(); |
+ HValue* buffer; |
+ if (!arguments->at(kBufferArg)->IsNullLiteral()) { |
+ CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg))); |
+ buffer = Pop(); |
+ } else { |
+ buffer = NULL; |
+ } |
HValue* byte_offset; |
bool is_zero_byte_offset; |
@@ -8491,6 +8524,7 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg))); |
byte_offset = Pop(); |
is_zero_byte_offset = false; |
+ ASSERT(buffer != NULL); |
} |
CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg))); |
@@ -8503,13 +8537,24 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
byte_offset_smi.Then(); |
} |
+ ExternalArrayType array_type = |
+ kExternalInt8Array; // Bogus initialization. |
+ size_t element_size = 1; // Bogus initialization. |
+ ElementsKind external_elements_kind = // Bogus initialization. |
+ EXTERNAL_INT8_ELEMENTS; |
+ ElementsKind fixed_elements_kind = // Bogus initialization. |
+ INT8_ELEMENTS; |
+ Runtime::ArrayIdToTypeAndSize(array_id, |
+ &array_type, |
+ &external_elements_kind, |
+ &fixed_elements_kind, |
+ &element_size); |
+ |
+ |
{ // byte_offset is Smi. |
BuildArrayBufferViewInitialization<JSTypedArray>( |
obj, buffer, byte_offset, byte_length); |
- ExternalArrayType array_type = kExternalInt8Array; // Bogus initialization. |
- size_t element_size = 1; // Bogus initialization. |
- Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size); |
HInstruction* length = AddUncasted<HDiv>(byte_length, |
Add<HConstant>(static_cast<int32_t>(element_size))); |
@@ -8518,40 +8563,94 @@ void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
HObjectAccess::ForJSTypedArrayLength(), |
length); |
- Handle<Map> external_array_map( |
- isolate()->heap()->MapForExternalArrayType(array_type)); |
- |
- HValue* elements = |
- Add<HAllocate>( |
- Add<HConstant>(ExternalArray::kAlignedSize), |
- HType::JSArray(), |
- NOT_TENURED, |
- external_array_map->instance_type()); |
+ HValue* elements; |
+ if (buffer != NULL) { |
+ Handle<Map> external_array_map( |
+ isolate()->heap()->MapForExternalArrayType(array_type)); |
+ elements = |
+ Add<HAllocate>( |
+ Add<HConstant>(ExternalArray::kAlignedSize), |
+ HType::JSArray(), |
+ NOT_TENURED, |
+ external_array_map->instance_type()); |
+ |
+ AddStoreMapConstant(elements, external_array_map); |
+ |
+ HValue* backing_store = Add<HLoadNamedField>( |
+ buffer, static_cast<HValue*>(NULL), |
+ HObjectAccess::ForJSArrayBufferBackingStore()); |
+ |
+ HValue* typed_array_start; |
+ if (is_zero_byte_offset) { |
+ typed_array_start = backing_store; |
+ } else { |
+ HInstruction* external_pointer = |
+ AddUncasted<HAdd>(backing_store, byte_offset); |
+ // Arguments are checked prior to call to TypedArrayInitialize, |
+ // including byte_offset. |
+ external_pointer->ClearFlag(HValue::kCanOverflow); |
+ typed_array_start = external_pointer; |
+ } |
- AddStoreMapConstant(elements, external_array_map); |
- HValue* backing_store = Add<HLoadNamedField>( |
- buffer, static_cast<HValue*>(NULL), |
- HObjectAccess::ForJSArrayBufferBackingStore()); |
+ Add<HStoreNamedField>(elements, |
+ HObjectAccess::ForExternalArrayExternalPointer(), |
+ typed_array_start); |
- HValue* typed_array_start; |
- if (is_zero_byte_offset) { |
- typed_array_start = backing_store; |
+ Handle<Map> obj_map = TypedArrayMap( |
+ isolate(), array_type, external_elements_kind); |
+ AddStoreMapConstant(obj, obj_map); |
+ Add<HStoreNamedField>(elements, |
+ HObjectAccess::ForFixedArrayLength(), |
+ length, INITIALIZING_STORE); |
} else { |
- HInstruction* external_pointer = |
- AddUncasted<HAdd>(backing_store, byte_offset); |
- // Arguments are checked prior to call to TypedArrayInitialize, |
- // including byte_offset. |
- external_pointer->ClearFlag(HValue::kCanOverflow); |
- typed_array_start = external_pointer; |
- } |
- |
- Add<HStoreNamedField>(elements, |
- HObjectAccess::ForExternalArrayExternalPointer(), |
- typed_array_start); |
- Add<HStoreNamedField>(elements, |
- HObjectAccess::ForFixedArrayLength(), |
- length); |
+ ASSERT(is_zero_byte_offset); |
+ |
+ STATIC_ASSERT( |
+ (FixedTypedArrayBase::kHeaderSize & kObjectAlignmentMask) == 0); |
+ HValue* total_size; |
+ |
mvstanton
2014/03/11 10:43:51
A short comment here to explain what you are doing
Dmitry Lomov (no reviews)
2014/03/24 08:31:22
Done.
|
+ if (element_size % kObjectAlignment != 0) { |
+ HConstant* header_size = Add<HConstant>(static_cast<int32_t>( |
+ FixedTypedArrayBase::kHeaderSize + kObjectAlignmentMask)); |
+ HValue* unaligned_size = AddUncasted<HAdd>(byte_length, header_size); |
+ unaligned_size->ClearFlag(HValue::kCanOverflow); |
+ total_size = AddUncasted<HBitwise>( |
+ Token::BIT_AND, unaligned_size, |
+ Add<HConstant>(static_cast<int32_t>(~kObjectAlignmentMask))); |
+ } else { |
+ total_size = AddUncasted<HAdd>(byte_length, |
+ Add<HConstant>(FixedTypedArrayBase::kHeaderSize)); |
+ total_size->ClearFlag(HValue::kCanOverflow); |
+ } |
+ |
+ Handle<Map> fixed_typed_array_map( |
+ isolate()->heap()->MapForFixedTypedArray(array_type)); |
+ elements = |
+ Add<HAllocate>(total_size, HType::JSArray(), |
+ NOT_TENURED, |
+ fixed_typed_array_map->instance_type()); |
+ AddStoreMapConstant(elements, fixed_typed_array_map); |
+ |
+ Add<HStoreNamedField>(elements, |
+ HObjectAccess::ForFixedArrayLength(), |
+ length, INITIALIZING_STORE); |
+ HValue* filler = Add<HConstant>(static_cast<int32_t>(0)); |
+ |
+ { |
+ LoopBuilder builder(this, context(), LoopBuilder::kPostIncrement); |
+ |
+ HValue* key = builder.BeginBody( |
+ Add<HConstant>(static_cast<int32_t>(0)), |
+ length, Token::LT); |
+ Add<HStoreKeyed>(elements, key, filler, fixed_elements_kind); |
+ |
+ builder.EndBody(); |
+ } |
+ } |
+ Add<HStoreNamedField>( |
+ elements, HObjectAccess::ForFixedArrayLength(), length, |
+ INITIALIZING_STORE); |
Add<HStoreNamedField>( |
obj, HObjectAccess::ForElementsPointer(), elements); |
} |
@@ -8597,6 +8696,14 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) { |
return ast_context()->ReturnInstruction(max_smi, expr->id()); |
} |
+ |
+ if (function->function_id == Runtime::kTypedArrayMaxSizeInHeap) { |
+ ASSERT(expr->arguments()->length() == 0); |
+ HConstant* value = New<HConstant>( |
+ static_cast<int32_t>(FLAG_typed_array_max_size_in_heap)); |
+ return ast_context()->ReturnInstruction(value, expr->id()); |
+ } |
+ |
if (function->intrinsic_type == Runtime::INLINE) { |
ASSERT(expr->name()->length() > 0); |
ASSERT(expr->name()->Get(0) == '_'); |