[turbofan]: Add better encapsulation to LinkageLocation
Add factory methods for different types of LinkageLocations, and ensure that accesses to the underlying data in the location are classified by type and funneled through explicit accessors. Also change the representation of LinkageLocation to use a BitField rather than using a reserved section of the integer range. Review URL: https://codereview.chromium.org/1262343002 Cr-Commit-Position: refs/heads/master@{#29938}
This commit is contained in:
parent
8ae236c0c4
commit
3c9f69d399
@ -16,13 +16,13 @@ namespace compiler {
|
||||
namespace {
|
||||
// Platform-specific configuration for C calling convention.
|
||||
LinkageLocation regloc(Register reg) {
|
||||
return LinkageLocation(Register::ToAllocationIndex(reg));
|
||||
return LinkageLocation::ForRegister(Register::ToAllocationIndex(reg));
|
||||
}
|
||||
|
||||
|
||||
LinkageLocation stackloc(int i) {
|
||||
DCHECK_LT(i, 0);
|
||||
return LinkageLocation(i);
|
||||
return LinkageLocation::ForCallerFrameSlot(i);
|
||||
}
|
||||
|
||||
|
||||
@ -226,7 +226,7 @@ CallDescriptor* Linkage::GetSimplifiedCDescriptor(
|
||||
|
||||
// The target for C calls is always an address (i.e. machine pointer).
|
||||
MachineType target_type = kMachPtr;
|
||||
LinkageLocation target_loc = LinkageLocation::AnyRegister();
|
||||
LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
|
||||
return new (zone) CallDescriptor( // --
|
||||
CallDescriptor::kCallAddress, // kind
|
||||
target_type, // target MachineType
|
||||
|
@ -208,30 +208,28 @@ class OperandGenerator {
|
||||
UnallocatedOperand ToUnallocatedOperand(LinkageLocation location,
|
||||
MachineType type,
|
||||
int virtual_register) {
|
||||
if (location.location_ == LinkageLocation::ANY_REGISTER) {
|
||||
if (location.IsAnyRegister()) {
|
||||
// any machine register.
|
||||
return UnallocatedOperand(UnallocatedOperand::MUST_HAVE_REGISTER,
|
||||
virtual_register);
|
||||
}
|
||||
if (location.location_ < 0) {
|
||||
if (location.IsCallerFrameSlot()) {
|
||||
// a location on the caller frame.
|
||||
return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
|
||||
location.location_, virtual_register);
|
||||
location.AsCallerFrameSlot(), virtual_register);
|
||||
}
|
||||
if (location.location_ > LinkageLocation::ANY_REGISTER) {
|
||||
if (location.IsCalleeFrameSlot()) {
|
||||
// a spill location on this (callee) frame.
|
||||
return UnallocatedOperand(
|
||||
UnallocatedOperand::FIXED_SLOT,
|
||||
location.location_ - LinkageLocation::ANY_REGISTER - 1,
|
||||
virtual_register);
|
||||
return UnallocatedOperand(UnallocatedOperand::FIXED_SLOT,
|
||||
location.AsCalleeFrameSlot(), virtual_register);
|
||||
}
|
||||
// a fixed register.
|
||||
if (RepresentationOf(type) == kRepFloat64) {
|
||||
return UnallocatedOperand(UnallocatedOperand::FIXED_DOUBLE_REGISTER,
|
||||
location.location_, virtual_register);
|
||||
location.AsRegister(), virtual_register);
|
||||
}
|
||||
return UnallocatedOperand(UnallocatedOperand::FIXED_REGISTER,
|
||||
location.location_, virtual_register);
|
||||
location.AsRegister(), virtual_register);
|
||||
}
|
||||
|
||||
InstructionSelector* selector_;
|
||||
|
@ -122,7 +122,7 @@ class LinkageHelper {
|
||||
|
||||
// The target for runtime calls is a code object.
|
||||
MachineType target_type = kMachAnyTagged;
|
||||
LinkageLocation target_loc = LinkageLocation::AnyRegister();
|
||||
LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
|
||||
return new (zone) CallDescriptor( // --
|
||||
CallDescriptor::kCallCodeObject, // kind
|
||||
target_type, // target MachineType
|
||||
@ -182,7 +182,7 @@ class LinkageHelper {
|
||||
|
||||
// The target for stub calls is a code object.
|
||||
MachineType target_type = kMachAnyTagged;
|
||||
LinkageLocation target_loc = LinkageLocation::AnyRegister();
|
||||
LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
|
||||
return new (zone) CallDescriptor( // --
|
||||
CallDescriptor::kCallCodeObject, // kind
|
||||
target_type, // target MachineType
|
||||
@ -214,7 +214,7 @@ class LinkageHelper {
|
||||
types.AddParam(kMachPtr);
|
||||
locations.AddParam(regloc(LinkageTraits::InterpreterDispatchTableReg()));
|
||||
|
||||
LinkageLocation target_loc = LinkageLocation::AnyRegister();
|
||||
LinkageLocation target_loc = LinkageLocation::ForAnyRegister();
|
||||
return new (zone) CallDescriptor( // --
|
||||
CallDescriptor::kInterpreterDispatch, // kind
|
||||
kMachNone, // target MachineType
|
||||
@ -230,12 +230,11 @@ class LinkageHelper {
|
||||
}
|
||||
|
||||
static LinkageLocation regloc(Register reg) {
|
||||
return LinkageLocation(Register::ToAllocationIndex(reg));
|
||||
return LinkageLocation::ForRegister(Register::ToAllocationIndex(reg));
|
||||
}
|
||||
|
||||
static LinkageLocation stackloc(int i) {
|
||||
DCHECK_LT(i, 0);
|
||||
return LinkageLocation(i);
|
||||
return LinkageLocation::ForCallerFrameSlot(i);
|
||||
}
|
||||
|
||||
static MachineType reptyp(Representation representation) {
|
||||
@ -280,11 +279,8 @@ LinkageLocation Linkage::GetOsrValueLocation(int index) const {
|
||||
return incoming_->GetInputLocation(context_index);
|
||||
} else if (index >= first_stack_slot) {
|
||||
// Local variable stored in this (callee) stack.
|
||||
int spill_index =
|
||||
LinkageLocation::ANY_REGISTER + 1 + index - first_stack_slot;
|
||||
// TODO(titzer): bailout instead of crashing here.
|
||||
CHECK(spill_index <= LinkageLocation::MAX_STACK_SLOT);
|
||||
return LinkageLocation(spill_index);
|
||||
int spill_index = index - first_stack_slot;
|
||||
return LinkageLocation::ForCalleeFrameSlot(spill_index);
|
||||
} else {
|
||||
// Parameter. Use the assigned location from the incoming call descriptor.
|
||||
int parameter_index = 1 + index; // skip index 0, which is the target.
|
||||
|
@ -56,17 +56,17 @@ bool CallDescriptor::CanTailCall(const Node* node) const {
|
||||
// Determine the number of stack parameters passed in
|
||||
size_t stack_params = 0;
|
||||
for (size_t i = 0; i < InputCount(); ++i) {
|
||||
if (!GetInputLocation(i).is_register()) {
|
||||
if (!GetInputLocation(i).IsRegister()) {
|
||||
++stack_params;
|
||||
}
|
||||
}
|
||||
// Ensure the input linkage contains the stack parameters in the right order
|
||||
size_t current_stack_param = 0;
|
||||
for (size_t i = 0; i < InputCount(); ++i) {
|
||||
if (!GetInputLocation(i).is_register()) {
|
||||
if (GetInputLocation(i) !=
|
||||
LinkageLocation(static_cast<int>(current_stack_param) -
|
||||
static_cast<int>(stack_params))) {
|
||||
if (!GetInputLocation(i).IsRegister()) {
|
||||
if (GetInputLocation(i) != LinkageLocation::ForCallerFrameSlot(
|
||||
static_cast<int>(current_stack_param) -
|
||||
static_cast<int>(stack_params))) {
|
||||
return false;
|
||||
}
|
||||
++current_stack_param;
|
||||
@ -82,7 +82,7 @@ bool CallDescriptor::CanTailCall(const Node* node) const {
|
||||
while (true) {
|
||||
if (other_input >= other->InputCount()) {
|
||||
while (current_input < InputCount()) {
|
||||
if (!GetInputLocation(current_input).is_register()) {
|
||||
if (!GetInputLocation(current_input).IsRegister()) {
|
||||
return false;
|
||||
}
|
||||
++current_input;
|
||||
@ -91,18 +91,18 @@ bool CallDescriptor::CanTailCall(const Node* node) const {
|
||||
}
|
||||
if (current_input >= InputCount()) {
|
||||
while (other_input < other->InputCount()) {
|
||||
if (!other->GetInputLocation(other_input).is_register()) {
|
||||
if (!other->GetInputLocation(other_input).IsRegister()) {
|
||||
return false;
|
||||
}
|
||||
++other_input;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (GetInputLocation(current_input).is_register()) {
|
||||
if (GetInputLocation(current_input).IsRegister()) {
|
||||
++current_input;
|
||||
continue;
|
||||
}
|
||||
if (other->GetInputLocation(other_input).is_register()) {
|
||||
if (other->GetInputLocation(other_input).IsRegister()) {
|
||||
++other_input;
|
||||
continue;
|
||||
}
|
||||
@ -238,10 +238,10 @@ int Linkage::FrameStateInputCount(Runtime::FunctionId function) {
|
||||
|
||||
bool CallDescriptor::UsesOnlyRegisters() const {
|
||||
for (size_t i = 0; i < InputCount(); ++i) {
|
||||
if (!GetInputLocation(i).is_register()) return false;
|
||||
if (!GetInputLocation(i).IsRegister()) return false;
|
||||
}
|
||||
for (size_t i = 0; i < ReturnCount(); ++i) {
|
||||
if (!GetReturnLocation(i).is_register()) return false;
|
||||
if (!GetReturnLocation(i).IsRegister()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -26,33 +26,77 @@ class OsrHelper;
|
||||
// Describes the location for a parameter or a return value to a call.
|
||||
class LinkageLocation {
|
||||
public:
|
||||
explicit LinkageLocation(int location) : location_(location) {}
|
||||
|
||||
bool is_register() const {
|
||||
return 0 <= location_ && location_ <= ANY_REGISTER;
|
||||
}
|
||||
|
||||
static const int16_t ANY_REGISTER = 1023;
|
||||
static const int16_t MAX_STACK_SLOT = 32767;
|
||||
|
||||
static LinkageLocation AnyRegister() { return LinkageLocation(ANY_REGISTER); }
|
||||
|
||||
bool operator==(const LinkageLocation& other) const {
|
||||
return location_ == other.location_;
|
||||
return bit_field_ == other.bit_field_;
|
||||
}
|
||||
|
||||
bool operator!=(const LinkageLocation& other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
static LinkageLocation ForAnyRegister() {
|
||||
return LinkageLocation(REGISTER, ANY_REGISTER);
|
||||
}
|
||||
|
||||
static LinkageLocation ForRegister(int32_t reg) {
|
||||
DCHECK(reg >= 0);
|
||||
return LinkageLocation(REGISTER, reg);
|
||||
}
|
||||
|
||||
static LinkageLocation ForCallerFrameSlot(int32_t slot) {
|
||||
DCHECK(slot < 0);
|
||||
return LinkageLocation(STACK_SLOT, slot);
|
||||
}
|
||||
|
||||
static LinkageLocation ForCalleeFrameSlot(int32_t slot) {
|
||||
// TODO(titzer): bailout instead of crashing here.
|
||||
DCHECK(slot >= 0 && slot < LinkageLocation::MAX_STACK_SLOT);
|
||||
return LinkageLocation(STACK_SLOT, slot);
|
||||
}
|
||||
|
||||
private:
|
||||
friend class CallDescriptor;
|
||||
friend class OperandGenerator;
|
||||
// location < 0 -> a stack slot on the caller frame
|
||||
// 0 <= location < 1023 -> a specific machine register
|
||||
// 1023 <= location < 1024 -> any machine register
|
||||
// 1024 <= location -> a stack slot in the callee frame
|
||||
int16_t location_;
|
||||
|
||||
enum LocationType { REGISTER, STACK_SLOT };
|
||||
|
||||
class TypeField : public BitField<LocationType, 0, 1> {};
|
||||
class LocationField : public BitField<int32_t, TypeField::kNext, 31> {};
|
||||
|
||||
static const int32_t ANY_REGISTER = -1;
|
||||
static const int32_t MAX_STACK_SLOT = 32767;
|
||||
|
||||
LinkageLocation(LocationType type, int32_t location) {
|
||||
bit_field_ = TypeField::encode(type) |
|
||||
((location << LocationField::kShift) & LocationField::kMask);
|
||||
}
|
||||
|
||||
int32_t GetLocation() const {
|
||||
return static_cast<int32_t>(bit_field_ & LocationField::kMask) >>
|
||||
LocationField::kShift;
|
||||
}
|
||||
|
||||
bool IsRegister() const { return TypeField::decode(bit_field_) == REGISTER; }
|
||||
bool IsAnyRegister() const {
|
||||
return IsRegister() && GetLocation() == ANY_REGISTER;
|
||||
}
|
||||
bool IsCallerFrameSlot() const { return !IsRegister() && GetLocation() < 0; }
|
||||
bool IsCalleeFrameSlot() const { return !IsRegister() && GetLocation() >= 0; }
|
||||
|
||||
int32_t AsRegister() const {
|
||||
DCHECK(IsRegister());
|
||||
return GetLocation();
|
||||
}
|
||||
int32_t AsCallerFrameSlot() const {
|
||||
DCHECK(IsCallerFrameSlot());
|
||||
return GetLocation();
|
||||
}
|
||||
int32_t AsCalleeFrameSlot() const {
|
||||
DCHECK(IsCalleeFrameSlot());
|
||||
return GetLocation();
|
||||
}
|
||||
|
||||
int32_t bit_field_;
|
||||
};
|
||||
|
||||
typedef Signature<LinkageLocation> LocationSignature;
|
||||
|
@ -28,7 +28,7 @@ class LinkageTailCall : public TestWithZone {
|
||||
locations->return_count(), locations->parameter_count(), kMachineTypes);
|
||||
return new (zone())
|
||||
CallDescriptor(CallDescriptor::kCallCodeObject, kMachAnyTagged,
|
||||
LinkageLocation::AnyRegister(),
|
||||
LinkageLocation::ForAnyRegister(),
|
||||
types, // machine_sig
|
||||
locations, // location_sig
|
||||
0, // js_parameter_count
|
||||
@ -39,9 +39,13 @@ class LinkageTailCall : public TestWithZone {
|
||||
"");
|
||||
}
|
||||
|
||||
LinkageLocation StackLocation(int loc) { return LinkageLocation(-loc); }
|
||||
LinkageLocation StackLocation(int loc) {
|
||||
return LinkageLocation::ForCallerFrameSlot(-loc);
|
||||
}
|
||||
|
||||
LinkageLocation RegisterLocation(int loc) { return LinkageLocation(loc); }
|
||||
LinkageLocation RegisterLocation(int loc) {
|
||||
return LinkageLocation::ForRegister(loc);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
@ -27,10 +27,11 @@ class TailCallOptimizationTest : public GraphTest {
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallCodeObject0) {
|
||||
MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation(0),
|
||||
LinkageLocation(1)};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
|
||||
CallDescriptor::kCallCodeObject, kMachAnyTagged,
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) MachineSignature(1, 1, kMachineSignature),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
|
||||
@ -47,10 +48,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject0) {
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallCodeObject1) {
|
||||
MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation(0),
|
||||
LinkageLocation(1)};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
|
||||
CallDescriptor::kCallCodeObject, kMachAnyTagged,
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) MachineSignature(1, 1, kMachineSignature),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
@ -71,10 +73,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject1) {
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallCodeObject2) {
|
||||
MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation(0),
|
||||
LinkageLocation(1)};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallCodeObject, kMachAnyTagged, LinkageLocation(0),
|
||||
CallDescriptor::kCallCodeObject, kMachAnyTagged,
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) MachineSignature(1, 1, kMachineSignature),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
@ -93,10 +96,11 @@ TEST_F(TailCallOptimizationTest, CallCodeObject2) {
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallJSFunction0) {
|
||||
MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation(0),
|
||||
LinkageLocation(1)};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
|
||||
CallDescriptor::kCallJSFunction, kMachAnyTagged,
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) MachineSignature(1, 1, kMachineSignature),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kNoFlags);
|
||||
@ -113,10 +117,11 @@ TEST_F(TailCallOptimizationTest, CallJSFunction0) {
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallJSFunction1) {
|
||||
MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation(0),
|
||||
LinkageLocation(1)};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
|
||||
CallDescriptor::kCallJSFunction, kMachAnyTagged,
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) MachineSignature(1, 1, kMachineSignature),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
@ -137,10 +142,11 @@ TEST_F(TailCallOptimizationTest, CallJSFunction1) {
|
||||
|
||||
TEST_F(TailCallOptimizationTest, CallJSFunction2) {
|
||||
MachineType kMachineSignature[] = {kMachAnyTagged, kMachAnyTagged};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation(0),
|
||||
LinkageLocation(1)};
|
||||
LinkageLocation kLocationSignature[] = {LinkageLocation::ForRegister(0),
|
||||
LinkageLocation::ForRegister(1)};
|
||||
const CallDescriptor* kCallDescriptor = new (zone()) CallDescriptor(
|
||||
CallDescriptor::kCallJSFunction, kMachAnyTagged, LinkageLocation(0),
|
||||
CallDescriptor::kCallJSFunction, kMachAnyTagged,
|
||||
LinkageLocation::ForRegister(0),
|
||||
new (zone()) MachineSignature(1, 1, kMachineSignature),
|
||||
new (zone()) LocationSignature(1, 1, kLocationSignature), 0,
|
||||
Operator::kNoProperties, 0, 0, CallDescriptor::kSupportsTailCalls);
|
||||
|
Loading…
Reference in New Issue
Block a user