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

Unified Diff: vm/object.cc

Issue 8963001: Add Double::NewCanonical and Mint::NewCanonical so that it is possible to (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/runtime/
Patch Set: '' Created 9 years 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
« vm/object.h ('K') | « vm/object.h ('k') | vm/object_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: vm/object.cc
===================================================================
--- vm/object.cc (revision 2470)
+++ vm/object.cc (working copy)
@@ -5011,6 +5011,24 @@
}
+static void InsertCanonicalConstant(const Class& cls,
+ const Array& canonical_list,
+ intptr_t index,
+ const Instance& constant) {
srdjan 2011/12/15 22:02:26 Why not make it a Class function?
siva 2011/12/15 23:42:54 Done.
+ // The constant needs to be added to the list. Grow the list if it is full.
+ const intptr_t list_len = canonical_list.Length();
+ if (index == list_len) {
srdjan 2011/12/15 22:02:26 index >= list_len ?
siva 2011/12/15 23:42:54 Done.
+ const intptr_t new_length = (list_len == 0) ? 4 : list_len * 2;
srdjan 2011/12/15 22:02:26 That grows a little bit too quickly, IMHO.
siva 2011/12/15 23:42:54 Changed it to (list_len + 4) for growth, so grow b
+ const Array& new_canonical_list =
+ Array::Handle(Array::Grow(canonical_list, new_length, Heap::kOld));
+ cls.set_constants(new_canonical_list);
+ new_canonical_list.SetAt(index, constant);
+ } else {
+ canonical_list.SetAt(index, constant);
+ }
+}
+
+
RawInstance* Instance::Canonicalize() const {
ASSERT(!IsNull());
if (!IsCanonical()) {
srdjan 2011/12/15 22:02:26 Can we move all this code into Class, thus no acce
siva 2011/12/15 23:42:54 As discussed off-line, I have added a TODO to cons
@@ -5034,18 +5052,7 @@
// The value needs to be added to the list. Grow the list if
// it is full.
// TODO(srdjan): Copy instance into old space if canonicalized?
- if (index == constants_len) {
- const intptr_t kInitialConstLength = 4;
- const intptr_t old_length = constants.Length();
- const intptr_t new_length =
- (old_length == 0) ? kInitialConstLength : old_length * 2;
- const Array& new_constants =
- Array::Handle(Array::Grow(constants, new_length, Heap::kOld));
- cls.set_constants(new_constants);
- new_constants.SetAt(index, *this);
- } else {
- constants.SetAt(index, *this);
- }
+ InsertCanonicalConstant(cls, constants, index, *this);
SetCanonical();
}
return this->raw();
@@ -5383,6 +5390,36 @@
}
+RawMint* Mint::NewCanonical(int64_t value) {
+ // Do not allocate a Mint if Smi would do.
+ ASSERT(!Smi::IsValid64(value));
srdjan 2011/12/15 22:02:26 If we move this code into Class, we could share it
siva 2011/12/15 23:42:54 Ditto. On 2011/12/15 22:02:26, srdjan wrote:
+ const Class& cls =
+ Class::Handle(Isolate::Current()->object_store()->mint_class());
srdjan 2011/12/15 22:02:26 Isn't cls = Class::Handle(clazz()); ?
siva 2011/12/15 23:42:54 This is a static method, clazz() is not valid. On
+ 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.
+ Mint& canonical_value = Mint::Handle();
+ intptr_t index = 0;
+ while (index < constants_len) {
+ canonical_value ^= constants.At(index);
+ if (canonical_value.IsNull()) {
+ break;
+ }
+ if (canonical_value.value() == value) {
+ return canonical_value.raw();
+ }
+ index++;
+ }
+ // The value needs to be added to the constants list. Grow the list if
+ // it is full.
+ canonical_value = Mint::New(value, Heap::kOld);
+ InsertCanonicalConstant(cls, constants, index, canonical_value);
+ canonical_value.SetCanonical();
+ return canonical_value.raw();
+}
+
+
bool Mint::Equals(const Instance& other) const {
if (this->raw() == other.raw()) {
// Both handles point to the same raw instance.
@@ -5453,6 +5490,28 @@
}
+bool Double::Equals(double value) const {
+ intptr_t value_offset = Double::value_offset();
+ void* this_addr = reinterpret_cast<void*>(
+ reinterpret_cast<uword>(this->raw_ptr()) + value_offset);
+ void* other_addr = reinterpret_cast<void*>(&value);
+ return memcmp(this_addr, other_addr, sizeof(value)) == 0;
+}
srdjan 2011/12/15 22:02:26 Can you use (*reinterpret_cast<int64_t*>(&value) t
siva 2011/12/15 23:42:54 If I do that I get : error: dereferencing type-pun
+
+
+bool Double::Equals(const Instance& other) const {
+ if (this->raw() == other.raw()) {
+ return true; // "===".
+ }
+ if (other.IsNull() || !other.IsDouble()) {
+ return false;
+ }
+ Double& other_dbl = Double::Handle();
+ other_dbl ^= other.raw();
+ return Equals(other_dbl.value());
+}
+
+
RawDouble* Double::New(double d, Heap::Space space) {
Isolate* isolate = Isolate::Current();
const Class& cls =
@@ -5473,20 +5532,67 @@
}
-RawDouble* Double::New(const String& str, Heap::Space space) {
+static bool StringToDouble(const String& str, double* double_value) {
+ ASSERT(double_value != NULL);
// TODO(regis): For now, we use strtod to convert a string to double.
const char* nptr = str.ToCString();
char* endptr = NULL;
- double double_value = strtod(nptr, &endptr);
+ *double_value = strtod(nptr, &endptr);
// We do not treat overflow or underflow as an error and therefore do not
// check errno for ERANGE.
if (!IsWhiteSpace(*endptr)) {
+ return false;
+ }
+ return true;
+}
+
+
+RawDouble* Double::New(const String& str, Heap::Space space) {
+ double double_value;
+ if (!StringToDouble(str, &double_value)) {
return Double::Handle().raw();
}
return New(double_value, space);
}
+RawDouble* Double::NewCanonical(double value) {
+ const Class& cls =
+ Class::Handle(Isolate::Current()->object_store()->double_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.
+ Double& canonical_value = Double::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.
+ canonical_value = Double::New(value, Heap::kOld);
+ InsertCanonicalConstant(cls, constants, index, canonical_value);
+ canonical_value.SetCanonical();
+ return canonical_value.raw();
+}
+
+
+RawDouble* Double::NewCanonical(const String& str) {
+ double double_value;
+ if (!StringToDouble(str, &double_value)) {
+ return Double::Handle().raw();
+ }
+ return NewCanonical(double_value);
+}
+
+
const char* Double::ToCString() const {
if (isnan(value())) {
return "NaN";
« vm/object.h ('K') | « vm/object.h ('k') | vm/object_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698