Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 0be9dfbc0a6719b1daca562313c1e1e0b6cb9043..1d53f03aa03fae63f3d5cae724b9e2a2cdf5c279 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -6466,7 +6466,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( |
| @@ -8418,9 +8419,6 @@ void HGraphBuilder::BuildArrayBufferViewInitialization( |
| Add<HStoreNamedField>( |
| obj, |
| - HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); |
| - Add<HStoreNamedField>( |
| - obj, |
| HObjectAccess::ForJSArrayBufferViewByteOffset(), |
| byte_offset); |
| Add<HStoreNamedField>( |
| @@ -8428,14 +8426,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()); |
| + } |
| } |
| @@ -8462,8 +8473,26 @@ void HOptimizedGraphBuilder::VisitDataViewInitialize( |
| } |
| -void HOptimizedGraphBuilder::VisitTypedArrayInitialize( |
| - CallRuntime* expr) { |
| +static Handle<Map> TypedArrayMap(Isolate* isolate, |
| + 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) { |
| ZoneList<Expression*>* arguments = expr->arguments(); |
| NoObservableSideEffectsScope scope(this); |
| @@ -8485,8 +8514,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; |
| @@ -8500,6 +8534,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))); |
| @@ -8512,13 +8547,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))); |
| @@ -8527,40 +8573,96 @@ 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(), |
|
Toon Verwaest
2014/03/24 11:16:12
Is this correct? I'd think only obj is HType::JSAr
Dmitry Lomov (no reviews)
2014/03/25 10:17:40
Done.
|
| + 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; |
| + |
| + // if fixed array's elements are not aligned to object's alignment, |
| + // we need to align the whole array to object alignment. |
| + 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); |
|
Toon Verwaest
2014/03/24 11:16:12
Is this the only place where we do alignment? If n
Dmitry Lomov (no reviews)
2014/03/25 10:17:40
Done.
|
| + } |
| + |
| + Handle<Map> fixed_typed_array_map( |
| + isolate()->heap()->MapForFixedTypedArray(array_type)); |
| + elements = |
| + Add<HAllocate>(total_size, HType::JSArray(), |
|
Toon Verwaest
2014/03/24 11:16:12
Not a JSArray()
Dmitry Lomov (no reviews)
2014/03/25 10:17:40
Done.
|
| + 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); |
| } |
| @@ -8606,6 +8708,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) == '_'); |