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