diff --git a/src/compiler/c-linkage.cc b/src/compiler/c-linkage.cc index 7ec4976019..613337c908 100644 --- a/src/compiler/c-linkage.cc +++ b/src/compiler/c-linkage.cc @@ -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 diff --git a/src/compiler/instruction-selector-impl.h b/src/compiler/instruction-selector-impl.h index b34a914efc..db9e100e01 100644 --- a/src/compiler/instruction-selector-impl.h +++ b/src/compiler/instruction-selector-impl.h @@ -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_; diff --git a/src/compiler/linkage-impl.h b/src/compiler/linkage-impl.h index e65ad9ef7a..7118e24b99 100644 --- a/src/compiler/linkage-impl.h +++ b/src/compiler/linkage-impl.h @@ -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. diff --git a/src/compiler/linkage.cc b/src/compiler/linkage.cc index b2e1aec1df..c604909b8a 100644 --- a/src/compiler/linkage.cc +++ b/src/compiler/linkage.cc @@ -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(current_stack_param) - - static_cast(stack_params))) { + if (!GetInputLocation(i).IsRegister()) { + if (GetInputLocation(i) != LinkageLocation::ForCallerFrameSlot( + static_cast(current_stack_param) - + static_cast(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; } diff --git a/src/compiler/linkage.h b/src/compiler/linkage.h index 2fee957fa3..033a1cfae6 100644 --- a/src/compiler/linkage.h +++ b/src/compiler/linkage.h @@ -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 {}; + class LocationField : public BitField {}; + + 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(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 LocationSignature; diff --git a/test/unittests/compiler/linkage-tail-call-unittest.cc b/test/unittests/compiler/linkage-tail-call-unittest.cc index cd9ba00d74..5d24a3bd1d 100644 --- a/test/unittests/compiler/linkage-tail-call-unittest.cc +++ b/test/unittests/compiler/linkage-tail-call-unittest.cc @@ -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); + } }; diff --git a/test/unittests/compiler/tail-call-optimization-unittest.cc b/test/unittests/compiler/tail-call-optimization-unittest.cc index 449299bb1d..7257cc9802 100644 --- a/test/unittests/compiler/tail-call-optimization-unittest.cc +++ b/test/unittests/compiler/tail-call-optimization-unittest.cc @@ -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);