From 98140318fac953e675369d0e97dc8f8646324060 Mon Sep 17 00:00:00 2001 From: jochen Date: Thu, 30 Apr 2015 06:46:27 -0700 Subject: [PATCH] Unify internal and external typed arrays a bit Just give internal ones an ArrayBuffer with a NULL backing store. This simplifies the access checks a lot. BUG=v8:3996 R=hpayer@chromium.org,verwaest@chromium.org LOG=n Review URL: https://codereview.chromium.org/1109353003 Cr-Commit-Position: refs/heads/master@{#28168} --- include/v8.h | 2 +- src/api.cc | 42 ++++++---------- src/arm/lithium-codegen-arm.cc | 4 -- src/arm64/lithium-codegen-arm64.cc | 4 -- src/bootstrapper.cc | 1 + src/contexts.h | 2 + src/factory.cc | 4 +- src/hydrogen-instructions.h | 5 ++ src/hydrogen.cc | 96 +++++++++++++++++++++++------------- src/hydrogen.h | 1 + src/ia32/lithium-codegen-ia32.cc | 4 -- src/mips/lithium-codegen-mips.cc | 4 -- src/mips64/lithium-codegen-mips64.cc | 4 -- src/objects-inl.h | 2 +- src/objects.cc | 19 ++++--- src/ppc/lithium-codegen-ppc.cc | 4 -- src/runtime/runtime-typedarray.cc | 4 +- src/x64/lithium-codegen-x64.cc | 4 -- src/x87/lithium-codegen-x87.cc | 4 -- 19 files changed, 105 insertions(+), 105 deletions(-) diff --git a/include/v8.h b/include/v8.h index 9103845..73e5e5c 100644 --- a/include/v8.h +++ b/include/v8.h @@ -6670,7 +6670,7 @@ class Internals { static const int kJSObjectHeaderSize = 3 * kApiPointerSize; static const int kFixedArrayHeaderSize = 2 * kApiPointerSize; static const int kContextHeaderSize = 2 * kApiPointerSize; - static const int kContextEmbedderDataIndex = 76; + static const int kContextEmbedderDataIndex = 77; static const int kFullStringRepresentationMask = 0x07; static const int kStringEncodingMask = 0x4; static const int kExternalTwoByteRepresentationTag = 0x02; diff --git a/src/api.cc b/src/api.cc index c42cab6..a750c0c 100644 --- a/src/api.cc +++ b/src/api.cc @@ -6336,31 +6336,21 @@ Local v8::ArrayBufferView::Buffer() { size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { - i::Handle obj = Utils::OpenHandle(this); - i::Isolate* isolate = obj->GetIsolate(); - size_t byte_offset = i::NumberToSize(isolate, obj->byte_offset()); + i::Handle self = Utils::OpenHandle(this); + i::Isolate* isolate = self->GetIsolate(); + size_t byte_offset = i::NumberToSize(isolate, self->byte_offset()); size_t bytes_to_copy = - i::Min(byte_length, i::NumberToSize(isolate, obj->byte_length())); + i::Min(byte_length, i::NumberToSize(isolate, self->byte_length())); if (bytes_to_copy) { i::DisallowHeapAllocation no_gc; - const char* source = nullptr; - if (obj->IsJSDataView()) { - i::Handle data_view(i::JSDataView::cast(*obj)); - i::Handle buffer( - i::JSArrayBuffer::cast(data_view->buffer())); - source = reinterpret_cast(buffer->backing_store()); - } else { - DCHECK(obj->IsJSTypedArray()); - i::Handle typed_array(i::JSTypedArray::cast(*obj)); - if (typed_array->buffer()->IsSmi()) { - i::Handle fixed_array( - i::FixedTypedArrayBase::cast(typed_array->elements())); - source = reinterpret_cast(fixed_array->DataPtr()); - } else { - i::Handle buffer( - i::JSArrayBuffer::cast(typed_array->buffer())); - source = reinterpret_cast(buffer->backing_store()); - } + i::Handle buffer(i::JSArrayBuffer::cast(self->buffer())); + const char* source = reinterpret_cast(buffer->backing_store()); + if (source == nullptr) { + DCHECK(self->IsJSTypedArray()); + i::Handle typed_array(i::JSTypedArray::cast(*self)); + i::Handle fixed_array( + i::FixedTypedArrayBase::cast(typed_array->elements())); + source = reinterpret_cast(fixed_array->DataPtr()); } memcpy(dest, source + byte_offset, bytes_to_copy); } @@ -6369,11 +6359,9 @@ size_t v8::ArrayBufferView::CopyContents(void* dest, size_t byte_length) { bool v8::ArrayBufferView::HasBuffer() const { - i::Handle obj = Utils::OpenHandle(this); - if (obj->IsJSDataView()) return true; - DCHECK(obj->IsJSTypedArray()); - i::Handle typed_array(i::JSTypedArray::cast(*obj)); - return !typed_array->buffer()->IsSmi(); + i::Handle self = Utils::OpenHandle(this); + i::Handle buffer(i::JSArrayBuffer::cast(self->buffer())); + return buffer->backing_store() != nullptr; } diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index be7958e..b480fd9 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -5163,14 +5163,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = scratch0(); - Label has_no_buffer; __ ldr(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ ldr(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); __ tst(scratch, Operand(1 << JSArrayBuffer::WasNeutered::kShift)); DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds); - - __ bind(&has_no_buffer); } diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index badd177..a249ca4 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -2235,14 +2235,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = temps.AcquireX(); - Label has_no_buffer; __ Ldr(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ Ldr(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); __ Tst(scratch, Operand(1 << JSArrayBuffer::WasNeutered::kShift)); DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds); - - __ Bind(&has_no_buffer); } diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc index cf79f37..4117ce0 100644 --- a/src/bootstrapper.cc +++ b/src/bootstrapper.cc @@ -1151,6 +1151,7 @@ void Genesis::InitializeGlobal(Handle global_object, isolate->initial_object_prototype(), Builtins::kIllegal); native_context()->set_array_buffer_fun(*array_buffer_fun); + native_context()->set_array_buffer_map(array_buffer_fun->initial_map()); } { // -- T y p e d A r r a y s diff --git a/src/contexts.h b/src/contexts.h index 4fe0621..2d04da2 100644 --- a/src/contexts.h +++ b/src/contexts.h @@ -101,6 +101,7 @@ enum BindingFlags { V(TO_LENGTH_FUN_INDEX, JSFunction, to_length_fun) \ V(GLOBAL_EVAL_FUN_INDEX, JSFunction, global_eval_fun) \ V(ARRAY_BUFFER_FUN_INDEX, JSFunction, array_buffer_fun) \ + V(ARRAY_BUFFER_MAP_INDEX, Map, array_buffer_map) \ V(UINT8_ARRAY_FUN_INDEX, JSFunction, uint8_array_fun) \ V(INT8_ARRAY_FUN_INDEX, JSFunction, int8_array_fun) \ V(UINT16_ARRAY_FUN_INDEX, JSFunction, uint16_array_fun) \ @@ -352,6 +353,7 @@ class Context: public FixedArray { TO_BOOLEAN_FUN_INDEX, GLOBAL_EVAL_FUN_INDEX, ARRAY_BUFFER_FUN_INDEX, + ARRAY_BUFFER_MAP_INDEX, UINT8_ARRAY_FUN_INDEX, INT8_ARRAY_FUN_INDEX, UINT16_ARRAY_FUN_INDEX, diff --git a/src/factory.cc b/src/factory.cc index ddb6a64..3df71b1 100644 --- a/src/factory.cc +++ b/src/factory.cc @@ -1987,7 +1987,9 @@ Handle Factory::NewJSTypedArray(ElementsKind elements_kind, Handle length_object = NewNumberFromSize(number_of_elements); obj->set_length(*length_object); - obj->set_buffer(Smi::FromInt(0)); + Handle buffer = isolate()->factory()->NewJSArrayBuffer(); + Runtime::SetupArrayBuffer(isolate(), buffer, true, NULL, byte_length); + obj->set_buffer(*buffer); Handle elements = isolate()->factory()->NewFixedTypedArray( static_cast(number_of_elements), array_type); diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 6f56c76..e49e860 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -6130,6 +6130,11 @@ class HObjectAccess final { JSArrayBuffer::kBitFieldOffset, Representation::Integer32()); } + static HObjectAccess ForJSArrayBufferBitFieldSlot() { + return HObjectAccess::ForObservableJSObjectOffset( + JSArrayBuffer::kBitFieldSlot, Representation::Smi()); + } + static HObjectAccess ForExternalArrayExternalPointer() { return HObjectAccess::ForObservableJSObjectOffset( ExternalArray::kExternalPointerOffset, Representation::External()); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index 5827059..e03a205 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -3191,29 +3191,21 @@ HValue* HGraphBuilder::BuildArrayBufferViewFieldAccessor(HValue* object, object, checked_object, HObjectAccess::ForJSArrayBufferViewBuffer()); HInstruction* field = Add(object, checked_object, access); - IfBuilder if_has_buffer(this); - HValue* has_buffer = if_has_buffer.IfNot(buffer); - if_has_buffer.Then(); - { - HInstruction* flags = Add( - buffer, has_buffer, HObjectAccess::ForJSArrayBufferBitField()); - HValue* was_neutered_mask = - Add(1 << JSArrayBuffer::WasNeutered::kShift); - HValue* was_neutered_test = - AddUncasted(Token::BIT_AND, flags, was_neutered_mask); - - IfBuilder if_was_neutered(this); - if_was_neutered.If( - was_neutered_test, graph()->GetConstant0(), Token::NE); - if_was_neutered.Then(); - Push(graph()->GetConstant0()); - if_was_neutered.Else(); - Push(field); - if_was_neutered.End(); - } - if_has_buffer.Else(); + HInstruction* flags = Add( + buffer, nullptr, HObjectAccess::ForJSArrayBufferBitField()); + HValue* was_neutered_mask = + Add(1 << JSArrayBuffer::WasNeutered::kShift); + HValue* was_neutered_test = + AddUncasted(Token::BIT_AND, flags, was_neutered_mask); + + IfBuilder if_was_neutered(this); + if_was_neutered.If( + was_neutered_test, graph()->GetConstant0(), Token::NE); + if_was_neutered.Then(); + Push(graph()->GetConstant0()); + if_was_neutered.Else(); Push(field); - if_has_buffer.End(); + if_was_neutered.End(); return Pop(); } @@ -9726,6 +9718,45 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { } +HValue* HGraphBuilder::BuildAllocateEmptyArrayBuffer(HValue* byte_length) { + HAllocate* result = + BuildAllocate(Add(JSArrayBuffer::kSizeWithInternalFields), + HType::JSObject(), JS_ARRAY_BUFFER_TYPE, HAllocationMode()); + + HValue* global_object = Add( + context(), nullptr, + HObjectAccess::ForContextSlot(Context::GLOBAL_OBJECT_INDEX)); + HValue* native_context = Add( + global_object, nullptr, HObjectAccess::ForGlobalObjectNativeContext()); + Add( + result, HObjectAccess::ForMap(), + Add( + native_context, nullptr, + HObjectAccess::ForContextSlot(Context::ARRAY_BUFFER_MAP_INDEX))); + + Add(result, HObjectAccess::ForJSArrayBufferBackingStore(), + Add(ExternalReference())); + Add(result, HObjectAccess::ForJSArrayBufferByteLength(), + byte_length); + Add(result, HObjectAccess::ForJSArrayBufferBitFieldSlot(), + graph()->GetConstant0()); + Add( + result, HObjectAccess::ForJSArrayBufferBitField(), + Add((1 << JSArrayBuffer::IsExternal::kShift) | + (1 << JSArrayBuffer::IsNeuterable::kShift))); + + for (int field = 0; field < v8::ArrayBuffer::kInternalFieldCount; ++field) { + Add( + result, + HObjectAccess::ForObservableJSObjectOffset( + JSArrayBuffer::kSize + field * kPointerSize, Representation::Smi()), + graph()->GetConstant0()); + } + + return result; +} + + template void HGraphBuilder::BuildArrayBufferViewInitialization( HValue* obj, @@ -9749,17 +9780,8 @@ void HGraphBuilder::BuildArrayBufferViewInitialization( obj, HObjectAccess::ForJSArrayBufferViewByteLength(), byte_length); - - if (buffer != NULL) { - Add( - obj, - HObjectAccess::ForJSArrayBufferViewBuffer(), buffer); - } else { - Add( - obj, - HObjectAccess::ForJSArrayBufferViewBuffer(), - Add(static_cast(0))); - } + Add(obj, HObjectAccess::ForJSArrayBufferViewBuffer(), + buffer); } @@ -9981,8 +10003,12 @@ void HOptimizedGraphBuilder::GenerateTypedArrayInitialize( { // byte_offset is Smi. - BuildArrayBufferViewInitialization( - obj, buffer, byte_offset, byte_length); + HValue* allocated_buffer = buffer; + if (buffer == NULL) { + allocated_buffer = BuildAllocateEmptyArrayBuffer(byte_length); + } + BuildArrayBufferViewInitialization(obj, allocated_buffer, + byte_offset, byte_length); HInstruction* length = AddUncasted(byte_length, diff --git a/src/hydrogen.h b/src/hydrogen.h index e229b04..f5fa62f 100644 --- a/src/hydrogen.h +++ b/src/hydrogen.h @@ -1899,6 +1899,7 @@ class HGraphBuilder { SourcePosition source_position() { return position_; } void set_source_position(SourcePosition position) { position_ = position; } + HValue* BuildAllocateEmptyArrayBuffer(HValue* byte_length); template void BuildArrayBufferViewInitialization(HValue* obj, HValue* buffer, diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index d4b8b61..f28afa8 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -4978,14 +4978,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = ToRegister(instr->scratch()); - Label has_no_buffer; __ mov(scratch, FieldOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ test_b(FieldOperand(scratch, JSArrayBuffer::kBitFieldOffset), 1 << JSArrayBuffer::WasNeutered::kShift); DeoptimizeIf(not_zero, instr, Deoptimizer::kOutOfBounds); - - __ bind(&has_no_buffer); } diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 8100ae1..2abde16 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -5173,14 +5173,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = scratch0(); - Label has_no_buffer; __ lw(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ lw(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); __ And(at, scratch, 1 << JSArrayBuffer::WasNeutered::kShift); DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds, at, Operand(zero_reg)); - - __ bind(&has_no_buffer); } diff --git a/src/mips64/lithium-codegen-mips64.cc b/src/mips64/lithium-codegen-mips64.cc index 340f57b..58ea58c 100644 --- a/src/mips64/lithium-codegen-mips64.cc +++ b/src/mips64/lithium-codegen-mips64.cc @@ -5233,14 +5233,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = scratch0(); - Label has_no_buffer; __ ld(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ lw(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); __ And(at, scratch, 1 << JSArrayBuffer::WasNeutered::kShift); DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds, at, Operand(zero_reg)); - - __ bind(&has_no_buffer); } diff --git a/src/objects-inl.h b/src/objects-inl.h index c0be396..4fde394 100644 --- a/src/objects-inl.h +++ b/src/objects-inl.h @@ -6508,7 +6508,7 @@ ACCESSORS(JSArrayBufferView, raw_byte_length, Object, kByteLengthOffset) bool JSArrayBufferView::WasNeutered() const { - return !buffer()->IsSmi() && JSArrayBuffer::cast(buffer())->was_neutered(); + return JSArrayBuffer::cast(buffer())->was_neutered(); } diff --git a/src/objects.cc b/src/objects.cc index 6798d0f..002c3c2 100644 --- a/src/objects.cc +++ b/src/objects.cc @@ -17076,11 +17076,18 @@ Handle JSTypedArray::MaterializeArrayBuffer( map, FixedToExternalElementsKind(map->elements_kind())); - Handle buffer = isolate->factory()->NewJSArrayBuffer(); Handle fixed_typed_array( FixedTypedArrayBase::cast(typed_array->elements())); - Runtime::SetupArrayBufferAllocatingData(isolate, buffer, - fixed_typed_array->DataSize(), false); + + Handle buffer(JSArrayBuffer::cast(typed_array->buffer()), + isolate); + void* backing_store = + isolate->array_buffer_allocator()->AllocateUninitialized( + fixed_typed_array->DataSize()); + isolate->heap()->RegisterNewArrayBuffer(backing_store, + fixed_typed_array->DataSize()); + buffer->set_backing_store(backing_store); + buffer->set_is_external(false); memcpy(buffer->backing_store(), fixed_typed_array->DataPtr(), fixed_typed_array->DataSize()); @@ -17089,7 +17096,6 @@ Handle JSTypedArray::MaterializeArrayBuffer( fixed_typed_array->length(), typed_array->type(), static_cast(buffer->backing_store())); - typed_array->set_buffer(*buffer); JSObject::SetMapAndElements(typed_array, new_map, new_elements); return buffer; @@ -17097,9 +17103,8 @@ Handle JSTypedArray::MaterializeArrayBuffer( Handle JSTypedArray::GetBuffer() { - Handle result(buffer(), GetIsolate()); - if (*result != Smi::FromInt(0)) { - DCHECK(IsExternalArrayElementsKind(map()->elements_kind())); + if (IsExternalArrayElementsKind(map()->elements_kind())) { + Handle result(buffer(), GetIsolate()); return Handle::cast(result); } Handle self(this); diff --git a/src/ppc/lithium-codegen-ppc.cc b/src/ppc/lithium-codegen-ppc.cc index 6ef5b58..50dcd19 100644 --- a/src/ppc/lithium-codegen-ppc.cc +++ b/src/ppc/lithium-codegen-ppc.cc @@ -5430,14 +5430,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = scratch0(); - Label has_no_buffer; __ LoadP(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ lwz(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); __ andi(r0, scratch, Operand(1 << JSArrayBuffer::WasNeutered::kShift)); DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds, cr0); - - __ bind(&has_no_buffer); } diff --git a/src/runtime/runtime-typedarray.cc b/src/runtime/runtime-typedarray.cc index b95d20f..93ff56d 100644 --- a/src/runtime/runtime-typedarray.cc +++ b/src/runtime/runtime-typedarray.cc @@ -241,7 +241,9 @@ RUNTIME_FUNCTION(Runtime_TypedArrayInitialize) { JSObject::SetMapAndElements(holder, map, elements); DCHECK(IsExternalArrayElementsKind(holder->map()->elements_kind())); } else { - holder->set_buffer(Smi::FromInt(0)); + Handle buffer = isolate->factory()->NewJSArrayBuffer(); + Runtime::SetupArrayBuffer(isolate, buffer, true, NULL, byte_length); + holder->set_buffer(*buffer); Handle elements = isolate->factory()->NewFixedTypedArray(static_cast(length), array_type); diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index b095119..e70bebd 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -5165,15 +5165,11 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( LCheckArrayBufferNotNeutered* instr) { Register view = ToRegister(instr->view()); - Label has_no_buffer; __ movp(kScratchRegister, FieldOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(kScratchRegister, &has_no_buffer); __ testb(FieldOperand(kScratchRegister, JSArrayBuffer::kBitFieldOffset), Immediate(1 << JSArrayBuffer::WasNeutered::kShift)); DeoptimizeIf(not_zero, instr, Deoptimizer::kOutOfBounds); - - __ bind(&has_no_buffer); } diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc index fd2d3bb..af118d5 100644 --- a/src/x87/lithium-codegen-x87.cc +++ b/src/x87/lithium-codegen-x87.cc @@ -5497,14 +5497,10 @@ void LCodeGen::DoCheckArrayBufferNotNeutered( Register view = ToRegister(instr->view()); Register scratch = ToRegister(instr->scratch()); - Label has_no_buffer; __ mov(scratch, FieldOperand(view, JSArrayBufferView::kBufferOffset)); - __ JumpIfSmi(scratch, &has_no_buffer); __ test_b(FieldOperand(scratch, JSArrayBuffer::kBitFieldOffset), 1 << JSArrayBuffer::WasNeutered::kShift); DeoptimizeIf(not_zero, instr, Deoptimizer::kOutOfBounds); - - __ bind(&has_no_buffer); } -- 2.7.4