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

Unified Diff: runtime/vm/object.cc

Issue 11348259: Canonicalize all integer constants taht we create by parsing a string. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month 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
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 15426)
+++ runtime/vm/object.cc (working copy)
@@ -4497,7 +4497,7 @@
result.set_kind(kind);
result.set_literal(literal);
if (kind == Token::kINTEGER) {
- const Integer& value = Integer::Handle(Integer::New(literal, Heap::kOld));
+ const Integer& value = Integer::Handle(Integer::NewCanonical(literal));
ASSERT(value.IsSmi() || value.IsOld());
result.set_value(value);
} else if (kind == Token::kDOUBLE) {
@@ -9243,8 +9243,7 @@
RawInteger* Integer::New(const String& str, Heap::Space space) {
- // We are not supposed to have integers represented as two byte or
- // four byte strings.
+ // We are not supposed to have integers represented as two byte strings.
ASSERT(str.IsOneByteString());
int64_t value;
if (!OS::StringToInt64(str.ToCString(), &value)) {
@@ -9257,6 +9256,23 @@
}
+RawInteger* Integer::NewCanonical(const String& str) {
+ // We are not supposed to have integers represented as two byte strings.
+ ASSERT(str.IsOneByteString());
+ int64_t value;
+ if (!OS::StringToInt64(str.ToCString(), &value)) {
+ const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str));
+ ASSERT(!BigintOperations::FitsIntoSmi(big));
+ ASSERT(!BigintOperations::FitsIntoMint(big));
+ return big.raw();
+ }
+ if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
+ return Smi::New(value);
+ }
+ return Mint::NewCanonical(value);
+}
+
+
RawInteger* Integer::New(int64_t value, Heap::Space space) {
if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
return Smi::New(value);
@@ -9858,6 +9874,10 @@
const Bigint& other_bgi = Bigint::Cast(other);
+ if (this->IsNegative() != other_bgi.IsNegative()) {
+ return false;
+ }
+
intptr_t len = this->Length();
if (len != other_bgi.Length()) {
return false;
@@ -9880,6 +9900,36 @@
}
+RawBigint* Bigint::NewCanonical(const String& str) {
+ const Bigint& value = Bigint::Handle(
+ BigintOperations::NewFromCString(str.ToCString(), Heap::kOld));
+ ASSERT(!BigintOperations::FitsIntoMint(value));
+ const Class& cls =
+ Class::Handle(Isolate::Current()->object_store()->bigint_class());
+ const Array& constants = Array::Handle(cls.constants());
+ const intptr_t constants_len = constants.Length();
+ // Linear search to see whether this value is already present in the
+ // list of canonicalized constants.
+ Bigint& canonical_value = Bigint::Handle();
+ intptr_t index = 0;
+ while (index < constants_len) {
+ canonical_value ^= constants.At(index);
+ if (canonical_value.IsNull()) {
+ break;
+ }
+ if (canonical_value.Equals(value)) {
+ return canonical_value.raw();
+ }
+ index++;
+ }
+ // The value needs to be added to the constants list. Grow the list if
+ // it is full.
+ cls.InsertCanonicalConstant(index, value);
+ value.SetCanonical();
+ return value.raw();
+}
+
+
double Bigint::AsDoubleValue() const {
return Double::Handle(BigintOperations::ToDouble(*this)).value();
}
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698