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 |