OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
182 if (to_start + copy_size > to_length) { | 182 if (to_start + copy_size > to_length) { |
183 copy_size = to_length - to_start; | 183 copy_size = to_length - to_start; |
184 } | 184 } |
185 WriteBarrierMode write_barrier_mode = IsFastObjectElementsKind(to_kind) | 185 WriteBarrierMode write_barrier_mode = IsFastObjectElementsKind(to_kind) |
186 ? UPDATE_WRITE_BARRIER | 186 ? UPDATE_WRITE_BARRIER |
187 : SKIP_WRITE_BARRIER; | 187 : SKIP_WRITE_BARRIER; |
188 for (int i = 0; i < copy_size; i++) { | 188 for (int i = 0; i < copy_size; i++) { |
189 int entry = from->FindEntry(i + from_start); | 189 int entry = from->FindEntry(i + from_start); |
190 if (entry != SeededNumberDictionary::kNotFound) { | 190 if (entry != SeededNumberDictionary::kNotFound) { |
191 Object* value = from->ValueAt(entry); | 191 Object* value = from->ValueAt(entry); |
192 DCHECK(!value->IsTheHole()); | 192 DCHECK(!value->IsTheHole(from->GetIsolate())); |
193 to->set(i + to_start, value, write_barrier_mode); | 193 to->set(i + to_start, value, write_barrier_mode); |
194 } else { | 194 } else { |
195 to->set_the_hole(i + to_start); | 195 to->set_the_hole(i + to_start); |
196 } | 196 } |
197 } | 197 } |
198 } | 198 } |
199 | 199 |
200 | 200 |
201 // NOTE: this method violates the handlified function signature convention: | 201 // NOTE: this method violates the handlified function signature convention: |
202 // raw pointer parameters in the function that allocates. | 202 // raw pointer parameters in the function that allocates. |
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 DCHECK(static_cast<int>(to_end) <= to_base->length()); | 345 DCHECK(static_cast<int>(to_end) <= to_base->length()); |
346 DCHECK(packed_size >= 0 && packed_size <= copy_size); | 346 DCHECK(packed_size >= 0 && packed_size <= copy_size); |
347 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && | 347 DCHECK((copy_size + static_cast<int>(to_start)) <= to_base->length() && |
348 (copy_size + static_cast<int>(from_start)) <= from_base->length()); | 348 (copy_size + static_cast<int>(from_start)) <= from_base->length()); |
349 if (copy_size == 0) return; | 349 if (copy_size == 0) return; |
350 FixedArray* from = FixedArray::cast(from_base); | 350 FixedArray* from = FixedArray::cast(from_base); |
351 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); | 351 FixedDoubleArray* to = FixedDoubleArray::cast(to_base); |
352 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); | 352 for (uint32_t from_end = from_start + static_cast<uint32_t>(packed_size); |
353 from_start < from_end; from_start++, to_start++) { | 353 from_start < from_end; from_start++, to_start++) { |
354 Object* smi = from->get(from_start); | 354 Object* smi = from->get(from_start); |
355 DCHECK(!smi->IsTheHole()); | 355 DCHECK(!smi->IsTheHole(from->GetIsolate())); |
356 to->set(to_start, Smi::cast(smi)->value()); | 356 to->set(to_start, Smi::cast(smi)->value()); |
357 } | 357 } |
358 } | 358 } |
359 | 359 |
360 | 360 |
361 static void CopyObjectToDoubleElements(FixedArrayBase* from_base, | 361 static void CopyObjectToDoubleElements(FixedArrayBase* from_base, |
362 uint32_t from_start, | 362 uint32_t from_start, |
363 FixedArrayBase* to_base, | 363 FixedArrayBase* to_base, |
364 uint32_t to_start, int raw_copy_size) { | 364 uint32_t to_start, int raw_copy_size) { |
365 DisallowHeapAllocation no_allocation; | 365 DisallowHeapAllocation no_allocation; |
(...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1249 object->map()->is_prototype_map()); | 1249 object->map()->is_prototype_map()); |
1250 if (attributes != NONE) object->RequireSlowElements(*new_dictionary); | 1250 if (attributes != NONE) object->RequireSlowElements(*new_dictionary); |
1251 if (dictionary.is_identical_to(new_dictionary)) return; | 1251 if (dictionary.is_identical_to(new_dictionary)) return; |
1252 object->set_elements(*new_dictionary); | 1252 object->set_elements(*new_dictionary); |
1253 } | 1253 } |
1254 | 1254 |
1255 static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1255 static bool HasEntryImpl(FixedArrayBase* store, uint32_t entry) { |
1256 DisallowHeapAllocation no_gc; | 1256 DisallowHeapAllocation no_gc; |
1257 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1257 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1258 Object* index = dict->KeyAt(entry); | 1258 Object* index = dict->KeyAt(entry); |
1259 return !index->IsTheHole(); | 1259 return !index->IsTheHole(dict->GetIsolate()); |
1260 } | 1260 } |
1261 | 1261 |
1262 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { | 1262 static uint32_t GetIndexForEntryImpl(FixedArrayBase* store, uint32_t entry) { |
1263 DisallowHeapAllocation no_gc; | 1263 DisallowHeapAllocation no_gc; |
1264 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); | 1264 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1265 uint32_t result = 0; | 1265 uint32_t result = 0; |
1266 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); | 1266 CHECK(dict->KeyAt(entry)->ToArrayIndex(&result)); |
1267 return result; | 1267 return result; |
1268 } | 1268 } |
1269 | 1269 |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 Handle<Object> the_hole = isolate->factory()->the_hole_value(); | 1382 Handle<Object> the_hole = isolate->factory()->the_hole_value(); |
1383 SeededNumberDictionary* dictionary = | 1383 SeededNumberDictionary* dictionary = |
1384 SeededNumberDictionary::cast(receiver->elements()); | 1384 SeededNumberDictionary::cast(receiver->elements()); |
1385 int capacity = dictionary->Capacity(); | 1385 int capacity = dictionary->Capacity(); |
1386 for (int i = 0; i < capacity; i++) { | 1386 for (int i = 0; i < capacity; i++) { |
1387 Object* k = dictionary->KeyAt(i); | 1387 Object* k = dictionary->KeyAt(i); |
1388 if (k == *undefined) continue; | 1388 if (k == *undefined) continue; |
1389 if (k == *the_hole) continue; | 1389 if (k == *the_hole) continue; |
1390 if (dictionary->IsDeleted(i)) continue; | 1390 if (dictionary->IsDeleted(i)) continue; |
1391 Object* value = dictionary->ValueAt(i); | 1391 Object* value = dictionary->ValueAt(i); |
1392 DCHECK(!value->IsTheHole()); | 1392 DCHECK(!value->IsTheHole(isolate)); |
1393 DCHECK(!value->IsAccessorPair()); | 1393 DCHECK(!value->IsAccessorPair()); |
1394 DCHECK(!value->IsAccessorInfo()); | 1394 DCHECK(!value->IsAccessorInfo()); |
1395 accumulator->AddKey(value, convert); | 1395 accumulator->AddKey(value, convert); |
1396 } | 1396 } |
1397 } | 1397 } |
1398 }; | 1398 }; |
1399 | 1399 |
1400 | 1400 |
1401 // Super class for all fast element arrays. | 1401 // Super class for all fast element arrays. |
1402 template <typename Subclass, typename KindTraits> | 1402 template <typename Subclass, typename KindTraits> |
(...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1813 DCHECK(length > 0); | 1813 DCHECK(length > 0); |
1814 int new_length = length - 1; | 1814 int new_length = length - 1; |
1815 int remove_index = remove_position == AT_START ? 0 : new_length; | 1815 int remove_index = remove_position == AT_START ? 0 : new_length; |
1816 Handle<Object> result = Subclass::GetImpl(*backing_store, remove_index); | 1816 Handle<Object> result = Subclass::GetImpl(*backing_store, remove_index); |
1817 if (remove_position == AT_START) { | 1817 if (remove_position == AT_START) { |
1818 Subclass::MoveElements(isolate, receiver, backing_store, 0, 1, new_length, | 1818 Subclass::MoveElements(isolate, receiver, backing_store, 0, 1, new_length, |
1819 0, 0); | 1819 0, 0); |
1820 } | 1820 } |
1821 Subclass::SetLengthImpl(isolate, receiver, new_length, backing_store); | 1821 Subclass::SetLengthImpl(isolate, receiver, new_length, backing_store); |
1822 | 1822 |
1823 if (IsHoleyElementsKind(kind) && result->IsTheHole()) { | 1823 if (IsHoleyElementsKind(kind) && result->IsTheHole(isolate)) { |
1824 return isolate->factory()->undefined_value(); | 1824 return isolate->factory()->undefined_value(); |
1825 } | 1825 } |
1826 return result; | 1826 return result; |
1827 } | 1827 } |
1828 | 1828 |
1829 static uint32_t AddArguments(Handle<JSArray> receiver, | 1829 static uint32_t AddArguments(Handle<JSArray> receiver, |
1830 Handle<FixedArrayBase> backing_store, | 1830 Handle<FixedArrayBase> backing_store, |
1831 Arguments* args, uint32_t add_size, | 1831 Arguments* args, uint32_t add_size, |
1832 Where add_position) { | 1832 Where add_position) { |
1833 uint32_t length = Smi::cast(receiver->length())->value(); | 1833 uint32_t length = Smi::cast(receiver->length())->value(); |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1865 | 1865 |
1866 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, | 1866 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, |
1867 uint32_t copy_size, uint32_t src_index, | 1867 uint32_t copy_size, uint32_t src_index, |
1868 uint32_t dst_index) { | 1868 uint32_t dst_index) { |
1869 // Add the provided values. | 1869 // Add the provided values. |
1870 DisallowHeapAllocation no_gc; | 1870 DisallowHeapAllocation no_gc; |
1871 FixedArrayBase* raw_backing_store = *dst_store; | 1871 FixedArrayBase* raw_backing_store = *dst_store; |
1872 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); | 1872 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
1873 for (uint32_t i = 0; i < copy_size; i++) { | 1873 for (uint32_t i = 0; i < copy_size; i++) { |
1874 Object* argument = (*args)[src_index + i]; | 1874 Object* argument = (*args)[src_index + i]; |
1875 DCHECK(!argument->IsTheHole()); | 1875 DCHECK(!argument->IsTheHole(raw_backing_store->GetIsolate())); |
1876 Subclass::SetImpl(raw_backing_store, dst_index + i, argument, mode); | 1876 Subclass::SetImpl(raw_backing_store, dst_index + i, argument, mode); |
1877 } | 1877 } |
1878 } | 1878 } |
1879 }; | 1879 }; |
1880 | 1880 |
1881 template <typename Subclass, typename KindTraits> | 1881 template <typename Subclass, typename KindTraits> |
1882 class FastSmiOrObjectElementsAccessor | 1882 class FastSmiOrObjectElementsAccessor |
1883 : public FastElementsAccessor<Subclass, KindTraits> { | 1883 : public FastElementsAccessor<Subclass, KindTraits> { |
1884 public: | 1884 public: |
1885 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1885 explicit FastSmiOrObjectElementsAccessor(const char* name) |
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2242 | 2242 |
2243 static Handle<Object> GetImpl(FixedArrayBase* parameters, uint32_t entry) { | 2243 static Handle<Object> GetImpl(FixedArrayBase* parameters, uint32_t entry) { |
2244 Isolate* isolate = parameters->GetIsolate(); | 2244 Isolate* isolate = parameters->GetIsolate(); |
2245 Handle<FixedArray> parameter_map(FixedArray::cast(parameters), isolate); | 2245 Handle<FixedArray> parameter_map(FixedArray::cast(parameters), isolate); |
2246 uint32_t length = parameter_map->length() - 2; | 2246 uint32_t length = parameter_map->length() - 2; |
2247 if (entry < length) { | 2247 if (entry < length) { |
2248 DisallowHeapAllocation no_gc; | 2248 DisallowHeapAllocation no_gc; |
2249 Object* probe = parameter_map->get(entry + 2); | 2249 Object* probe = parameter_map->get(entry + 2); |
2250 Context* context = Context::cast(parameter_map->get(0)); | 2250 Context* context = Context::cast(parameter_map->get(0)); |
2251 int context_entry = Smi::cast(probe)->value(); | 2251 int context_entry = Smi::cast(probe)->value(); |
2252 DCHECK(!context->get(context_entry)->IsTheHole()); | 2252 DCHECK(!context->get(context_entry)->IsTheHole(isolate)); |
2253 return handle(context->get(context_entry), isolate); | 2253 return handle(context->get(context_entry), isolate); |
2254 } else { | 2254 } else { |
2255 // Object is not mapped, defer to the arguments. | 2255 // Object is not mapped, defer to the arguments. |
2256 Handle<Object> result = ArgumentsAccessor::GetImpl( | 2256 Handle<Object> result = ArgumentsAccessor::GetImpl( |
2257 FixedArray::cast(parameter_map->get(1)), entry - length); | 2257 FixedArray::cast(parameter_map->get(1)), entry - length); |
2258 // Elements of the arguments object in slow mode might be slow aliases. | 2258 // Elements of the arguments object in slow mode might be slow aliases. |
2259 if (result->IsAliasedArgumentsEntry()) { | 2259 if (result->IsAliasedArgumentsEntry()) { |
2260 DisallowHeapAllocation no_gc; | 2260 DisallowHeapAllocation no_gc; |
2261 AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(*result); | 2261 AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(*result); |
2262 Context* context = Context::cast(parameter_map->get(0)); | 2262 Context* context = Context::cast(parameter_map->get(0)); |
2263 int context_entry = alias->aliased_context_slot(); | 2263 int context_entry = alias->aliased_context_slot(); |
2264 DCHECK(!context->get(context_entry)->IsTheHole()); | 2264 DCHECK(!context->get(context_entry)->IsTheHole(isolate)); |
2265 return handle(context->get(context_entry), isolate); | 2265 return handle(context->get(context_entry), isolate); |
2266 } | 2266 } |
2267 return result; | 2267 return result; |
2268 } | 2268 } |
2269 } | 2269 } |
2270 | 2270 |
2271 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, | 2271 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, |
2272 uint32_t capacity) { | 2272 uint32_t capacity) { |
2273 UNREACHABLE(); | 2273 UNREACHABLE(); |
2274 } | 2274 } |
2275 | 2275 |
2276 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, | 2276 static inline void SetImpl(Handle<JSObject> holder, uint32_t entry, |
2277 Object* value) { | 2277 Object* value) { |
2278 SetImpl(holder->elements(), entry, value); | 2278 SetImpl(holder->elements(), entry, value); |
2279 } | 2279 } |
2280 | 2280 |
2281 static inline void SetImpl(FixedArrayBase* store, uint32_t entry, | 2281 static inline void SetImpl(FixedArrayBase* store, uint32_t entry, |
2282 Object* value) { | 2282 Object* value) { |
2283 FixedArray* parameter_map = FixedArray::cast(store); | 2283 FixedArray* parameter_map = FixedArray::cast(store); |
2284 uint32_t length = parameter_map->length() - 2; | 2284 uint32_t length = parameter_map->length() - 2; |
2285 if (entry < length) { | 2285 if (entry < length) { |
2286 Object* probe = parameter_map->get(entry + 2); | 2286 Object* probe = parameter_map->get(entry + 2); |
2287 Context* context = Context::cast(parameter_map->get(0)); | 2287 Context* context = Context::cast(parameter_map->get(0)); |
2288 int context_entry = Smi::cast(probe)->value(); | 2288 int context_entry = Smi::cast(probe)->value(); |
2289 DCHECK(!context->get(context_entry)->IsTheHole()); | 2289 DCHECK(!context->get(context_entry)->IsTheHole(store->GetIsolate())); |
2290 context->set(context_entry, value); | 2290 context->set(context_entry, value); |
2291 } else { | 2291 } else { |
2292 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 2292 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
2293 Object* current = ArgumentsAccessor::GetRaw(arguments, entry - length); | 2293 Object* current = ArgumentsAccessor::GetRaw(arguments, entry - length); |
2294 if (current->IsAliasedArgumentsEntry()) { | 2294 if (current->IsAliasedArgumentsEntry()) { |
2295 AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(current); | 2295 AliasedArgumentsEntry* alias = AliasedArgumentsEntry::cast(current); |
2296 Context* context = Context::cast(parameter_map->get(0)); | 2296 Context* context = Context::cast(parameter_map->get(0)); |
2297 int context_entry = alias->aliased_context_slot(); | 2297 int context_entry = alias->aliased_context_slot(); |
2298 DCHECK(!context->get(context_entry)->IsTheHole()); | 2298 DCHECK(!context->get(context_entry)->IsTheHole(store->GetIsolate())); |
2299 context->set(context_entry, value); | 2299 context->set(context_entry, value); |
2300 } else { | 2300 } else { |
2301 ArgumentsAccessor::SetImpl(arguments, entry - length, value); | 2301 ArgumentsAccessor::SetImpl(arguments, entry - length, value); |
2302 } | 2302 } |
2303 } | 2303 } |
2304 } | 2304 } |
2305 | 2305 |
2306 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 2306 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
2307 uint32_t length, | 2307 uint32_t length, |
2308 Handle<FixedArrayBase> parameter_map) { | 2308 Handle<FixedArrayBase> parameter_map) { |
(...skipping 18 matching lines...) Expand all Loading... |
2327 if (!HasEntryImpl(elements, entry)) continue; | 2327 if (!HasEntryImpl(elements, entry)) continue; |
2328 Handle<Object> value = GetImpl(elements, entry); | 2328 Handle<Object> value = GetImpl(elements, entry); |
2329 accumulator->AddKey(value, convert); | 2329 accumulator->AddKey(value, convert); |
2330 } | 2330 } |
2331 } | 2331 } |
2332 | 2332 |
2333 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) { | 2333 static bool HasEntryImpl(FixedArrayBase* parameters, uint32_t entry) { |
2334 FixedArray* parameter_map = FixedArray::cast(parameters); | 2334 FixedArray* parameter_map = FixedArray::cast(parameters); |
2335 uint32_t length = parameter_map->length() - 2; | 2335 uint32_t length = parameter_map->length() - 2; |
2336 if (entry < length) { | 2336 if (entry < length) { |
2337 return !GetParameterMapArg(parameter_map, entry)->IsTheHole(); | 2337 return !GetParameterMapArg(parameter_map, entry) |
| 2338 ->IsTheHole(parameter_map->GetIsolate()); |
2338 } | 2339 } |
2339 | 2340 |
2340 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 2341 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
2341 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length); | 2342 return ArgumentsAccessor::HasEntryImpl(arguments, entry - length); |
2342 } | 2343 } |
2343 | 2344 |
2344 static bool HasAccessorsImpl(JSObject* holder, | 2345 static bool HasAccessorsImpl(JSObject* holder, |
2345 FixedArrayBase* backing_store) { | 2346 FixedArrayBase* backing_store) { |
2346 FixedArray* parameter_map = FixedArray::cast(backing_store); | 2347 FixedArray* parameter_map = FixedArray::cast(backing_store); |
2347 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 2348 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
2348 return ArgumentsAccessor::HasAccessorsImpl(holder, arguments); | 2349 return ArgumentsAccessor::HasAccessorsImpl(holder, arguments); |
2349 } | 2350 } |
2350 | 2351 |
2351 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters, | 2352 static uint32_t GetIndexForEntryImpl(FixedArrayBase* parameters, |
2352 uint32_t entry) { | 2353 uint32_t entry) { |
2353 FixedArray* parameter_map = FixedArray::cast(parameters); | 2354 FixedArray* parameter_map = FixedArray::cast(parameters); |
2354 uint32_t length = parameter_map->length() - 2; | 2355 uint32_t length = parameter_map->length() - 2; |
2355 if (entry < length) return entry; | 2356 if (entry < length) return entry; |
2356 | 2357 |
2357 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 2358 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
2358 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); | 2359 return ArgumentsAccessor::GetIndexForEntryImpl(arguments, entry - length); |
2359 } | 2360 } |
2360 | 2361 |
2361 static uint32_t GetEntryForIndexImpl(JSObject* holder, | 2362 static uint32_t GetEntryForIndexImpl(JSObject* holder, |
2362 FixedArrayBase* parameters, | 2363 FixedArrayBase* parameters, |
2363 uint32_t index, PropertyFilter filter) { | 2364 uint32_t index, PropertyFilter filter) { |
2364 FixedArray* parameter_map = FixedArray::cast(parameters); | 2365 FixedArray* parameter_map = FixedArray::cast(parameters); |
2365 Object* probe = GetParameterMapArg(parameter_map, index); | 2366 Object* probe = GetParameterMapArg(parameter_map, index); |
2366 if (!probe->IsTheHole()) return index; | 2367 if (!probe->IsTheHole(holder->GetIsolate())) return index; |
2367 | 2368 |
2368 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 2369 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
2369 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, | 2370 uint32_t entry = ArgumentsAccessor::GetEntryForIndexImpl(holder, arguments, |
2370 index, filter); | 2371 index, filter); |
2371 if (entry == kMaxUInt32) return kMaxUInt32; | 2372 if (entry == kMaxUInt32) return kMaxUInt32; |
2372 return (parameter_map->length() - 2) + entry; | 2373 return (parameter_map->length() - 2) + entry; |
2373 } | 2374 } |
2374 | 2375 |
2375 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { | 2376 static PropertyDetails GetDetailsImpl(JSObject* holder, uint32_t entry) { |
2376 FixedArray* parameter_map = FixedArray::cast(holder->elements()); | 2377 FixedArray* parameter_map = FixedArray::cast(holder->elements()); |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2420 | 2421 |
2421 static Handle<FixedArray> DirectCollectElementIndicesImpl( | 2422 static Handle<FixedArray> DirectCollectElementIndicesImpl( |
2422 Isolate* isolate, Handle<JSObject> object, | 2423 Isolate* isolate, Handle<JSObject> object, |
2423 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, | 2424 Handle<FixedArrayBase> backing_store, GetKeysConversion convert, |
2424 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, | 2425 PropertyFilter filter, Handle<FixedArray> list, uint32_t* nof_indices, |
2425 uint32_t insertion_index = 0) { | 2426 uint32_t insertion_index = 0) { |
2426 FixedArray* parameter_map = FixedArray::cast(*backing_store); | 2427 FixedArray* parameter_map = FixedArray::cast(*backing_store); |
2427 uint32_t length = parameter_map->length() - 2; | 2428 uint32_t length = parameter_map->length() - 2; |
2428 | 2429 |
2429 for (uint32_t i = 0; i < length; ++i) { | 2430 for (uint32_t i = 0; i < length; ++i) { |
2430 if (parameter_map->get(i + 2)->IsTheHole()) continue; | 2431 if (parameter_map->get(i + 2)->IsTheHole(isolate)) continue; |
2431 if (convert == GetKeysConversion::kConvertToString) { | 2432 if (convert == GetKeysConversion::kConvertToString) { |
2432 Handle<String> index_string = isolate->factory()->Uint32ToString(i); | 2433 Handle<String> index_string = isolate->factory()->Uint32ToString(i); |
2433 list->set(insertion_index, *index_string); | 2434 list->set(insertion_index, *index_string); |
2434 } else { | 2435 } else { |
2435 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); | 2436 list->set(insertion_index, Smi::FromInt(i), SKIP_WRITE_BARRIER); |
2436 } | 2437 } |
2437 insertion_index++; | 2438 insertion_index++; |
2438 } | 2439 } |
2439 | 2440 |
2440 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); | 2441 Handle<FixedArrayBase> store(FixedArrayBase::cast(parameter_map->get(1))); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2489 FixedArray::cast(object->elements())->set(1, *new_dictionary); | 2490 FixedArray::cast(object->elements())->set(1, *new_dictionary); |
2490 } | 2491 } |
2491 } | 2492 } |
2492 | 2493 |
2493 static void ReconfigureImpl(Handle<JSObject> object, | 2494 static void ReconfigureImpl(Handle<JSObject> object, |
2494 Handle<FixedArrayBase> store, uint32_t entry, | 2495 Handle<FixedArrayBase> store, uint32_t entry, |
2495 Handle<Object> value, | 2496 Handle<Object> value, |
2496 PropertyAttributes attributes) { | 2497 PropertyAttributes attributes) { |
2497 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store); | 2498 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store); |
2498 uint32_t length = parameter_map->length() - 2; | 2499 uint32_t length = parameter_map->length() - 2; |
| 2500 Isolate* isolate = store->GetIsolate(); |
2499 if (entry < length) { | 2501 if (entry < length) { |
2500 Object* probe = parameter_map->get(entry + 2); | 2502 Object* probe = parameter_map->get(entry + 2); |
2501 DCHECK(!probe->IsTheHole()); | 2503 DCHECK(!probe->IsTheHole(isolate)); |
2502 Context* context = Context::cast(parameter_map->get(0)); | 2504 Context* context = Context::cast(parameter_map->get(0)); |
2503 int context_entry = Smi::cast(probe)->value(); | 2505 int context_entry = Smi::cast(probe)->value(); |
2504 DCHECK(!context->get(context_entry)->IsTheHole()); | 2506 DCHECK(!context->get(context_entry)->IsTheHole(isolate)); |
2505 context->set(context_entry, *value); | 2507 context->set(context_entry, *value); |
2506 | 2508 |
2507 // Redefining attributes of an aliased element destroys fast aliasing. | 2509 // Redefining attributes of an aliased element destroys fast aliasing. |
2508 parameter_map->set_the_hole(entry + 2); | 2510 parameter_map->set_the_hole(entry + 2); |
2509 // For elements that are still writable we re-establish slow aliasing. | 2511 // For elements that are still writable we re-establish slow aliasing. |
2510 if ((attributes & READ_ONLY) == 0) { | 2512 if ((attributes & READ_ONLY) == 0) { |
2511 Isolate* isolate = store->GetIsolate(); | |
2512 value = isolate->factory()->NewAliasedArgumentsEntry(context_entry); | 2513 value = isolate->factory()->NewAliasedArgumentsEntry(context_entry); |
2513 } | 2514 } |
2514 | 2515 |
2515 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); | 2516 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell); |
2516 Handle<SeededNumberDictionary> arguments( | 2517 Handle<SeededNumberDictionary> arguments( |
2517 SeededNumberDictionary::cast(parameter_map->get(1))); | 2518 SeededNumberDictionary::cast(parameter_map->get(1)), isolate); |
2518 arguments = SeededNumberDictionary::AddNumberEntry( | 2519 arguments = SeededNumberDictionary::AddNumberEntry( |
2519 arguments, entry, value, details, object->map()->is_prototype_map()); | 2520 arguments, entry, value, details, object->map()->is_prototype_map()); |
2520 // If the attributes were NONE, we would have called set rather than | 2521 // If the attributes were NONE, we would have called set rather than |
2521 // reconfigure. | 2522 // reconfigure. |
2522 DCHECK_NE(NONE, attributes); | 2523 DCHECK_NE(NONE, attributes); |
2523 object->RequireSlowElements(*arguments); | 2524 object->RequireSlowElements(*arguments); |
2524 parameter_map->set(1, *arguments); | 2525 parameter_map->set(1, *arguments); |
2525 } else { | 2526 } else { |
2526 Handle<FixedArrayBase> arguments( | 2527 Handle<FixedArrayBase> arguments( |
2527 FixedArrayBase::cast(parameter_map->get(1))); | 2528 FixedArrayBase::cast(parameter_map->get(1)), isolate); |
2528 DictionaryElementsAccessor::ReconfigureImpl( | 2529 DictionaryElementsAccessor::ReconfigureImpl( |
2529 object, arguments, entry - length, value, attributes); | 2530 object, arguments, entry - length, value, attributes); |
2530 } | 2531 } |
2531 } | 2532 } |
2532 }; | 2533 }; |
2533 | 2534 |
2534 | 2535 |
2535 class FastSloppyArgumentsElementsAccessor | 2536 class FastSloppyArgumentsElementsAccessor |
2536 : public SloppyArgumentsElementsAccessor< | 2537 : public SloppyArgumentsElementsAccessor< |
2537 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, | 2538 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, |
(...skipping 504 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3042 insertion_index += len; | 3043 insertion_index += len; |
3043 } | 3044 } |
3044 | 3045 |
3045 DCHECK_EQ(insertion_index, result_len); | 3046 DCHECK_EQ(insertion_index, result_len); |
3046 return result_array; | 3047 return result_array; |
3047 } | 3048 } |
3048 | 3049 |
3049 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3050 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3050 } // namespace internal | 3051 } // namespace internal |
3051 } // namespace v8 | 3052 } // namespace v8 |
OLD | NEW |