From a2e6f970c766c4e197a20eb7badd251757249355 Mon Sep 17 00:00:00 2001 From: jochen Date: Tue, 28 Apr 2015 06:42:54 -0700 Subject: [PATCH] Add HArrayBufferNotNeutered instruction This instruction can be hoisted out of loops even though it contains a branch. BUG=v8:3996 R=bmeurer@chromium.org LOG=n Review URL: https://codereview.chromium.org/1108313003 Cr-Commit-Position: refs/heads/master@{#28109} --- src/arm/lithium-arm.cc | 9 ++++++++ src/arm/lithium-arm.h | 14 +++++++++++++ src/arm/lithium-codegen-arm.cc | 16 ++++++++++++++ src/arm64/lithium-arm64.cc | 9 ++++++++ src/arm64/lithium-arm64.h | 14 +++++++++++++ src/arm64/lithium-codegen-arm64.cc | 17 +++++++++++++++ src/hydrogen-instructions.cc | 1 + src/hydrogen-instructions.h | 31 ++++++++++++++++++++++++++++ src/hydrogen.cc | 31 ++++------------------------ src/ia32/lithium-codegen-ia32.cc | 16 ++++++++++++++ src/ia32/lithium-ia32.cc | 10 +++++++++ src/ia32/lithium-ia32.h | 18 ++++++++++++++++ src/mips/lithium-codegen-mips.cc | 16 ++++++++++++++ src/mips/lithium-mips.cc | 9 ++++++++ src/mips/lithium-mips.h | 14 +++++++++++++ src/mips64/lithium-codegen-mips64.cc | 16 ++++++++++++++ src/mips64/lithium-mips64.cc | 9 ++++++++ src/mips64/lithium-mips64.h | 14 +++++++++++++ src/ppc/lithium-codegen-ppc.cc | 16 ++++++++++++++ src/ppc/lithium-ppc.cc | 9 ++++++++ src/ppc/lithium-ppc.h | 14 +++++++++++++ src/x64/lithium-codegen-x64.cc | 16 ++++++++++++++ src/x64/lithium-x64.cc | 9 ++++++++ src/x64/lithium-x64.h | 14 +++++++++++++ src/x87/lithium-codegen-x87.cc | 16 ++++++++++++++ src/x87/lithium-x87.cc | 10 +++++++++ src/x87/lithium-x87.h | 18 ++++++++++++++++ 27 files changed, 359 insertions(+), 27 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 6268df3df..7d600db93 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -2046,6 +2046,15 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LInstruction* result = new(zone()) LCheckInstanceType(value); diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h index 7fca1ee7c..66df46a3b 100644 --- a/src/arm/lithium-arm.h +++ b/src/arm/lithium-arm.h @@ -37,6 +37,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckNonSmi) \ V(CheckMaps) \ @@ -2375,6 +2376,19 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 0> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } + + LOperand* view() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { public: explicit LCheckInstanceType(LOperand* value) { diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc index 667646474..fc33139cb 100644 --- a/src/arm/lithium-codegen-arm.cc +++ b/src/arm/lithium-codegen-arm.cc @@ -5154,6 +5154,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + 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); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register scratch = scratch0(); diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc index 2dfcdb086..a9daec492 100644 --- a/src/arm64/lithium-arm64.cc +++ b/src/arm64/lithium-arm64.cc @@ -1221,6 +1221,15 @@ LInstruction* LChunkBuilder::DoCheckValue(HCheckValue* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LOperand* temp = TempRegister(); diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h index 506110c77..af8ef00d1 100644 --- a/src/arm64/lithium-arm64.h +++ b/src/arm64/lithium-arm64.h @@ -40,6 +40,7 @@ class LCodeGen; V(CallRuntime) \ V(CallStub) \ V(CallWithDescriptor) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckMapValue) \ V(CheckMaps) \ @@ -935,6 +936,19 @@ class LCallStub final : public LTemplateInstruction<1, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 0> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } + + LOperand* view() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 1> { public: explicit LCheckInstanceType(LOperand* value, LOperand* temp) { diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 13da0b99b..badd17737 100644 --- a/src/arm64/lithium-codegen-arm64.cc +++ b/src/arm64/lithium-codegen-arm64.cc @@ -2229,6 +2229,23 @@ void LCodeGen::DoCheckSmi(LCheckSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + UseScratchRegisterScope temps(masm()); + 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); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register scratch = ToRegister(instr->temp()); diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc index 674096b30..7956437bd 100644 --- a/src/hydrogen-instructions.cc +++ b/src/hydrogen-instructions.cc @@ -854,6 +854,7 @@ bool HInstruction::CanDeoptimize() { case HValue::kCallRuntime: case HValue::kCallWithDescriptor: case HValue::kChange: + case HValue::kCheckArrayBufferNotNeutered: case HValue::kCheckHeapObject: case HValue::kCheckInstanceType: case HValue::kCheckMapValue: diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index 71fc0f99a..771197d51 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -70,6 +70,7 @@ class LChunkBuilder; V(CallStub) \ V(CapturedObject) \ V(Change) \ + V(CheckArrayBufferNotNeutered) \ V(CheckHeapObject) \ V(CheckInstanceType) \ V(CheckMaps) \ @@ -2952,6 +2953,36 @@ class HCheckSmi final : public HUnaryOperation { }; +class HCheckArrayBufferNotNeutered final : public HUnaryOperation { + public: + DECLARE_INSTRUCTION_FACTORY_P1(HCheckArrayBufferNotNeutered, HValue*); + + bool HasEscapingOperandAt(int index) override { return false; } + Representation RequiredInputRepresentation(int index) override { + return Representation::Tagged(); + } + + HType CalculateInferredType() override { + if (value()->type().IsHeapObject()) return value()->type(); + return HType::HeapObject(); + } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered) + + protected: + bool DataEquals(HValue* other) override { return true; } + int RedefinedOperandIndex() override { return 0; } + + private: + explicit HCheckArrayBufferNotNeutered(HValue* value) + : HUnaryOperation(value) { + set_representation(Representation::Tagged()); + SetFlag(kUseGVN); + SetDependsOnFlag(kCalls); + } +}; + + class HCheckHeapObject final : public HUnaryOperation { public: DECLARE_INSTRUCTION_FACTORY_P1(HCheckHeapObject, HValue*); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index adc4aa4d5..937f5b086 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -2425,6 +2425,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( HValue* checked_key = NULL; if (IsExternalArrayElementsKind(elements_kind) || IsFixedTypedArrayElementsKind(elements_kind)) { + checked_object = Add(checked_object); + HValue* backing_store; if (IsExternalArrayElementsKind(elements_kind)) { backing_store = Add( @@ -2434,23 +2436,6 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( } if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) { NoObservableSideEffectsScope no_effects(this); - if (IsExternalArrayElementsKind(elements_kind)) { - HInstruction* buffer = - Add(checked_object, nullptr, - HObjectAccess::ForJSArrayBufferViewBuffer()); - 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.ThenDeopt(Deoptimizer::kOutOfBounds); - if_was_neutered.End(); - } IfBuilder length_checker(this); length_checker.If(key, length, Token::LT); length_checker.Then(); @@ -2465,14 +2450,6 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( length_checker.End(); return result; } else { - if (IsExternalArrayElementsKind(elements_kind)) { - HInstruction* buffer = - Add(checked_object, nullptr, - HObjectAccess::ForJSArrayBufferViewBuffer()); - HInstruction* buffer_length = Add( - buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength()); - Add(graph()->GetConstant0(), buffer_length); - } DCHECK(store_mode == STANDARD_STORE); checked_key = Add(key, length); return AddElementAccess( @@ -6340,8 +6317,8 @@ HValue* HOptimizedGraphBuilder::BuildMonomorphicAccess( if (info->GetJSArrayBufferViewFieldAccess(&access)) { DCHECK(info->IsLoad()); - return BuildArrayBufferViewFieldAccessor( - object, checked_object, FieldIndex::ForInObjectOffset(access.offset())); + checked_object = Add(checked_object); + return New(object, checked_object, access); } if (info->name().is_identical_to(isolate()->factory()->prototype_string()) && diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 5af19d01e..d4b8b6186 100644 --- a/src/ia32/lithium-codegen-ia32.cc +++ b/src/ia32/lithium-codegen-ia32.cc @@ -4973,6 +4973,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + 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); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 6ff143155..d9cef76af 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -2030,6 +2030,16 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LOperand* scratch = TempRegister(); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view, scratch); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LOperand* temp = TempRegister(); diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h index f40df09fb..d64d3626d 100644 --- a/src/ia32/lithium-ia32.h +++ b/src/ia32/lithium-ia32.h @@ -41,6 +41,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckMaps) \ V(CheckMapValue) \ @@ -2377,6 +2378,23 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 1> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view, LOperand* scratch) { + inputs_[0] = view; + temps_[0] = scratch; + } + + LOperand* view() { return inputs_[0]; } + LOperand* scratch() { return temps_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 1> { public: LCheckInstanceType(LOperand* value, LOperand* temp) { diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc index 4e1cd8140..0ba5e23ce 100644 --- a/src/mips/lithium-codegen-mips.cc +++ b/src/mips/lithium-codegen-mips.cc @@ -5168,6 +5168,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + 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); + + __ bind(&has_no_buffer); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register scratch = scratch0(); diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index 578db3b31..c2d22ea2c 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1993,6 +1993,15 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LInstruction* result = new(zone()) LCheckInstanceType(value); diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h index c5d2eb28c..b2ab1a058 100644 --- a/src/mips/lithium-mips.h +++ b/src/mips/lithium-mips.h @@ -37,6 +37,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckMaps) \ V(CheckMapValue) \ @@ -2332,6 +2333,19 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 0> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } + + LOperand* view() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { public: explicit LCheckInstanceType(LOperand* value) { diff --git a/src/mips64/lithium-codegen-mips64.cc b/src/mips64/lithium-codegen-mips64.cc index c7dd637c2..bf3119d08 100644 --- a/src/mips64/lithium-codegen-mips64.cc +++ b/src/mips64/lithium-codegen-mips64.cc @@ -5228,6 +5228,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + 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); + + __ bind(&has_no_buffer); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register scratch = scratch0(); diff --git a/src/mips64/lithium-mips64.cc b/src/mips64/lithium-mips64.cc index ee32dcef4..7495b7477 100644 --- a/src/mips64/lithium-mips64.cc +++ b/src/mips64/lithium-mips64.cc @@ -1991,6 +1991,15 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LInstruction* result = new(zone()) LCheckInstanceType(value); diff --git a/src/mips64/lithium-mips64.h b/src/mips64/lithium-mips64.h index 0aa66776a..3805fb90a 100644 --- a/src/mips64/lithium-mips64.h +++ b/src/mips64/lithium-mips64.h @@ -37,6 +37,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckMaps) \ V(CheckMapValue) \ @@ -2314,6 +2315,19 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 0> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } + + LOperand* view() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { public: explicit LCheckInstanceType(LOperand* value) { diff --git a/src/ppc/lithium-codegen-ppc.cc b/src/ppc/lithium-codegen-ppc.cc index ae58f31ea..c34718bad 100644 --- a/src/ppc/lithium-codegen-ppc.cc +++ b/src/ppc/lithium-codegen-ppc.cc @@ -5425,6 +5425,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + Register view = ToRegister(instr->view()); + Register scratch = scratch0(); + + Label has_no_buffer; + __ LoadP(scratch, FieldMemOperand(view, JSArrayBufferView::kBufferOffset)); + __ JumpIfSmi(scratch, &has_no_buffer); + __ LoadP(scratch, FieldMemOperand(scratch, JSArrayBuffer::kBitFieldOffset)); + __ andi(r0, scratch, Operand(1 << JSArrayBuffer::WasNeutered::kShift)); + DeoptimizeIf(ne, instr, Deoptimizer::kOutOfBounds); + + __ bind(&has_no_buffer); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register scratch = scratch0(); diff --git a/src/ppc/lithium-ppc.cc b/src/ppc/lithium-ppc.cc index 81eb3fd6e..fd2cc44ce 100644 --- a/src/ppc/lithium-ppc.cc +++ b/src/ppc/lithium-ppc.cc @@ -2006,6 +2006,15 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LInstruction* result = new (zone()) LCheckInstanceType(value); diff --git a/src/ppc/lithium-ppc.h b/src/ppc/lithium-ppc.h index 63c70992c..052e60c29 100644 --- a/src/ppc/lithium-ppc.h +++ b/src/ppc/lithium-ppc.h @@ -37,6 +37,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckNonSmi) \ V(CheckMaps) \ @@ -2279,6 +2280,19 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 0> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } + + LOperand* view() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { public: explicit LCheckInstanceType(LOperand* value) { inputs_[0] = value; } diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index 7c1668f1f..b095119a5 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -5161,6 +5161,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +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); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 6cffc1c1e..80f9f0b49 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1991,6 +1991,15 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LCheckInstanceType* result = new(zone()) LCheckInstanceType(value); diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h index cddaa885b..be5941c2a 100644 --- a/src/x64/lithium-x64.h +++ b/src/x64/lithium-x64.h @@ -37,6 +37,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckMaps) \ V(CheckMapValue) \ @@ -2351,6 +2352,19 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 0> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; } + + LOperand* view() { return inputs_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> { public: explicit LCheckInstanceType(LOperand* value) { diff --git a/src/x87/lithium-codegen-x87.cc b/src/x87/lithium-codegen-x87.cc index 13dfc1734..62bb19087 100644 --- a/src/x87/lithium-codegen-x87.cc +++ b/src/x87/lithium-codegen-x87.cc @@ -5476,6 +5476,22 @@ void LCodeGen::DoCheckNonSmi(LCheckNonSmi* instr) { } +void LCodeGen::DoCheckArrayBufferNotNeutered( + LCheckArrayBufferNotNeutered* instr) { + 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); +} + + void LCodeGen::DoCheckInstanceType(LCheckInstanceType* instr) { Register input = ToRegister(instr->value()); Register temp = ToRegister(instr->temp()); diff --git a/src/x87/lithium-x87.cc b/src/x87/lithium-x87.cc index 0bf162c25..a1bf2f1e6 100644 --- a/src/x87/lithium-x87.cc +++ b/src/x87/lithium-x87.cc @@ -2031,6 +2031,16 @@ LInstruction* LChunkBuilder::DoCheckSmi(HCheckSmi* instr) { } +LInstruction* LChunkBuilder::DoCheckArrayBufferNotNeutered( + HCheckArrayBufferNotNeutered* instr) { + LOperand* view = UseRegisterAtStart(instr->value()); + LOperand* scratch = TempRegister(); + LCheckArrayBufferNotNeutered* result = + new (zone()) LCheckArrayBufferNotNeutered(view, scratch); + return AssignEnvironment(result); +} + + LInstruction* LChunkBuilder::DoCheckInstanceType(HCheckInstanceType* instr) { LOperand* value = UseRegisterAtStart(instr->value()); LOperand* temp = TempRegister(); diff --git a/src/x87/lithium-x87.h b/src/x87/lithium-x87.h index 6cc89b1fb..7a8b1e7d8 100644 --- a/src/x87/lithium-x87.h +++ b/src/x87/lithium-x87.h @@ -41,6 +41,7 @@ class LCodeGen; V(CallNewArray) \ V(CallRuntime) \ V(CallStub) \ + V(CheckArrayBufferNotNeutered) \ V(CheckInstanceType) \ V(CheckMaps) \ V(CheckMapValue) \ @@ -2381,6 +2382,23 @@ class LCheckValue final : public LTemplateInstruction<0, 1, 0> { }; +class LCheckArrayBufferNotNeutered final + : public LTemplateInstruction<0, 1, 1> { + public: + explicit LCheckArrayBufferNotNeutered(LOperand* view, LOperand* scratch) { + inputs_[0] = view; + temps_[0] = scratch; + } + + LOperand* view() { return inputs_[0]; } + LOperand* scratch() { return temps_[0]; } + + DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered, + "check-array-buffer-not-neutered") + DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered) +}; + + class LCheckInstanceType final : public LTemplateInstruction<0, 1, 1> { public: LCheckInstanceType(LOperand* value, LOperand* temp) { -- 2.34.1