Skip to content

Commit

Permalink
Perform Smi operations without untagging and retagging.
Browse files Browse the repository at this point in the history
  • Loading branch information
rmacnak committed Nov 9, 2024
1 parent ea97030 commit 09315e7
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 103 deletions.
65 changes: 38 additions & 27 deletions vm/interpreter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1204,12 +1204,12 @@ void Interpreter::Interpret() {
// +
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
intptr_t raw_left = static_cast<SmallInteger>(left)->value();
intptr_t raw_right = static_cast<SmallInteger>(right)->value();
intptr_t raw_result = raw_left + raw_right;
if (SmallInteger::IsSmiValue(raw_result)) {
PopNAndPush(2, SmallInteger::New(raw_result));
if (Object::BothSmallIntegers(left, right)) {
intptr_t raw_left = static_cast<intptr_t>(left);
intptr_t raw_right = static_cast<intptr_t>(right);
intptr_t raw_result;
if (!Math::AddHasOverflow(raw_left, raw_right, &raw_result)) {
PopNAndPush(2, static_cast<SmallInteger>(raw_result));
break;
}
}
Expand All @@ -1219,19 +1219,30 @@ void Interpreter::Interpret() {
// -
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
intptr_t raw_left = static_cast<SmallInteger>(left)->value();
intptr_t raw_right = static_cast<SmallInteger>(right)->value();
intptr_t raw_result = raw_left - raw_right;
if (SmallInteger::IsSmiValue(raw_result)) {
PopNAndPush(2, SmallInteger::New(raw_result));
if (Object::BothSmallIntegers(left, right)) {
intptr_t raw_left = static_cast<intptr_t>(left);
intptr_t raw_right = static_cast<intptr_t>(right);
intptr_t raw_result;
if (!Math::SubtractHasOverflow(raw_left, raw_right, &raw_result)) {
PopNAndPush(2, static_cast<SmallInteger>(raw_result));
break;
}
}
goto CommonSendDispatch;
}
case 178: {
// *
Object left = Stack(1);
Object right = Stack(0);
if (Object::BothSmallIntegers(left, right)) {
intptr_t raw_left = static_cast<intptr_t>(left);
intptr_t raw_right = static_cast<intptr_t>(right) >> kSmiTagShift;
intptr_t raw_result;
if (!Math::MultiplyHasOverflow(raw_left, raw_right, &raw_result)) {
PopNAndPush(2, static_cast<SmallInteger>(raw_result));
break;
}
}
goto CommonSendDispatch;
}
case 179: {
Expand All @@ -1242,7 +1253,7 @@ void Interpreter::Interpret() {
/* \\ */
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
if (Object::BothSmallIntegers(left, right)) {
intptr_t raw_left = static_cast<SmallInteger>(left)->value();
intptr_t raw_right = static_cast<SmallInteger>(right)->value();
if (raw_right != 0) {
Expand All @@ -1266,9 +1277,9 @@ void Interpreter::Interpret() {
// &
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
PopNAndPush(2, static_cast<SmallInteger>(
static_cast<intptr_t>(left) & static_cast<intptr_t>(right)));
if (Object::BothSmallIntegers(left, right)) {
PopNAndPush(2, static_cast<SmallInteger>(static_cast<intptr_t>(left) &
static_cast<intptr_t>(right)));
break;
}
goto CommonSendDispatch;
Expand All @@ -1277,9 +1288,9 @@ void Interpreter::Interpret() {
// |
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
PopNAndPush(2, static_cast<SmallInteger>(
static_cast<intptr_t>(left) | static_cast<intptr_t>(right)));
if (Object::BothSmallIntegers(left, right)) {
PopNAndPush(2, static_cast<SmallInteger>(static_cast<intptr_t>(left) |
static_cast<intptr_t>(right)));
break;
}
goto CommonSendDispatch;
Expand All @@ -1288,7 +1299,7 @@ void Interpreter::Interpret() {
// <
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
if (Object::BothSmallIntegers(left, right)) {
if (static_cast<intptr_t>(left) < static_cast<intptr_t>(right)) {
PopNAndPush(2, true_);
} else {
Expand All @@ -1302,7 +1313,7 @@ void Interpreter::Interpret() {
// >
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
if (Object::BothSmallIntegers(left, right)) {
if (static_cast<intptr_t>(left) > static_cast<intptr_t>(right)) {
PopNAndPush(2, true_);
} else {
Expand All @@ -1316,7 +1327,7 @@ void Interpreter::Interpret() {
// <=
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
if (Object::BothSmallIntegers(left, right)) {
if (static_cast<intptr_t>(left) <= static_cast<intptr_t>(right)) {
PopNAndPush(2, true_);
} else {
Expand All @@ -1330,7 +1341,7 @@ void Interpreter::Interpret() {
// >=
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
if (Object::BothSmallIntegers(left, right)) {
if (static_cast<intptr_t>(left) >= static_cast<intptr_t>(right)) {
PopNAndPush(2, true_);
} else {
Expand All @@ -1344,7 +1355,7 @@ void Interpreter::Interpret() {
// =
Object left = Stack(1);
Object right = Stack(0);
if (left->IsSmallInteger() && right->IsSmallInteger()) {
if (Object::BothSmallIntegers(left, right)) {
if (static_cast<intptr_t>(left) == static_cast<intptr_t>(right)) {
PopNAndPush(2, true_);
} else {
Expand Down Expand Up @@ -1404,9 +1415,9 @@ void Interpreter::Interpret() {
SmallInteger value = static_cast<SmallInteger>(Stack(0));
if ((raw_index >= 0) &&
(raw_index < static_cast<ByteArray>(array)->Size()) &&
static_cast<uword>(value) <= 255) {
static_cast<ByteArray>(array)->set_element(raw_index,
value->value());
SmallInteger::IsByte(value)) {
static_cast<ByteArray>(array)->set_element(
raw_index, SmallInteger::Byte(value));
PopNAndPush(3, value);
break;
}
Expand Down
13 changes: 13 additions & 0 deletions vm/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,10 @@ class Object {
bool IsSmallInteger() const {
return (tagged_pointer_ & kSmiTagMask) == kSmiTag;
}
static bool BothSmallIntegers(Object a, Object b) {
return ((static_cast<uintptr_t>(a) | static_cast<uintptr_t>(b))
& kSmiTagMask) == kSmiTag;
}
bool IsOldObject() const {
return (tagged_pointer_ & kObjectAlignmentMask) == kOldObjectBits;
}
Expand Down Expand Up @@ -348,6 +352,15 @@ class SmallInteger : public Object {
intptr_t untagged = tagged >> kSmiTagShift;
return untagged == value;
}

static bool IsByte(Object obj) {
return static_cast<uintptr_t>(obj) <=
static_cast<uintptr_t>(255 << kSmiTagShift);
}
static uint8_t Byte(Object obj) {
ASSERT(IsByte(obj));
return static_cast<intptr_t>(obj) >> kSmiTagShift;
}
};

class MediumInteger : public HeapObject {
Expand Down
Loading

0 comments on commit 09315e7

Please sign in to comment.