OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/v8.h" | 5 #include "src/v8.h" |
6 | 6 |
7 #include "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/allocation-site-scopes.h" | 8 #include "src/allocation-site-scopes.h" |
9 #include "src/api.h" | 9 #include "src/api.h" |
10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
(...skipping 1522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1533 String::cast(symbol->name())->StringShortPrint(accumulator); | 1533 String::cast(symbol->name())->StringShortPrint(accumulator); |
1534 } | 1534 } |
1535 accumulator->Add(">"); | 1535 accumulator->Add(">"); |
1536 break; | 1536 break; |
1537 } | 1537 } |
1538 case HEAP_NUMBER_TYPE: | 1538 case HEAP_NUMBER_TYPE: |
1539 accumulator->Add("<Number: "); | 1539 accumulator->Add("<Number: "); |
1540 HeapNumber::cast(this)->HeapNumberPrint(accumulator); | 1540 HeapNumber::cast(this)->HeapNumberPrint(accumulator); |
1541 accumulator->Put('>'); | 1541 accumulator->Put('>'); |
1542 break; | 1542 break; |
| 1543 case MUTABLE_HEAP_NUMBER_TYPE: |
| 1544 accumulator->Add("<MutableNumber: "); |
| 1545 HeapNumber::cast(this)->HeapNumberPrint(accumulator); |
| 1546 accumulator->Put('>'); |
| 1547 break; |
1543 case JS_PROXY_TYPE: | 1548 case JS_PROXY_TYPE: |
1544 accumulator->Add("<JSProxy>"); | 1549 accumulator->Add("<JSProxy>"); |
1545 break; | 1550 break; |
1546 case JS_FUNCTION_PROXY_TYPE: | 1551 case JS_FUNCTION_PROXY_TYPE: |
1547 accumulator->Add("<JSFunctionProxy>"); | 1552 accumulator->Add("<JSFunctionProxy>"); |
1548 break; | 1553 break; |
1549 case FOREIGN_TYPE: | 1554 case FOREIGN_TYPE: |
1550 accumulator->Add("<Foreign>"); | 1555 accumulator->Add("<Foreign>"); |
1551 break; | 1556 break; |
1552 case CELL_TYPE: | 1557 case CELL_TYPE: |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1658 Cell::BodyDescriptor::IterateBody(this, v); | 1663 Cell::BodyDescriptor::IterateBody(this, v); |
1659 break; | 1664 break; |
1660 case PROPERTY_CELL_TYPE: | 1665 case PROPERTY_CELL_TYPE: |
1661 PropertyCell::BodyDescriptor::IterateBody(this, v); | 1666 PropertyCell::BodyDescriptor::IterateBody(this, v); |
1662 break; | 1667 break; |
1663 case SYMBOL_TYPE: | 1668 case SYMBOL_TYPE: |
1664 Symbol::BodyDescriptor::IterateBody(this, v); | 1669 Symbol::BodyDescriptor::IterateBody(this, v); |
1665 break; | 1670 break; |
1666 | 1671 |
1667 case HEAP_NUMBER_TYPE: | 1672 case HEAP_NUMBER_TYPE: |
| 1673 case MUTABLE_HEAP_NUMBER_TYPE: |
1668 case FILLER_TYPE: | 1674 case FILLER_TYPE: |
1669 case BYTE_ARRAY_TYPE: | 1675 case BYTE_ARRAY_TYPE: |
1670 case FREE_SPACE_TYPE: | 1676 case FREE_SPACE_TYPE: |
1671 break; | 1677 break; |
1672 | 1678 |
1673 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1679 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1674 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ | 1680 case EXTERNAL_##TYPE##_ARRAY_TYPE: \ |
1675 case FIXED_##TYPE##_ARRAY_TYPE: \ | 1681 case FIXED_##TYPE##_ARRAY_TYPE: \ |
1676 break; | 1682 break; |
1677 | 1683 |
(...skipping 21 matching lines...) Expand all Loading... |
1699 } | 1705 } |
1700 } | 1706 } |
1701 | 1707 |
1702 | 1708 |
1703 bool HeapNumber::HeapNumberBooleanValue() { | 1709 bool HeapNumber::HeapNumberBooleanValue() { |
1704 return DoubleToBoolean(value()); | 1710 return DoubleToBoolean(value()); |
1705 } | 1711 } |
1706 | 1712 |
1707 | 1713 |
1708 void HeapNumber::HeapNumberPrint(FILE* out) { | 1714 void HeapNumber::HeapNumberPrint(FILE* out) { |
1709 PrintF(out, "%.16g", Number()); | 1715 PrintF(out, "%.16g", value()); |
1710 } | 1716 } |
1711 | 1717 |
1712 | 1718 |
1713 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { | 1719 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { |
1714 // The Windows version of vsnprintf can allocate when printing a %g string | 1720 // The Windows version of vsnprintf can allocate when printing a %g string |
1715 // into a buffer that may not be big enough. We don't want random memory | 1721 // into a buffer that may not be big enough. We don't want random memory |
1716 // allocation when producing post-crash stack traces, so we print into a | 1722 // allocation when producing post-crash stack traces, so we print into a |
1717 // buffer that is plenty big enough for any floating point number, then | 1723 // buffer that is plenty big enough for any floating point number, then |
1718 // print that using vsnprintf (which may truncate but never allocate if | 1724 // print that using vsnprintf (which may truncate but never allocate if |
1719 // there is no more space in the buffer). | 1725 // there is no more space in the buffer). |
1720 EmbeddedVector<char, 100> buffer; | 1726 EmbeddedVector<char, 100> buffer; |
1721 SNPrintF(buffer, "%.16g", Number()); | 1727 SNPrintF(buffer, "%.16g", value()); |
1722 accumulator->Add("%s", buffer.start()); | 1728 accumulator->Add("%s", buffer.start()); |
1723 } | 1729 } |
1724 | 1730 |
1725 | 1731 |
1726 String* JSReceiver::class_name() { | 1732 String* JSReceiver::class_name() { |
1727 if (IsJSFunction() && IsJSFunctionProxy()) { | 1733 if (IsJSFunction() && IsJSFunctionProxy()) { |
1728 return GetHeap()->function_class_string(); | 1734 return GetHeap()->function_class_string(); |
1729 } | 1735 } |
1730 if (map()->constructor()->IsJSFunction()) { | 1736 if (map()->constructor()->IsJSFunction()) { |
1731 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1737 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2063 // If fields were added (or removed), rewrite the instance. | 2069 // If fields were added (or removed), rewrite the instance. |
2064 int number_of_fields = NumberOfFields(); | 2070 int number_of_fields = NumberOfFields(); |
2065 ASSERT(target_number_of_fields >= number_of_fields); | 2071 ASSERT(target_number_of_fields >= number_of_fields); |
2066 if (target_number_of_fields != number_of_fields) return true; | 2072 if (target_number_of_fields != number_of_fields) return true; |
2067 | 2073 |
2068 // If smi descriptors were replaced by double descriptors, rewrite. | 2074 // If smi descriptors were replaced by double descriptors, rewrite. |
2069 DescriptorArray* old_desc = instance_descriptors(); | 2075 DescriptorArray* old_desc = instance_descriptors(); |
2070 DescriptorArray* new_desc = target->instance_descriptors(); | 2076 DescriptorArray* new_desc = target->instance_descriptors(); |
2071 int limit = NumberOfOwnDescriptors(); | 2077 int limit = NumberOfOwnDescriptors(); |
2072 for (int i = 0; i < limit; i++) { | 2078 for (int i = 0; i < limit; i++) { |
2073 if (new_desc->GetDetails(i).representation().IsDouble() && | 2079 if (new_desc->GetDetails(i).representation().IsDouble() != |
2074 !old_desc->GetDetails(i).representation().IsDouble()) { | 2080 old_desc->GetDetails(i).representation().IsDouble()) { |
2075 return true; | 2081 return true; |
2076 } | 2082 } |
2077 } | 2083 } |
2078 | 2084 |
2079 // If no fields were added, and no inobject properties were removed, setting | 2085 // If no fields were added, and no inobject properties were removed, setting |
2080 // the map is sufficient. | 2086 // the map is sufficient. |
2081 if (target_inobject == inobject_properties()) return false; | 2087 if (target_inobject == inobject_properties()) return false; |
2082 // In-object slack tracking may have reduced the object size of the new map. | 2088 // In-object slack tracking may have reduced the object size of the new map. |
2083 // In that case, succeed if all existing fields were inobject, and they still | 2089 // In that case, succeed if all existing fields were inobject, and they still |
2084 // fit within the new inobject size. | 2090 // fit within the new inobject size. |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2161 // This migration is a transition from a map that has run out out property | 2167 // This migration is a transition from a map that has run out out property |
2162 // space. Therefore it could be done by extending the backing store. | 2168 // space. Therefore it could be done by extending the backing store. |
2163 Handle<FixedArray> old_storage = handle(object->properties(), isolate); | 2169 Handle<FixedArray> old_storage = handle(object->properties(), isolate); |
2164 Handle<FixedArray> new_storage = | 2170 Handle<FixedArray> new_storage = |
2165 FixedArray::CopySize(old_storage, external); | 2171 FixedArray::CopySize(old_storage, external); |
2166 | 2172 |
2167 // Properly initialize newly added property. | 2173 // Properly initialize newly added property. |
2168 PropertyDetails details = new_map->GetLastDescriptorDetails(); | 2174 PropertyDetails details = new_map->GetLastDescriptorDetails(); |
2169 Handle<Object> value; | 2175 Handle<Object> value; |
2170 if (details.representation().IsDouble()) { | 2176 if (details.representation().IsDouble()) { |
2171 value = isolate->factory()->NewHeapNumber(0); | 2177 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
2172 } else { | 2178 } else { |
2173 value = isolate->factory()->uninitialized_value(); | 2179 value = isolate->factory()->uninitialized_value(); |
2174 } | 2180 } |
2175 ASSERT(details.type() == FIELD); | 2181 ASSERT(details.type() == FIELD); |
2176 int target_index = details.field_index() - inobject; | 2182 int target_index = details.field_index() - inobject; |
2177 ASSERT(target_index >= 0); // Must be a backing store index. | 2183 ASSERT(target_index >= 0); // Must be a backing store index. |
2178 new_storage->set(target_index, *value); | 2184 new_storage->set(target_index, *value); |
2179 | 2185 |
2180 // From here on we cannot fail and we shouldn't GC anymore. | 2186 // From here on we cannot fail and we shouldn't GC anymore. |
2181 DisallowHeapAllocation no_allocation; | 2187 DisallowHeapAllocation no_allocation; |
(...skipping 27 matching lines...) Expand all Loading... |
2209 Object* raw_value = old_details.type() == CONSTANT | 2215 Object* raw_value = old_details.type() == CONSTANT |
2210 ? old_descriptors->GetValue(i) | 2216 ? old_descriptors->GetValue(i) |
2211 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); | 2217 : object->RawFastPropertyAt(FieldIndex::ForDescriptor(*old_map, i)); |
2212 Handle<Object> value(raw_value, isolate); | 2218 Handle<Object> value(raw_value, isolate); |
2213 if (!old_details.representation().IsDouble() && | 2219 if (!old_details.representation().IsDouble() && |
2214 details.representation().IsDouble()) { | 2220 details.representation().IsDouble()) { |
2215 if (old_details.representation().IsNone()) { | 2221 if (old_details.representation().IsNone()) { |
2216 value = handle(Smi::FromInt(0), isolate); | 2222 value = handle(Smi::FromInt(0), isolate); |
2217 } | 2223 } |
2218 value = Object::NewStorageFor(isolate, value, details.representation()); | 2224 value = Object::NewStorageFor(isolate, value, details.representation()); |
| 2225 } else if (old_details.representation().IsDouble() && |
| 2226 !details.representation().IsDouble()) { |
| 2227 value = Object::WrapForRead(isolate, value, old_details.representation()); |
2219 } | 2228 } |
2220 ASSERT(!(details.representation().IsDouble() && value->IsSmi())); | 2229 ASSERT(!(details.representation().IsDouble() && value->IsSmi())); |
2221 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2230 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
2222 if (target_index < 0) target_index += total_size; | 2231 if (target_index < 0) target_index += total_size; |
2223 array->set(target_index, *value); | 2232 array->set(target_index, *value); |
2224 } | 2233 } |
2225 | 2234 |
2226 for (int i = old_nof; i < new_nof; i++) { | 2235 for (int i = old_nof; i < new_nof; i++) { |
2227 PropertyDetails details = new_descriptors->GetDetails(i); | 2236 PropertyDetails details = new_descriptors->GetDetails(i); |
2228 if (details.type() != FIELD) continue; | 2237 if (details.type() != FIELD) continue; |
2229 Handle<Object> value; | 2238 Handle<Object> value; |
2230 if (details.representation().IsDouble()) { | 2239 if (details.representation().IsDouble()) { |
2231 value = isolate->factory()->NewHeapNumber(0); | 2240 value = isolate->factory()->NewHeapNumber(0, MUTABLE); |
2232 } else { | 2241 } else { |
2233 value = isolate->factory()->uninitialized_value(); | 2242 value = isolate->factory()->uninitialized_value(); |
2234 } | 2243 } |
2235 int target_index = new_descriptors->GetFieldIndex(i) - inobject; | 2244 int target_index = new_descriptors->GetFieldIndex(i) - inobject; |
2236 if (target_index < 0) target_index += total_size; | 2245 if (target_index < 0) target_index += total_size; |
2237 array->set(target_index, *value); | 2246 array->set(target_index, *value); |
2238 } | 2247 } |
2239 | 2248 |
2240 // From here on we cannot fail and we shouldn't GC anymore. | 2249 // From here on we cannot fail and we shouldn't GC anymore. |
2241 DisallowHeapAllocation no_allocation; | 2250 DisallowHeapAllocation no_allocation; |
(...skipping 1726 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3968 DescriptorArray* desc = map()->instance_descriptors(); | 3977 DescriptorArray* desc = map()->instance_descriptors(); |
3969 PropertyDetails details = desc->GetDetails(descriptor); | 3978 PropertyDetails details = desc->GetDetails(descriptor); |
3970 | 3979 |
3971 ASSERT(details.type() == FIELD); | 3980 ASSERT(details.type() == FIELD); |
3972 | 3981 |
3973 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); | 3982 FieldIndex index = FieldIndex::ForDescriptor(map(), descriptor); |
3974 if (details.representation().IsDouble()) { | 3983 if (details.representation().IsDouble()) { |
3975 // Nothing more to be done. | 3984 // Nothing more to be done. |
3976 if (value->IsUninitialized()) return; | 3985 if (value->IsUninitialized()) return; |
3977 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); | 3986 HeapNumber* box = HeapNumber::cast(RawFastPropertyAt(index)); |
| 3987 ASSERT(box->IsMutableHeapNumber()); |
3978 box->set_value(value->Number()); | 3988 box->set_value(value->Number()); |
3979 } else { | 3989 } else { |
3980 FastPropertyAtPut(index, value); | 3990 FastPropertyAtPut(index, value); |
3981 } | 3991 } |
3982 } | 3992 } |
3983 | 3993 |
3984 | 3994 |
3985 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { | 3995 void JSObject::SetPropertyToField(LookupResult* lookup, Handle<Object> value) { |
3986 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { | 3996 if (lookup->type() == CONSTANT || !lookup->CanHoldValue(value)) { |
3987 Representation field_representation = value->OptimalRepresentation(); | 3997 Representation field_representation = value->OptimalRepresentation(); |
(...skipping 627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4615 PropertyDetails d = PropertyDetails( | 4625 PropertyDetails d = PropertyDetails( |
4616 details.attributes(), NORMAL, i + 1); | 4626 details.attributes(), NORMAL, i + 1); |
4617 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4627 dictionary = NameDictionary::Add(dictionary, key, value, d); |
4618 break; | 4628 break; |
4619 } | 4629 } |
4620 case FIELD: { | 4630 case FIELD: { |
4621 Handle<Name> key(descs->GetKey(i)); | 4631 Handle<Name> key(descs->GetKey(i)); |
4622 FieldIndex index = FieldIndex::ForDescriptor(*map, i); | 4632 FieldIndex index = FieldIndex::ForDescriptor(*map, i); |
4623 Handle<Object> value( | 4633 Handle<Object> value( |
4624 object->RawFastPropertyAt(index), isolate); | 4634 object->RawFastPropertyAt(index), isolate); |
| 4635 if (details.representation().IsDouble()) { |
| 4636 ASSERT(value->IsMutableHeapNumber()); |
| 4637 Handle<HeapNumber> old = Handle<HeapNumber>::cast(value); |
| 4638 value = isolate->factory()->NewHeapNumber(old->value()); |
| 4639 } |
4625 PropertyDetails d = | 4640 PropertyDetails d = |
4626 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4641 PropertyDetails(details.attributes(), NORMAL, i + 1); |
4627 dictionary = NameDictionary::Add(dictionary, key, value, d); | 4642 dictionary = NameDictionary::Add(dictionary, key, value, d); |
4628 break; | 4643 break; |
4629 } | 4644 } |
4630 case CALLBACKS: { | 4645 case CALLBACKS: { |
4631 Handle<Name> key(descs->GetKey(i)); | 4646 Handle<Name> key(descs->GetKey(i)); |
4632 Handle<Object> value(descs->GetCallbacksObject(i), isolate); | 4647 Handle<Object> value(descs->GetCallbacksObject(i), isolate); |
4633 PropertyDetails d = PropertyDetails( | 4648 PropertyDetails d = PropertyDetails( |
4634 details.attributes(), CALLBACKS, i + 1); | 4649 details.attributes(), CALLBACKS, i + 1); |
(...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5787 } | 5802 } |
5788 JSObject::MigrateToMap(object, new_map); | 5803 JSObject::MigrateToMap(object, new_map); |
5789 } | 5804 } |
5790 | 5805 |
5791 | 5806 |
5792 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, | 5807 Handle<Object> JSObject::FastPropertyAt(Handle<JSObject> object, |
5793 Representation representation, | 5808 Representation representation, |
5794 FieldIndex index) { | 5809 FieldIndex index) { |
5795 Isolate* isolate = object->GetIsolate(); | 5810 Isolate* isolate = object->GetIsolate(); |
5796 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); | 5811 Handle<Object> raw_value(object->RawFastPropertyAt(index), isolate); |
5797 return Object::NewStorageFor(isolate, raw_value, representation); | 5812 return Object::WrapForRead(isolate, raw_value, representation); |
5798 } | 5813 } |
5799 | 5814 |
5800 | 5815 |
5801 template<class ContextObject> | 5816 template<class ContextObject> |
5802 class JSObjectWalkVisitor { | 5817 class JSObjectWalkVisitor { |
5803 public: | 5818 public: |
5804 JSObjectWalkVisitor(ContextObject* site_context, bool copying, | 5819 JSObjectWalkVisitor(ContextObject* site_context, bool copying, |
5805 JSObject::DeepCopyHints hints) | 5820 JSObject::DeepCopyHints hints) |
5806 : site_context_(site_context), | 5821 : site_context_(site_context), |
5807 copying_(copying), | 5822 copying_(copying), |
(...skipping 1170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6978 | 6993 |
6979 Object* JSObject::SlowReverseLookup(Object* value) { | 6994 Object* JSObject::SlowReverseLookup(Object* value) { |
6980 if (HasFastProperties()) { | 6995 if (HasFastProperties()) { |
6981 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); | 6996 int number_of_own_descriptors = map()->NumberOfOwnDescriptors(); |
6982 DescriptorArray* descs = map()->instance_descriptors(); | 6997 DescriptorArray* descs = map()->instance_descriptors(); |
6983 for (int i = 0; i < number_of_own_descriptors; i++) { | 6998 for (int i = 0; i < number_of_own_descriptors; i++) { |
6984 if (descs->GetType(i) == FIELD) { | 6999 if (descs->GetType(i) == FIELD) { |
6985 Object* property = | 7000 Object* property = |
6986 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); | 7001 RawFastPropertyAt(FieldIndex::ForDescriptor(map(), i)); |
6987 if (descs->GetDetails(i).representation().IsDouble()) { | 7002 if (descs->GetDetails(i).representation().IsDouble()) { |
6988 ASSERT(property->IsHeapNumber()); | 7003 ASSERT(property->IsMutableHeapNumber()); |
6989 if (value->IsNumber() && property->Number() == value->Number()) { | 7004 if (value->IsNumber() && property->Number() == value->Number()) { |
6990 return descs->GetKey(i); | 7005 return descs->GetKey(i); |
6991 } | 7006 } |
6992 } else if (property == value) { | 7007 } else if (property == value) { |
6993 return descs->GetKey(i); | 7008 return descs->GetKey(i); |
6994 } | 7009 } |
6995 } else if (descs->GetType(i) == CONSTANT) { | 7010 } else if (descs->GetType(i) == CONSTANT) { |
6996 if (descs->GetConstant(i) == value) { | 7011 if (descs->GetConstant(i) == value) { |
6997 return descs->GetKey(i); | 7012 return descs->GetKey(i); |
6998 } | 7013 } |
(...skipping 9941 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16940 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16955 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16941 static const char* error_messages_[] = { | 16956 static const char* error_messages_[] = { |
16942 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16957 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16943 }; | 16958 }; |
16944 #undef ERROR_MESSAGES_TEXTS | 16959 #undef ERROR_MESSAGES_TEXTS |
16945 return error_messages_[reason]; | 16960 return error_messages_[reason]; |
16946 } | 16961 } |
16947 | 16962 |
16948 | 16963 |
16949 } } // namespace v8::internal | 16964 } } // namespace v8::internal |
OLD | NEW |