| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 25 matching lines...) Expand all Loading... |
| 36 #include "scanner.h" | 36 #include "scanner.h" |
| 37 #include "scopeinfo.h" | 37 #include "scopeinfo.h" |
| 38 #include "string-stream.h" | 38 #include "string-stream.h" |
| 39 | 39 |
| 40 #ifdef ENABLE_DISASSEMBLER | 40 #ifdef ENABLE_DISASSEMBLER |
| 41 #include "disassembler.h" | 41 #include "disassembler.h" |
| 42 #endif | 42 #endif |
| 43 | 43 |
| 44 namespace v8 { namespace internal { | 44 namespace v8 { namespace internal { |
| 45 | 45 |
| 46 #define FIELD_ADDR(p, offset) \ |
| 47 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag) |
| 48 |
| 49 |
| 50 #define WRITE_FIELD(p, offset, value) \ |
| 51 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value) |
| 52 |
| 53 |
| 54 #define WRITE_INT_FIELD(p, offset, value) \ |
| 55 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value) |
| 56 |
| 57 |
| 58 #define WRITE_BARRIER(object, offset) \ |
| 59 Heap::RecordWrite(object->address(), offset); |
| 60 |
| 61 |
| 46 // Getters and setters are stored in a fixed array property. These are | 62 // Getters and setters are stored in a fixed array property. These are |
| 47 // constants for their indices. | 63 // constants for their indices. |
| 48 const int kGetterIndex = 0; | 64 const int kGetterIndex = 0; |
| 49 const int kSetterIndex = 1; | 65 const int kSetterIndex = 1; |
| 50 | 66 |
| 51 bool Object::IsInstanceOf(FunctionTemplateInfo* expected) { | 67 bool Object::IsInstanceOf(FunctionTemplateInfo* expected) { |
| 52 // There is a constraint on the object; check | 68 // There is a constraint on the object; check |
| 53 if (!this->IsJSObject()) return false; | 69 if (!this->IsJSObject()) return false; |
| 54 // Fetch the constructor function of the object | 70 // Fetch the constructor function of the object |
| 55 Object* cons_obj = JSObject::cast(this)->map()->constructor(); | 71 Object* cons_obj = JSObject::cast(this)->map()->constructor(); |
| (...skipping 977 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1033 return FastPropertyAtPut(index, value); | 1049 return FastPropertyAtPut(index, value); |
| 1034 } | 1050 } |
| 1035 | 1051 |
| 1036 | 1052 |
| 1037 Object* JSObject::AddFastProperty(String* name, | 1053 Object* JSObject::AddFastProperty(String* name, |
| 1038 Object* value, | 1054 Object* value, |
| 1039 PropertyAttributes attributes) { | 1055 PropertyAttributes attributes) { |
| 1040 // Normalize the object if the name is not a real identifier. | 1056 // Normalize the object if the name is not a real identifier. |
| 1041 StringInputBuffer buffer(name); | 1057 StringInputBuffer buffer(name); |
| 1042 if (!Scanner::IsIdentifier(&buffer)) { | 1058 if (!Scanner::IsIdentifier(&buffer)) { |
| 1043 Object* obj = NormalizeProperties(); | 1059 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 1044 if (obj->IsFailure()) return obj; | 1060 if (obj->IsFailure()) return obj; |
| 1045 return AddSlowProperty(name, value, attributes); | 1061 return AddSlowProperty(name, value, attributes); |
| 1046 } | 1062 } |
| 1047 | 1063 |
| 1048 DescriptorArray* old_descriptors = map()->instance_descriptors(); | 1064 DescriptorArray* old_descriptors = map()->instance_descriptors(); |
| 1049 // Compute the new index for new field. | 1065 // Compute the new index for new field. |
| 1050 int index = map()->NextFreePropertyIndex(); | 1066 int index = map()->NextFreePropertyIndex(); |
| 1051 | 1067 |
| 1052 // Allocate new instance descriptors with (name, index) added | 1068 // Allocate new instance descriptors with (name, index) added |
| 1053 FieldDescriptor new_field(name, index, attributes); | 1069 FieldDescriptor new_field(name, index, attributes); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1071 if (allow_map_transition) { | 1087 if (allow_map_transition) { |
| 1072 // Allocate new instance descriptors for the old map with map transition. | 1088 // Allocate new instance descriptors for the old map with map transition. |
| 1073 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); | 1089 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); |
| 1074 Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); | 1090 Object* r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); |
| 1075 if (r->IsFailure()) return r; | 1091 if (r->IsFailure()) return r; |
| 1076 old_descriptors = DescriptorArray::cast(r); | 1092 old_descriptors = DescriptorArray::cast(r); |
| 1077 } | 1093 } |
| 1078 | 1094 |
| 1079 if (map()->unused_property_fields() == 0) { | 1095 if (map()->unused_property_fields() == 0) { |
| 1080 if (properties()->length() > kMaxFastProperties) { | 1096 if (properties()->length() > kMaxFastProperties) { |
| 1081 Object* obj = NormalizeProperties(); | 1097 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 1082 if (obj->IsFailure()) return obj; | 1098 if (obj->IsFailure()) return obj; |
| 1083 return AddSlowProperty(name, value, attributes); | 1099 return AddSlowProperty(name, value, attributes); |
| 1084 } | 1100 } |
| 1085 // Make room for the new value | 1101 // Make room for the new value |
| 1086 Object* values = | 1102 Object* values = |
| 1087 properties()->CopySize(properties()->length() + kFieldsAdded); | 1103 properties()->CopySize(properties()->length() + kFieldsAdded); |
| 1088 if (values->IsFailure()) return values; | 1104 if (values->IsFailure()) return values; |
| 1089 set_properties(FixedArray::cast(values)); | 1105 set_properties(FixedArray::cast(values)); |
| 1090 new_map->set_unused_property_fields(kFieldsAdded - 1); | 1106 new_map->set_unused_property_fields(kFieldsAdded - 1); |
| 1091 } else { | 1107 } else { |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1173 if (value->IsJSFunction()) { | 1189 if (value->IsJSFunction()) { |
| 1174 return AddConstantFunctionProperty(name, | 1190 return AddConstantFunctionProperty(name, |
| 1175 JSFunction::cast(value), | 1191 JSFunction::cast(value), |
| 1176 attributes); | 1192 attributes); |
| 1177 } else { | 1193 } else { |
| 1178 return AddFastProperty(name, value, attributes); | 1194 return AddFastProperty(name, value, attributes); |
| 1179 } | 1195 } |
| 1180 } else { | 1196 } else { |
| 1181 // Normalize the object to prevent very large instance descriptors. | 1197 // Normalize the object to prevent very large instance descriptors. |
| 1182 // This eliminates unwanted N^2 allocation and lookup behavior. | 1198 // This eliminates unwanted N^2 allocation and lookup behavior. |
| 1183 Object* obj = NormalizeProperties(); | 1199 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 1184 if (obj->IsFailure()) return obj; | 1200 if (obj->IsFailure()) return obj; |
| 1185 } | 1201 } |
| 1186 } | 1202 } |
| 1187 return AddSlowProperty(name, value, attributes); | 1203 return AddSlowProperty(name, value, attributes); |
| 1188 } | 1204 } |
| 1189 | 1205 |
| 1190 | 1206 |
| 1191 Object* JSObject::SetPropertyPostInterceptor(String* name, | 1207 Object* JSObject::SetPropertyPostInterceptor(String* name, |
| 1192 Object* value, | 1208 Object* value, |
| 1193 PropertyAttributes attributes) { | 1209 PropertyAttributes attributes) { |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1246 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1262 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1247 return result; | 1263 return result; |
| 1248 } | 1264 } |
| 1249 | 1265 |
| 1250 | 1266 |
| 1251 Object* JSObject::ConvertDescriptorToField(String* name, | 1267 Object* JSObject::ConvertDescriptorToField(String* name, |
| 1252 Object* new_value, | 1268 Object* new_value, |
| 1253 PropertyAttributes attributes) { | 1269 PropertyAttributes attributes) { |
| 1254 if (map()->unused_property_fields() == 0 && | 1270 if (map()->unused_property_fields() == 0 && |
| 1255 properties()->length() > kMaxFastProperties) { | 1271 properties()->length() > kMaxFastProperties) { |
| 1256 Object* obj = NormalizeProperties(); | 1272 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 1257 if (obj->IsFailure()) return obj; | 1273 if (obj->IsFailure()) return obj; |
| 1258 return ReplaceSlowProperty(name, new_value, attributes); | 1274 return ReplaceSlowProperty(name, new_value, attributes); |
| 1259 } | 1275 } |
| 1260 | 1276 |
| 1261 int index = map()->NextFreePropertyIndex(); | 1277 int index = map()->NextFreePropertyIndex(); |
| 1262 FieldDescriptor new_field(name, index, attributes); | 1278 FieldDescriptor new_field(name, index, attributes); |
| 1263 // Make a new DescriptorArray replacing an entry with FieldDescriptor. | 1279 // Make a new DescriptorArray replacing an entry with FieldDescriptor. |
| 1264 Object* descriptors_unchecked = map()->instance_descriptors()-> | 1280 Object* descriptors_unchecked = map()->instance_descriptors()-> |
| 1265 CopyInsert(&new_field, REMOVE_TRANSITIONS); | 1281 CopyInsert(&new_field, REMOVE_TRANSITIONS); |
| 1266 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; | 1282 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1841 if (HasLocalElement(index)) return NONE; | 1857 if (HasLocalElement(index)) return NONE; |
| 1842 return ABSENT; | 1858 return ABSENT; |
| 1843 } | 1859 } |
| 1844 // Named property. | 1860 // Named property. |
| 1845 LookupResult result; | 1861 LookupResult result; |
| 1846 LocalLookup(name, &result); | 1862 LocalLookup(name, &result); |
| 1847 return GetPropertyAttribute(this, &result, name, false); | 1863 return GetPropertyAttribute(this, &result, name, false); |
| 1848 } | 1864 } |
| 1849 | 1865 |
| 1850 | 1866 |
| 1851 Object* JSObject::NormalizeProperties() { | 1867 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode) { |
| 1852 if (!HasFastProperties()) return this; | 1868 if (!HasFastProperties()) return this; |
| 1853 | 1869 |
| 1854 // Allocate new content | 1870 // Allocate new content |
| 1855 Object* obj = | 1871 Object* obj = |
| 1856 Dictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); | 1872 Dictionary::Allocate(map()->NumberOfDescribedProperties() * 2 + 4); |
| 1857 if (obj->IsFailure()) return obj; | 1873 if (obj->IsFailure()) return obj; |
| 1858 Dictionary* dictionary = Dictionary::cast(obj); | 1874 Dictionary* dictionary = Dictionary::cast(obj); |
| 1859 | 1875 |
| 1860 for (DescriptorReader r(map()->instance_descriptors()); | 1876 for (DescriptorReader r(map()->instance_descriptors()); |
| 1861 !r.eos(); | 1877 !r.eos(); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1901 } | 1917 } |
| 1902 } | 1918 } |
| 1903 | 1919 |
| 1904 // Copy the next enumeration index from instance descriptor. | 1920 // Copy the next enumeration index from instance descriptor. |
| 1905 int index = map()->instance_descriptors()->NextEnumerationIndex(); | 1921 int index = map()->instance_descriptors()->NextEnumerationIndex(); |
| 1906 dictionary->SetNextEnumerationIndex(index); | 1922 dictionary->SetNextEnumerationIndex(index); |
| 1907 | 1923 |
| 1908 // Allocate new map. | 1924 // Allocate new map. |
| 1909 obj = map()->Copy(); | 1925 obj = map()->Copy(); |
| 1910 if (obj->IsFailure()) return obj; | 1926 if (obj->IsFailure()) return obj; |
| 1927 Map* new_map = Map::cast(obj); |
| 1928 |
| 1929 // Clear inobject properties if needed by adjusting the instance |
| 1930 // size and putting in a filler or byte array instead of the |
| 1931 // inobject properties. |
| 1932 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { |
| 1933 int instance_size_delta = map()->inobject_properties() * kPointerSize; |
| 1934 int new_instance_size = map()->instance_size() - instance_size_delta; |
| 1935 new_map->set_inobject_properties(0); |
| 1936 new_map->set_instance_size(new_instance_size); |
| 1937 if (instance_size_delta == kPointerSize) { |
| 1938 WRITE_FIELD(this, new_instance_size, Heap::one_word_filler_map()); |
| 1939 } else { |
| 1940 int byte_array_length = ByteArray::LengthFor(instance_size_delta); |
| 1941 int byte_array_length_offset = new_instance_size + kPointerSize; |
| 1942 WRITE_FIELD(this, new_instance_size, Heap::byte_array_map()); |
| 1943 WRITE_INT_FIELD(this, byte_array_length_offset, byte_array_length); |
| 1944 } |
| 1945 WRITE_BARRIER(this, new_instance_size); |
| 1946 } |
| 1947 new_map->set_unused_property_fields(0); |
| 1911 | 1948 |
| 1912 // We have now sucessfully allocated all the necessary objects. | 1949 // We have now sucessfully allocated all the necessary objects. |
| 1913 // Changes can now be made with the guarantee that all of them take effect. | 1950 // Changes can now be made with the guarantee that all of them take effect. |
| 1914 set_map(Map::cast(obj)); | 1951 set_map(new_map); |
| 1915 map()->set_instance_descriptors(Heap::empty_descriptor_array()); | 1952 map()->set_instance_descriptors(Heap::empty_descriptor_array()); |
| 1916 | 1953 |
| 1917 map()->set_unused_property_fields(0); | |
| 1918 set_properties(dictionary); | 1954 set_properties(dictionary); |
| 1919 | 1955 |
| 1920 Counters::props_to_dictionary.Increment(); | 1956 Counters::props_to_dictionary.Increment(); |
| 1921 | 1957 |
| 1922 #ifdef DEBUG | 1958 #ifdef DEBUG |
| 1923 if (FLAG_trace_normalization) { | 1959 if (FLAG_trace_normalization) { |
| 1924 PrintF("Object properties have been normalized:\n"); | 1960 PrintF("Object properties have been normalized:\n"); |
| 1925 Print(); | 1961 Print(); |
| 1926 } | 1962 } |
| 1927 #endif | 1963 #endif |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1975 } | 2011 } |
| 1976 | 2012 |
| 1977 | 2013 |
| 1978 Object* JSObject::DeletePropertyPostInterceptor(String* name) { | 2014 Object* JSObject::DeletePropertyPostInterceptor(String* name) { |
| 1979 // Check local property, ignore interceptor. | 2015 // Check local property, ignore interceptor. |
| 1980 LookupResult result; | 2016 LookupResult result; |
| 1981 LocalLookupRealNamedProperty(name, &result); | 2017 LocalLookupRealNamedProperty(name, &result); |
| 1982 if (!result.IsValid()) return Heap::true_value(); | 2018 if (!result.IsValid()) return Heap::true_value(); |
| 1983 | 2019 |
| 1984 // Normalize object if needed. | 2020 // Normalize object if needed. |
| 1985 Object* obj = NormalizeProperties(); | 2021 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 1986 if (obj->IsFailure()) return obj; | 2022 if (obj->IsFailure()) return obj; |
| 1987 | 2023 |
| 1988 ASSERT(!HasFastProperties()); | 2024 ASSERT(!HasFastProperties()); |
| 1989 // Attempt to remove the property from the property dictionary. | 2025 // Attempt to remove the property from the property dictionary. |
| 1990 Dictionary* dictionary = property_dictionary(); | 2026 Dictionary* dictionary = property_dictionary(); |
| 1991 int entry = dictionary->FindStringEntry(name); | 2027 int entry = dictionary->FindStringEntry(name); |
| 1992 if (entry != -1) return dictionary->DeleteProperty(entry); | 2028 if (entry != -1) return dictionary->DeleteProperty(entry); |
| 1993 return Heap::true_value(); | 2029 return Heap::true_value(); |
| 1994 } | 2030 } |
| 1995 | 2031 |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2138 if (!result.IsValid()) return Heap::true_value(); | 2174 if (!result.IsValid()) return Heap::true_value(); |
| 2139 if (result.IsDontDelete()) return Heap::false_value(); | 2175 if (result.IsDontDelete()) return Heap::false_value(); |
| 2140 // Check for interceptor. | 2176 // Check for interceptor. |
| 2141 if (result.type() == INTERCEPTOR) { | 2177 if (result.type() == INTERCEPTOR) { |
| 2142 return DeletePropertyWithInterceptor(name); | 2178 return DeletePropertyWithInterceptor(name); |
| 2143 } | 2179 } |
| 2144 if (!result.IsLoaded()) { | 2180 if (!result.IsLoaded()) { |
| 2145 return JSObject::cast(this)->DeleteLazyProperty(&result, name); | 2181 return JSObject::cast(this)->DeleteLazyProperty(&result, name); |
| 2146 } | 2182 } |
| 2147 // Normalize object if needed. | 2183 // Normalize object if needed. |
| 2148 Object* obj = NormalizeProperties(); | 2184 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2149 if (obj->IsFailure()) return obj; | 2185 if (obj->IsFailure()) return obj; |
| 2150 // Make sure the properties are normalized before removing the entry. | 2186 // Make sure the properties are normalized before removing the entry. |
| 2151 Dictionary* dictionary = property_dictionary(); | 2187 Dictionary* dictionary = property_dictionary(); |
| 2152 int entry = dictionary->FindStringEntry(name); | 2188 int entry = dictionary->FindStringEntry(name); |
| 2153 if (entry != -1) return dictionary->DeleteProperty(entry); | 2189 if (entry != -1) return dictionary->DeleteProperty(entry); |
| 2154 return Heap::true_value(); | 2190 return Heap::true_value(); |
| 2155 } | 2191 } |
| 2156 } | 2192 } |
| 2157 | 2193 |
| 2158 | 2194 |
| (...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2404 LocalLookup(name, &result); | 2440 LocalLookup(name, &result); |
| 2405 if (result.IsValid()) { | 2441 if (result.IsValid()) { |
| 2406 if (result.IsReadOnly()) return Heap::undefined_value(); | 2442 if (result.IsReadOnly()) return Heap::undefined_value(); |
| 2407 if (result.type() == CALLBACKS) { | 2443 if (result.type() == CALLBACKS) { |
| 2408 Object* obj = result.GetCallbackObject(); | 2444 Object* obj = result.GetCallbackObject(); |
| 2409 if (obj->IsFixedArray()) return obj; | 2445 if (obj->IsFixedArray()) return obj; |
| 2410 } | 2446 } |
| 2411 } | 2447 } |
| 2412 | 2448 |
| 2413 // Normalize object to make this operation simple. | 2449 // Normalize object to make this operation simple. |
| 2414 Object* ok = NormalizeProperties(); | 2450 Object* ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES); |
| 2415 if (ok->IsFailure()) return ok; | 2451 if (ok->IsFailure()) return ok; |
| 2416 | 2452 |
| 2417 // Allocate the fixed array to hold getter and setter. | 2453 // Allocate the fixed array to hold getter and setter. |
| 2418 Object* array = Heap::AllocateFixedArray(2); | 2454 Object* array = Heap::AllocateFixedArray(2); |
| 2419 if (array->IsFailure()) return array; | 2455 if (array->IsFailure()) return array; |
| 2420 | 2456 |
| 2421 // Update the dictionary with the new CALLBACKS property. | 2457 // Update the dictionary with the new CALLBACKS property. |
| 2422 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); | 2458 PropertyDetails details = PropertyDetails(attributes, CALLBACKS); |
| 2423 Object* dict = | 2459 Object* dict = |
| 2424 property_dictionary()->SetOrAddStringEntry(name, array, details); | 2460 property_dictionary()->SetOrAddStringEntry(name, array, details); |
| (...skipping 4232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6657 if (type == NORMAL && !value->IsJSFunction()) number_of_fields += 1; | 6693 if (type == NORMAL && !value->IsJSFunction()) number_of_fields += 1; |
| 6658 } | 6694 } |
| 6659 } | 6695 } |
| 6660 | 6696 |
| 6661 // Allocate the instance descriptor. | 6697 // Allocate the instance descriptor. |
| 6662 Object* descriptors_unchecked = | 6698 Object* descriptors_unchecked = |
| 6663 DescriptorArray::Allocate(instance_descriptor_length); | 6699 DescriptorArray::Allocate(instance_descriptor_length); |
| 6664 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; | 6700 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; |
| 6665 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); | 6701 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); |
| 6666 | 6702 |
| 6667 int number_of_allocated_fields = number_of_fields + unused_property_fields; | 6703 int inobject_props = obj->map()->inobject_properties(); |
| 6704 int number_of_allocated_fields = |
| 6705 number_of_fields + unused_property_fields - inobject_props; |
| 6668 | 6706 |
| 6669 // Allocate the fixed array for the fields. | 6707 // Allocate the fixed array for the fields. |
| 6670 Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields); | 6708 Object* fields = Heap::AllocateFixedArray(number_of_allocated_fields); |
| 6671 if (fields->IsFailure()) return fields; | 6709 if (fields->IsFailure()) return fields; |
| 6672 | 6710 |
| 6673 // Fill in the instance descriptor and the fields. | 6711 // Fill in the instance descriptor and the fields. |
| 6674 DescriptorWriter w(descriptors); | 6712 DescriptorWriter w(descriptors); |
| 6675 int current_offset = 0; | 6713 int current_offset = 0; |
| 6676 for (int i = 0; i < capacity; i++) { | 6714 for (int i = 0; i < capacity; i++) { |
| 6677 Object* k = KeyAt(i); | 6715 Object* k = KeyAt(i); |
| 6678 if (IsKey(k)) { | 6716 if (IsKey(k)) { |
| 6679 Object* value = ValueAt(i); | 6717 Object* value = ValueAt(i); |
| 6680 // Ensure the key is a symbol before writing into the instance descriptor. | 6718 // Ensure the key is a symbol before writing into the instance descriptor. |
| 6681 Object* key = Heap::LookupSymbol(String::cast(k)); | 6719 Object* key = Heap::LookupSymbol(String::cast(k)); |
| 6682 if (key->IsFailure()) return key; | 6720 if (key->IsFailure()) return key; |
| 6683 PropertyDetails details = DetailsAt(i); | 6721 PropertyDetails details = DetailsAt(i); |
| 6684 PropertyType type = details.type(); | 6722 PropertyType type = details.type(); |
| 6723 |
| 6685 if (value->IsJSFunction()) { | 6724 if (value->IsJSFunction()) { |
| 6686 ConstantFunctionDescriptor d(String::cast(key), | 6725 ConstantFunctionDescriptor d(String::cast(key), |
| 6687 JSFunction::cast(value), | 6726 JSFunction::cast(value), |
| 6688 details.attributes(), | 6727 details.attributes(), |
| 6689 details.index()); | 6728 details.index()); |
| 6690 w.Write(&d); | 6729 w.Write(&d); |
| 6691 } else if (type == NORMAL) { | 6730 } else if (type == NORMAL) { |
| 6692 FixedArray::cast(fields)->set(current_offset, value); | 6731 if (current_offset < inobject_props) { |
| 6732 obj->InObjectPropertyAtPut(current_offset, |
| 6733 value, |
| 6734 UPDATE_WRITE_BARRIER); |
| 6735 } else { |
| 6736 int offset = current_offset - inobject_props; |
| 6737 FixedArray::cast(fields)->set(offset, value); |
| 6738 } |
| 6693 FieldDescriptor d(String::cast(key), | 6739 FieldDescriptor d(String::cast(key), |
| 6694 current_offset++, | 6740 current_offset++, |
| 6695 details.attributes(), | 6741 details.attributes(), |
| 6696 details.index()); | 6742 details.index()); |
| 6697 w.Write(&d); | 6743 w.Write(&d); |
| 6698 } else if (type == CALLBACKS) { | 6744 } else if (type == CALLBACKS) { |
| 6699 CallbacksDescriptor d(String::cast(key), | 6745 CallbacksDescriptor d(String::cast(key), |
| 6700 value, | 6746 value, |
| 6701 details.attributes(), | 6747 details.attributes(), |
| 6702 details.index()); | 6748 details.index()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 6715 | 6761 |
| 6716 // Transform the object. | 6762 // Transform the object. |
| 6717 obj->set_map(Map::cast(new_map)); | 6763 obj->set_map(Map::cast(new_map)); |
| 6718 obj->map()->set_instance_descriptors(descriptors); | 6764 obj->map()->set_instance_descriptors(descriptors); |
| 6719 obj->map()->set_unused_property_fields(unused_property_fields); | 6765 obj->map()->set_unused_property_fields(unused_property_fields); |
| 6720 | 6766 |
| 6721 obj->set_properties(FixedArray::cast(fields)); | 6767 obj->set_properties(FixedArray::cast(fields)); |
| 6722 ASSERT(obj->IsJSObject()); | 6768 ASSERT(obj->IsJSObject()); |
| 6723 | 6769 |
| 6724 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); | 6770 descriptors->SetNextEnumerationIndex(NextEnumerationIndex()); |
| 6725 // Check it really works. | 6771 // Check that it really works. |
| 6726 ASSERT(obj->HasFastProperties()); | 6772 ASSERT(obj->HasFastProperties()); |
| 6773 |
| 6727 return obj; | 6774 return obj; |
| 6728 } | 6775 } |
| 6729 | 6776 |
| 6730 | 6777 |
| 6731 // Check if there is a break point at this code position. | 6778 // Check if there is a break point at this code position. |
| 6732 bool DebugInfo::HasBreakPoint(int code_position) { | 6779 bool DebugInfo::HasBreakPoint(int code_position) { |
| 6733 // Get the break point info object for this code position. | 6780 // Get the break point info object for this code position. |
| 6734 Object* break_point_info = GetBreakPointInfo(code_position); | 6781 Object* break_point_info = GetBreakPointInfo(code_position); |
| 6735 | 6782 |
| 6736 // If there is no break point info object or no break points in the break | 6783 // If there is no break point info object or no break points in the break |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6967 // No break point. | 7014 // No break point. |
| 6968 if (break_point_objects()->IsUndefined()) return 0; | 7015 if (break_point_objects()->IsUndefined()) return 0; |
| 6969 // Single beak point. | 7016 // Single beak point. |
| 6970 if (!break_point_objects()->IsFixedArray()) return 1; | 7017 if (!break_point_objects()->IsFixedArray()) return 1; |
| 6971 // Multiple break points. | 7018 // Multiple break points. |
| 6972 return FixedArray::cast(break_point_objects())->length(); | 7019 return FixedArray::cast(break_point_objects())->length(); |
| 6973 } | 7020 } |
| 6974 | 7021 |
| 6975 | 7022 |
| 6976 } } // namespace v8::internal | 7023 } } // namespace v8::internal |
| OLD | NEW |