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

Side by Side 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, 2 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 unified diff | Download patch | Annotate | Revision Log
« runtime/vm/flow_graph_optimizer.cc ('K') | « runtime/vm/object.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/bigint_operations.h" 10 #include "vm/bigint_operations.h"
(...skipping 8790 matching lines...) Expand 10 before | Expand all | Expand 10 after
8801 if (BigintOperations::FitsIntoSmi(big_value)) { 8801 if (BigintOperations::FitsIntoSmi(big_value)) {
8802 return BigintOperations::ToSmi(big_value); 8802 return BigintOperations::ToSmi(big_value);
8803 } else if (BigintOperations::FitsIntoMint(big_value)) { 8803 } else if (BigintOperations::FitsIntoMint(big_value)) {
8804 return Mint::New(BigintOperations::ToMint(big_value)); 8804 return Mint::New(BigintOperations::ToMint(big_value));
8805 } else { 8805 } else {
8806 return big_value.raw(); 8806 return big_value.raw();
8807 } 8807 }
8808 } 8808 }
8809 8809
8810 8810
8811 RawInteger* Integer::BinaryOp(Token::Kind operation, 8811 RawInteger* Integer::ArithmeticOp(Token::Kind operation,
8812 const Integer& other) const { 8812 const Integer& other) const {
8813 // In 32-bit mode, the result of any operation between two Smis will fit in a 8813 // In 32-bit mode, the result of any operation between two Smis will fit in a
8814 // 32-bit signed result, except the product of two Smis, which will be 64-bit. 8814 // 32-bit signed result, except the product of two Smis, which will be 64-bit.
8815 // In 64-bit mode, the result of any operation between two Smis will fit in a 8815 // In 64-bit mode, the result of any operation between two Smis will fit in a
8816 // 64-bit signed result, except the product of two Smis (unless the Smis are 8816 // 64-bit signed result, except the product of two Smis (unless the Smis are
8817 // 32-bit or less). 8817 // 32-bit or less).
8818 if (IsSmi() && other.IsSmi()) { 8818 if (IsSmi() && other.IsSmi()) {
8819 Smi& left_smi = Smi::Handle(); 8819 Smi& left_smi = Smi::Handle();
8820 Smi& right_smi = Smi::Handle(); 8820 Smi& right_smi = Smi::Handle();
8821 left_smi ^= raw(); 8821 left_smi ^= raw();
8822 right_smi ^= other.raw(); 8822 right_smi ^= other.raw();
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
8895 } 8895 }
8896 default: 8896 default:
8897 UNIMPLEMENTED(); 8897 UNIMPLEMENTED();
8898 } 8898 }
8899 } 8899 }
8900 } 8900 }
8901 } 8901 }
8902 const Bigint& left_big = Bigint::Handle(AsBigint()); 8902 const Bigint& left_big = Bigint::Handle(AsBigint());
8903 const Bigint& right_big = Bigint::Handle(other.AsBigint()); 8903 const Bigint& right_big = Bigint::Handle(other.AsBigint());
8904 const Bigint& result = 8904 const Bigint& result =
8905 Bigint::Handle(left_big.BinaryOp(operation, right_big)); 8905 Bigint::Handle(left_big.ArithmeticOp(operation, right_big));
8906 return Integer::Handle(result.AsInteger()).raw(); 8906 return Integer::Handle(result.AsInteger()).raw();
8907 } 8907 }
8908 8908
8909 8909
8910 static bool Are64bitOperands(const Integer& op1, const Integer& op2) {
8911 return !op1.IsBigint() && !op2.IsBigint();
8912 }
8913
8914
8915 RawInteger* Integer::BitOp(Token::Kind kind, const Integer& other) const {
8916 if (IsSmi() && other.IsSmi()) {
8917 Smi& op1 = Smi::Handle();
8918 Smi& op2 = Smi::Handle();
8919 op1 ^= raw();
8920 op2 ^= other.raw();
8921 intptr_t result = 0;
8922 switch (kind) {
8923 case Token::kBIT_AND:
8924 result = op1.Value() & op2.Value();
8925 break;
8926 case Token::kBIT_OR:
8927 result = op1.Value() | op2.Value();
8928 break;
8929 case Token::kBIT_XOR:
8930 result = op1.Value() ^ op2.Value();
8931 break;
8932 default:
8933 UNIMPLEMENTED();
8934 }
8935 ASSERT(Smi::IsValid(result));
8936 return Smi::New(result);
8937 } else if (Are64bitOperands(*this, other)) {
8938 int64_t a = AsInt64Value();
8939 int64_t b = other.AsInt64Value();
8940 switch (kind) {
8941 case Token::kBIT_AND:
8942 return Integer::New(a & b);
8943 case Token::kBIT_OR:
8944 return Integer::New(a | b);
8945 case Token::kBIT_XOR:
8946 return Integer::New(a ^ b);
8947 default:
8948 UNIMPLEMENTED();
8949 }
8950 } else {
8951 Bigint& op1 = Bigint::Handle(AsBigint());
8952 Bigint& op2 = Bigint::Handle(other.AsBigint());
8953 switch (kind) {
8954 case Token::kBIT_AND:
8955 return BigintOperations::BitAnd(op1, op2);
8956 case Token::kBIT_OR:
8957 return BigintOperations::BitOr(op1, op2);
8958 case Token::kBIT_XOR:
8959 return BigintOperations::BitXor(op1, op2);
8960 default:
8961 UNIMPLEMENTED();
8962 }
8963 }
8964 return Integer::null();
8965 }
8966
8967
8968 // TODO(srdjan): Clarify handling of negative right operand in a shift op.
8969 RawInteger* Smi::ShiftOp(Token::Kind kind, const Smi& other) const {
8970 intptr_t result = 0;
8971 const intptr_t left_value = Value();
8972 const intptr_t right_value = other.Value();
8973 ASSERT(right_value >= 0);
8974 switch (kind) {
8975 case Token::kSHL: {
8976 if ((left_value == 0) || (right_value == 0)) {
8977 return raw();
8978 }
8979 { // Check for overflow.
8980 int cnt = Utils::HighestBit(left_value);
8981 if ((cnt + right_value) >= Smi::kBits) {
8982 if ((cnt + right_value) >= Mint::kBits) {
8983 return BigintOperations::ShiftLeft(
8984 Bigint::Handle(AsBigint()), right_value);
8985 } else {
8986 int64_t left_64 = left_value;
8987 return Integer::New(left_64 << right_value);
8988 }
8989 }
8990 }
8991 result = left_value << right_value;
8992 break;
8993 }
8994 case Token::kSHR: {
8995 const intptr_t shift_amount =
8996 (right_value >= kBitsPerWord) ? (kBitsPerWord - 1) : right_value;
8997 result = left_value >> shift_amount;
8998 break;
8999 }
9000 default:
9001 UNIMPLEMENTED();
9002 }
9003 ASSERT(Smi::IsValid(result));
9004 return Smi::New(result);
9005 }
9006
9007
8910 bool Smi::Equals(const Instance& other) const { 9008 bool Smi::Equals(const Instance& other) const {
8911 if (other.IsNull() || !other.IsSmi()) { 9009 if (other.IsNull() || !other.IsSmi()) {
8912 return false; 9010 return false;
8913 } 9011 }
8914 return (this->Value() == Smi::Cast(other).Value()); 9012 return (this->Value() == Smi::Cast(other).Value());
8915 } 9013 }
8916 9014
8917 9015
8918 double Smi::AsDoubleValue() const { 9016 double Smi::AsDoubleValue() const {
8919 return static_cast<double>(this->Value()); 9017 return static_cast<double>(this->Value());
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after
9222 } else { 9320 } else {
9223 ASSERT(IsBigint()); 9321 ASSERT(IsBigint());
9224 Bigint& big = Bigint::Handle(); 9322 Bigint& big = Bigint::Handle();
9225 big ^= raw(); 9323 big ^= raw();
9226 ASSERT(!BigintOperations::FitsIntoSmi(big)); 9324 ASSERT(!BigintOperations::FitsIntoSmi(big));
9227 return big.raw(); 9325 return big.raw();
9228 } 9326 }
9229 } 9327 }
9230 9328
9231 9329
9232 RawBigint* Bigint::BinaryOp(Token::Kind operation, const Bigint& other) const { 9330 RawBigint* Bigint::ArithmeticOp(Token::Kind operation,
9331 const Bigint& other) const {
9233 switch (operation) { 9332 switch (operation) {
9234 case Token::kADD: 9333 case Token::kADD:
9235 return BigintOperations::Add(*this, other); 9334 return BigintOperations::Add(*this, other);
9236 case Token::kSUB: 9335 case Token::kSUB:
9237 return BigintOperations::Subtract(*this, other); 9336 return BigintOperations::Subtract(*this, other);
9238 case Token::kMUL: 9337 case Token::kMUL:
9239 return BigintOperations::Multiply(*this, other); 9338 return BigintOperations::Multiply(*this, other);
9240 case Token::kTRUNCDIV: 9339 case Token::kTRUNCDIV:
9241 return BigintOperations::Divide(*this, other); 9340 return BigintOperations::Divide(*this, other);
9242 case Token::kMOD: 9341 case Token::kMOD:
(...skipping 2591 matching lines...) Expand 10 before | Expand all | Expand 10 after
11834 } 11933 }
11835 return result.raw(); 11934 return result.raw();
11836 } 11935 }
11837 11936
11838 11937
11839 const char* WeakProperty::ToCString() const { 11938 const char* WeakProperty::ToCString() const {
11840 return "_WeakProperty"; 11939 return "_WeakProperty";
11841 } 11940 }
11842 11941
11843 } // namespace dart 11942 } // namespace dart
OLDNEW
« 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