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/builtins.h" | 5 #include "src/builtins.h" |
6 | 6 |
7 #include "src/api.h" | 7 #include "src/api.h" |
8 #include "src/api-natives.h" | 8 #include "src/api-natives.h" |
9 #include "src/arguments.h" | 9 #include "src/arguments.h" |
10 #include "src/base/once.h" | 10 #include "src/base/once.h" |
(...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 } | 202 } |
203 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); | 203 Object* len_obj = object->InObjectPropertyAt(Heap::kArgumentsLengthIndex); |
204 if (!len_obj->IsSmi()) { | 204 if (!len_obj->IsSmi()) { |
205 return false; | 205 return false; |
206 } | 206 } |
207 *out = Smi::cast(len_obj)->value(); | 207 *out = Smi::cast(len_obj)->value(); |
208 return *out <= object->elements()->length(); | 208 return *out <= object->elements()->length(); |
209 } | 209 } |
210 | 210 |
211 | 211 |
212 bool PrototypeHasNoElements(PrototypeIterator* iter) { | 212 inline bool PrototypeHasNoElements(PrototypeIterator* iter) { |
213 DisallowHeapAllocation no_gc; | 213 DisallowHeapAllocation no_gc; |
214 for (; !iter->IsAtEnd(); iter->Advance()) { | 214 for (; !iter->IsAtEnd(); iter->Advance()) { |
215 if (iter->GetCurrent()->IsJSProxy()) return false; | 215 if (iter->GetCurrent()->IsJSProxy()) return false; |
216 JSObject* current = JSObject::cast(iter->GetCurrent()); | 216 JSObject* current = JSObject::cast(iter->GetCurrent()); |
217 if (current->IsAccessCheckNeeded()) return false; | 217 if (current->IsAccessCheckNeeded()) return false; |
218 if (current->HasIndexedInterceptor()) return false; | 218 if (current->HasIndexedInterceptor()) return false; |
219 if (current->elements()->length() != 0) return false; | 219 if (current->elements()->length() != 0) return false; |
220 } | 220 } |
221 return true; | 221 return true; |
222 } | 222 } |
(...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
379 Handle<JSArray> array = Handle<JSArray>::cast(receiver); | 379 Handle<JSArray> array = Handle<JSArray>::cast(receiver); |
380 DCHECK(!array->map()->is_observed()); | 380 DCHECK(!array->map()->is_observed()); |
381 | 381 |
382 uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value()); | 382 uint32_t len = static_cast<uint32_t>(Smi::cast(array->length())->value()); |
383 if (len == 0) return isolate->heap()->undefined_value(); | 383 if (len == 0) return isolate->heap()->undefined_value(); |
384 | 384 |
385 if (JSArray::HasReadOnlyLength(array)) { | 385 if (JSArray::HasReadOnlyLength(array)) { |
386 return CallJsIntrinsic(isolate, isolate->array_pop(), args); | 386 return CallJsIntrinsic(isolate, isolate->array_pop(), args); |
387 } | 387 } |
388 | 388 |
389 uint32_t new_length = len - 1; | 389 Handle<Object> result; |
390 Handle<Object> element; | 390 if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { |
Camillo Bruni
2015/08/31 07:45:50
Using this separate branch I gain roughly 50% spee
| |
391 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 391 // Fast Elements Path |
392 isolate, element, Object::GetElement(isolate, array, new_length)); | 392 result = array->GetElementsAccessor()->Pop(array, elms_obj); |
393 | 393 if (result->IsTheHole()) { |
Igor Sheludko
2015/08/31 14:08:03
I think hole handling should be in elements.cc and
Camillo Bruni
2015/08/31 14:41:35
Makes sense.
| |
394 JSArray::SetLength(array, new_length); | 394 result = isolate->factory()->undefined_value(); |
Camillo Bruni
2015/08/28 14:08:11
I am not fully convinced about this branch myself.
| |
395 return *element; | 395 } |
396 } else { | |
397 // Use Slow Lookup otherwise | |
398 uint32_t new_length = len - 1; | |
399 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
400 isolate, result, Object::GetElement(isolate, array, new_length)); | |
401 JSArray::SetLength(array, new_length); | |
402 } | |
403 return *result; | |
396 } | 404 } |
397 | 405 |
398 | 406 |
399 BUILTIN(ArrayShift) { | 407 BUILTIN(ArrayShift) { |
400 HandleScope scope(isolate); | 408 HandleScope scope(isolate); |
401 Heap* heap = isolate->heap(); | 409 Heap* heap = isolate->heap(); |
402 Handle<Object> receiver = args.receiver(); | 410 Handle<Object> receiver = args.receiver(); |
403 MaybeHandle<FixedArrayBase> maybe_elms_obj = | 411 MaybeHandle<FixedArrayBase> maybe_elms_obj = |
404 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); | 412 EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0); |
405 Handle<FixedArrayBase> elms_obj; | 413 Handle<FixedArrayBase> elms_obj; |
(...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1341 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) | 1349 BUILTIN_LIST_C(DEFINE_BUILTIN_ACCESSOR_C) |
1342 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) | 1350 BUILTIN_LIST_A(DEFINE_BUILTIN_ACCESSOR_A) |
1343 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) | 1351 BUILTIN_LIST_H(DEFINE_BUILTIN_ACCESSOR_H) |
1344 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) | 1352 BUILTIN_LIST_DEBUG_A(DEFINE_BUILTIN_ACCESSOR_A) |
1345 #undef DEFINE_BUILTIN_ACCESSOR_C | 1353 #undef DEFINE_BUILTIN_ACCESSOR_C |
1346 #undef DEFINE_BUILTIN_ACCESSOR_A | 1354 #undef DEFINE_BUILTIN_ACCESSOR_A |
1347 | 1355 |
1348 | 1356 |
1349 } // namespace internal | 1357 } // namespace internal |
1350 } // namespace v8 | 1358 } // namespace v8 |
OLD | NEW |