}
+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);
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckNonSmi) \
V(CheckMaps) \
};
+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) {
}
+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();
}
+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();
V(CallRuntime) \
V(CallStub) \
V(CallWithDescriptor) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckMapValue) \
V(CheckMaps) \
};
+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) {
}
+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());
case HValue::kCallRuntime:
case HValue::kCallWithDescriptor:
case HValue::kChange:
+ case HValue::kCheckArrayBufferNotNeutered:
case HValue::kCheckHeapObject:
case HValue::kCheckInstanceType:
case HValue::kCheckMapValue:
V(CallStub) \
V(CapturedObject) \
V(Change) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckHeapObject) \
V(CheckInstanceType) \
V(CheckMaps) \
};
+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*);
HValue* checked_key = NULL;
if (IsExternalArrayElementsKind(elements_kind) ||
IsFixedTypedArrayElementsKind(elements_kind)) {
+ checked_object = Add<HCheckArrayBufferNotNeutered>(checked_object);
+
HValue* backing_store;
if (IsExternalArrayElementsKind(elements_kind)) {
backing_store = Add<HLoadNamedField>(
}
if (store_mode == STORE_NO_TRANSITION_IGNORE_OUT_OF_BOUNDS) {
NoObservableSideEffectsScope no_effects(this);
- if (IsExternalArrayElementsKind(elements_kind)) {
- HInstruction* buffer =
- Add<HLoadNamedField>(checked_object, nullptr,
- HObjectAccess::ForJSArrayBufferViewBuffer());
- HInstruction* flags = Add<HLoadNamedField>(
- buffer, nullptr, HObjectAccess::ForJSArrayBufferBitField());
- HValue* was_neutered_mask =
- Add<HConstant>(1 << JSArrayBuffer::WasNeutered::kShift);
- HValue* was_neutered_test =
- AddUncasted<HBitwise>(Token::BIT_AND, flags, was_neutered_mask);
-
- IfBuilder if_was_neutered(this);
- if_was_neutered.If<HCompareNumericAndBranch>(
- was_neutered_test, graph()->GetConstant0(), Token::NE);
- if_was_neutered.ThenDeopt(Deoptimizer::kOutOfBounds);
- if_was_neutered.End();
- }
IfBuilder length_checker(this);
length_checker.If<HCompareNumericAndBranch>(key, length, Token::LT);
length_checker.Then();
length_checker.End();
return result;
} else {
- if (IsExternalArrayElementsKind(elements_kind)) {
- HInstruction* buffer =
- Add<HLoadNamedField>(checked_object, nullptr,
- HObjectAccess::ForJSArrayBufferViewBuffer());
- HInstruction* buffer_length = Add<HLoadNamedField>(
- buffer, nullptr, HObjectAccess::ForJSArrayBufferByteLength());
- Add<HBoundsCheck>(graph()->GetConstant0(), buffer_length);
- }
DCHECK(store_mode == STANDARD_STORE);
checked_key = Add<HBoundsCheck>(key, length);
return AddElementAccess(
if (info->GetJSArrayBufferViewFieldAccess(&access)) {
DCHECK(info->IsLoad());
- return BuildArrayBufferViewFieldAccessor(
- object, checked_object, FieldIndex::ForInObjectOffset(access.offset()));
+ checked_object = Add<HCheckArrayBufferNotNeutered>(checked_object);
+ return New<HLoadNamedField>(object, checked_object, access);
}
if (info->name().is_identical_to(isolate()->factory()->prototype_string()) &&
}
+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());
}
+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();
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
};
+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) {
}
+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();
}
+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);
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
};
+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) {
}
+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();
}
+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);
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
};
+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) {
}
+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();
}
+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);
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckNonSmi) \
V(CheckMaps) \
};
+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; }
}
+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());
}
+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);
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
};
+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) {
}
+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());
}
+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();
V(CallNewArray) \
V(CallRuntime) \
V(CallStub) \
+ V(CheckArrayBufferNotNeutered) \
V(CheckInstanceType) \
V(CheckMaps) \
V(CheckMapValue) \
};
+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) {