| Index: src/hydrogen.cc
|
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc
|
| index fd93ce3296dd5e75cbf1e733a41b3bdf9903720b..c5f5414cd2c19ee37f5881cb0b3dd660df3e72ba 100644
|
| --- a/src/hydrogen.cc
|
| +++ b/src/hydrogen.cc
|
| @@ -58,6 +58,7 @@
|
| #include "hydrogen-uint32-analysis.h"
|
| #include "lithium-allocator.h"
|
| #include "parser.h"
|
| +#include "runtime.h"
|
| #include "scopeinfo.h"
|
| #include "scopes.h"
|
| #include "stub-cache.h"
|
| @@ -8075,6 +8076,42 @@ const HOptimizedGraphBuilder::InlineFunctionGenerator
|
| #undef INLINE_FUNCTION_GENERATOR_ADDRESS
|
|
|
|
|
| +template <class ViewClass>
|
| +void HGraphBuilder::BuildArrayBufferViewInitialization(
|
| + HValue* obj,
|
| + HValue* buffer,
|
| + HValue* byte_offset,
|
| + HValue* byte_length) {
|
| +
|
| + for (int offset = ViewClass::kSize;
|
| + offset < ViewClass::kSizeWithInternalFields;
|
| + offset += kPointerSize) {
|
| + Add<HStoreNamedField>(obj,
|
| + HObjectAccess::ForJSObjectOffset(offset),
|
| + Add<HConstant>(static_cast<int32_t>(0)));
|
| + }
|
| +
|
| + Add<HStoreNamedField>(
|
| + obj,
|
| + HObjectAccess::ForJSArrayBufferViewBuffer(), buffer);
|
| + Add<HStoreNamedField>(
|
| + obj,
|
| + HObjectAccess::ForJSArrayBufferViewByteOffset(),
|
| + byte_offset);
|
| + Add<HStoreNamedField>(
|
| + obj,
|
| + HObjectAccess::ForJSArrayBufferViewByteLength(),
|
| + byte_length);
|
| +
|
| + HObjectAccess weak_first_view_access =
|
| + HObjectAccess::ForJSArrayBufferWeakFirstView();
|
| + Add<HStoreNamedField>(obj,
|
| + HObjectAccess::ForJSArrayBufferViewWeakNext(),
|
| + Add<HLoadNamedField>(buffer, weak_first_view_access));
|
| + Add<HStoreNamedField>(buffer, weak_first_view_access, obj);
|
| +}
|
| +
|
| +
|
| void HOptimizedGraphBuilder::VisitDataViewInitialize(
|
| CallRuntime* expr) {
|
| ZoneList<Expression*>* arguments = expr->arguments();
|
| @@ -8093,31 +8130,127 @@ void HOptimizedGraphBuilder::VisitDataViewInitialize(
|
| CHECK_ALIVE(VisitForValue(arguments->at(3)));
|
| HValue* byte_length = Pop();
|
|
|
| - for (int offset = JSDataView::kSize;
|
| - offset < JSDataView::kSizeWithInternalFields;
|
| - offset += kPointerSize) {
|
| - Add<HStoreNamedField>(obj,
|
| - HObjectAccess::ForJSObjectOffset(offset),
|
| - Add<HConstant>(static_cast<int32_t>(0)));
|
| + BuildArrayBufferViewInitialization<JSDataView>(
|
| + obj, buffer, byte_offset, byte_length);
|
| +}
|
| +
|
| +
|
| +void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
|
| + CallRuntime* expr) {
|
| + ZoneList<Expression*>* arguments = expr->arguments();
|
| +
|
| + NoObservableSideEffectsScope scope(this);
|
| + static const int kObjectArg = 0;
|
| + static const int kArrayIdArg = 1;
|
| + static const int kBufferArg = 2;
|
| + static const int kByteOffsetArg = 3;
|
| + static const int kByteLengthArg = 4;
|
| + static const int kArgsLength = 5;
|
| + ASSERT(arguments->length() == kArgsLength);
|
| +
|
| +
|
| + CHECK_ALIVE(VisitForValue(arguments->at(kObjectArg)));
|
| + HValue* obj = Pop();
|
| +
|
| + ASSERT(arguments->at(kArrayIdArg)->node_type() == AstNode::kLiteral);
|
| + Handle<Object> value =
|
| + static_cast<Literal*>(arguments->at(kArrayIdArg))->value();
|
| + ASSERT(value->IsSmi());
|
| + int array_id = Smi::cast(*value)->value();
|
| +
|
| + CHECK_ALIVE(VisitForValue(arguments->at(kBufferArg)));
|
| + HValue* buffer = Pop();
|
| +
|
| + HValue* byte_offset;
|
| + bool is_zero_byte_offset;
|
| +
|
| + if (arguments->at(kByteOffsetArg)->node_type() == AstNode::kLiteral
|
| + && Smi::FromInt(0) ==
|
| + *static_cast<Literal*>(arguments->at(kByteOffsetArg))->value()) {
|
| + byte_offset = Add<HConstant>(static_cast<int32_t>(0));
|
| + is_zero_byte_offset = true;
|
| + } else {
|
| + CHECK_ALIVE(VisitForValue(arguments->at(kByteOffsetArg)));
|
| + byte_offset = Pop();
|
| + is_zero_byte_offset = false;
|
| }
|
|
|
| - Add<HStoreNamedField>(obj,
|
| - HObjectAccess::ForJSObjectOffset(JSDataView::kBufferOffset), buffer);
|
| - Add<HStoreNamedField>(obj,
|
| - HObjectAccess::ForJSObjectOffset(JSDataView::kByteOffsetOffset),
|
| - byte_offset);
|
| - Add<HStoreNamedField>(obj,
|
| - HObjectAccess::ForJSObjectOffset(JSDataView::kByteLengthOffset),
|
| - byte_length);
|
| + CHECK_ALIVE(VisitForValue(arguments->at(kByteLengthArg)));
|
| + HValue* byte_length = Pop();
|
|
|
| - Add<HStoreNamedField>(obj,
|
| - HObjectAccess::ForJSObjectOffset(JSDataView::kWeakNextOffset),
|
| - Add<HLoadNamedField>(buffer,
|
| - HObjectAccess::ForJSObjectOffset(
|
| - JSArrayBuffer::kWeakFirstViewOffset)));
|
| - Add<HStoreNamedField>(buffer,
|
| - HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset),
|
| - obj);
|
| + IfBuilder byte_offset_smi(this);
|
| +
|
| + if (!is_zero_byte_offset) {
|
| + byte_offset_smi.If<HIsSmiAndBranch>(byte_offset);
|
| + byte_offset_smi.Then();
|
| + }
|
| +
|
| + { // byte_offset is Smi.
|
| + BuildArrayBufferViewInitialization<JSTypedArray>(
|
| + obj, buffer, byte_offset, byte_length);
|
| +
|
| + ExternalArrayType array_type = kExternalByteArray; // 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)));
|
| +
|
| + Add<HStoreNamedField>(obj,
|
| + HObjectAccess::ForJSTypedArrayLength(),
|
| + length);
|
| +
|
| + HValue* elements =
|
| + Add<HAllocate>(
|
| + Add<HConstant>(ExternalArray::kAlignedSize),
|
| + HType::JSArray(),
|
| + NOT_TENURED,
|
| + static_cast<InstanceType>(FIRST_EXTERNAL_ARRAY_TYPE + array_type));
|
| +
|
| + Handle<Map> external_array_map(
|
| + isolate()->heap()->MapForExternalArrayType(array_type));
|
| + Add<HStoreNamedField>(elements,
|
| + HObjectAccess::ForMap(),
|
| + Add<HConstant>(external_array_map));
|
| +
|
| + HValue* backing_store = Add<HLoadNamedField>(
|
| + buffer, 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;
|
| + }
|
| +
|
| + Add<HStoreNamedField>(elements,
|
| + HObjectAccess::ForExternalArrayExternalPointer(),
|
| + typed_array_start);
|
| + Add<HStoreNamedField>(elements,
|
| + HObjectAccess::ForFixedArrayLength(),
|
| + length);
|
| + Add<HStoreNamedField>(
|
| + obj, HObjectAccess::ForElementsPointer(), elements);
|
| + }
|
| +
|
| + if (!is_zero_byte_offset) {
|
| + byte_offset_smi.Else();
|
| + { // byte_offset is not Smi.
|
| + Push(Add<HPushArgument>(obj));
|
| + VisitArgument(arguments->at(kArrayIdArg));
|
| + Push(Add<HPushArgument>(buffer));
|
| + Push(Add<HPushArgument>(byte_offset));
|
| + Push(Add<HPushArgument>(byte_length));
|
| + Add<HCallRuntime>(expr->name(), expr->function(), kArgsLength);
|
| + Drop(kArgsLength);
|
| + }
|
| + }
|
| + byte_offset_smi.End();
|
| }
|
|
|
|
|
| @@ -8136,6 +8269,16 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
|
| return VisitDataViewInitialize(expr);
|
| }
|
|
|
| + if (function->function_id == Runtime::kTypedArrayInitialize) {
|
| + return VisitTypedArrayInitialize(expr);
|
| + }
|
| +
|
| + if (function->function_id == Runtime::kMaxSmi) {
|
| + ASSERT(expr->arguments()->length() == 0);
|
| + HConstant* max_smi = New<HConstant>(static_cast<int32_t>(Smi::kMaxValue));
|
| + return ast_context()->ReturnInstruction(max_smi, expr->id());
|
| + }
|
| +
|
| if (function->intrinsic_type == Runtime::INLINE) {
|
| ASSERT(expr->name()->length() > 0);
|
| ASSERT(expr->name()->Get(0) == '_');
|
|
|