| 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 |