| Index: src/objects.cc
|
| diff --git a/src/objects.cc b/src/objects.cc
|
| index 9a6b26aaf11a9afd280ccd0bfca53a0c1e54cad5..cdf498ab12597e93d0f1b893f8a0812870bb4df6 100644
|
| --- a/src/objects.cc
|
| +++ b/src/objects.cc
|
| @@ -1728,6 +1728,11 @@ void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
|
| HeapNumber::cast(this)->HeapNumberPrint(accumulator);
|
| accumulator->Put('>');
|
| break;
|
| + case MUTABLE_HEAP_NUMBER_TYPE:
|
| + accumulator->Add("<MutableNumber: ");
|
| + HeapNumber::cast(this)->HeapNumberPrint(accumulator);
|
| + accumulator->Put('>');
|
| + break;
|
| case JS_PROXY_TYPE:
|
| accumulator->Add("<JSProxy>");
|
| break;
|
| @@ -1851,6 +1856,7 @@ void HeapObject::IterateBody(InstanceType type, int object_size,
|
| break;
|
|
|
| case HEAP_NUMBER_TYPE:
|
| + case MUTABLE_HEAP_NUMBER_TYPE:
|
| case FILLER_TYPE:
|
| case BYTE_ARRAY_TYPE:
|
| case FREE_SPACE_TYPE:
|
| @@ -1907,7 +1913,7 @@ bool HeapNumber::HeapNumberBooleanValue() {
|
|
|
|
|
| void HeapNumber::HeapNumberPrint(FILE* out) {
|
| - PrintF(out, "%.16g", Number());
|
| + PrintF(out, "%.16g", value());
|
| }
|
|
|
|
|
| @@ -1919,7 +1925,7 @@ void HeapNumber::HeapNumberPrint(StringStream* accumulator) {
|
| // print that using vsnprintf (which may truncate but never allocate if
|
| // there is no more space in the buffer).
|
| EmbeddedVector<char, 100> buffer;
|
| - OS::SNPrintF(buffer, "%.16g", Number());
|
| + OS::SNPrintF(buffer, "%.16g", value());
|
| accumulator->Add("%s", buffer.start());
|
| }
|
|
|
| @@ -2039,6 +2045,7 @@ void JSObject::AddFastProperty(Handle<JSObject> object,
|
| // Nothing more to be done.
|
| if (value->IsUninitialized()) return;
|
| HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
|
| + ASSERT(box->IsMutableHeapNumber());
|
| box->set_value(value->Number());
|
| } else {
|
| object->FastPropertyAtPut(index, *value);
|
| @@ -2331,6 +2338,9 @@ bool Map::InstancesNeedRewriting(Map* target,
|
| if (new_desc->GetDetails(i).representation().IsDouble() &&
|
| !old_desc->GetDetails(i).representation().IsDouble()) {
|
| return true;
|
| + } else if (old_desc->GetDetails(i).representation().IsDouble() &&
|
| + !new_desc->GetDetails(i).representation().IsDouble()) {
|
| + return true;
|
| }
|
| }
|
|
|
| @@ -2413,6 +2423,10 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
|
| value = handle(Smi::FromInt(0), isolate);
|
| }
|
| value = NewStorageFor(isolate, value, details.representation());
|
| + } else if (old_details.representation().IsDouble() &&
|
| + !details.representation().IsDouble()) {
|
| + Handle<HeapNumber> old_value = Handle<HeapNumber>::cast(value);
|
| + value = isolate->factory()->NewHeapNumber(old_value->value());
|
| }
|
| ASSERT(!(details.representation().IsDouble() && value->IsSmi()));
|
| int target_index = new_descriptors->GetFieldIndex(i) - inobject;
|
| @@ -2426,7 +2440,7 @@ void JSObject::MigrateToMap(Handle<JSObject> object, Handle<Map> new_map) {
|
| if (details.representation().IsDouble()) {
|
| int target_index = new_descriptors->GetFieldIndex(i) - inobject;
|
| if (target_index < 0) target_index += total_size;
|
| - Handle<Object> box = isolate->factory()->NewHeapNumber(0);
|
| + Handle<Object> box = isolate->factory()->NewHeapNumber(0, MUTABLE);
|
| array->set(target_index, *box);
|
| }
|
| }
|
| @@ -3922,6 +3936,7 @@ Handle<Object> JSObject::SetPropertyUsingTransition(
|
| // Nothing more to be done.
|
| if (value->IsUninitialized()) return value;
|
| HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index));
|
| + ASSERT(box->IsMutableHeapNumber());
|
| box->set_value(value->Number());
|
| } else {
|
| object->FastPropertyAtPut(field_index, *value);
|
| @@ -3949,6 +3964,7 @@ static void SetPropertyToField(LookupResult* lookup,
|
| if (representation.IsDouble()) {
|
| HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
|
| lookup->GetFieldIndex().field_index()));
|
| + ASSERT(storage->IsMutableHeapNumber());
|
| storage->set_value(value->Number());
|
| return;
|
| }
|
| @@ -4599,6 +4615,11 @@ void JSObject::NormalizeProperties(Handle<JSObject> object,
|
| Handle<Name> key(descs->GetKey(i));
|
| Handle<Object> value(
|
| object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate);
|
| + if (details.representation().IsDouble()) {
|
| + ASSERT(value->IsMutableHeapNumber());
|
| + Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
|
| + value = isolate->factory()->NewHeapNumber(old->value());
|
| + }
|
| PropertyDetails d =
|
| PropertyDetails(details.attributes(), NORMAL, i + 1);
|
| dictionary = NameDictionaryAdd(dictionary, key, value, d);
|
| @@ -5641,6 +5662,15 @@ Handle<JSObject> JSObject::Copy(Handle<JSObject> object) {
|
| }
|
|
|
|
|
| +Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object,
|
| + Representation representation,
|
| + int index) {
|
| + Isolate* isolate = object->GetIsolate();
|
| + CALL_HEAP_FUNCTION(isolate,
|
| + object->FastPropertyAt(representation, index), Object);
|
| +}
|
| +
|
| +
|
| template<class ContextObject>
|
| class JSObjectWalkVisitor {
|
| public:
|
| @@ -6630,7 +6660,7 @@ Object* JSObject::SlowReverseLookup(Object* value) {
|
| if (descs->GetType(i) == FIELD) {
|
| Object* property = RawFastPropertyAt(descs->GetFieldIndex(i));
|
| if (descs->GetDetails(i).representation().IsDouble()) {
|
| - ASSERT(property->IsHeapNumber());
|
| + ASSERT(property->IsMutableHeapNumber());
|
| if (value->IsNumber() && property->Number() == value->Number()) {
|
| return descs->GetKey(i);
|
| }
|
|
|