Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(59)

Side by Side Diff: src/runtime.cc

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/string-stream.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 190 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 if (!maybe_result->ToObject(&result)) return maybe_result; 201 if (!maybe_result->ToObject(&result)) return maybe_result;
202 } 202 }
203 } 203 }
204 } 204 }
205 } 205 }
206 206
207 // Deep copy local elements. 207 // Deep copy local elements.
208 // Pixel elements cannot be created using an object literal. 208 // Pixel elements cannot be created using an object literal.
209 ASSERT(!copy->HasExternalArrayElements()); 209 ASSERT(!copy->HasExternalArrayElements());
210 switch (copy->GetElementsKind()) { 210 switch (copy->GetElementsKind()) {
211 case FAST_SMI_ONLY_ELEMENTS: 211 case FAST_SMI_ELEMENTS:
212 case FAST_ELEMENTS: { 212 case FAST_ELEMENTS:
213 case FAST_HOLEY_SMI_ELEMENTS:
214 case FAST_HOLEY_ELEMENTS: {
213 FixedArray* elements = FixedArray::cast(copy->elements()); 215 FixedArray* elements = FixedArray::cast(copy->elements());
214 if (elements->map() == heap->fixed_cow_array_map()) { 216 if (elements->map() == heap->fixed_cow_array_map()) {
215 isolate->counters()->cow_arrays_created_runtime()->Increment(); 217 isolate->counters()->cow_arrays_created_runtime()->Increment();
216 #ifdef DEBUG 218 #ifdef DEBUG
217 for (int i = 0; i < elements->length(); i++) { 219 for (int i = 0; i < elements->length(); i++) {
218 ASSERT(!elements->get(i)->IsJSObject()); 220 ASSERT(!elements->get(i)->IsJSObject());
219 } 221 }
220 #endif 222 #endif
221 } else { 223 } else {
222 for (int i = 0; i < elements->length(); i++) { 224 for (int i = 0; i < elements->length(); i++) {
223 Object* value = elements->get(i); 225 Object* value = elements->get(i);
224 ASSERT(value->IsSmi() || 226 ASSERT(value->IsSmi() ||
225 value->IsTheHole() || 227 value->IsTheHole() ||
226 (copy->GetElementsKind() == FAST_ELEMENTS)); 228 (IsFastObjectElementsKind(copy->GetElementsKind())));
227 if (value->IsJSObject()) { 229 if (value->IsJSObject()) {
228 JSObject* js_object = JSObject::cast(value); 230 JSObject* js_object = JSObject::cast(value);
229 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, 231 { MaybeObject* maybe_result = DeepCopyBoilerplate(isolate,
230 js_object); 232 js_object);
231 if (!maybe_result->ToObject(&result)) return maybe_result; 233 if (!maybe_result->ToObject(&result)) return maybe_result;
232 } 234 }
233 elements->set(i, result); 235 elements->set(i, result);
234 } 236 }
235 } 237 }
236 } 238 }
(...skipping 24 matching lines...) Expand all
261 case EXTERNAL_PIXEL_ELEMENTS: 263 case EXTERNAL_PIXEL_ELEMENTS:
262 case EXTERNAL_BYTE_ELEMENTS: 264 case EXTERNAL_BYTE_ELEMENTS:
263 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 265 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
264 case EXTERNAL_SHORT_ELEMENTS: 266 case EXTERNAL_SHORT_ELEMENTS:
265 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 267 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
266 case EXTERNAL_INT_ELEMENTS: 268 case EXTERNAL_INT_ELEMENTS:
267 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 269 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
268 case EXTERNAL_FLOAT_ELEMENTS: 270 case EXTERNAL_FLOAT_ELEMENTS:
269 case EXTERNAL_DOUBLE_ELEMENTS: 271 case EXTERNAL_DOUBLE_ELEMENTS:
270 case FAST_DOUBLE_ELEMENTS: 272 case FAST_DOUBLE_ELEMENTS:
273 case FAST_HOLEY_DOUBLE_ELEMENTS:
271 // No contained objects, nothing to do. 274 // No contained objects, nothing to do.
272 break; 275 break;
273 } 276 }
274 return copy; 277 return copy;
275 } 278 }
276 279
277 280
278 static Handle<Map> ComputeObjectLiteralMap( 281 static Handle<Map> ComputeObjectLiteralMap(
279 Handle<Context> context, 282 Handle<Context> context,
280 Handle<FixedArray> constant_properties, 283 Handle<FixedArray> constant_properties,
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 if (Map::IsValidElementsTransition(from_kind, to_kind)) { 448 if (Map::IsValidElementsTransition(from_kind, to_kind)) {
446 Handle<Object> result = JSObject::TransitionElementsKind( 449 Handle<Object> result = JSObject::TransitionElementsKind(
447 Handle<JSObject>::cast(object), to_kind); 450 Handle<JSObject>::cast(object), to_kind);
448 if (result.is_null()) return isolate->ThrowIllegalOperation(); 451 if (result.is_null()) return isolate->ThrowIllegalOperation();
449 return *result; 452 return *result;
450 } 453 }
451 return isolate->ThrowIllegalOperation(); 454 return isolate->ThrowIllegalOperation();
452 } 455 }
453 456
454 457
455 static const int kSmiOnlyLiteralMinimumLength = 1024; 458 static const int kSmiLiteralMinimumLength = 1024;
456 459
457 460
458 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( 461 Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
459 Isolate* isolate, 462 Isolate* isolate,
460 Handle<FixedArray> literals, 463 Handle<FixedArray> literals,
461 Handle<FixedArray> elements) { 464 Handle<FixedArray> elements) {
462 // Create the JSArray. 465 // Create the JSArray.
463 Handle<JSFunction> constructor( 466 Handle<JSFunction> constructor(
464 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); 467 JSFunction::GlobalContextFromLiterals(*literals)->array_function());
465 Handle<JSArray> object = 468 Handle<JSArray> object =
466 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); 469 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor));
467 470
468 ElementsKind constant_elements_kind = 471 ElementsKind constant_elements_kind =
469 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); 472 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
470 Handle<FixedArrayBase> constant_elements_values( 473 Handle<FixedArrayBase> constant_elements_values(
471 FixedArrayBase::cast(elements->get(1))); 474 FixedArrayBase::cast(elements->get(1)));
472 475
476 ASSERT(IsFastElementsKind(constant_elements_kind));
473 Context* global_context = isolate->context()->global_context(); 477 Context* global_context = isolate->context()->global_context();
474 if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) { 478 Object* maybe_maps_array = global_context->js_array_maps();
475 object->set_map(Map::cast(global_context->smi_js_array_map())); 479 ASSERT(!maybe_maps_array->IsUndefined());
476 } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { 480 Object* maybe_map = FixedArray::cast(maybe_maps_array)->get(
477 object->set_map(Map::cast(global_context->double_js_array_map())); 481 constant_elements_kind);
478 } else { 482 ASSERT(maybe_map->IsMap());
479 object->set_map(Map::cast(global_context->object_js_array_map())); 483 object->set_map(Map::cast(maybe_map));
480 }
481 484
482 Handle<FixedArrayBase> copied_elements_values; 485 Handle<FixedArrayBase> copied_elements_values;
483 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { 486 if (IsFastDoubleElementsKind(constant_elements_kind)) {
484 ASSERT(FLAG_smi_only_arrays); 487 ASSERT(FLAG_smi_only_arrays);
485 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( 488 copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
486 Handle<FixedDoubleArray>::cast(constant_elements_values)); 489 Handle<FixedDoubleArray>::cast(constant_elements_values));
487 } else { 490 } else {
488 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || 491 ASSERT(IsFastSmiOrObjectElementsKind(constant_elements_kind));
489 constant_elements_kind == FAST_ELEMENTS);
490 const bool is_cow = 492 const bool is_cow =
491 (constant_elements_values->map() == 493 (constant_elements_values->map() ==
492 isolate->heap()->fixed_cow_array_map()); 494 isolate->heap()->fixed_cow_array_map());
493 if (is_cow) { 495 if (is_cow) {
494 copied_elements_values = constant_elements_values; 496 copied_elements_values = constant_elements_values;
495 #if DEBUG 497 #if DEBUG
496 Handle<FixedArray> fixed_array_values = 498 Handle<FixedArray> fixed_array_values =
497 Handle<FixedArray>::cast(copied_elements_values); 499 Handle<FixedArray>::cast(copied_elements_values);
498 for (int i = 0; i < fixed_array_values->length(); i++) { 500 for (int i = 0; i < fixed_array_values->length(); i++) {
499 ASSERT(!fixed_array_values->get(i)->IsFixedArray()); 501 ASSERT(!fixed_array_values->get(i)->IsFixedArray());
(...skipping 15 matching lines...) Expand all
515 CreateLiteralBoilerplate(isolate, literals, fa); 517 CreateLiteralBoilerplate(isolate, literals, fa);
516 if (result.is_null()) return result; 518 if (result.is_null()) return result;
517 fixed_array_values_copy->set(i, *result); 519 fixed_array_values_copy->set(i, *result);
518 } 520 }
519 } 521 }
520 } 522 }
521 } 523 }
522 object->set_elements(*copied_elements_values); 524 object->set_elements(*copied_elements_values);
523 object->set_length(Smi::FromInt(copied_elements_values->length())); 525 object->set_length(Smi::FromInt(copied_elements_values->length()));
524 526
525 // Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is 527 // Ensure that the boilerplate object has FAST_*_ELEMENTS, unless the flag is
526 // on or the object is larger than the threshold. 528 // on or the object is larger than the threshold.
527 if (!FLAG_smi_only_arrays && 529 if (!FLAG_smi_only_arrays &&
528 constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) { 530 constant_elements_values->length() < kSmiLiteralMinimumLength) {
529 if (object->GetElementsKind() != FAST_ELEMENTS) { 531 ElementsKind elements_kind = object->GetElementsKind();
530 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure()); 532 if (!IsFastObjectElementsKind(elements_kind)) {
533 if (IsFastHoleyElementsKind(elements_kind)) {
534 CHECK(!TransitionElements(object, FAST_HOLEY_ELEMENTS,
535 isolate)->IsFailure());
536 } else {
537 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
538 }
531 } 539 }
532 } 540 }
533 541
542 object->ValidateElements();
534 return object; 543 return object;
535 } 544 }
536 545
537 546
538 static Handle<Object> CreateLiteralBoilerplate( 547 static Handle<Object> CreateLiteralBoilerplate(
539 Isolate* isolate, 548 Isolate* isolate,
540 Handle<FixedArray> literals, 549 Handle<FixedArray> literals,
541 Handle<FixedArray> array) { 550 Handle<FixedArray> array) {
542 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 551 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
543 const bool kHasNoFunctionLiteral = false; 552 const bool kHasNoFunctionLiteral = false;
(...skipping 1179 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 1732
1724 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { 1733 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1725 HandleScope scope(isolate); 1734 HandleScope scope(isolate);
1726 ASSERT(args.length() == 4); 1735 ASSERT(args.length() == 4);
1727 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); 1736 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
1728 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); 1737 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
1729 // Due to the way the JS calls are constructed this must be less than the 1738 // Due to the way the JS calls are constructed this must be less than the
1730 // length of a string, i.e. it is always a Smi. We check anyway for security. 1739 // length of a string, i.e. it is always a Smi. We check anyway for security.
1731 CONVERT_SMI_ARG_CHECKED(index, 2); 1740 CONVERT_SMI_ARG_CHECKED(index, 2);
1732 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3); 1741 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 3);
1733 RUNTIME_ASSERT(last_match_info->HasFastElements()); 1742 RUNTIME_ASSERT(last_match_info->HasFastObjectElements());
1734 RUNTIME_ASSERT(index >= 0); 1743 RUNTIME_ASSERT(index >= 0);
1735 RUNTIME_ASSERT(index <= subject->length()); 1744 RUNTIME_ASSERT(index <= subject->length());
1736 isolate->counters()->regexp_entry_runtime()->Increment(); 1745 isolate->counters()->regexp_entry_runtime()->Increment();
1737 Handle<Object> result = RegExpImpl::Exec(regexp, 1746 Handle<Object> result = RegExpImpl::Exec(regexp,
1738 subject, 1747 subject,
1739 index, 1748 index,
1740 last_match_info); 1749 last_match_info);
1741 if (result.is_null()) return Failure::Exception(); 1750 if (result.is_null()) return Failure::Exception();
1742 return *result; 1751 return *result;
1743 } 1752 }
(...skipping 1353 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 3106
3098 // Index of end of last match. 3107 // Index of end of last match.
3099 int prev = 0; 3108 int prev = 0;
3100 3109
3101 // Number of parts added by compiled replacement plus preceeding 3110 // Number of parts added by compiled replacement plus preceeding
3102 // string and possibly suffix after last match. It is possible for 3111 // string and possibly suffix after last match. It is possible for
3103 // all components to use two elements when encoded as two smis. 3112 // all components to use two elements when encoded as two smis.
3104 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2); 3113 const int parts_added_per_loop = 2 * (compiled_replacement.parts() + 2);
3105 bool matched = true; 3114 bool matched = true;
3106 do { 3115 do {
3107 ASSERT(last_match_info_handle->HasFastElements()); 3116 ASSERT(last_match_info_handle->HasFastObjectElements());
3108 // Increase the capacity of the builder before entering local handle-scope, 3117 // Increase the capacity of the builder before entering local handle-scope,
3109 // so its internal buffer can safely allocate a new handle if it grows. 3118 // so its internal buffer can safely allocate a new handle if it grows.
3110 builder.EnsureCapacity(parts_added_per_loop); 3119 builder.EnsureCapacity(parts_added_per_loop);
3111 3120
3112 HandleScope loop_scope(isolate); 3121 HandleScope loop_scope(isolate);
3113 int start, end; 3122 int start, end;
3114 { 3123 {
3115 AssertNoAllocation match_info_array_is_not_in_a_handle; 3124 AssertNoAllocation match_info_array_is_not_in_a_handle;
3116 FixedArray* match_info_array = 3125 FixedArray* match_info_array =
3117 FixedArray::cast(last_match_info_handle->elements()); 3126 FixedArray::cast(last_match_info_handle->elements());
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3194 } 3203 }
3195 } 3204 }
3196 3205
3197 Handle<Object> match = RegExpImpl::Exec(regexp_handle, 3206 Handle<Object> match = RegExpImpl::Exec(regexp_handle,
3198 subject_handle, 3207 subject_handle,
3199 0, 3208 0,
3200 last_match_info_handle); 3209 last_match_info_handle);
3201 if (match.is_null()) return Failure::Exception(); 3210 if (match.is_null()) return Failure::Exception();
3202 if (match->IsNull()) return *subject_handle; 3211 if (match->IsNull()) return *subject_handle;
3203 3212
3204 ASSERT(last_match_info_handle->HasFastElements()); 3213 ASSERT(last_match_info_handle->HasFastObjectElements());
3205 3214
3206 int start, end; 3215 int start, end;
3207 { 3216 {
3208 AssertNoAllocation match_info_array_is_not_in_a_handle; 3217 AssertNoAllocation match_info_array_is_not_in_a_handle;
3209 FixedArray* match_info_array = 3218 FixedArray* match_info_array =
3210 FixedArray::cast(last_match_info_handle->elements()); 3219 FixedArray::cast(last_match_info_handle->elements());
3211 3220
3212 start = RegExpImpl::GetCapture(match_info_array, 0); 3221 start = RegExpImpl::GetCapture(match_info_array, 0);
3213 end = RegExpImpl::GetCapture(match_info_array, 1); 3222 end = RegExpImpl::GetCapture(match_info_array, 1);
3214 } 3223 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
3268 next++; 3277 next++;
3269 if (next > length) break; 3278 if (next > length) break;
3270 } 3279 }
3271 match = RegExpImpl::Exec(regexp_handle, 3280 match = RegExpImpl::Exec(regexp_handle,
3272 subject_handle, 3281 subject_handle,
3273 next, 3282 next,
3274 last_match_info_handle); 3283 last_match_info_handle);
3275 if (match.is_null()) return Failure::Exception(); 3284 if (match.is_null()) return Failure::Exception();
3276 if (match->IsNull()) break; 3285 if (match->IsNull()) break;
3277 3286
3278 ASSERT(last_match_info_handle->HasFastElements()); 3287 ASSERT(last_match_info_handle->HasFastObjectElements());
3279 HandleScope loop_scope(isolate); 3288 HandleScope loop_scope(isolate);
3280 { 3289 {
3281 AssertNoAllocation match_info_array_is_not_in_a_handle; 3290 AssertNoAllocation match_info_array_is_not_in_a_handle;
3282 FixedArray* match_info_array = 3291 FixedArray* match_info_array =
3283 FixedArray::cast(last_match_info_handle->elements()); 3292 FixedArray::cast(last_match_info_handle->elements());
3284 start = RegExpImpl::GetCapture(match_info_array, 0); 3293 start = RegExpImpl::GetCapture(match_info_array, 0);
3285 end = RegExpImpl::GetCapture(match_info_array, 1); 3294 end = RegExpImpl::GetCapture(match_info_array, 1);
3286 } 3295 }
3287 } while (true); 3296 } while (true);
3288 3297
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3338 if (!maybe_flat_replacement->ToObject(&flat_replacement)) { 3347 if (!maybe_flat_replacement->ToObject(&flat_replacement)) {
3339 return maybe_flat_replacement; 3348 return maybe_flat_replacement;
3340 } 3349 }
3341 } 3350 }
3342 replacement = String::cast(flat_replacement); 3351 replacement = String::cast(flat_replacement);
3343 } 3352 }
3344 3353
3345 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1); 3354 CONVERT_ARG_CHECKED(JSRegExp, regexp, 1);
3346 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); 3355 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
3347 3356
3348 ASSERT(last_match_info->HasFastElements()); 3357 ASSERT(last_match_info->HasFastObjectElements());
3349 3358
3350 if (replacement->length() == 0) { 3359 if (replacement->length() == 0) {
3351 if (subject->HasOnlyAsciiChars()) { 3360 if (subject->HasOnlyAsciiChars()) {
3352 return StringReplaceRegExpWithEmptyString<SeqAsciiString>( 3361 return StringReplaceRegExpWithEmptyString<SeqAsciiString>(
3353 isolate, subject, regexp, last_match_info); 3362 isolate, subject, regexp, last_match_info);
3354 } else { 3363 } else {
3355 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>( 3364 return StringReplaceRegExpWithEmptyString<SeqTwoByteString>(
3356 isolate, subject, regexp, last_match_info); 3365 isolate, subject, regexp, last_match_info);
3357 } 3366 }
3358 } 3367 }
(...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after
4003 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) { 4012 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExecMultiple) {
4004 ASSERT(args.length() == 4); 4013 ASSERT(args.length() == 4);
4005 HandleScope handles(isolate); 4014 HandleScope handles(isolate);
4006 4015
4007 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1); 4016 CONVERT_ARG_HANDLE_CHECKED(String, subject, 1);
4008 if (!subject->IsFlat()) FlattenString(subject); 4017 if (!subject->IsFlat()) FlattenString(subject);
4009 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0); 4018 CONVERT_ARG_HANDLE_CHECKED(JSRegExp, regexp, 0);
4010 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2); 4019 CONVERT_ARG_HANDLE_CHECKED(JSArray, last_match_info, 2);
4011 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3); 4020 CONVERT_ARG_HANDLE_CHECKED(JSArray, result_array, 3);
4012 4021
4013 ASSERT(last_match_info->HasFastElements()); 4022 ASSERT(last_match_info->HasFastObjectElements());
4014 ASSERT(regexp->GetFlags().is_global()); 4023 ASSERT(regexp->GetFlags().is_global());
4015 Handle<FixedArray> result_elements; 4024 Handle<FixedArray> result_elements;
4016 if (result_array->HasFastElements()) { 4025 if (result_array->HasFastObjectElements()) {
4017 result_elements = 4026 result_elements =
4018 Handle<FixedArray>(FixedArray::cast(result_array->elements())); 4027 Handle<FixedArray>(FixedArray::cast(result_array->elements()));
4019 } 4028 }
4020 if (result_elements.is_null() || result_elements->length() < 16) { 4029 if (result_elements.is_null() || result_elements->length() < 16) {
4021 result_elements = isolate->factory()->NewFixedArrayWithHoles(16); 4030 result_elements = isolate->factory()->NewFixedArrayWithHoles(16);
4022 } 4031 }
4023 FixedArrayBuilder builder(result_elements); 4032 FixedArrayBuilder builder(result_elements);
4024 4033
4025 if (regexp->TypeTag() == JSRegExp::ATOM) { 4034 if (regexp->TypeTag() == JSRegExp::ATOM) {
4026 Handle<String> pattern( 4035 Handle<String> pattern(
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
4308 if (!receiver->IsGlobalObject()) return value; 4317 if (!receiver->IsGlobalObject()) return value;
4309 value = JSGlobalPropertyCell::cast(value)->value(); 4318 value = JSGlobalPropertyCell::cast(value)->value();
4310 if (!value->IsTheHole()) return value; 4319 if (!value->IsTheHole()) return value;
4311 // If value is the hole do the general lookup. 4320 // If value is the hole do the general lookup.
4312 } 4321 }
4313 } 4322 }
4314 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) { 4323 } else if (FLAG_smi_only_arrays && args.at<Object>(1)->IsSmi()) {
4315 // JSObject without a string key. If the key is a Smi, check for a 4324 // JSObject without a string key. If the key is a Smi, check for a
4316 // definite out-of-bounds access to elements, which is a strong indicator 4325 // definite out-of-bounds access to elements, which is a strong indicator
4317 // that subsequent accesses will also call the runtime. Proactively 4326 // that subsequent accesses will also call the runtime. Proactively
4318 // transition elements to FAST_ELEMENTS to avoid excessive boxing of 4327 // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
4319 // doubles for those future calls in the case that the elements would 4328 // doubles for those future calls in the case that the elements would
4320 // become FAST_DOUBLE_ELEMENTS. 4329 // become FAST_DOUBLE_ELEMENTS.
4321 Handle<JSObject> js_object(args.at<JSObject>(0)); 4330 Handle<JSObject> js_object(args.at<JSObject>(0));
4322 ElementsKind elements_kind = js_object->GetElementsKind(); 4331 ElementsKind elements_kind = js_object->GetElementsKind();
4323 if (elements_kind == FAST_SMI_ONLY_ELEMENTS || 4332 if (IsFastElementsKind(elements_kind) &&
4324 elements_kind == FAST_DOUBLE_ELEMENTS) { 4333 !IsFastObjectElementsKind(elements_kind)) {
4325 FixedArrayBase* elements = js_object->elements(); 4334 FixedArrayBase* elements = js_object->elements();
4326 if (args.at<Smi>(1)->value() >= elements->length()) { 4335 if (args.at<Smi>(1)->value() >= elements->length()) {
4336 if (IsFastHoleyElementsKind(elements_kind)) {
4337 elements_kind = FAST_HOLEY_ELEMENTS;
4338 } else {
4339 elements_kind = FAST_ELEMENTS;
4340 }
4327 MaybeObject* maybe_object = TransitionElements(js_object, 4341 MaybeObject* maybe_object = TransitionElements(js_object,
4328 FAST_ELEMENTS, 4342 elements_kind,
4329 isolate); 4343 isolate);
4330 if (maybe_object->IsFailure()) return maybe_object; 4344 if (maybe_object->IsFailure()) return maybe_object;
4331 } 4345 }
4332 } 4346 }
4333 } 4347 }
4334 } else if (args[0]->IsString() && args[1]->IsSmi()) { 4348 } else if (args[0]->IsString() && args[1]->IsSmi()) {
4335 // Fast case for string indexing using [] with a smi index. 4349 // Fast case for string indexing using [] with a smi index.
4336 HandleScope scope(isolate); 4350 HandleScope scope(isolate);
4337 Handle<String> str = args.at<String>(0); 4351 Handle<String> str = args.at<String>(0);
4338 int index = args.smi_at(1); 4352 int index = args.smi_at(1);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
4488 // of a string using [] notation. We need to support this too in 4502 // of a string using [] notation. We need to support this too in
4489 // JavaScript. 4503 // JavaScript.
4490 // In the case of a String object we just need to redirect the assignment to 4504 // In the case of a String object we just need to redirect the assignment to
4491 // the underlying string if the index is in range. Since the underlying 4505 // the underlying string if the index is in range. Since the underlying
4492 // string does nothing with the assignment then we can ignore such 4506 // string does nothing with the assignment then we can ignore such
4493 // assignments. 4507 // assignments.
4494 if (js_object->IsStringObjectWithCharacterAt(index)) { 4508 if (js_object->IsStringObjectWithCharacterAt(index)) {
4495 return *value; 4509 return *value;
4496 } 4510 }
4497 4511
4512 js_object->ValidateElements();
4498 Handle<Object> result = JSObject::SetElement( 4513 Handle<Object> result = JSObject::SetElement(
4499 js_object, index, value, attr, strict_mode, set_mode); 4514 js_object, index, value, attr, strict_mode, set_mode);
4515 js_object->ValidateElements();
4500 if (result.is_null()) return Failure::Exception(); 4516 if (result.is_null()) return Failure::Exception();
4501 return *value; 4517 return *value;
4502 } 4518 }
4503 4519
4504 if (key->IsString()) { 4520 if (key->IsString()) {
4505 Handle<Object> result; 4521 Handle<Object> result;
4506 if (Handle<String>::cast(key)->AsArrayIndex(&index)) { 4522 if (Handle<String>::cast(key)->AsArrayIndex(&index)) {
4507 result = JSObject::SetElement( 4523 result = JSObject::SetElement(
4508 js_object, index, value, attr, strict_mode, set_mode); 4524 js_object, index, value, attr, strict_mode, set_mode);
4509 } else { 4525 } else {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
4647 value, 4663 value,
4648 attributes, 4664 attributes,
4649 strict_mode); 4665 strict_mode);
4650 } 4666 }
4651 4667
4652 4668
4653 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) { 4669 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsSmiToDouble) {
4654 NoHandleAllocation ha; 4670 NoHandleAllocation ha;
4655 RUNTIME_ASSERT(args.length() == 1); 4671 RUNTIME_ASSERT(args.length() == 1);
4656 Handle<Object> object = args.at<Object>(0); 4672 Handle<Object> object = args.at<Object>(0);
4657 return TransitionElements(object, FAST_DOUBLE_ELEMENTS, isolate); 4673 if (object->IsJSObject()) {
4674 Handle<JSObject> js_object(Handle<JSObject>::cast(object));
4675 ElementsKind new_kind = js_object->HasFastHoleyElements()
4676 ? FAST_HOLEY_DOUBLE_ELEMENTS
4677 : FAST_DOUBLE_ELEMENTS;
4678 return TransitionElements(object, new_kind, isolate);
4679 } else {
4680 return *object;
4681 }
4658 } 4682 }
4659 4683
4660 4684
4661 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) { 4685 RUNTIME_FUNCTION(MaybeObject*, Runtime_TransitionElementsDoubleToObject) {
4662 NoHandleAllocation ha; 4686 NoHandleAllocation ha;
4663 RUNTIME_ASSERT(args.length() == 1); 4687 RUNTIME_ASSERT(args.length() == 1);
4664 Handle<Object> object = args.at<Object>(0); 4688 Handle<Object> object = args.at<Object>(0);
4665 return TransitionElements(object, FAST_ELEMENTS, isolate); 4689 if (object->IsJSObject()) {
4690 Handle<JSObject> js_object(Handle<JSObject>::cast(object));
4691 ElementsKind new_kind = js_object->HasFastHoleyElements()
4692 ? FAST_HOLEY_ELEMENTS
4693 : FAST_ELEMENTS;
4694 return TransitionElements(object, new_kind, isolate);
4695 } else {
4696 return *object;
4697 }
4666 } 4698 }
4667 4699
4668 4700
4669 // Set the native flag on the function. 4701 // Set the native flag on the function.
4670 // This is used to decide if we should transform null and undefined 4702 // This is used to decide if we should transform null and undefined
4671 // into the global object when doing call and apply. 4703 // into the global object when doing call and apply.
4672 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) { 4704 RUNTIME_FUNCTION(MaybeObject*, Runtime_SetNativeFlag) {
4673 NoHandleAllocation ha; 4705 NoHandleAllocation ha;
4674 RUNTIME_ASSERT(args.length() == 1); 4706 RUNTIME_ASSERT(args.length() == 1);
4675 4707
(...skipping 10 matching lines...) Expand all
4686 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { 4718 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
4687 RUNTIME_ASSERT(args.length() == 5); 4719 RUNTIME_ASSERT(args.length() == 5);
4688 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 4720 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
4689 CONVERT_SMI_ARG_CHECKED(store_index, 1); 4721 CONVERT_SMI_ARG_CHECKED(store_index, 1);
4690 Handle<Object> value = args.at<Object>(2); 4722 Handle<Object> value = args.at<Object>(2);
4691 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); 4723 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
4692 CONVERT_SMI_ARG_CHECKED(literal_index, 4); 4724 CONVERT_SMI_ARG_CHECKED(literal_index, 4);
4693 HandleScope scope; 4725 HandleScope scope;
4694 4726
4695 Object* raw_boilerplate_object = literals->get(literal_index); 4727 Object* raw_boilerplate_object = literals->get(literal_index);
4696 Handle<JSArray> boilerplate(JSArray::cast(raw_boilerplate_object)); 4728 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object));
4697 #if DEBUG
4698 ElementsKind elements_kind = object->GetElementsKind(); 4729 ElementsKind elements_kind = object->GetElementsKind();
4699 #endif 4730 ASSERT(IsFastElementsKind(elements_kind));
4700 ASSERT(elements_kind <= FAST_DOUBLE_ELEMENTS);
4701 // Smis should never trigger transitions. 4731 // Smis should never trigger transitions.
4702 ASSERT(!value->IsSmi()); 4732 ASSERT(!value->IsSmi());
4703 4733
4704 if (value->IsNumber()) { 4734 if (value->IsNumber()) {
4705 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); 4735 ASSERT(IsFastSmiElementsKind(elements_kind));
4706 JSObject::TransitionElementsKind(object, FAST_DOUBLE_ELEMENTS); 4736 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
4707 if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), 4737 ? FAST_HOLEY_DOUBLE_ELEMENTS
4708 FAST_DOUBLE_ELEMENTS)) { 4738 : FAST_DOUBLE_ELEMENTS;
4709 JSObject::TransitionElementsKind(boilerplate, FAST_DOUBLE_ELEMENTS); 4739 if (IsMoreGeneralElementsKindTransition(
4740 boilerplate_object->GetElementsKind(),
4741 transitioned_kind)) {
4742 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
4710 } 4743 }
4711 ASSERT(object->GetElementsKind() == FAST_DOUBLE_ELEMENTS); 4744 JSObject::TransitionElementsKind(object, transitioned_kind);
4745 ASSERT(IsFastDoubleElementsKind(object->GetElementsKind()));
4712 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements()); 4746 FixedDoubleArray* double_array = FixedDoubleArray::cast(object->elements());
4713 HeapNumber* number = HeapNumber::cast(*value); 4747 HeapNumber* number = HeapNumber::cast(*value);
4714 double_array->set(store_index, number->Number()); 4748 double_array->set(store_index, number->Number());
4715 } else { 4749 } else {
4716 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS || 4750 ASSERT(IsFastSmiElementsKind(elements_kind) ||
4717 elements_kind == FAST_DOUBLE_ELEMENTS); 4751 IsFastDoubleElementsKind(elements_kind));
4718 JSObject::TransitionElementsKind(object, FAST_ELEMENTS); 4752 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
4719 if (IsMoreGeneralElementsKindTransition(boilerplate->GetElementsKind(), 4753 ? FAST_HOLEY_ELEMENTS
4720 FAST_ELEMENTS)) { 4754 : FAST_ELEMENTS;
4721 JSObject::TransitionElementsKind(boilerplate, FAST_ELEMENTS); 4755 JSObject::TransitionElementsKind(object, transitioned_kind);
4756 if (IsMoreGeneralElementsKindTransition(
4757 boilerplate_object->GetElementsKind(),
4758 transitioned_kind)) {
4759 JSObject::TransitionElementsKind(boilerplate_object, transitioned_kind);
4722 } 4760 }
4723 FixedArray* object_array = FixedArray::cast(object->elements()); 4761 FixedArray* object_array = FixedArray::cast(object->elements());
4724 object_array->set(store_index, *value); 4762 object_array->set(store_index, *value);
4725 } 4763 }
4726 return *object; 4764 return *object;
4727 } 4765 }
4728 4766
4729 4767
4730 // Check whether debugger and is about to step into the callback that is passed 4768 // Check whether debugger and is about to step into the callback that is passed
4731 // to a built-in function such as Array.forEach. 4769 // to a built-in function such as Array.forEach.
(...skipping 1192 matching lines...) Expand 10 before | Expand all | Expand 10 after
5924 new_string, final_length); 5962 new_string, final_length);
5925 return new_string; 5963 return new_string;
5926 } 5964 }
5927 5965
5928 5966
5929 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) { 5967 RUNTIME_FUNCTION(MaybeObject*, Runtime_QuoteJSONStringArray) {
5930 NoHandleAllocation ha; 5968 NoHandleAllocation ha;
5931 ASSERT(args.length() == 1); 5969 ASSERT(args.length() == 1);
5932 CONVERT_ARG_CHECKED(JSArray, array, 0); 5970 CONVERT_ARG_CHECKED(JSArray, array, 0);
5933 5971
5934 if (!array->HasFastElements()) return isolate->heap()->undefined_value(); 5972 if (!array->HasFastObjectElements()) {
5973 return isolate->heap()->undefined_value();
5974 }
5935 FixedArray* elements = FixedArray::cast(array->elements()); 5975 FixedArray* elements = FixedArray::cast(array->elements());
5936 int n = elements->length(); 5976 int n = elements->length();
5937 bool ascii = true; 5977 bool ascii = true;
5938 int total_length = 0; 5978 int total_length = 0;
5939 5979
5940 for (int i = 0; i < n; i++) { 5980 for (int i = 0; i < n; i++) {
5941 Object* elt = elements->get(i); 5981 Object* elt = elements->get(i);
5942 if (!elt->IsString()) return isolate->heap()->undefined_value(); 5982 if (!elt->IsString()) return isolate->heap()->undefined_value();
5943 String* element = String::cast(elt); 5983 String* element = String::cast(elt);
5944 if (!element->IsFlat()) return isolate->heap()->undefined_value(); 5984 if (!element->IsFlat()) return isolate->heap()->undefined_value();
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
6367 // The list indices now contains the end of each part to create. 6407 // The list indices now contains the end of each part to create.
6368 6408
6369 // Create JSArray of substrings separated by separator. 6409 // Create JSArray of substrings separated by separator.
6370 int part_count = indices.length(); 6410 int part_count = indices.length();
6371 6411
6372 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); 6412 Handle<JSArray> result = isolate->factory()->NewJSArray(part_count);
6373 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements(); 6413 MaybeObject* maybe_result = result->EnsureCanContainHeapObjectElements();
6374 if (maybe_result->IsFailure()) return maybe_result; 6414 if (maybe_result->IsFailure()) return maybe_result;
6375 result->set_length(Smi::FromInt(part_count)); 6415 result->set_length(Smi::FromInt(part_count));
6376 6416
6377 ASSERT(result->HasFastElements()); 6417 ASSERT(result->HasFastObjectElements());
6378 6418
6379 if (part_count == 1 && indices.at(0) == subject_length) { 6419 if (part_count == 1 && indices.at(0) == subject_length) {
6380 FixedArray::cast(result->elements())->set(0, *subject); 6420 FixedArray::cast(result->elements())->set(0, *subject);
6381 return *result; 6421 return *result;
6382 } 6422 }
6383 6423
6384 Handle<FixedArray> elements(FixedArray::cast(result->elements())); 6424 Handle<FixedArray> elements(FixedArray::cast(result->elements()));
6385 int part_start = 0; 6425 int part_start = 0;
6386 for (int i = 0; i < part_count; i++) { 6426 for (int i = 0; i < part_count; i++) {
6387 HandleScope local_loop_handle; 6427 HandleScope local_loop_handle;
6388 int part_end = indices.at(i); 6428 int part_end = indices.at(i);
6389 Handle<String> substring = 6429 Handle<String> substring =
6390 isolate->factory()->NewProperSubString(subject, part_start, part_end); 6430 isolate->factory()->NewProperSubString(subject, part_start, part_end);
6391 elements->set(i, *substring); 6431 elements->set(i, *substring);
6392 part_start = part_end + pattern_length; 6432 part_start = part_end + pattern_length;
6393 } 6433 }
6394 6434
6395 if (limit == 0xffffffffu) { 6435 if (limit == 0xffffffffu) {
6396 if (result->HasFastElements()) { 6436 if (result->HasFastObjectElements()) {
6397 StringSplitCache::Enter(isolate->heap(), 6437 StringSplitCache::Enter(isolate->heap(),
6398 isolate->heap()->string_split_cache(), 6438 isolate->heap()->string_split_cache(),
6399 *subject, 6439 *subject,
6400 *pattern, 6440 *pattern,
6401 *elements); 6441 *elements);
6402 } 6442 }
6403 } 6443 }
6404 6444
6405 return *result; 6445 return *result;
6406 } 6446 }
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
6743 int array_length = args.smi_at(1); 6783 int array_length = args.smi_at(1);
6744 CONVERT_ARG_CHECKED(String, special, 2); 6784 CONVERT_ARG_CHECKED(String, special, 2);
6745 6785
6746 // This assumption is used by the slice encoding in one or two smis. 6786 // This assumption is used by the slice encoding in one or two smis.
6747 ASSERT(Smi::kMaxValue >= String::kMaxLength); 6787 ASSERT(Smi::kMaxValue >= String::kMaxLength);
6748 6788
6749 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements(); 6789 MaybeObject* maybe_result = array->EnsureCanContainHeapObjectElements();
6750 if (maybe_result->IsFailure()) return maybe_result; 6790 if (maybe_result->IsFailure()) return maybe_result;
6751 6791
6752 int special_length = special->length(); 6792 int special_length = special->length();
6753 if (!array->HasFastElements()) { 6793 if (!array->HasFastObjectElements()) {
6754 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6794 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6755 } 6795 }
6756 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6796 FixedArray* fixed_array = FixedArray::cast(array->elements());
6757 if (fixed_array->length() < array_length) { 6797 if (fixed_array->length() < array_length) {
6758 array_length = fixed_array->length(); 6798 array_length = fixed_array->length();
6759 } 6799 }
6760 6800
6761 if (array_length == 0) { 6801 if (array_length == 0) {
6762 return isolate->heap()->empty_string(); 6802 return isolate->heap()->empty_string();
6763 } else if (array_length == 1) { 6803 } else if (array_length == 1) {
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
6853 NoHandleAllocation ha; 6893 NoHandleAllocation ha;
6854 ASSERT(args.length() == 3); 6894 ASSERT(args.length() == 3);
6855 CONVERT_ARG_CHECKED(JSArray, array, 0); 6895 CONVERT_ARG_CHECKED(JSArray, array, 0);
6856 if (!args[1]->IsSmi()) { 6896 if (!args[1]->IsSmi()) {
6857 isolate->context()->mark_out_of_memory(); 6897 isolate->context()->mark_out_of_memory();
6858 return Failure::OutOfMemoryException(); 6898 return Failure::OutOfMemoryException();
6859 } 6899 }
6860 int array_length = args.smi_at(1); 6900 int array_length = args.smi_at(1);
6861 CONVERT_ARG_CHECKED(String, separator, 2); 6901 CONVERT_ARG_CHECKED(String, separator, 2);
6862 6902
6863 if (!array->HasFastElements()) { 6903 if (!array->HasFastObjectElements()) {
6864 return isolate->Throw(isolate->heap()->illegal_argument_symbol()); 6904 return isolate->Throw(isolate->heap()->illegal_argument_symbol());
6865 } 6905 }
6866 FixedArray* fixed_array = FixedArray::cast(array->elements()); 6906 FixedArray* fixed_array = FixedArray::cast(array->elements());
6867 if (fixed_array->length() < array_length) { 6907 if (fixed_array->length() < array_length) {
6868 array_length = fixed_array->length(); 6908 array_length = fixed_array->length();
6869 } 6909 }
6870 6910
6871 if (array_length == 0) { 6911 if (array_length == 0) {
6872 return isolate->heap()->empty_string(); 6912 return isolate->heap()->empty_string();
6873 } else if (array_length == 1) { 6913 } else if (array_length == 1) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
6970 } 7010 }
6971 } 7011 }
6972 ASSERT(cursor <= buffer.length()); 7012 ASSERT(cursor <= buffer.length());
6973 } 7013 }
6974 7014
6975 7015
6976 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { 7016 RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) {
6977 NoHandleAllocation ha; 7017 NoHandleAllocation ha;
6978 ASSERT(args.length() == 3); 7018 ASSERT(args.length() == 3);
6979 CONVERT_ARG_CHECKED(JSArray, elements_array, 0); 7019 CONVERT_ARG_CHECKED(JSArray, elements_array, 0);
6980 RUNTIME_ASSERT(elements_array->HasFastElements() || 7020 RUNTIME_ASSERT(elements_array->HasFastSmiOrObjectElements());
6981 elements_array->HasFastSmiOnlyElements());
6982 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); 7021 CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]);
6983 CONVERT_ARG_CHECKED(String, separator, 2); 7022 CONVERT_ARG_CHECKED(String, separator, 2);
6984 // elements_array is fast-mode JSarray of alternating positions 7023 // elements_array is fast-mode JSarray of alternating positions
6985 // (increasing order) and strings. 7024 // (increasing order) and strings.
6986 // array_length is length of original array (used to add separators); 7025 // array_length is length of original array (used to add separators);
6987 // separator is string to put between elements. Assumed to be non-empty. 7026 // separator is string to put between elements. Assumed to be non-empty.
6988 7027
6989 // Find total length of join result. 7028 // Find total length of join result.
6990 int string_length = 0; 7029 int string_length = 0;
6991 bool is_ascii = separator->IsAsciiRepresentation(); 7030 bool is_ascii = separator->IsAsciiRepresentation();
(...skipping 2140 matching lines...) Expand 10 before | Expand all | Expand 10 after
9132 ASSERT(args.length() == 2); 9171 ASSERT(args.length() == 2);
9133 9172
9134 CONVERT_ARG_HANDLE_CHECKED(String, str, 0); 9173 CONVERT_ARG_HANDLE_CHECKED(String, str, 0);
9135 FlattenString(str); 9174 FlattenString(str);
9136 9175
9137 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1); 9176 CONVERT_ARG_HANDLE_CHECKED(JSArray, output, 1);
9138 9177
9139 MaybeObject* maybe_result_array = 9178 MaybeObject* maybe_result_array =
9140 output->EnsureCanContainHeapObjectElements(); 9179 output->EnsureCanContainHeapObjectElements();
9141 if (maybe_result_array->IsFailure()) return maybe_result_array; 9180 if (maybe_result_array->IsFailure()) return maybe_result_array;
9142 RUNTIME_ASSERT(output->HasFastElements()); 9181 RUNTIME_ASSERT(output->HasFastObjectElements());
9143 9182
9144 AssertNoAllocation no_allocation; 9183 AssertNoAllocation no_allocation;
9145 9184
9146 FixedArray* output_array = FixedArray::cast(output->elements()); 9185 FixedArray* output_array = FixedArray::cast(output->elements());
9147 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE); 9186 RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
9148 bool result; 9187 bool result;
9149 String::FlatContent str_content = str->GetFlatContent(); 9188 String::FlatContent str_content = str->GetFlatContent();
9150 if (str_content.IsAscii()) { 9189 if (str_content.IsAscii()) {
9151 result = DateParser::Parse(str_content.ToAsciiVector(), 9190 result = DateParser::Parse(str_content.ToAsciiVector(),
9152 output_array, 9191 output_array,
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
9364 } 9403 }
9365 9404
9366 9405
9367 // Push an object unto an array of objects if it is not already in the 9406 // Push an object unto an array of objects if it is not already in the
9368 // array. Returns true if the element was pushed on the stack and 9407 // array. Returns true if the element was pushed on the stack and
9369 // false otherwise. 9408 // false otherwise.
9370 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { 9409 RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) {
9371 ASSERT(args.length() == 2); 9410 ASSERT(args.length() == 2);
9372 CONVERT_ARG_CHECKED(JSArray, array, 0); 9411 CONVERT_ARG_CHECKED(JSArray, array, 0);
9373 CONVERT_ARG_CHECKED(JSObject, element, 1); 9412 CONVERT_ARG_CHECKED(JSObject, element, 1);
9374 RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); 9413 RUNTIME_ASSERT(array->HasFastSmiOrObjectElements());
9375 int length = Smi::cast(array->length())->value(); 9414 int length = Smi::cast(array->length())->value();
9376 FixedArray* elements = FixedArray::cast(array->elements()); 9415 FixedArray* elements = FixedArray::cast(array->elements());
9377 for (int i = 0; i < length; i++) { 9416 for (int i = 0; i < length; i++) {
9378 if (elements->get(i) == element) return isolate->heap()->false_value(); 9417 if (elements->get(i) == element) return isolate->heap()->false_value();
9379 } 9418 }
9380 Object* obj; 9419 Object* obj;
9381 // Strict not needed. Used for cycle detection in Array join implementation. 9420 // Strict not needed. Used for cycle detection in Array join implementation.
9382 { MaybeObject* maybe_obj = 9421 { MaybeObject* maybe_obj =
9383 array->SetFastElement(length, element, kNonStrictMode, true); 9422 array->SetFastElement(length, element, kNonStrictMode, true);
9384 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 9423 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
9449 } 9488 }
9450 } 9489 }
9451 9490
9452 Handle<JSArray> ToArray() { 9491 Handle<JSArray> ToArray() {
9453 Handle<JSArray> array = isolate_->factory()->NewJSArray(0); 9492 Handle<JSArray> array = isolate_->factory()->NewJSArray(0);
9454 Handle<Object> length = 9493 Handle<Object> length =
9455 isolate_->factory()->NewNumber(static_cast<double>(index_offset_)); 9494 isolate_->factory()->NewNumber(static_cast<double>(index_offset_));
9456 Handle<Map> map; 9495 Handle<Map> map;
9457 if (fast_elements_) { 9496 if (fast_elements_) {
9458 map = isolate_->factory()->GetElementsTransitionMap(array, 9497 map = isolate_->factory()->GetElementsTransitionMap(array,
9459 FAST_ELEMENTS); 9498 FAST_HOLEY_ELEMENTS);
9460 } else { 9499 } else {
9461 map = isolate_->factory()->GetElementsTransitionMap(array, 9500 map = isolate_->factory()->GetElementsTransitionMap(array,
9462 DICTIONARY_ELEMENTS); 9501 DICTIONARY_ELEMENTS);
9463 } 9502 }
9464 array->set_map(*map); 9503 array->set_map(*map);
9465 array->set_length(*length); 9504 array->set_length(*length);
9466 array->set_elements(*storage_); 9505 array->set_elements(*storage_);
9467 return array; 9506 return array;
9468 } 9507 }
9469 9508
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
9508 // JSObject::kMaxElementCount. 9547 // JSObject::kMaxElementCount.
9509 uint32_t index_offset_; 9548 uint32_t index_offset_;
9510 bool fast_elements_; 9549 bool fast_elements_;
9511 }; 9550 };
9512 9551
9513 9552
9514 static uint32_t EstimateElementCount(Handle<JSArray> array) { 9553 static uint32_t EstimateElementCount(Handle<JSArray> array) {
9515 uint32_t length = static_cast<uint32_t>(array->length()->Number()); 9554 uint32_t length = static_cast<uint32_t>(array->length()->Number());
9516 int element_count = 0; 9555 int element_count = 0;
9517 switch (array->GetElementsKind()) { 9556 switch (array->GetElementsKind()) {
9518 case FAST_SMI_ONLY_ELEMENTS: 9557 case FAST_SMI_ELEMENTS:
9519 case FAST_ELEMENTS: { 9558 case FAST_HOLEY_SMI_ELEMENTS:
9559 case FAST_ELEMENTS:
9560 case FAST_HOLEY_ELEMENTS: {
9520 // Fast elements can't have lengths that are not representable by 9561 // Fast elements can't have lengths that are not representable by
9521 // a 32-bit signed integer. 9562 // a 32-bit signed integer.
9522 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0); 9563 ASSERT(static_cast<int32_t>(FixedArray::kMaxLength) >= 0);
9523 int fast_length = static_cast<int>(length); 9564 int fast_length = static_cast<int>(length);
9524 Handle<FixedArray> elements(FixedArray::cast(array->elements())); 9565 Handle<FixedArray> elements(FixedArray::cast(array->elements()));
9525 for (int i = 0; i < fast_length; i++) { 9566 for (int i = 0; i < fast_length; i++) {
9526 if (!elements->get(i)->IsTheHole()) element_count++; 9567 if (!elements->get(i)->IsTheHole()) element_count++;
9527 } 9568 }
9528 break; 9569 break;
9529 } 9570 }
9530 case FAST_DOUBLE_ELEMENTS: 9571 case FAST_DOUBLE_ELEMENTS:
9572 case FAST_HOLEY_DOUBLE_ELEMENTS:
9531 // TODO(1810): Decide if it's worthwhile to implement this. 9573 // TODO(1810): Decide if it's worthwhile to implement this.
9532 UNREACHABLE(); 9574 UNREACHABLE();
9533 break; 9575 break;
9534 case DICTIONARY_ELEMENTS: { 9576 case DICTIONARY_ELEMENTS: {
9535 Handle<SeededNumberDictionary> dictionary( 9577 Handle<SeededNumberDictionary> dictionary(
9536 SeededNumberDictionary::cast(array->elements())); 9578 SeededNumberDictionary::cast(array->elements()));
9537 int capacity = dictionary->Capacity(); 9579 int capacity = dictionary->Capacity();
9538 for (int i = 0; i < capacity; i++) { 9580 for (int i = 0; i < capacity; i++) {
9539 Handle<Object> key(dictionary->KeyAt(i)); 9581 Handle<Object> key(dictionary->KeyAt(i));
9540 if (dictionary->IsKey(*key)) { 9582 if (dictionary->IsKey(*key)) {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
9611 uint32_t b = *bp; 9653 uint32_t b = *bp;
9612 return (a == b) ? 0 : (a < b) ? -1 : 1; 9654 return (a == b) ? 0 : (a < b) ? -1 : 1;
9613 } 9655 }
9614 9656
9615 9657
9616 static void CollectElementIndices(Handle<JSObject> object, 9658 static void CollectElementIndices(Handle<JSObject> object,
9617 uint32_t range, 9659 uint32_t range,
9618 List<uint32_t>* indices) { 9660 List<uint32_t>* indices) {
9619 ElementsKind kind = object->GetElementsKind(); 9661 ElementsKind kind = object->GetElementsKind();
9620 switch (kind) { 9662 switch (kind) {
9621 case FAST_SMI_ONLY_ELEMENTS: 9663 case FAST_SMI_ELEMENTS:
9622 case FAST_ELEMENTS: { 9664 case FAST_ELEMENTS:
9665 case FAST_HOLEY_SMI_ELEMENTS:
9666 case FAST_HOLEY_ELEMENTS: {
9623 Handle<FixedArray> elements(FixedArray::cast(object->elements())); 9667 Handle<FixedArray> elements(FixedArray::cast(object->elements()));
9624 uint32_t length = static_cast<uint32_t>(elements->length()); 9668 uint32_t length = static_cast<uint32_t>(elements->length());
9625 if (range < length) length = range; 9669 if (range < length) length = range;
9626 for (uint32_t i = 0; i < length; i++) { 9670 for (uint32_t i = 0; i < length; i++) {
9627 if (!elements->get(i)->IsTheHole()) { 9671 if (!elements->get(i)->IsTheHole()) {
9628 indices->Add(i); 9672 indices->Add(i);
9629 } 9673 }
9630 } 9674 }
9631 break; 9675 break;
9632 } 9676 }
9677 case FAST_HOLEY_DOUBLE_ELEMENTS:
9633 case FAST_DOUBLE_ELEMENTS: { 9678 case FAST_DOUBLE_ELEMENTS: {
9634 // TODO(1810): Decide if it's worthwhile to implement this. 9679 // TODO(1810): Decide if it's worthwhile to implement this.
9635 UNREACHABLE(); 9680 UNREACHABLE();
9636 break; 9681 break;
9637 } 9682 }
9638 case DICTIONARY_ELEMENTS: { 9683 case DICTIONARY_ELEMENTS: {
9639 Handle<SeededNumberDictionary> dict( 9684 Handle<SeededNumberDictionary> dict(
9640 SeededNumberDictionary::cast(object->elements())); 9685 SeededNumberDictionary::cast(object->elements()));
9641 uint32_t capacity = dict->Capacity(); 9686 uint32_t capacity = dict->Capacity();
9642 for (uint32_t j = 0; j < capacity; j++) { 9687 for (uint32_t j = 0; j < capacity; j++) {
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
9737 * with the element index and the element's value. 9782 * with the element index and the element's value.
9738 * Afterwards it increments the base-index of the visitor by the array 9783 * Afterwards it increments the base-index of the visitor by the array
9739 * length. 9784 * length.
9740 * Returns false if any access threw an exception, otherwise true. 9785 * Returns false if any access threw an exception, otherwise true.
9741 */ 9786 */
9742 static bool IterateElements(Isolate* isolate, 9787 static bool IterateElements(Isolate* isolate,
9743 Handle<JSArray> receiver, 9788 Handle<JSArray> receiver,
9744 ArrayConcatVisitor* visitor) { 9789 ArrayConcatVisitor* visitor) {
9745 uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); 9790 uint32_t length = static_cast<uint32_t>(receiver->length()->Number());
9746 switch (receiver->GetElementsKind()) { 9791 switch (receiver->GetElementsKind()) {
9747 case FAST_SMI_ONLY_ELEMENTS: 9792 case FAST_SMI_ELEMENTS:
9748 case FAST_ELEMENTS: { 9793 case FAST_ELEMENTS:
9794 case FAST_HOLEY_SMI_ELEMENTS:
9795 case FAST_HOLEY_ELEMENTS: {
9749 // Run through the elements FixedArray and use HasElement and GetElement 9796 // Run through the elements FixedArray and use HasElement and GetElement
9750 // to check the prototype for missing elements. 9797 // to check the prototype for missing elements.
9751 Handle<FixedArray> elements(FixedArray::cast(receiver->elements())); 9798 Handle<FixedArray> elements(FixedArray::cast(receiver->elements()));
9752 int fast_length = static_cast<int>(length); 9799 int fast_length = static_cast<int>(length);
9753 ASSERT(fast_length <= elements->length()); 9800 ASSERT(fast_length <= elements->length());
9754 for (int j = 0; j < fast_length; j++) { 9801 for (int j = 0; j < fast_length; j++) {
9755 HandleScope loop_scope(isolate); 9802 HandleScope loop_scope(isolate);
9756 Handle<Object> element_value(elements->get(j), isolate); 9803 Handle<Object> element_value(elements->get(j), isolate);
9757 if (!element_value->IsTheHole()) { 9804 if (!element_value->IsTheHole()) {
9758 visitor->visit(j, element_value); 9805 visitor->visit(j, element_value);
9759 } else if (receiver->HasElement(j)) { 9806 } else if (receiver->HasElement(j)) {
9760 // Call GetElement on receiver, not its prototype, or getters won't 9807 // Call GetElement on receiver, not its prototype, or getters won't
9761 // have the correct receiver. 9808 // have the correct receiver.
9762 element_value = Object::GetElement(receiver, j); 9809 element_value = Object::GetElement(receiver, j);
9763 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false); 9810 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, element_value, false);
9764 visitor->visit(j, element_value); 9811 visitor->visit(j, element_value);
9765 } 9812 }
9766 } 9813 }
9767 break; 9814 break;
9768 } 9815 }
9816 case FAST_HOLEY_DOUBLE_ELEMENTS:
9769 case FAST_DOUBLE_ELEMENTS: { 9817 case FAST_DOUBLE_ELEMENTS: {
9770 // TODO(1810): Decide if it's worthwhile to implement this. 9818 // TODO(1810): Decide if it's worthwhile to implement this.
9771 UNREACHABLE(); 9819 UNREACHABLE();
9772 break; 9820 break;
9773 } 9821 }
9774 case DICTIONARY_ELEMENTS: { 9822 case DICTIONARY_ELEMENTS: {
9775 Handle<SeededNumberDictionary> dict(receiver->element_dictionary()); 9823 Handle<SeededNumberDictionary> dict(receiver->element_dictionary());
9776 List<uint32_t> indices(dict->Capacity() / 2); 9824 List<uint32_t> indices(dict->Capacity() / 2);
9777 // Collect all indices in the object and the prototypes less 9825 // Collect all indices in the object and the prototypes less
9778 // than length. This might introduce duplicates in the indices list. 9826 // than length. This might introduce duplicates in the indices list.
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
9856 * See ECMAScript 262, 15.4.4.4. 9904 * See ECMAScript 262, 15.4.4.4.
9857 * TODO(581): Fix non-compliance for very large concatenations and update to 9905 * TODO(581): Fix non-compliance for very large concatenations and update to
9858 * following the ECMAScript 5 specification. 9906 * following the ECMAScript 5 specification.
9859 */ 9907 */
9860 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) { 9908 RUNTIME_FUNCTION(MaybeObject*, Runtime_ArrayConcat) {
9861 ASSERT(args.length() == 1); 9909 ASSERT(args.length() == 1);
9862 HandleScope handle_scope(isolate); 9910 HandleScope handle_scope(isolate);
9863 9911
9864 CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0); 9912 CONVERT_ARG_HANDLE_CHECKED(JSArray, arguments, 0);
9865 int argument_count = static_cast<int>(arguments->length()->Number()); 9913 int argument_count = static_cast<int>(arguments->length()->Number());
9866 RUNTIME_ASSERT(arguments->HasFastElements()); 9914 RUNTIME_ASSERT(arguments->HasFastObjectElements());
9867 Handle<FixedArray> elements(FixedArray::cast(arguments->elements())); 9915 Handle<FixedArray> elements(FixedArray::cast(arguments->elements()));
9868 9916
9869 // Pass 1: estimate the length and number of elements of the result. 9917 // Pass 1: estimate the length and number of elements of the result.
9870 // The actual length can be larger if any of the arguments have getters 9918 // The actual length can be larger if any of the arguments have getters
9871 // that mutate other arguments (but will otherwise be precise). 9919 // that mutate other arguments (but will otherwise be precise).
9872 // The number of elements is precise if there are no inherited elements. 9920 // The number of elements is precise if there are no inherited elements.
9873 9921
9874 uint32_t estimate_result_length = 0; 9922 uint32_t estimate_result_length = 0;
9875 uint32_t estimate_nof_elements = 0; 9923 uint32_t estimate_nof_elements = 0;
9876 { 9924 {
9877 for (int i = 0; i < argument_count; i++) { 9925 for (int i = 0; i < argument_count; i++) {
9878 HandleScope loop_scope; 9926 HandleScope loop_scope;
9879 Handle<Object> obj(elements->get(i)); 9927 Handle<Object> obj(elements->get(i));
9880 uint32_t length_estimate; 9928 uint32_t length_estimate;
9881 uint32_t element_estimate; 9929 uint32_t element_estimate;
9882 if (obj->IsJSArray()) { 9930 if (obj->IsJSArray()) {
9883 Handle<JSArray> array(Handle<JSArray>::cast(obj)); 9931 Handle<JSArray> array(Handle<JSArray>::cast(obj));
9884 // TODO(1810): Find out if it's worthwhile to properly support 9932 // TODO(1810): Find out if it's worthwhile to properly support
9885 // arbitrary ElementsKinds. For now, pessimistically transition to 9933 // arbitrary ElementsKinds. For now, pessimistically transition to
9886 // FAST_ELEMENTS. 9934 // FAST_*_ELEMENTS.
9887 if (array->HasFastDoubleElements()) { 9935 if (array->HasFastDoubleElements()) {
9936 ElementsKind to_kind = FAST_ELEMENTS;
9937 if (array->HasFastHoleyElements()) {
9938 to_kind = FAST_HOLEY_ELEMENTS;
9939 }
9888 array = Handle<JSArray>::cast( 9940 array = Handle<JSArray>::cast(
9889 JSObject::TransitionElementsKind(array, FAST_ELEMENTS)); 9941 JSObject::TransitionElementsKind(array, to_kind));
9890 } 9942 }
9891 length_estimate = 9943 length_estimate =
9892 static_cast<uint32_t>(array->length()->Number()); 9944 static_cast<uint32_t>(array->length()->Number());
9893 element_estimate = 9945 element_estimate =
9894 EstimateElementCount(array); 9946 EstimateElementCount(array);
9895 } else { 9947 } else {
9896 length_estimate = 1; 9948 length_estimate = 1;
9897 element_estimate = 1; 9949 element_estimate = 1;
9898 } 9950 }
9899 // Avoid overflows by capping at kMaxElementCount. 9951 // Avoid overflows by capping at kMaxElementCount.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
9976 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]); 10028 CONVERT_NUMBER_CHECKED(uint32_t, limit, Uint32, args[1]);
9977 return object->PrepareElementsForSort(limit); 10029 return object->PrepareElementsForSort(limit);
9978 } 10030 }
9979 10031
9980 10032
9981 // Move contents of argument 0 (an array) to argument 1 (an array) 10033 // Move contents of argument 0 (an array) to argument 1 (an array)
9982 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { 10034 RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) {
9983 ASSERT(args.length() == 2); 10035 ASSERT(args.length() == 2);
9984 CONVERT_ARG_CHECKED(JSArray, from, 0); 10036 CONVERT_ARG_CHECKED(JSArray, from, 0);
9985 CONVERT_ARG_CHECKED(JSArray, to, 1); 10037 CONVERT_ARG_CHECKED(JSArray, to, 1);
10038 from->ValidateElements();
10039 to->ValidateElements();
9986 FixedArrayBase* new_elements = from->elements(); 10040 FixedArrayBase* new_elements = from->elements();
10041 ElementsKind from_kind = from->GetElementsKind();
9987 MaybeObject* maybe_new_map; 10042 MaybeObject* maybe_new_map;
9988 ElementsKind elements_kind; 10043 maybe_new_map = to->GetElementsTransitionMap(isolate, from_kind);
9989 if (new_elements->map() == isolate->heap()->fixed_array_map() ||
9990 new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
9991 elements_kind = FAST_ELEMENTS;
9992 } else if (new_elements->map() ==
9993 isolate->heap()->fixed_double_array_map()) {
9994 elements_kind = FAST_DOUBLE_ELEMENTS;
9995 } else {
9996 elements_kind = DICTIONARY_ELEMENTS;
9997 }
9998 maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind);
9999 Object* new_map; 10044 Object* new_map;
10000 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 10045 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
10001 to->set_map(Map::cast(new_map)); 10046 to->set_map_and_elements(Map::cast(new_map), new_elements);
10002 to->set_elements(new_elements);
10003 to->set_length(from->length()); 10047 to->set_length(from->length());
10004 Object* obj; 10048 Object* obj;
10005 { MaybeObject* maybe_obj = from->ResetElements(); 10049 { MaybeObject* maybe_obj = from->ResetElements();
10006 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10050 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10007 } 10051 }
10008 from->set_length(Smi::FromInt(0)); 10052 from->set_length(Smi::FromInt(0));
10053 to->ValidateElements();
10009 return to; 10054 return to;
10010 } 10055 }
10011 10056
10012 10057
10013 // How many elements does this object/array have? 10058 // How many elements does this object/array have?
10014 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) { 10059 RUNTIME_FUNCTION(MaybeObject*, Runtime_EstimateNumberOfElements) {
10015 ASSERT(args.length() == 1); 10060 ASSERT(args.length() == 1);
10016 CONVERT_ARG_CHECKED(JSObject, object, 0); 10061 CONVERT_ARG_CHECKED(JSObject, object, 0);
10017 HeapObject* elements = object->elements(); 10062 HeapObject* elements = object->elements();
10018 if (elements->IsDictionary()) { 10063 if (elements->IsDictionary()) {
(...skipping 29 matching lines...) Expand all
10048 for (int i = 0; i < keys_length; i++) { 10093 for (int i = 0; i < keys_length; i++) {
10049 Object* key = keys->get(i); 10094 Object* key = keys->get(i);
10050 uint32_t index = 0; 10095 uint32_t index = 0;
10051 if (!key->ToArrayIndex(&index) || index >= length) { 10096 if (!key->ToArrayIndex(&index) || index >= length) {
10052 // Zap invalid keys. 10097 // Zap invalid keys.
10053 keys->set_undefined(i); 10098 keys->set_undefined(i);
10054 } 10099 }
10055 } 10100 }
10056 return *isolate->factory()->NewJSArrayWithElements(keys); 10101 return *isolate->factory()->NewJSArrayWithElements(keys);
10057 } else { 10102 } else {
10058 ASSERT(array->HasFastElements() || 10103 ASSERT(array->HasFastSmiOrObjectElements() ||
10059 array->HasFastSmiOnlyElements() ||
10060 array->HasFastDoubleElements()); 10104 array->HasFastDoubleElements());
10061 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); 10105 Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2);
10062 // -1 means start of array. 10106 // -1 means start of array.
10063 single_interval->set(0, Smi::FromInt(-1)); 10107 single_interval->set(0, Smi::FromInt(-1));
10064 FixedArrayBase* elements = FixedArrayBase::cast(array->elements()); 10108 FixedArrayBase* elements = FixedArrayBase::cast(array->elements());
10065 uint32_t actual_length = 10109 uint32_t actual_length =
10066 static_cast<uint32_t>(elements->length()); 10110 static_cast<uint32_t>(elements->length());
10067 uint32_t min_length = actual_length < length ? actual_length : length; 10111 uint32_t min_length = actual_length < length ? actual_length : length;
10068 Handle<Object> length_object = 10112 Handle<Object> length_object =
10069 isolate->factory()->NewNumber(static_cast<double>(min_length)); 10113 isolate->factory()->NewNumber(static_cast<double>(min_length));
(...skipping 3294 matching lines...) Expand 10 before | Expand all | Expand 10 after
13364 return NULL; 13408 return NULL;
13365 } 13409 }
13366 13410
13367 13411
13368 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \ 13412 #define ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(Name) \
13369 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \ 13413 RUNTIME_FUNCTION(MaybeObject*, Runtime_Has##Name) { \
13370 CONVERT_ARG_CHECKED(JSObject, obj, 0); \ 13414 CONVERT_ARG_CHECKED(JSObject, obj, 0); \
13371 return isolate->heap()->ToBoolean(obj->Has##Name()); \ 13415 return isolate->heap()->ToBoolean(obj->Has##Name()); \
13372 } 13416 }
13373 13417
13374 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements) 13418 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiElements)
13375 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) 13419 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastObjectElements)
13420 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOrObjectElements)
13376 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) 13421 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements)
13422 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastHoleyElements)
13377 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) 13423 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements)
13378 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements) 13424 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalPixelElements)
13379 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements) 13425 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalArrayElements)
13380 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements) 13426 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalByteElements)
13381 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements) 13427 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedByteElements)
13382 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements) 13428 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalShortElements)
13383 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements) 13429 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedShortElements)
13384 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements) 13430 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalIntElements)
13385 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements) 13431 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalUnsignedIntElements)
13386 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements) 13432 ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(ExternalFloatElements)
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
13475 // Handle last resort GC and make sure to allow future allocations 13521 // Handle last resort GC and make sure to allow future allocations
13476 // to grow the heap without causing GCs (if possible). 13522 // to grow the heap without causing GCs (if possible).
13477 isolate->counters()->gc_last_resort_from_js()->Increment(); 13523 isolate->counters()->gc_last_resort_from_js()->Increment();
13478 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13524 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13479 "Runtime::PerformGC"); 13525 "Runtime::PerformGC");
13480 } 13526 }
13481 } 13527 }
13482 13528
13483 13529
13484 } } // namespace v8::internal 13530 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/string-stream.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698