[maglev] Create DataViewGetVariableLength builtin

kDataViewGetVariableLength has JS linkage, and so it has a strong
requirement to what should be in the stack and in the registers
(including having a JSFunction for kDataViewGetVariableLength).

These were missing before, which would crash when checking the frame.

Fixed: chromium:1406727
Bug: v8:7700
Change-Id: Iad878cbc06d46403e21162dfdfd3bcd1a2a063d3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4162926
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#85284}
This commit is contained in:
Victor Gomes 2023-01-13 14:31:11 +01:00 committed by V8 LUCI CQ
parent b5ada88ab6
commit d7d5049cfa
7 changed files with 67 additions and 13 deletions

View File

@ -3017,6 +3017,7 @@ filegroup(
"src/builtins/builtins-constructor.h",
"src/builtins/builtins-conversion-gen.cc",
"src/builtins/builtins-data-view-gen.h",
"src/builtins/builtins-data-view-gen.cc",
"src/builtins/builtins-date-gen.cc",
"src/builtins/builtins-generator-gen.cc",
"src/builtins/builtins-global-gen.cc",

View File

@ -2461,6 +2461,7 @@ v8_source_set("v8_initializers") {
"src/builtins/builtins-constructor-gen.h",
"src/builtins/builtins-constructor.h",
"src/builtins/builtins-conversion-gen.cc",
"src/builtins/builtins-data-view-gen.cc",
"src/builtins/builtins-data-view-gen.h",
"src/builtins/builtins-date-gen.cc",
"src/builtins/builtins-generator-gen.cc",

View File

@ -0,0 +1,30 @@
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/builtins/builtins-data-view-gen.h"
#include "src/builtins/builtins-utils-gen.h"
namespace v8 {
namespace internal {
// Returns (intptr) a byte length value from [0..JSArrayBuffer::kMaxLength]
// If it fails (due to detached or OOB), it returns -1.
TF_BUILTIN(DataViewGetVariableLength, DataViewBuiltinsAssembler) {
auto dataview = Parameter<JSDataView>(Descriptor::kDataView);
CSA_CHECK(this, IsVariableLengthJSArrayBufferView(dataview));
Label detached_or_oob(this);
auto buffer =
LoadObjectField<JSArrayBuffer>(dataview, JSDataView::kBufferOffset);
TNode<UintPtrT> byte_length = LoadVariableLengthJSArrayBufferViewByteLength(
dataview, buffer, &detached_or_oob);
Return(byte_length);
BIND(&detached_or_oob);
Return(IntPtrConstant(-1));
}
} // namespace internal
} // namespace v8

View File

@ -502,6 +502,7 @@ namespace internal {
/* DataView */ \
/* ES #sec-dataview-constructor */ \
CPP(DataViewConstructor) \
TFC(DataViewGetVariableLength, DataViewGetVariableLength) \
\
/* Date */ \
/* ES #sec-date-constructor */ \

View File

@ -72,6 +72,7 @@ namespace internal {
V(CopyDataPropertiesWithExcludedProperties) \
V(CopyDataPropertiesWithExcludedPropertiesOnStack) \
V(CppBuiltinAdaptor) \
V(DataViewGetVariableLength) \
V(FastNewObject) \
V(FindNonDefaultConstructorOrConstruct) \
V(ForInPrepare) \
@ -1639,6 +1640,16 @@ class CppBuiltinAdaptorDescriptor
DECLARE_JS_COMPATIBLE_DESCRIPTOR(CppBuiltinAdaptorDescriptor)
};
class DataViewGetVariableLengthDescriptor
: public StaticCallInterfaceDescriptor<
DataViewGetVariableLengthDescriptor> {
public:
DEFINE_PARAMETERS(kDataView)
DEFINE_RESULT_AND_PARAMETER_TYPES(MachineType::IntPtr(), // Byte Length
MachineType::AnyTagged()) // kDataView
DECLARE_DESCRIPTOR(DataViewGetVariableLengthDescriptor)
};
class CEntry1ArgvOnStackDescriptor
: public StaticCallInterfaceDescriptor<CEntry1ArgvOnStackDescriptor> {
public:

View File

@ -1433,17 +1433,22 @@ void CheckJSDataViewBounds::GenerateCode(MaglevAssembler* masm,
[](MaglevAssembler* masm, CheckJSDataViewBounds* node, ZoneLabelRef done,
Register object, Register index, Register byte_length) {
RegisterSnapshot snapshot = node->register_snapshot();
AddDeoptRegistersToSnapshot(&snapshot, node->eager_deopt_info());
snapshot.live_registers.set(index); // Make sure index is saved.
DCHECK(!snapshot.live_registers.has(byte_length));
{
// TODO(v8:7700): Inline DataViewPrototypeGetByteLength or create a
// different builtin that does not re-check the DataView object.
using D = CallInterfaceDescriptorFor<
Builtin::kDataViewGetVariableLength>::type;
SaveRegisterStateForCall save_register_state(masm, snapshot);
__ PushReverse(object);
__ Mov(kContextRegister, masm->native_context().object());
__ Mov(kJavaScriptCallArgCountRegister, 1);
__ CallBuiltin(Builtin::kDataViewPrototypeGetByteLength);
__ Move(D::GetRegisterParameter(D::kDataView), object);
__ Move(kContextRegister, masm->native_context().object());
__ CallBuiltin(Builtin::kDataViewGetVariableLength);
__ Move(byte_length, kReturnRegister0);
}
__ SmiUntag(byte_length, kReturnRegister0);
__ Cmp(byte_length, Immediate(0));
// The reason might not be OOB, but because array was detached.
// Unfortunately we can only add one reason type in Maglev.
__ EmitEagerDeoptIf(lt, DeoptimizeReason::kOutOfBounds, node);
__ B(*done);
},
this, done_byte_length, object, index, byte_length);

View File

@ -531,17 +531,22 @@ void CheckJSDataViewBounds::GenerateCode(MaglevAssembler* masm,
[](MaglevAssembler* masm, CheckJSDataViewBounds* node, ZoneLabelRef done,
Register object, Register index, Register byte_length) {
RegisterSnapshot snapshot = node->register_snapshot();
AddDeoptRegistersToSnapshot(&snapshot, node->eager_deopt_info());
snapshot.live_registers.set(index); // Make sure index is saved.
DCHECK(!snapshot.live_registers.has(byte_length));
{
// TODO(v8:7700): Inline DataViewPrototypeGetByteLength or create a
// different builtin that does not re-check the DataView object.
using D = CallInterfaceDescriptorFor<
Builtin::kDataViewGetVariableLength>::type;
SaveRegisterStateForCall save_register_state(masm, snapshot);
__ PushReverse(object);
__ Move(D::GetRegisterParameter(D::kDataView), object);
__ Move(kContextRegister, masm->native_context().object());
__ Move(kJavaScriptCallArgCountRegister, 1);
__ CallBuiltin(Builtin::kDataViewPrototypeGetByteLength);
__ CallBuiltin(Builtin::kDataViewGetVariableLength);
__ Move(byte_length, kReturnRegister0);
}
__ SmiUntag(byte_length, kReturnRegister0);
__ cmpq(byte_length, Immediate(0));
// The reason might not be OOB, but because array was detached.
// Unfortunately we can only add one reason type in Maglev.
__ EmitEagerDeoptIf(less, DeoptimizeReason::kOutOfBounds, node);
__ jmp(*done);
},
this, done_byte_length, object, index, byte_length);