Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Unified Diff: src/hydrogen.cc

Issue 59023003: Generate TypedArrayInitialize builtin in hydrogen. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Rebased and updated Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index b5449045ded6eb1e29e4e5161968214f5eaec5ac..e08717f50c702129eac8535a89ec3702d8fd333a 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"
@@ -8052,6 +8053,139 @@ const HOptimizedGraphBuilder::InlineFunctionGenerator
#undef INLINE_FUNCTION_GENERATOR_ADDRESS
+void HOptimizedGraphBuilder::VisitTypedArrayInitialize(
+ CallRuntime* expr) {
+ ZoneList<Expression*>* arguments = expr->arguments();
+
+ NoObservableSideEffectsScope scope(this);
+ ASSERT(arguments->length()== 5);
+ CHECK_ALIVE(VisitForValue(arguments->at(0)));
+ HValue* obj = Pop();
+
+ ASSERT(arguments->at(1)->node_type() == AstNode::kLiteral);
mvstanton 2013/11/18 10:44:49 Could you use constants for these arguments with a
Dmitry Lomov (no reviews) 2013/11/18 13:48:14 Done. Great suggestion, because it uncovered a bug
+ Handle<Object> value = static_cast<Literal*>(arguments->at(1))->value();
+ ASSERT(value->IsSmi());
mvstanton 2013/11/18 10:44:49 The assert is unnecessary because the Smi::cast wi
Dmitry Lomov (no reviews) 2013/11/18 13:48:14 I am paranoid lately.
+ int array_id = Smi::cast(*value)->value();
+
+ CHECK_ALIVE(VisitForValue(arguments->at(2)));
+ HValue* buffer = Pop();
+
+ HValue* byte_offset;
+ bool is_zero_byte_offset;
+
+ if (arguments->at(3)->node_type() == AstNode::kLiteral
+ && Smi::FromInt(0) == *static_cast<Literal*>(arguments->at(1))->value()) {
+ byte_offset = Add<HConstant>(static_cast<int32_t>(0));
+ is_zero_byte_offset = true;
+ } else {
+ CHECK_ALIVE(VisitForValue(arguments->at(3)));
+ byte_offset = Pop();
+ is_zero_byte_offset = false;
+ }
+
+ CHECK_ALIVE(VisitForValue(arguments->at(4)));
+ HValue* byte_length = Pop();
+
+ IfBuilder byte_offset_smi(this);
+
+ if (!is_zero_byte_offset) {
+ byte_offset_smi.If<HIsSmiAndBranch>(byte_offset);
+ byte_offset_smi.Then();
+ }
+
+ ExternalArrayType array_type = kExternalByteArray; // Bogus initialization.
+ size_t element_size = 1; // Bogus initialization.
+ Runtime::ArrayIdToTypeAndSize(array_id, &array_type, &element_size);
+
+ for (int offset = JSTypedArray::kSize;
+ offset < JSTypedArray::kSizeWithInternalFields;
+ offset += kPointerSize) {
+ Add<HStoreNamedField>(obj,
+ HObjectAccess::ForJSObjectOffset(offset),
+ Add<HConstant>(static_cast<int32_t>(0)));
mvstanton 2013/11/18 10:44:49 Not something we have to do now, but it would be n
Dmitry Lomov (no reviews) 2013/11/18 13:48:14 Agreed.
+ }
+
+ Add<HStoreNamedField>(obj,
+ HObjectAccess::ForJSObjectOffset(JSTypedArray::kBufferOffset), buffer);
+ Add<HStoreNamedField>(obj,
+ HObjectAccess::ForJSObjectOffset(JSTypedArray::kByteOffsetOffset),
+ byte_offset);
+ Add<HStoreNamedField>(obj,
+ HObjectAccess::ForJSObjectOffset(JSTypedArray::kByteLengthOffset),
+ byte_length);
+
+ HInstruction* length = Add<HDiv>(byte_length,
+ Add<HConstant>(static_cast<int32_t>(element_size)));
+
+ Add<HStoreNamedField>(obj,
+ HObjectAccess::ForJSObjectOffset(JSTypedArray::kLengthOffset),
+ length);
+
+ Add<HStoreNamedField>(obj,
+ HObjectAccess::ForJSObjectOffset(JSTypedArray::kWeakNextOffset),
+ Add<HLoadNamedField>(buffer,
+ HObjectAccess::ForJSObjectOffset(
+
mvstanton 2013/11/18 10:44:49 nit: Remove newline.
Dmitry Lomov (no reviews) 2013/11/18 13:48:14 Done.
+ JSArrayBuffer::kWeakFirstViewOffset)));
+ Add<HStoreNamedField>(buffer,
+ HObjectAccess::ForJSObjectOffset(JSArrayBuffer::kWeakFirstViewOffset),
+ obj);
+
+ HValue* elements =
+ Add<HAllocate>(
+ Add<HConstant>(ExternalArray::kAlignedSize),
+ HType::JSArray(),
+ isolate()->heap()->GetPretenureMode(),
mvstanton 2013/11/18 10:44:49 It would be good if you continue passing NOT_TENUR
Dmitry Lomov (no reviews) 2013/11/18 13:48:14 Done.
+ 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::ForJSObjectOffset(
+ JSArrayBuffer::kBackingStoreOffset, Representation::External()));
+
+ HValue* typed_array_start;
+ if (is_zero_byte_offset) {
+ typed_array_start = backing_store;
+ } else {
+ HAdd* external_pointer =
+ HAdd::NewExternalPointerOffset(
+ zone(), graph()->GetInvalidContext(), backing_store, byte_offset);
+ // Arguments are checked prior to call to TypedArrayInitialize,
+ // including byte_offset.
+ external_pointer->ClearFlag(HValue::kCanOverflow);
danno 2013/11/18 14:26:17 This should be folded into the constructor of the
Dmitry Lomov (no reviews) 2013/11/18 16:43:54 No, because it is in this particular case (in Type
+ typed_array_start = AddInstruction(external_pointer);
+ }
+
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForJSObjectOffset(
+ ExternalArray::kExternalPointerOffset, Representation::External()),
+ typed_array_start);
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForJSObjectOffset(ExternalArray::kLengthOffset),
+ length);
+ Add<HStoreNamedField>(
+ obj, HObjectAccess::ForElementsPointer(), elements);
+
+ if (!is_zero_byte_offset) {
+ byte_offset_smi.Else();
danno 2013/11/18 14:26:17 Perhaps use the {} indenting style used in code-st
Dmitry Lomov (no reviews) 2013/11/18 16:43:54 Done.
+ Push(Add<HPushArgument>(obj));
+ VisitArgument(arguments->at(1));
+ Push(Add<HPushArgument>(buffer));
+ Push(Add<HPushArgument>(byte_offset));
+ Push(Add<HPushArgument>(byte_length));
+ Add<HCallRuntime>(expr->name(), expr->function(), 5);
+ Drop(5);
+ byte_offset_smi.End();
+ }
+}
+
+
void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
@@ -8062,6 +8196,17 @@ void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
const Runtime::Function* function = expr->function();
ASSERT(function != NULL);
+
+ 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) == '_');
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | src/hydrogen-instructions.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698