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

Side by Side Diff: src/objects.cc

Issue 211333002: Replace HeapNumber as doublebox with an explicit MutableHeapNumber. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 9 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
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1706 matching lines...) Expand 10 before | Expand all | Expand 10 after
1717 String::cast(symbol->name())->StringShortPrint(accumulator); 1717 String::cast(symbol->name())->StringShortPrint(accumulator);
1718 } 1718 }
1719 accumulator->Add(">"); 1719 accumulator->Add(">");
1720 break; 1720 break;
1721 } 1721 }
1722 case HEAP_NUMBER_TYPE: 1722 case HEAP_NUMBER_TYPE:
1723 accumulator->Add("<Number: "); 1723 accumulator->Add("<Number: ");
1724 HeapNumber::cast(this)->HeapNumberPrint(accumulator); 1724 HeapNumber::cast(this)->HeapNumberPrint(accumulator);
1725 accumulator->Put('>'); 1725 accumulator->Put('>');
1726 break; 1726 break;
1727 case MUTABLE_HEAP_NUMBER_TYPE:
1728 accumulator->Add("<MutableNumber: ");
1729 HeapNumber::cast(this)->HeapNumberPrint(accumulator);
1730 accumulator->Put('>');
1731 break;
1727 case JS_PROXY_TYPE: 1732 case JS_PROXY_TYPE:
1728 accumulator->Add("<JSProxy>"); 1733 accumulator->Add("<JSProxy>");
1729 break; 1734 break;
1730 case JS_FUNCTION_PROXY_TYPE: 1735 case JS_FUNCTION_PROXY_TYPE:
1731 accumulator->Add("<JSFunctionProxy>"); 1736 accumulator->Add("<JSFunctionProxy>");
1732 break; 1737 break;
1733 case FOREIGN_TYPE: 1738 case FOREIGN_TYPE:
1734 accumulator->Add("<Foreign>"); 1739 accumulator->Add("<Foreign>");
1735 break; 1740 break;
1736 case CELL_TYPE: 1741 case CELL_TYPE:
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
1840 Cell::BodyDescriptor::IterateBody(this, v); 1845 Cell::BodyDescriptor::IterateBody(this, v);
1841 break; 1846 break;
1842 case PROPERTY_CELL_TYPE: 1847 case PROPERTY_CELL_TYPE:
1843 PropertyCell::BodyDescriptor::IterateBody(this, v); 1848 PropertyCell::BodyDescriptor::IterateBody(this, v);
1844 break; 1849 break;
1845 case SYMBOL_TYPE: 1850 case SYMBOL_TYPE:
1846 Symbol::BodyDescriptor::IterateBody(this, v); 1851 Symbol::BodyDescriptor::IterateBody(this, v);
1847 break; 1852 break;
1848 1853
1849 case HEAP_NUMBER_TYPE: 1854 case HEAP_NUMBER_TYPE:
1855 case MUTABLE_HEAP_NUMBER_TYPE:
1850 case FILLER_TYPE: 1856 case FILLER_TYPE:
1851 case BYTE_ARRAY_TYPE: 1857 case BYTE_ARRAY_TYPE:
1852 case FREE_SPACE_TYPE: 1858 case FREE_SPACE_TYPE:
1853 break; 1859 break;
1854 1860
1855 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1861 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1856 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ 1862 case EXTERNAL_##TYPE##_ARRAY_TYPE: \
1857 case FIXED_##TYPE##_ARRAY_TYPE: \ 1863 case FIXED_##TYPE##_ARRAY_TYPE: \
1858 break; 1864 break;
1859 1865
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1896 } 1902 }
1897 if (u.bits.exp == 0) { 1903 if (u.bits.exp == 0) {
1898 // Detect +0, and -0 for IEEE double precision floating point. 1904 // Detect +0, and -0 for IEEE double precision floating point.
1899 if ((u.bits.man_low | u.bits.man_high) == 0) return false; 1905 if ((u.bits.man_low | u.bits.man_high) == 0) return false;
1900 } 1906 }
1901 return true; 1907 return true;
1902 } 1908 }
1903 1909
1904 1910
1905 void HeapNumber::HeapNumberPrint(FILE* out) { 1911 void HeapNumber::HeapNumberPrint(FILE* out) {
1906 PrintF(out, "%.16g", Number()); 1912 PrintF(out, "%.16g", value());
1907 } 1913 }
1908 1914
1909 1915
1910 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { 1916 void HeapNumber::HeapNumberPrint(StringStream* accumulator) {
1911 // The Windows version of vsnprintf can allocate when printing a %g string 1917 // The Windows version of vsnprintf can allocate when printing a %g string
1912 // into a buffer that may not be big enough. We don't want random memory 1918 // into a buffer that may not be big enough. We don't want random memory
1913 // allocation when producing post-crash stack traces, so we print into a 1919 // allocation when producing post-crash stack traces, so we print into a
1914 // buffer that is plenty big enough for any floating point number, then 1920 // buffer that is plenty big enough for any floating point number, then
1915 // print that using vsnprintf (which may truncate but never allocate if 1921 // print that using vsnprintf (which may truncate but never allocate if
1916 // there is no more space in the buffer). 1922 // there is no more space in the buffer).
1917 EmbeddedVector<char, 100> buffer; 1923 EmbeddedVector<char, 100> buffer;
1918 OS::SNPrintF(buffer, "%.16g", Number()); 1924 OS::SNPrintF(buffer, "%.16g", value());
1919 accumulator->Add("%s", buffer.start()); 1925 accumulator->Add("%s", buffer.start());
1920 } 1926 }
1921 1927
1922 1928
1923 String* JSReceiver::class_name() { 1929 String* JSReceiver::class_name() {
1924 if (IsJSFunction() && IsJSFunctionProxy()) { 1930 if (IsJSFunction() && IsJSFunctionProxy()) {
1925 return GetHeap()->function_class_string(); 1931 return GetHeap()->function_class_string();
1926 } 1932 }
1927 if (map()->constructor()->IsJSFunction()) { 1933 if (map()->constructor()->IsJSFunction()) {
1928 JSFunction* constructor = JSFunction::cast(map()->constructor()); 1934 JSFunction* constructor = JSFunction::cast(map()->constructor());
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
2028 Representation representation = value->OptimalRepresentation(value_type); 2034 Representation representation = value->OptimalRepresentation(value_type);
2029 Handle<Map> new_map = CopyAddFieldDescriptor( 2035 Handle<Map> new_map = CopyAddFieldDescriptor(
2030 handle(object->map()), name, index, attributes, representation, flag); 2036 handle(object->map()), name, index, attributes, representation, flag);
2031 2037
2032 JSObject::MigrateToMap(object, new_map); 2038 JSObject::MigrateToMap(object, new_map);
2033 2039
2034 if (representation.IsDouble()) { 2040 if (representation.IsDouble()) {
2035 // Nothing more to be done. 2041 // Nothing more to be done.
2036 if (value->IsUninitialized()) return; 2042 if (value->IsUninitialized()) return;
2037 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index)); 2043 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(index));
2044 ASSERT(box->IsMutableHeapNumber());
2038 box->set_value(value->Number()); 2045 box->set_value(value->Number());
2039 } else { 2046 } else {
2040 object->FastPropertyAtPut(index, *value); 2047 object->FastPropertyAtPut(index, *value);
2041 } 2048 }
2042 } 2049 }
2043 2050
2044 2051
2045 static MaybeObject* CopyAddConstantDescriptor(Map* map, 2052 static MaybeObject* CopyAddConstantDescriptor(Map* map,
2046 Name* name, 2053 Name* name,
2047 Object* value, 2054 Object* value,
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2320 if (target_number_of_fields != number_of_fields) return true; 2327 if (target_number_of_fields != number_of_fields) return true;
2321 2328
2322 // If smi descriptors were replaced by double descriptors, rewrite. 2329 // If smi descriptors were replaced by double descriptors, rewrite.
2323 DescriptorArray* old_desc = instance_descriptors(); 2330 DescriptorArray* old_desc = instance_descriptors();
2324 DescriptorArray* new_desc = target->instance_descriptors(); 2331 DescriptorArray* new_desc = target->instance_descriptors();
2325 int limit = NumberOfOwnDescriptors(); 2332 int limit = NumberOfOwnDescriptors();
2326 for (int i = 0; i < limit; i++) { 2333 for (int i = 0; i < limit; i++) {
2327 if (new_desc->GetDetails(i).representation().IsDouble() && 2334 if (new_desc->GetDetails(i).representation().IsDouble() &&
2328 !old_desc->GetDetails(i).representation().IsDouble()) { 2335 !old_desc->GetDetails(i).representation().IsDouble()) {
2329 return true; 2336 return true;
2337 } else if (old_desc->GetDetails(i).representation().IsDouble() &&
2338 !new_desc->GetDetails(i).representation().IsDouble()) {
2339 return true;
2330 } 2340 }
2331 } 2341 }
2332 2342
2333 // If no fields were added, and no inobject properties were removed, setting 2343 // If no fields were added, and no inobject properties were removed, setting
2334 // the map is sufficient. 2344 // the map is sufficient.
2335 if (target_inobject == inobject_properties()) return false; 2345 if (target_inobject == inobject_properties()) return false;
2336 // In-object slack tracking may have reduced the object size of the new map. 2346 // In-object slack tracking may have reduced the object size of the new map.
2337 // In that case, succeed if all existing fields were inobject, and they still 2347 // In that case, succeed if all existing fields were inobject, and they still
2338 // fit within the new inobject size. 2348 // fit within the new inobject size.
2339 ASSERT(target_inobject < inobject_properties()); 2349 ASSERT(target_inobject < inobject_properties());
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2402 Object* raw_value = old_details.type() == CONSTANT 2412 Object* raw_value = old_details.type() == CONSTANT
2403 ? old_descriptors->GetValue(i) 2413 ? old_descriptors->GetValue(i)
2404 : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); 2414 : object->RawFastPropertyAt(old_descriptors->GetFieldIndex(i));
2405 Handle<Object> value(raw_value, isolate); 2415 Handle<Object> value(raw_value, isolate);
2406 if (!old_details.representation().IsDouble() && 2416 if (!old_details.representation().IsDouble() &&
2407 details.representation().IsDouble()) { 2417 details.representation().IsDouble()) {
2408 if (old_details.representation().IsNone()) { 2418 if (old_details.representation().IsNone()) {
2409 value = handle(Smi::FromInt(0), isolate); 2419 value = handle(Smi::FromInt(0), isolate);
2410 } 2420 }
2411 value = NewStorageFor(isolate, value, details.representation()); 2421 value = NewStorageFor(isolate, value, details.representation());
2422 } else if (old_details.representation().IsDouble() &&
2423 !details.representation().IsDouble()) {
2424 Handle<HeapNumber> old_value = Handle<HeapNumber>::cast(value);
2425 value = isolate->factory()->NewHeapNumber(old_value->value());
2412 } 2426 }
2413 ASSERT(!(details.representation().IsDouble() && value->IsSmi())); 2427 ASSERT(!(details.representation().IsDouble() && value->IsSmi()));
2414 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2428 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2415 if (target_index < 0) target_index += total_size; 2429 if (target_index < 0) target_index += total_size;
2416 array->set(target_index, *value); 2430 array->set(target_index, *value);
2417 } 2431 }
2418 2432
2419 for (int i = old_nof; i < new_nof; i++) { 2433 for (int i = old_nof; i < new_nof; i++) {
2420 PropertyDetails details = new_descriptors->GetDetails(i); 2434 PropertyDetails details = new_descriptors->GetDetails(i);
2421 if (details.type() != FIELD) continue; 2435 if (details.type() != FIELD) continue;
2422 if (details.representation().IsDouble()) { 2436 if (details.representation().IsDouble()) {
2423 int target_index = new_descriptors->GetFieldIndex(i) - inobject; 2437 int target_index = new_descriptors->GetFieldIndex(i) - inobject;
2424 if (target_index < 0) target_index += total_size; 2438 if (target_index < 0) target_index += total_size;
2425 Handle<Object> box = isolate->factory()->NewHeapNumber(0); 2439 Handle<Object> box = isolate->factory()->NewMutableHeapNumber(0);
2426 array->set(target_index, *box); 2440 array->set(target_index, *box);
2427 } 2441 }
2428 } 2442 }
2429 2443
2430 // From here on we cannot fail and we shouldn't GC anymore. 2444 // From here on we cannot fail and we shouldn't GC anymore.
2431 DisallowHeapAllocation no_allocation; 2445 DisallowHeapAllocation no_allocation;
2432 2446
2433 // Copy (real) inobject properties. If necessary, stop at number_of_fields to 2447 // Copy (real) inobject properties. If necessary, stop at number_of_fields to
2434 // avoid overwriting |one_pointer_filler_map|. 2448 // avoid overwriting |one_pointer_filler_map|.
2435 int limit = Min(inobject, number_of_fields); 2449 int limit = Min(inobject, number_of_fields);
(...skipping 1476 matching lines...) Expand 10 before | Expand all | Expand 10 after
3912 descriptors = transition_map->instance_descriptors(); 3926 descriptors = transition_map->instance_descriptors();
3913 details = descriptors->GetDetails(descriptor); 3927 details = descriptors->GetDetails(descriptor);
3914 3928
3915 if (details.type() != FIELD) return value; 3929 if (details.type() != FIELD) return value;
3916 3930
3917 int field_index = descriptors->GetFieldIndex(descriptor); 3931 int field_index = descriptors->GetFieldIndex(descriptor);
3918 if (details.representation().IsDouble()) { 3932 if (details.representation().IsDouble()) {
3919 // Nothing more to be done. 3933 // Nothing more to be done.
3920 if (value->IsUninitialized()) return value; 3934 if (value->IsUninitialized()) return value;
3921 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index)); 3935 HeapNumber* box = HeapNumber::cast(object->RawFastPropertyAt(field_index));
3936 ASSERT(box->IsMutableHeapNumber());
3922 box->set_value(value->Number()); 3937 box->set_value(value->Number());
3923 } else { 3938 } else {
3924 object->FastPropertyAtPut(field_index, *value); 3939 object->FastPropertyAtPut(field_index, *value);
3925 } 3940 }
3926 3941
3927 return value; 3942 return value;
3928 } 3943 }
3929 3944
3930 3945
3931 static void SetPropertyToField(LookupResult* lookup, 3946 static void SetPropertyToField(LookupResult* lookup,
3932 Handle<Name> name, 3947 Handle<Name> name,
3933 Handle<Object> value) { 3948 Handle<Object> value) {
3934 Representation representation = lookup->representation(); 3949 Representation representation = lookup->representation();
3935 if (!value->FitsRepresentation(representation) || 3950 if (!value->FitsRepresentation(representation) ||
3936 lookup->type() == CONSTANT) { 3951 lookup->type() == CONSTANT) {
3937 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()), 3952 JSObject::GeneralizeFieldRepresentation(handle(lookup->holder()),
3938 lookup->GetDescriptorIndex(), 3953 lookup->GetDescriptorIndex(),
3939 value->OptimalRepresentation(), 3954 value->OptimalRepresentation(),
3940 FORCE_FIELD); 3955 FORCE_FIELD);
3941 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors(); 3956 DescriptorArray* desc = lookup->holder()->map()->instance_descriptors();
3942 int descriptor = lookup->GetDescriptorIndex(); 3957 int descriptor = lookup->GetDescriptorIndex();
3943 representation = desc->GetDetails(descriptor).representation(); 3958 representation = desc->GetDetails(descriptor).representation();
3944 } 3959 }
3945 3960
3946 if (representation.IsDouble()) { 3961 if (representation.IsDouble()) {
3947 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt( 3962 HeapNumber* storage = HeapNumber::cast(lookup->holder()->RawFastPropertyAt(
3948 lookup->GetFieldIndex().field_index())); 3963 lookup->GetFieldIndex().field_index()));
3964 ASSERT(storage->IsMutableHeapNumber());
3949 storage->set_value(value->Number()); 3965 storage->set_value(value->Number());
3950 return; 3966 return;
3951 } 3967 }
3952 3968
3953 lookup->holder()->FastPropertyAtPut( 3969 lookup->holder()->FastPropertyAtPut(
3954 lookup->GetFieldIndex().field_index(), *value); 3970 lookup->GetFieldIndex().field_index(), *value);
3955 } 3971 }
3956 3972
3957 3973
3958 static void ConvertAndSetLocalProperty(LookupResult* lookup, 3974 static void ConvertAndSetLocalProperty(LookupResult* lookup,
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
4589 Handle<Object> value(descs->GetConstant(i), isolate); 4605 Handle<Object> value(descs->GetConstant(i), isolate);
4590 PropertyDetails d = PropertyDetails( 4606 PropertyDetails d = PropertyDetails(
4591 details.attributes(), NORMAL, i + 1); 4607 details.attributes(), NORMAL, i + 1);
4592 dictionary = NameDictionaryAdd(dictionary, key, value, d); 4608 dictionary = NameDictionaryAdd(dictionary, key, value, d);
4593 break; 4609 break;
4594 } 4610 }
4595 case FIELD: { 4611 case FIELD: {
4596 Handle<Name> key(descs->GetKey(i)); 4612 Handle<Name> key(descs->GetKey(i));
4597 Handle<Object> value( 4613 Handle<Object> value(
4598 object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate); 4614 object->RawFastPropertyAt(descs->GetFieldIndex(i)), isolate);
4615 if (details.representation().IsDouble()) {
4616 ASSERT(value->IsMutableHeapNumber());
4617 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value);
4618 value = isolate->factory()->NewHeapNumber(old->value());
4619 }
4599 PropertyDetails d = 4620 PropertyDetails d =
4600 PropertyDetails(details.attributes(), NORMAL, i + 1); 4621 PropertyDetails(details.attributes(), NORMAL, i + 1);
4601 dictionary = NameDictionaryAdd(dictionary, key, value, d); 4622 dictionary = NameDictionaryAdd(dictionary, key, value, d);
4602 break; 4623 break;
4603 } 4624 }
4604 case CALLBACKS: { 4625 case CALLBACKS: {
4605 Handle<Name> key(descs->GetKey(i)); 4626 Handle<Name> key(descs->GetKey(i));
4606 Handle<Object> value(descs->GetCallbacksObject(i), isolate); 4627 Handle<Object> value(descs->GetCallbacksObject(i), isolate);
4607 PropertyDetails d = PropertyDetails( 4628 PropertyDetails d = PropertyDetails(
4608 details.attributes(), CALLBACKS, i + 1); 4629 details.attributes(), CALLBACKS, i + 1);
(...skipping 2008 matching lines...) Expand 10 before | Expand all | Expand 10 after
6617 6638
6618 6639
6619 Object* JSObject::SlowReverseLookup(Object* value) { 6640 Object* JSObject::SlowReverseLookup(Object* value) {
6620 if (HasFastProperties()) { 6641 if (HasFastProperties()) {
6621 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); 6642 int number_of_own_descriptors = map()->NumberOfOwnDescriptors();
6622 DescriptorArray* descs = map()->instance_descriptors(); 6643 DescriptorArray* descs = map()->instance_descriptors();
6623 for (int i = 0; i < number_of_own_descriptors; i++) { 6644 for (int i = 0; i < number_of_own_descriptors; i++) {
6624 if (descs->GetType(i) == FIELD) { 6645 if (descs->GetType(i) == FIELD) {
6625 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i)); 6646 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i));
6626 if (descs->GetDetails(i).representation().IsDouble()) { 6647 if (descs->GetDetails(i).representation().IsDouble()) {
6627 ASSERT(property->IsHeapNumber()); 6648 ASSERT(property->IsMutableHeapNumber());
6628 if (value->IsNumber() && property->Number() == value->Number()) { 6649 if (value->IsNumber() && property->Number() == value->Number()) {
6629 return descs->GetKey(i); 6650 return descs->GetKey(i);
6630 } 6651 }
6631 } else if (property == value) { 6652 } else if (property == value) {
6632 return descs->GetKey(i); 6653 return descs->GetKey(i);
6633 } 6654 }
6634 } else if (descs->GetType(i) == CONSTANT) { 6655 } else if (descs->GetType(i) == CONSTANT) {
6635 if (descs->GetConstant(i) == value) { 6656 if (descs->GetConstant(i) == value) {
6636 return descs->GetKey(i); 6657 return descs->GetKey(i);
6637 } 6658 }
(...skipping 9725 matching lines...) Expand 10 before | Expand all | Expand 10 after
16363 #define ERROR_MESSAGES_TEXTS(C, T) T, 16384 #define ERROR_MESSAGES_TEXTS(C, T) T,
16364 static const char* error_messages_[] = { 16385 static const char* error_messages_[] = {
16365 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16386 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16366 }; 16387 };
16367 #undef ERROR_MESSAGES_TEXTS 16388 #undef ERROR_MESSAGES_TEXTS
16368 return error_messages_[reason]; 16389 return error_messages_[reason];
16369 } 16390 }
16370 16391
16371 16392
16372 } } // namespace v8::internal 16393 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698