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/messages.h" | 10 #include "src/messages.h" |
(...skipping 2332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2343 | 2343 |
2344 void ElementsAccessor::TearDown() { | 2344 void ElementsAccessor::TearDown() { |
2345 if (elements_accessors_ == NULL) return; | 2345 if (elements_accessors_ == NULL) return; |
2346 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 2346 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
2347 ELEMENTS_LIST(ACCESSOR_DELETE) | 2347 ELEMENTS_LIST(ACCESSOR_DELETE) |
2348 #undef ACCESSOR_DELETE | 2348 #undef ACCESSOR_DELETE |
2349 elements_accessors_ = NULL; | 2349 elements_accessors_ = NULL; |
2350 } | 2350 } |
2351 | 2351 |
2352 | 2352 |
| 2353 Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args, |
| 2354 uint32_t concat_size) { |
| 2355 int result_len = 0; |
| 2356 ElementsKind elements_kind = GetInitialFastElementsKind(); |
| 2357 bool has_double = false; |
| 2358 { |
| 2359 DisallowHeapAllocation no_gc; |
| 2360 // Iterate through all the arguments performing checks |
| 2361 // and calculating total length. |
| 2362 bool is_holey = false; |
| 2363 for (uint32_t i = 0; i < concat_size; i++) { |
| 2364 Object* arg = (*args)[i]; |
| 2365 int len = Smi::cast(JSArray::cast(arg)->length())->value(); |
| 2366 |
| 2367 // We shouldn't overflow when adding another len. |
| 2368 const int kHalfOfMaxInt = 1 << (kBitsPerInt - 2); |
| 2369 STATIC_ASSERT(FixedArray::kMaxLength < kHalfOfMaxInt); |
| 2370 USE(kHalfOfMaxInt); |
| 2371 result_len += len; |
| 2372 DCHECK(0 <= result_len); |
| 2373 DCHECK(result_len <= FixedDoubleArray::kMaxLength); |
| 2374 |
| 2375 ElementsKind arg_kind = JSArray::cast(arg)->map()->elements_kind(); |
| 2376 has_double = has_double || IsFastDoubleElementsKind(arg_kind); |
| 2377 is_holey = is_holey || IsFastHoleyElementsKind(arg_kind); |
| 2378 if (IsMoreGeneralElementsKindTransition(elements_kind, arg_kind)) { |
| 2379 elements_kind = arg_kind; |
| 2380 } |
| 2381 } |
| 2382 if (is_holey) { |
| 2383 elements_kind = GetHoleyElementsKind(elements_kind); |
| 2384 } |
| 2385 } |
| 2386 |
| 2387 // If a double array is concatted into a fast elements array, the fast |
| 2388 // elements array needs to be initialized to contain proper holes, since |
| 2389 // boxing doubles may cause incremental marking. |
| 2390 ArrayStorageAllocationMode mode = |
| 2391 has_double && IsFastObjectElementsKind(elements_kind) |
| 2392 ? INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE |
| 2393 : DONT_INITIALIZE_ARRAY_ELEMENTS; |
| 2394 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
| 2395 elements_kind, result_len, result_len, Strength::WEAK, mode); |
| 2396 if (result_len == 0) return result_array; |
| 2397 int j = 0; |
| 2398 Handle<FixedArrayBase> storage(result_array->elements(), isolate); |
| 2399 ElementsAccessor* accessor = ElementsAccessor::ForKind(elements_kind); |
| 2400 for (uint32_t i = 0; i < concat_size; i++) { |
| 2401 // It is crucial to keep |array| in a raw pointer form to avoid |
| 2402 // performance degradation. |
| 2403 JSArray* array = JSArray::cast((*args)[i]); |
| 2404 int len = Smi::cast(array->length())->value(); |
| 2405 if (len > 0) { |
| 2406 ElementsKind from_kind = array->GetElementsKind(); |
| 2407 accessor->CopyElements(array, 0, from_kind, storage, j, len); |
| 2408 j += len; |
| 2409 } |
| 2410 } |
| 2411 |
| 2412 DCHECK(j == result_len); |
| 2413 return result_array; |
| 2414 } |
| 2415 |
2353 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2416 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2354 } // namespace internal | 2417 } // namespace internal |
2355 } // namespace v8 | 2418 } // namespace v8 |
OLD | NEW |