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

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
Index: runtime/vm/object.cc
===================================================================
--- runtime/vm/object.cc (revision 15418)
+++ 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) {
@@ -9242,18 +9242,20 @@
}
-RawInteger* Integer::New(const String& str, Heap::Space space) {
- // We are not supposed to have integers represented as two byte or
- // four byte strings.
+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::New(str, space));
+ const Bigint& big = Bigint::Handle(Bigint::NewCanonical(str));
ASSERT(!BigintOperations::FitsIntoSmi(big));
ASSERT(!BigintOperations::FitsIntoMint(big));
return big.raw();
}
- return Integer::New(value, space);
+ if ((value <= Smi::kMaxValue) && (value >= Smi::kMinValue)) {
+ return Smi::New(value);
+ }
+ return Mint::NewCanonical(value);
}
@@ -9858,6 +9860,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;
@@ -9872,11 +9878,33 @@
}
-RawBigint* Bigint::New(const String& str, Heap::Space space) {
- const Bigint& result = Bigint::Handle(
- BigintOperations::NewFromCString(str.ToCString(), space));
- ASSERT(!BigintOperations::FitsIntoMint(result));
- return result.raw();
+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();
}

Powered by Google App Engine
This is Rietveld 408576698