Chromium Code Reviews| 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) == '_'); |