From 7cf9d1c8070668ff41c22d560bc6f192a8944087 Mon Sep 17 00:00:00 2001 From: "dslomov@chromium.org" Date: Fri, 17 Oct 2014 09:04:58 +0000 Subject: [PATCH] Share code between Factory::NewJSTypedArray and API R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/641343005 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24681 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/api.cc | 79 +++------------------- src/factory.cc | 72 +++++++++++++++----- src/factory.h | 4 +- .../compiler/js-typed-lowering-unittest.cc | 4 +- 4 files changed, 70 insertions(+), 89 deletions(-) diff --git a/src/api.cc b/src/api.cc index 4929fda..b190925 100644 --- a/src/api.cc +++ b/src/api.cc @@ -6100,78 +6100,22 @@ size_t v8::TypedArray::Length() { } -static inline void SetupArrayBufferView( - i::Isolate* isolate, - i::Handle obj, - i::Handle buffer, - size_t byte_offset, - size_t byte_length) { - DCHECK(byte_offset + byte_length <= - static_cast(buffer->byte_length()->Number())); - - obj->set_buffer(*buffer); - - obj->set_weak_next(buffer->weak_first_view()); - buffer->set_weak_first_view(*obj); - - i::Handle byte_offset_object = - isolate->factory()->NewNumberFromSize(byte_offset); - obj->set_byte_offset(*byte_offset_object); - - i::Handle byte_length_object = - isolate->factory()->NewNumberFromSize(byte_length); - obj->set_byte_length(*byte_length_object); -} - -template -i::Handle NewTypedArray( - i::Isolate* isolate, - Handle array_buffer, size_t byte_offset, size_t length) { - i::Handle obj = - isolate->factory()->NewJSTypedArray(array_type); - i::Handle buffer = Utils::OpenHandle(*array_buffer); - - DCHECK(byte_offset % sizeof(ElementType) == 0); - - CHECK(length <= (std::numeric_limits::max() / sizeof(ElementType))); - CHECK(length <= static_cast(i::Smi::kMaxValue)); - size_t byte_length = length * sizeof(ElementType); - SetupArrayBufferView( - isolate, obj, buffer, byte_offset, byte_length); - - i::Handle length_object = - isolate->factory()->NewNumberFromSize(length); - obj->set_length(*length_object); - - i::Handle elements = - isolate->factory()->NewExternalArray( - static_cast(length), array_type, - static_cast(buffer->backing_store()) + byte_offset); - i::Handle map = - i::JSObject::GetElementsTransitionMap(obj, elements_kind); - i::JSObject::SetMapAndElements(obj, map, elements); - return obj; -} - - #define TYPED_ARRAY_NEW(Type, type, TYPE, ctype, size) \ Local Type##Array::New(Handle array_buffer, \ - size_t byte_offset, size_t length) { \ + size_t byte_offset, size_t length) { \ i::Isolate* isolate = Utils::OpenHandle(*array_buffer)->GetIsolate(); \ LOG_API(isolate, \ - "v8::" #Type "Array::New(Handle, size_t, size_t)"); \ + "v8::" #Type "Array::New(Handle, size_t, size_t)"); \ ENTER_V8(isolate); \ if (!Utils::ApiCheck(length <= static_cast(i::Smi::kMaxValue), \ - "v8::" #Type "Array::New(Handle, size_t, size_t)", \ - "length exceeds max allowed value")) { \ - return Local(); \ + "v8::" #Type \ + "Array::New(Handle, size_t, size_t)", \ + "length exceeds max allowed value")) { \ + return Local(); \ } \ - i::Handle obj = \ - NewTypedArray( \ - isolate, array_buffer, byte_offset, length); \ + i::Handle buffer = Utils::OpenHandle(*array_buffer); \ + i::Handle obj = isolate->factory()->NewJSTypedArray( \ + v8::kExternal##Type##Array, buffer, byte_offset, length); \ return Utils::ToLocal##Type##Array(obj); \ } @@ -6185,9 +6129,8 @@ Local DataView::New(Handle array_buffer, i::Isolate* isolate = buffer->GetIsolate(); LOG_API(isolate, "v8::DataView::New(void*, size_t, size_t)"); ENTER_V8(isolate); - i::Handle obj = isolate->factory()->NewJSDataView(); - SetupArrayBufferView( - isolate, obj, buffer, byte_offset, byte_length); + i::Handle obj = + isolate->factory()->NewJSDataView(buffer, byte_offset, byte_length); return Utils::ToLocal(obj); } diff --git a/src/factory.cc b/src/factory.cc index d1deb75..e284382 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -1766,6 +1766,29 @@ JSFunction* GetTypedArrayFun(ExternalArrayType type, Isolate* isolate) { } } + +void SetupArrayBufferView(i::Isolate* isolate, + i::Handle obj, + i::Handle buffer, + size_t byte_offset, size_t byte_length) { + DCHECK(byte_offset + byte_length <= + static_cast(buffer->byte_length()->Number())); + + obj->set_buffer(*buffer); + + obj->set_weak_next(buffer->weak_first_view()); + buffer->set_weak_first_view(*obj); + + i::Handle byte_offset_object = + isolate->factory()->NewNumberFromSize(byte_offset); + obj->set_byte_offset(*byte_offset_object); + + i::Handle byte_length_object = + isolate->factory()->NewNumberFromSize(byte_length); + obj->set_byte_length(*byte_length_object); +} + + } // namespace @@ -1781,25 +1804,38 @@ Handle Factory::NewJSTypedArray(ExternalArrayType type) { Handle Factory::NewJSTypedArray(ExternalArrayType type, Handle buffer, + size_t byte_offset, size_t length) { - DCHECK(length <= static_cast(kMaxInt)); - Handle array = NewJSTypedArray(type); - array->set_buffer(*buffer); - array->set_weak_next(buffer->weak_first_view()); - buffer->set_weak_first_view(*array); - array->set_byte_offset(Smi::FromInt(0)); - Handle byte_length_handle = - NewNumberFromSize(length * GetExternalArrayElementSize(type)); - array->set_byte_length(*byte_length_handle); - Handle length_handle = NewNumberFromSize(length); - array->set_length(*length_handle); - Handle elements = - NewExternalArray(static_cast(length), type, buffer->backing_store()); - JSObject::SetMapAndElements(array, - JSObject::GetElementsTransitionMap( - array, GetExternalArrayElementsKind(type)), - elements); - return array; + Handle obj = NewJSTypedArray(type); + + size_t element_size = GetExternalArrayElementSize(type); + ElementsKind elements_kind = GetExternalArrayElementsKind(type); + + CHECK(byte_offset % element_size == 0); + + CHECK(length <= (std::numeric_limits::max() / element_size)); + CHECK(length <= static_cast(Smi::kMaxValue)); + size_t byte_length = length * element_size; + SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length); + + Handle length_object = NewNumberFromSize(length); + obj->set_length(*length_object); + + Handle elements = NewExternalArray( + static_cast(length), type, + static_cast(buffer->backing_store()) + byte_offset); + Handle map = JSObject::GetElementsTransitionMap(obj, elements_kind); + JSObject::SetMapAndElements(obj, map, elements); + return obj; +} + + +Handle Factory::NewJSDataView(Handle buffer, + size_t byte_offset, + size_t byte_length) { + Handle obj = NewJSDataView(); + SetupArrayBufferView(isolate(), obj, buffer, byte_offset, byte_length); + return obj; } diff --git a/src/factory.h b/src/factory.h index 089ab97..1a658d1 100644 --- a/src/factory.h +++ b/src/factory.h @@ -439,9 +439,11 @@ class Factory FINAL { // Creates a new JSTypedArray with the specified buffer. Handle NewJSTypedArray(ExternalArrayType type, Handle buffer, - size_t length); + size_t byte_offset, size_t length); Handle NewJSDataView(); + Handle NewJSDataView(Handle buffer, + size_t byte_offset, size_t byte_length); // Allocates a Harmony proxy. Handle NewJSProxy(Handle handler, Handle prototype); diff --git a/test/unittests/compiler/js-typed-lowering-unittest.cc b/test/unittests/compiler/js-typed-lowering-unittest.cc index 3ef5bdc..194591a 100644 --- a/test/unittests/compiler/js-typed-lowering-unittest.cc +++ b/test/unittests/compiler/js-typed-lowering-unittest.cc @@ -81,7 +81,7 @@ TEST_F(JSTypedLoweringTest, JSLoadPropertyFromExternalTypedArray) { FeedbackVectorSlot::Invalid()); TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { Handle array = - factory()->NewJSTypedArray(type, buffer, kLength); + factory()->NewJSTypedArray(type, buffer, 0, kLength); Node* key = Parameter(Type::Integral32()); Node* base = HeapConstant(array); @@ -120,7 +120,7 @@ TEST_F(JSTypedLoweringTest, JSStorePropertyToExternalTypedArray) { TRACED_FOREACH(ExternalArrayType, type, kExternalArrayTypes) { TRACED_FOREACH(StrictMode, strict_mode, kStrictModes) { Handle array = - factory()->NewJSTypedArray(type, buffer, kLength); + factory()->NewJSTypedArray(type, buffer, 0, kLength); Node* key = Parameter(Type::Integral32()); Node* base = HeapConstant(array); -- 2.7.4