Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(881)

Unified Diff: runtime/vm/object.cc

Issue 10968058: Support constant folding of instructions with constant smi values. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/object.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 356e1a5b7a816cc802af76037dba8bc9e4a6f5bf..6a63bed3636c75909e58f10a784c9419b208c826 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -8808,8 +8808,8 @@ RawInteger* Integer::AsInteger() const {
}
-RawInteger* Integer::BinaryOp(Token::Kind operation,
- const Integer& other) const {
+RawInteger* Integer::ArithmeticOp(Token::Kind operation,
+ const Integer& other) const {
// In 32-bit mode, the result of any operation between two Smis will fit in a
// 32-bit signed result, except the product of two Smis, which will be 64-bit.
// In 64-bit mode, the result of any operation between two Smis will fit in a
@@ -8902,11 +8902,109 @@ RawInteger* Integer::BinaryOp(Token::Kind operation,
const Bigint& left_big = Bigint::Handle(AsBigint());
const Bigint& right_big = Bigint::Handle(other.AsBigint());
const Bigint& result =
- Bigint::Handle(left_big.BinaryOp(operation, right_big));
+ Bigint::Handle(left_big.ArithmeticOp(operation, right_big));
return Integer::Handle(result.AsInteger()).raw();
}
+static bool Are64bitOperands(const Integer& op1, const Integer& op2) {
+ return !op1.IsBigint() && !op2.IsBigint();
+}
+
+
+RawInteger* Integer::BitOp(Token::Kind kind, const Integer& other) const {
+ if (IsSmi() && other.IsSmi()) {
+ Smi& op1 = Smi::Handle();
+ Smi& op2 = Smi::Handle();
+ op1 ^= raw();
+ op2 ^= other.raw();
+ intptr_t result = 0;
+ switch (kind) {
+ case Token::kBIT_AND:
+ result = op1.Value() & op2.Value();
+ break;
+ case Token::kBIT_OR:
+ result = op1.Value() | op2.Value();
+ break;
+ case Token::kBIT_XOR:
+ result = op1.Value() ^ op2.Value();
+ break;
+ default:
+ UNIMPLEMENTED();
+ }
+ ASSERT(Smi::IsValid(result));
+ return Smi::New(result);
+ } else if (Are64bitOperands(*this, other)) {
+ int64_t a = AsInt64Value();
+ int64_t b = other.AsInt64Value();
+ switch (kind) {
+ case Token::kBIT_AND:
+ return Integer::New(a & b);
+ case Token::kBIT_OR:
+ return Integer::New(a | b);
+ case Token::kBIT_XOR:
+ return Integer::New(a ^ b);
+ default:
+ UNIMPLEMENTED();
+ }
+ } else {
+ Bigint& op1 = Bigint::Handle(AsBigint());
+ Bigint& op2 = Bigint::Handle(other.AsBigint());
+ switch (kind) {
+ case Token::kBIT_AND:
+ return BigintOperations::BitAnd(op1, op2);
+ case Token::kBIT_OR:
+ return BigintOperations::BitOr(op1, op2);
+ case Token::kBIT_XOR:
+ return BigintOperations::BitXor(op1, op2);
+ default:
+ UNIMPLEMENTED();
+ }
+ }
+ return Integer::null();
+}
+
+
+// TODO(srdjan): Clarify handling of negative right operand in a shift op.
+RawInteger* Smi::ShiftOp(Token::Kind kind, const Smi& other) const {
+ intptr_t result = 0;
+ const intptr_t left_value = Value();
+ const intptr_t right_value = other.Value();
+ ASSERT(right_value >= 0);
+ switch (kind) {
+ case Token::kSHL: {
+ if ((left_value == 0) || (right_value == 0)) {
+ return raw();
+ }
+ { // Check for overflow.
+ int cnt = Utils::HighestBit(left_value);
+ if ((cnt + right_value) >= Smi::kBits) {
+ if ((cnt + right_value) >= Mint::kBits) {
+ return BigintOperations::ShiftLeft(
+ Bigint::Handle(AsBigint()), right_value);
+ } else {
+ int64_t left_64 = left_value;
+ return Integer::New(left_64 << right_value);
+ }
+ }
+ }
+ result = left_value << right_value;
+ break;
+ }
+ case Token::kSHR: {
+ const intptr_t shift_amount =
+ (right_value >= kBitsPerWord) ? (kBitsPerWord - 1) : right_value;
+ result = left_value >> shift_amount;
+ break;
+ }
+ default:
+ UNIMPLEMENTED();
+ }
+ ASSERT(Smi::IsValid(result));
+ return Smi::New(result);
+}
+
+
bool Smi::Equals(const Instance& other) const {
if (other.IsNull() || !other.IsSmi()) {
return false;
@@ -9229,7 +9327,8 @@ RawBigint* Integer::AsBigint() const {
}
-RawBigint* Bigint::BinaryOp(Token::Kind operation, const Bigint& other) const {
+RawBigint* Bigint::ArithmeticOp(Token::Kind operation,
+ const Bigint& other) const {
switch (operation) {
case Token::kADD:
return BigintOperations::Add(*this, other);
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/object.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698