OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 if (!maybe_result->ToObject(&result)) return maybe_result; | 170 if (!maybe_result->ToObject(&result)) return maybe_result; |
171 } | 171 } |
172 } | 172 } |
173 } | 173 } |
174 } | 174 } |
175 | 175 |
176 // Deep copy local elements. | 176 // Deep copy local elements. |
177 // Pixel elements cannot be created using an object literal. | 177 // Pixel elements cannot be created using an object literal. |
178 ASSERT(!copy->HasExternalArrayElements()); | 178 ASSERT(!copy->HasExternalArrayElements()); |
179 switch (copy->GetElementsKind()) { | 179 switch (copy->GetElementsKind()) { |
| 180 case FAST_SMI_ONLY_ELEMENTS: |
180 case FAST_ELEMENTS: { | 181 case FAST_ELEMENTS: { |
181 FixedArray* elements = FixedArray::cast(copy->elements()); | 182 FixedArray* elements = FixedArray::cast(copy->elements()); |
182 if (elements->map() == heap->fixed_cow_array_map()) { | 183 if (elements->map() == heap->fixed_cow_array_map()) { |
183 isolate->counters()->cow_arrays_created_runtime()->Increment(); | 184 isolate->counters()->cow_arrays_created_runtime()->Increment(); |
184 #ifdef DEBUG | 185 #ifdef DEBUG |
185 for (int i = 0; i < elements->length(); i++) { | 186 for (int i = 0; i < elements->length(); i++) { |
186 ASSERT(!elements->get(i)->IsJSObject()); | 187 ASSERT(!elements->get(i)->IsJSObject()); |
187 } | 188 } |
188 #endif | 189 #endif |
189 } else { | 190 } else { |
190 for (int i = 0; i < elements->length(); i++) { | 191 for (int i = 0; i < elements->length(); i++) { |
191 Object* value = elements->get(i); | 192 Object* value = elements->get(i); |
| 193 ASSERT(value->IsSmi() || |
| 194 value->IsTheHole() || |
| 195 (copy->GetElementsKind() == FAST_ELEMENTS)); |
192 if (value->IsJSObject()) { | 196 if (value->IsJSObject()) { |
193 JSObject* js_object = JSObject::cast(value); | 197 JSObject* js_object = JSObject::cast(value); |
194 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, | 198 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
195 js_object); | 199 js_object); |
196 if (!maybe_result->ToObject(&result)) return maybe_result; | 200 if (!maybe_result->ToObject(&result)) return maybe_result; |
197 } | 201 } |
198 elements->set(i, result); | 202 elements->set(i, result); |
199 } | 203 } |
200 } | 204 } |
201 } | 205 } |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
425 Handle<JSFunction> constructor( | 429 Handle<JSFunction> constructor( |
426 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); | 430 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
427 Handle<Object> object = isolate->factory()->NewJSObject(constructor); | 431 Handle<Object> object = isolate->factory()->NewJSObject(constructor); |
428 | 432 |
429 const bool is_cow = | 433 const bool is_cow = |
430 (elements->map() == isolate->heap()->fixed_cow_array_map()); | 434 (elements->map() == isolate->heap()->fixed_cow_array_map()); |
431 Handle<FixedArray> copied_elements = | 435 Handle<FixedArray> copied_elements = |
432 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); | 436 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); |
433 | 437 |
434 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); | 438 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
| 439 bool has_non_constant_subexpression = true; |
435 if (is_cow) { | 440 if (is_cow) { |
436 #ifdef DEBUG | 441 #ifdef DEBUG |
437 // Copy-on-write arrays must be shallow (and simple). | 442 // Copy-on-write arrays must be shallow (and simple). |
438 for (int i = 0; i < content->length(); i++) { | 443 for (int i = 0; i < content->length(); i++) { |
439 ASSERT(!content->get(i)->IsFixedArray()); | 444 ASSERT(!content->get(i)->IsFixedArray()); |
440 } | 445 } |
441 #endif | 446 #endif |
442 } else { | 447 } else { |
443 for (int i = 0; i < content->length(); i++) { | 448 for (int i = 0; i < content->length(); i++) { |
444 if (content->get(i)->IsFixedArray()) { | 449 if (content->get(i)->IsFixedArray()) { |
445 // The value contains the constant_properties of a | 450 // The value contains the constant_properties of a |
446 // simple object or array literal. | 451 // simple object or array literal. |
447 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); | 452 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
448 Handle<Object> result = | 453 Handle<Object> result = |
449 CreateLiteralBoilerplate(isolate, literals, fa); | 454 CreateLiteralBoilerplate(isolate, literals, fa); |
450 if (result.is_null()) return result; | 455 if (result.is_null()) return result; |
451 content->set(i, *result); | 456 content->set(i, *result); |
| 457 } else { |
| 458 has_non_constant_subexpression = true; |
452 } | 459 } |
453 } | 460 } |
454 } | 461 } |
455 | 462 |
456 // Set the elements. | 463 // Set the elements. |
457 Handle<JSArray>::cast(object)->SetContent(*content); | 464 Handle<JSArray> js_object(Handle<JSArray>::cast(object)); |
| 465 isolate->factory()->SetContent(js_object, content); |
| 466 |
| 467 // To simplify the code that fills in non-constant expressions, assume that |
| 468 // any array literal that has non-constant expressions has non smi elements. |
| 469 if (has_non_constant_subexpression && js_object->HasFastSmiOnlyElements()) { |
| 470 isolate->factory()->EnsureCanContainNonSmiElements(js_object); |
| 471 } |
458 return object; | 472 return object; |
459 } | 473 } |
460 | 474 |
461 | 475 |
462 static Handle<Object> CreateLiteralBoilerplate( | 476 static Handle<Object> CreateLiteralBoilerplate( |
463 Isolate* isolate, | 477 Isolate* isolate, |
464 Handle<FixedArray> literals, | 478 Handle<FixedArray> literals, |
465 Handle<FixedArray> array) { | 479 Handle<FixedArray> array) { |
466 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 480 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
467 const bool kHasNoFunctionLiteral = false; | 481 const bool kHasNoFunctionLiteral = false; |
(...skipping 1812 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2280 NoHandleAllocation ha; | 2294 NoHandleAllocation ha; |
2281 ASSERT(args.length() == 1); | 2295 ASSERT(args.length() == 1); |
2282 return CharFromCode(isolate, args[0]); | 2296 return CharFromCode(isolate, args[0]); |
2283 } | 2297 } |
2284 | 2298 |
2285 | 2299 |
2286 class FixedArrayBuilder { | 2300 class FixedArrayBuilder { |
2287 public: | 2301 public: |
2288 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) | 2302 explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) |
2289 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), | 2303 : array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), |
2290 length_(0) { | 2304 length_(0), |
| 2305 has_non_smi_elements_(false) { |
2291 // Require a non-zero initial size. Ensures that doubling the size to | 2306 // Require a non-zero initial size. Ensures that doubling the size to |
2292 // extend the array will work. | 2307 // extend the array will work. |
2293 ASSERT(initial_capacity > 0); | 2308 ASSERT(initial_capacity > 0); |
2294 } | 2309 } |
2295 | 2310 |
2296 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) | 2311 explicit FixedArrayBuilder(Handle<FixedArray> backing_store) |
2297 : array_(backing_store), | 2312 : array_(backing_store), |
2298 length_(0) { | 2313 length_(0), |
| 2314 has_non_smi_elements_(false) { |
2299 // Require a non-zero initial size. Ensures that doubling the size to | 2315 // Require a non-zero initial size. Ensures that doubling the size to |
2300 // extend the array will work. | 2316 // extend the array will work. |
2301 ASSERT(backing_store->length() > 0); | 2317 ASSERT(backing_store->length() > 0); |
2302 } | 2318 } |
2303 | 2319 |
2304 bool HasCapacity(int elements) { | 2320 bool HasCapacity(int elements) { |
2305 int length = array_->length(); | 2321 int length = array_->length(); |
2306 int required_length = length_ + elements; | 2322 int required_length = length_ + elements; |
2307 return (length >= required_length); | 2323 return (length >= required_length); |
2308 } | 2324 } |
2309 | 2325 |
2310 void EnsureCapacity(int elements) { | 2326 void EnsureCapacity(int elements) { |
2311 int length = array_->length(); | 2327 int length = array_->length(); |
2312 int required_length = length_ + elements; | 2328 int required_length = length_ + elements; |
2313 if (length < required_length) { | 2329 if (length < required_length) { |
2314 int new_length = length; | 2330 int new_length = length; |
2315 do { | 2331 do { |
2316 new_length *= 2; | 2332 new_length *= 2; |
2317 } while (new_length < required_length); | 2333 } while (new_length < required_length); |
2318 Handle<FixedArray> extended_array = | 2334 Handle<FixedArray> extended_array = |
2319 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); | 2335 array_->GetIsolate()->factory()->NewFixedArrayWithHoles(new_length); |
2320 array_->CopyTo(0, *extended_array, 0, length_); | 2336 array_->CopyTo(0, *extended_array, 0, length_); |
2321 array_ = extended_array; | 2337 array_ = extended_array; |
2322 } | 2338 } |
2323 } | 2339 } |
2324 | 2340 |
2325 void Add(Object* value) { | 2341 void Add(Object* value) { |
| 2342 ASSERT(!value->IsSmi()); |
2326 ASSERT(length_ < capacity()); | 2343 ASSERT(length_ < capacity()); |
2327 array_->set(length_, value); | 2344 array_->set(length_, value); |
2328 length_++; | 2345 length_++; |
| 2346 has_non_smi_elements_ = true; |
2329 } | 2347 } |
2330 | 2348 |
2331 void Add(Smi* value) { | 2349 void Add(Smi* value) { |
| 2350 ASSERT(value->IsSmi()); |
2332 ASSERT(length_ < capacity()); | 2351 ASSERT(length_ < capacity()); |
2333 array_->set(length_, value); | 2352 array_->set(length_, value); |
2334 length_++; | 2353 length_++; |
2335 } | 2354 } |
2336 | 2355 |
2337 Handle<FixedArray> array() { | 2356 Handle<FixedArray> array() { |
2338 return array_; | 2357 return array_; |
2339 } | 2358 } |
2340 | 2359 |
2341 int length() { | 2360 int length() { |
2342 return length_; | 2361 return length_; |
2343 } | 2362 } |
2344 | 2363 |
2345 int capacity() { | 2364 int capacity() { |
2346 return array_->length(); | 2365 return array_->length(); |
2347 } | 2366 } |
2348 | 2367 |
2349 Handle<JSArray> ToJSArray() { | 2368 Handle<JSArray> ToJSArray() { |
2350 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); | 2369 Handle<JSArray> result_array = FACTORY->NewJSArrayWithElements(array_); |
2351 result_array->set_length(Smi::FromInt(length_)); | 2370 result_array->set_length(Smi::FromInt(length_)); |
2352 return result_array; | 2371 return result_array; |
2353 } | 2372 } |
2354 | 2373 |
2355 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { | 2374 Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { |
2356 target_array->set_elements(*array_); | 2375 FACTORY->SetContent(target_array, array_); |
2357 target_array->set_length(Smi::FromInt(length_)); | 2376 target_array->set_length(Smi::FromInt(length_)); |
2358 return target_array; | 2377 return target_array; |
2359 } | 2378 } |
2360 | 2379 |
2361 private: | 2380 private: |
2362 Handle<FixedArray> array_; | 2381 Handle<FixedArray> array_; |
2363 int length_; | 2382 int length_; |
| 2383 bool has_non_smi_elements_; |
2364 }; | 2384 }; |
2365 | 2385 |
2366 | 2386 |
2367 // Forward declarations. | 2387 // Forward declarations. |
2368 const int kStringBuilderConcatHelperLengthBits = 11; | 2388 const int kStringBuilderConcatHelperLengthBits = 11; |
2369 const int kStringBuilderConcatHelperPositionBits = 19; | 2389 const int kStringBuilderConcatHelperPositionBits = 19; |
2370 | 2390 |
2371 template <typename schar> | 2391 template <typename schar> |
2372 static inline void StringBuilderConcatHelper(String*, | 2392 static inline void StringBuilderConcatHelper(String*, |
2373 schar*, | 2393 schar*, |
(...skipping 3809 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6183 if (static_cast<uint32_t>(indices.length()) < limit) { | 6203 if (static_cast<uint32_t>(indices.length()) < limit) { |
6184 indices.Add(subject_length); | 6204 indices.Add(subject_length); |
6185 } | 6205 } |
6186 | 6206 |
6187 // The list indices now contains the end of each part to create. | 6207 // The list indices now contains the end of each part to create. |
6188 | 6208 |
6189 // Create JSArray of substrings separated by separator. | 6209 // Create JSArray of substrings separated by separator. |
6190 int part_count = indices.length(); | 6210 int part_count = indices.length(); |
6191 | 6211 |
6192 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); | 6212 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
| 6213 MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements(); |
| 6214 if (maybe_result->IsFailure()) return maybe_result; |
6193 result->set_length(Smi::FromInt(part_count)); | 6215 result->set_length(Smi::FromInt(part_count)); |
6194 | 6216 |
6195 ASSERT(result->HasFastElements()); | 6217 ASSERT(result->HasFastElements()); |
6196 | 6218 |
6197 if (part_count == 1 && indices.at(0) == subject_length) { | 6219 if (part_count == 1 && indices.at(0) == subject_length) { |
6198 FixedArray::cast(result->elements())->set(0, *subject); | 6220 FixedArray::cast(result->elements())->set(0, *subject); |
6199 return *result; | 6221 return *result; |
6200 } | 6222 } |
6201 | 6223 |
6202 Handle<FixedArray> elements(FixedArray::cast(result->elements())); | 6224 Handle<FixedArray> elements(FixedArray::cast(result->elements())); |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6557 if (!args[1]->IsSmi()) { | 6579 if (!args[1]->IsSmi()) { |
6558 isolate->context()->mark_out_of_memory(); | 6580 isolate->context()->mark_out_of_memory(); |
6559 return Failure::OutOfMemoryException(); | 6581 return Failure::OutOfMemoryException(); |
6560 } | 6582 } |
6561 int array_length = args.smi_at(1); | 6583 int array_length = args.smi_at(1); |
6562 CONVERT_CHECKED(String, special, args[2]); | 6584 CONVERT_CHECKED(String, special, args[2]); |
6563 | 6585 |
6564 // This assumption is used by the slice encoding in one or two smis. | 6586 // This assumption is used by the slice encoding in one or two smis. |
6565 ASSERT(Smi::kMaxValue >= String::kMaxLength); | 6587 ASSERT(Smi::kMaxValue >= String::kMaxLength); |
6566 | 6588 |
| 6589 MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements(); |
| 6590 if (maybe_result->IsFailure()) return maybe_result; |
| 6591 |
6567 int special_length = special->length(); | 6592 int special_length = special->length(); |
6568 if (!array->HasFastElements()) { | 6593 if (!array->HasFastElements()) { |
6569 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); | 6594 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
6570 } | 6595 } |
6571 FixedArray* fixed_array = FixedArray::cast(array->elements()); | 6596 FixedArray* fixed_array = FixedArray::cast(array->elements()); |
6572 if (fixed_array->length() < array_length) { | 6597 if (fixed_array->length() < array_length) { |
6573 array_length = fixed_array->length(); | 6598 array_length = fixed_array->length(); |
6574 } | 6599 } |
6575 | 6600 |
6576 if (array_length == 0) { | 6601 if (array_length == 0) { |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6784 } | 6809 } |
6785 } | 6810 } |
6786 ASSERT(cursor <= buffer.length()); | 6811 ASSERT(cursor <= buffer.length()); |
6787 } | 6812 } |
6788 | 6813 |
6789 | 6814 |
6790 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { | 6815 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { |
6791 NoHandleAllocation ha; | 6816 NoHandleAllocation ha; |
6792 ASSERT(args.length() == 3); | 6817 ASSERT(args.length() == 3); |
6793 CONVERT_CHECKED(JSArray, elements_array, args[0]); | 6818 CONVERT_CHECKED(JSArray, elements_array, args[0]); |
6794 RUNTIME_ASSERT(elements_array->HasFastElements()); | 6819 RUNTIME_ASSERT(elements_array->HasFastElements() || |
| 6820 elements_array->HasFastSmiOnlyElements()); |
6795 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); | 6821 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
6796 CONVERT_CHECKED(String, separator, args[2]); | 6822 CONVERT_CHECKED(String, separator, args[2]); |
6797 // elements_array is fast-mode JSarray of alternating positions | 6823 // elements_array is fast-mode JSarray of alternating positions |
6798 // (increasing order) and strings. | 6824 // (increasing order) and strings. |
6799 // array_length is length of original array (used to add separators); | 6825 // array_length is length of original array (used to add separators); |
6800 // separator is string to put between elements. Assumed to be non-empty. | 6826 // separator is string to put between elements. Assumed to be non-empty. |
6801 | 6827 |
6802 // Find total length of join result. | 6828 // Find total length of join result. |
6803 int string_length = 0; | 6829 int string_length = 0; |
6804 bool is_ascii = true; | 6830 bool is_ascii = true; |
(...skipping 2235 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9040 | 9066 |
9041 | 9067 |
9042 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { | 9068 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { |
9043 HandleScope scope(isolate); | 9069 HandleScope scope(isolate); |
9044 ASSERT(args.length() == 2); | 9070 ASSERT(args.length() == 2); |
9045 | 9071 |
9046 CONVERT_ARG_CHECKED(String, str, 0); | 9072 CONVERT_ARG_CHECKED(String, str, 0); |
9047 FlattenString(str); | 9073 FlattenString(str); |
9048 | 9074 |
9049 CONVERT_ARG_CHECKED(JSArray, output, 1); | 9075 CONVERT_ARG_CHECKED(JSArray, output, 1); |
| 9076 |
| 9077 MaybeObject* maybe_result_array = |
| 9078 output->EnsureCanContainNonSmiElements(); |
| 9079 if (maybe_result_array->IsFailure()) return maybe_result_array; |
9050 RUNTIME_ASSERT(output->HasFastElements()); | 9080 RUNTIME_ASSERT(output->HasFastElements()); |
9051 | 9081 |
9052 AssertNoAllocation no_allocation; | 9082 AssertNoAllocation no_allocation; |
9053 | 9083 |
9054 FixedArray* output_array = FixedArray::cast(output->elements()); | 9084 FixedArray* output_array = FixedArray::cast(output->elements()); |
9055 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); | 9085 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); |
9056 bool result; | 9086 bool result; |
9057 String::FlatContent str_content = str->GetFlatContent(); | 9087 String::FlatContent str_content = str->GetFlatContent(); |
9058 if (str_content.IsAscii()) { | 9088 if (str_content.IsAscii()) { |
9059 result = DateParser::Parse(str_content.ToAsciiVector(), | 9089 result = DateParser::Parse(str_content.ToAsciiVector(), |
(...skipping 280 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9340 } | 9370 } |
9341 | 9371 |
9342 | 9372 |
9343 // Push an object unto an array of objects if it is not already in the | 9373 // Push an object unto an array of objects if it is not already in the |
9344 // array. Returns true if the element was pushed on the stack and | 9374 // array. Returns true if the element was pushed on the stack and |
9345 // false otherwise. | 9375 // false otherwise. |
9346 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { | 9376 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { |
9347 ASSERT(args.length() == 2); | 9377 ASSERT(args.length() == 2); |
9348 CONVERT_CHECKED(JSArray, array, args[0]); | 9378 CONVERT_CHECKED(JSArray, array, args[0]); |
9349 CONVERT_CHECKED(JSObject, element, args[1]); | 9379 CONVERT_CHECKED(JSObject, element, args[1]); |
9350 RUNTIME_ASSERT(array->HasFastElements()); | 9380 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
9351 int length = Smi::cast(array->length())->value(); | 9381 int length = Smi::cast(array->length())->value(); |
9352 FixedArray* elements = FixedArray::cast(array->elements()); | 9382 FixedArray* elements = FixedArray::cast(array->elements()); |
9353 for (int i = 0; i < length; i++) { | 9383 for (int i = 0; i < length; i++) { |
9354 if (elements->get(i) == element) return isolate->heap()->false_value(); | 9384 if (elements->get(i) == element) return isolate->heap()->false_value(); |
9355 } | 9385 } |
9356 Object* obj; | 9386 Object* obj; |
9357 // Strict not needed. Used for cycle detection in Array join implementation. | 9387 // Strict not needed. Used for cycle detection in Array join implementation. |
9358 { MaybeObject* maybe_obj = | 9388 { MaybeObject* maybe_obj = |
9359 array->SetFastElement(length, element, kNonStrictMode, true); | 9389 array->SetFastElement(length, element, kNonStrictMode, true); |
9360 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9390 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9571 uint32_t b = *bp; | 9601 uint32_t b = *bp; |
9572 return (a == b) ? 0 : (a < b) ? -1 : 1; | 9602 return (a == b) ? 0 : (a < b) ? -1 : 1; |
9573 } | 9603 } |
9574 | 9604 |
9575 | 9605 |
9576 static void CollectElementIndices(Handle<JSObject> object, | 9606 static void CollectElementIndices(Handle<JSObject> object, |
9577 uint32_t range, | 9607 uint32_t range, |
9578 List<uint32_t>* indices) { | 9608 List<uint32_t>* indices) { |
9579 ElementsKind kind = object->GetElementsKind(); | 9609 ElementsKind kind = object->GetElementsKind(); |
9580 switch (kind) { | 9610 switch (kind) { |
| 9611 case FAST_SMI_ONLY_ELEMENTS: |
9581 case FAST_ELEMENTS: { | 9612 case FAST_ELEMENTS: { |
9582 Handle<FixedArray> elements(FixedArray::cast(object->elements())); | 9613 Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
9583 uint32_t length = static_cast<uint32_t>(elements->length()); | 9614 uint32_t length = static_cast<uint32_t>(elements->length()); |
9584 if (range < length) length = range; | 9615 if (range < length) length = range; |
9585 for (uint32_t i = 0; i < length; i++) { | 9616 for (uint32_t i = 0; i < length; i++) { |
9586 if (!elements->get(i)->IsTheHole()) { | 9617 if (!elements->get(i)->IsTheHole()) { |
9587 indices->Add(i); | 9618 indices->Add(i); |
9588 } | 9619 } |
9589 } | 9620 } |
9590 break; | 9621 break; |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9690 * with the element index and the element's value. | 9721 * with the element index and the element's value. |
9691 * Afterwards it increments the base-index of the visitor by the array | 9722 * Afterwards it increments the base-index of the visitor by the array |
9692 * length. | 9723 * length. |
9693 * Returns false if any access threw an exception, otherwise true. | 9724 * Returns false if any access threw an exception, otherwise true. |
9694 */ | 9725 */ |
9695 static bool IterateElements(Isolate* isolate, | 9726 static bool IterateElements(Isolate* isolate, |
9696 Handle<JSArray> receiver, | 9727 Handle<JSArray> receiver, |
9697 ArrayConcatVisitor* visitor) { | 9728 ArrayConcatVisitor* visitor) { |
9698 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); | 9729 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
9699 switch (receiver->GetElementsKind()) { | 9730 switch (receiver->GetElementsKind()) { |
| 9731 case FAST_SMI_ONLY_ELEMENTS: |
9700 case FAST_ELEMENTS: { | 9732 case FAST_ELEMENTS: { |
9701 // Run through the elements FixedArray and use HasElement and GetElement | 9733 // Run through the elements FixedArray and use HasElement and GetElement |
9702 // to check the prototype for missing elements. | 9734 // to check the prototype for missing elements. |
9703 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); | 9735 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); |
9704 int fast_length = static_cast<int>(length); | 9736 int fast_length = static_cast<int>(length); |
9705 ASSERT(fast_length <= elements->length()); | 9737 ASSERT(fast_length <= elements->length()); |
9706 for (int j = 0; j < fast_length; j++) { | 9738 for (int j = 0; j < fast_length; j++) { |
9707 HandleScope loop_scope(isolate); | 9739 HandleScope loop_scope(isolate); |
9708 Handle<Object> element_value(elements->get(j), isolate); | 9740 Handle<Object> element_value(elements->get(j), isolate); |
9709 if (!element_value->IsTheHole()) { | 9741 if (!element_value->IsTheHole()) { |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10013 for (int i = 0; i < keys_length; i++) { | 10045 for (int i = 0; i < keys_length; i++) { |
10014 Object* key = keys->get(i); | 10046 Object* key = keys->get(i); |
10015 uint32_t index = 0; | 10047 uint32_t index = 0; |
10016 if (!key->ToArrayIndex(&index) || index >= length) { | 10048 if (!key->ToArrayIndex(&index) || index >= length) { |
10017 // Zap invalid keys. | 10049 // Zap invalid keys. |
10018 keys->set_undefined(i); | 10050 keys->set_undefined(i); |
10019 } | 10051 } |
10020 } | 10052 } |
10021 return *isolate->factory()->NewJSArrayWithElements(keys); | 10053 return *isolate->factory()->NewJSArrayWithElements(keys); |
10022 } else { | 10054 } else { |
10023 ASSERT(array->HasFastElements() || array->HasFastDoubleElements()); | 10055 ASSERT(array->HasFastElements() || |
| 10056 array->HasFastSmiOnlyElements() || |
| 10057 array->HasFastDoubleElements()); |
10024 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); | 10058 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); |
10025 // -1 means start of array. | 10059 // -1 means start of array. |
10026 single_interval->set(0, Smi::FromInt(-1)); | 10060 single_interval->set(0, Smi::FromInt(-1)); |
10027 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); | 10061 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); |
10028 uint32_t actual_length = | 10062 uint32_t actual_length = |
10029 static_cast<uint32_t>(elements->length()); | 10063 static_cast<uint32_t>(elements->length()); |
10030 uint32_t min_length = actual_length < length ? actual_length : length; | 10064 uint32_t min_length = actual_length < length ? actual_length : length; |
10031 Handle<Object> length_object = | 10065 Handle<Object> length_object = |
10032 isolate->factory()->NewNumber(static_cast<double>(min_length)); | 10066 isolate->factory()->NewNumber(static_cast<double>(min_length)); |
10033 single_interval->set(1, *length_object); | 10067 single_interval->set(1, *length_object); |
(...skipping 1881 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11915 // instances->set(i, *GetScriptWrapper(script)) | 11949 // instances->set(i, *GetScriptWrapper(script)) |
11916 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might | 11950 // is unsafe as GetScriptWrapper might call GC and the C++ compiler might |
11917 // already have deferenced the instances handle. | 11951 // already have deferenced the instances handle. |
11918 Handle<JSValue> wrapper = GetScriptWrapper(script); | 11952 Handle<JSValue> wrapper = GetScriptWrapper(script); |
11919 instances->set(i, *wrapper); | 11953 instances->set(i, *wrapper); |
11920 } | 11954 } |
11921 | 11955 |
11922 // Return result as a JS array. | 11956 // Return result as a JS array. |
11923 Handle<JSObject> result = | 11957 Handle<JSObject> result = |
11924 isolate->factory()->NewJSObject(isolate->array_function()); | 11958 isolate->factory()->NewJSObject(isolate->array_function()); |
11925 Handle<JSArray>::cast(result)->SetContent(*instances); | 11959 isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); |
11926 return *result; | 11960 return *result; |
11927 } | 11961 } |
11928 | 11962 |
11929 | 11963 |
11930 // Helper function used by Runtime_DebugReferencedBy below. | 11964 // Helper function used by Runtime_DebugReferencedBy below. |
11931 static int DebugReferencedBy(JSObject* target, | 11965 static int DebugReferencedBy(JSObject* target, |
11932 Object* instance_filter, int max_references, | 11966 Object* instance_filter, int max_references, |
11933 FixedArray* instances, int instances_size, | 11967 FixedArray* instances, int instances_size, |
11934 JSFunction* arguments_function) { | 11968 JSFunction* arguments_function) { |
11935 NoHandleAllocation ha; | 11969 NoHandleAllocation ha; |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12032 if (!maybe_object->ToObject(&object)) return maybe_object; | 12066 if (!maybe_object->ToObject(&object)) return maybe_object; |
12033 } | 12067 } |
12034 FixedArray* instances = FixedArray::cast(object); | 12068 FixedArray* instances = FixedArray::cast(object); |
12035 | 12069 |
12036 // Fill the referencing objects. | 12070 // Fill the referencing objects. |
12037 count = DebugReferencedBy(target, instance_filter, max_references, | 12071 count = DebugReferencedBy(target, instance_filter, max_references, |
12038 instances, count, arguments_function); | 12072 instances, count, arguments_function); |
12039 | 12073 |
12040 // Return result as JS array. | 12074 // Return result as JS array. |
12041 Object* result; | 12075 Object* result; |
12042 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | 12076 MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
12043 isolate->context()->global_context()->array_function()); | 12077 isolate->context()->global_context()->array_function()); |
12044 if (!maybe_result->ToObject(&result)) return maybe_result; | 12078 if (!maybe_result->ToObject(&result)) return maybe_result; |
12045 } | 12079 return JSArray::cast(result)->SetContent(instances); |
12046 JSArray::cast(result)->SetContent(instances); | |
12047 return result; | |
12048 } | 12080 } |
12049 | 12081 |
12050 | 12082 |
12051 // Helper function used by Runtime_DebugConstructedBy below. | 12083 // Helper function used by Runtime_DebugConstructedBy below. |
12052 static int DebugConstructedBy(JSFunction* constructor, int max_references, | 12084 static int DebugConstructedBy(JSFunction* constructor, int max_references, |
12053 FixedArray* instances, int instances_size) { | 12085 FixedArray* instances, int instances_size) { |
12054 AssertNoAllocation no_alloc; | 12086 AssertNoAllocation no_alloc; |
12055 | 12087 |
12056 // Iterate the heap. | 12088 // Iterate the heap. |
12057 int count = 0; | 12089 int count = 0; |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12105 | 12137 |
12106 // Fill the referencing objects. | 12138 // Fill the referencing objects. |
12107 count = DebugConstructedBy(constructor, max_references, instances, count); | 12139 count = DebugConstructedBy(constructor, max_references, instances, count); |
12108 | 12140 |
12109 // Return result as JS array. | 12141 // Return result as JS array. |
12110 Object* result; | 12142 Object* result; |
12111 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( | 12143 { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
12112 isolate->context()->global_context()->array_function()); | 12144 isolate->context()->global_context()->array_function()); |
12113 if (!maybe_result->ToObject(&result)) return maybe_result; | 12145 if (!maybe_result->ToObject(&result)) return maybe_result; |
12114 } | 12146 } |
12115 JSArray::cast(result)->SetContent(instances); | 12147 return JSArray::cast(result)->SetContent(instances); |
12116 return result; | |
12117 } | 12148 } |
12118 | 12149 |
12119 | 12150 |
12120 // Find the effective prototype object as returned by __proto__. | 12151 // Find the effective prototype object as returned by __proto__. |
12121 // args[0]: the object to find the prototype for. | 12152 // args[0]: the object to find the prototype for. |
12122 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { | 12153 RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetPrototype) { |
12123 ASSERT(args.length() == 1); | 12154 ASSERT(args.length() == 1); |
12124 | 12155 |
12125 CONVERT_CHECKED(JSObject, obj, args[0]); | 12156 CONVERT_CHECKED(JSObject, obj, args[0]); |
12126 | 12157 |
(...skipping 934 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13061 return NULL; | 13092 return NULL; |
13062 } | 13093 } |
13063 | 13094 |
13064 | 13095 |
13065 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ | 13096 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ |
13066 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ | 13097 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ |
13067 CONVERT_CHECKED(JSObject, obj, args[0]); \ | 13098 CONVERT_CHECKED(JSObject, obj, args[0]); \ |
13068 return isolate->heap()->ToBoolean(obj->Has##Name()); \ | 13099 return isolate->heap()->ToBoolean(obj->Has##Name()); \ |
13069 } | 13100 } |
13070 | 13101 |
| 13102 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements) |
13071 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) | 13103 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) |
13072 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) | 13104 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) |
13073 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) | 13105 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) |
13074 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) | 13106 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) |
13075 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) | 13107 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) |
13076 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) | 13108 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) |
13077 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) | 13109 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) |
13078 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) | 13110 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) |
13079 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) | 13111 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) |
13080 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) | 13112 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13157 } else { | 13189 } else { |
13158 // Handle last resort GC and make sure to allow future allocations | 13190 // Handle last resort GC and make sure to allow future allocations |
13159 // to grow the heap without causing GCs (if possible). | 13191 // to grow the heap without causing GCs (if possible). |
13160 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13192 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13161 isolate->heap()->CollectAllGarbage(false); | 13193 isolate->heap()->CollectAllGarbage(false); |
13162 } | 13194 } |
13163 } | 13195 } |
13164 | 13196 |
13165 | 13197 |
13166 } } // namespace v8::internal | 13198 } } // namespace v8::internal |
OLD | NEW |