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

Side by Side Diff: src/runtime.cc

Issue 8258015: Support array literals with FAST_DOUBLE_ELEMENTS ElementsKind. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: remove regressions Created 9 years, 2 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
OLDNEW
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 414 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 static const int kSmiOnlyLiteralMinimumLength = 1024; 425 static const int kSmiOnlyLiteralMinimumLength = 1024;
426 426
427 427
428 static Handle<Object> CreateArrayLiteralBoilerplate( 428 static Handle<Object> CreateArrayLiteralBoilerplate(
429 Isolate* isolate, 429 Isolate* isolate,
430 Handle<FixedArray> literals, 430 Handle<FixedArray> literals,
431 Handle<FixedArray> elements) { 431 Handle<FixedArray> elements) {
432 // Create the JSArray. 432 // Create the JSArray.
433 Handle<JSFunction> constructor( 433 Handle<JSFunction> constructor(
434 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); 434 JSFunction::GlobalContextFromLiterals(*literals)->array_function());
435 Handle<Object> object = isolate->factory()->NewJSObject(constructor); 435 Handle<JSArray> object =
436 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor));
436 437
437 if (elements->length() > kSmiOnlyLiteralMinimumLength) { 438 ElementsKind constant_elements_kind =
438 Handle<Map> smi_array_map = isolate->factory()->GetElementsTransitionMap( 439 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
439 Handle<JSObject>::cast(object), 440 Handle<FixedArrayBase> constant_elements_values(
440 FAST_SMI_ONLY_ELEMENTS); 441 FixedArrayBase::cast(elements->get(1)));
441 HeapObject::cast(*object)->set_map(*smi_array_map); 442
443 ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS ||
444 constant_elements_kind == FAST_SMI_ONLY_ELEMENTS);
445 bool allow_literal_kind_transition = FLAG_smi_only_arrays &&
446 constant_elements_kind > object->GetElementsKind();
447
448 if (!FLAG_smi_only_arrays &&
449 constant_elements_values->length() > kSmiOnlyLiteralMinimumLength &&
450 constant_elements_kind != object->GetElementsKind()) {
451 allow_literal_kind_transition = true;
442 } 452 }
443 453
444 const bool is_cow = 454 // If the ElementKinds of the constant values of the array literal are less
445 (elements->map() == isolate->heap()->fixed_cow_array_map()); 455 // specific that the ElementsKind of the boilerplate array object, change the
446 Handle<FixedArray> copied_elements = 456 // boilerplate array object's map to reflect that kind.
447 is_cow ? elements : isolate->factory()->CopyFixedArray(elements); 457 if (allow_literal_kind_transition) {
458 Handle<Map> smi_array_map = isolate->factory()->GetElementsTransitionMap(
459 object,
460 constant_elements_kind);
461 object->set_map(*smi_array_map);
462 }
448 463
449 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); 464 Handle<FixedArrayBase> copied_elements_values;
450 bool has_non_smi = false; 465 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
451 if (is_cow) { 466 ASSERT(FLAG_smi_only_arrays);
452 // Copy-on-write arrays must be shallow (and simple). 467 copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
453 for (int i = 0; i < content->length(); i++) { 468 Handle<FixedDoubleArray>::cast(constant_elements_values));
454 Object* current = content->get(i); 469 } else {
455 ASSERT(!current->IsFixedArray()); 470 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS ||
456 if (!current->IsSmi() && !current->IsTheHole()) { 471 constant_elements_kind == FAST_ELEMENTS);
457 has_non_smi = true; 472 const bool is_cow =
473 (constant_elements_values->map() ==
474 isolate->heap()->fixed_cow_array_map());
475 if (is_cow) {
476 copied_elements_values = constant_elements_values;
477 #if DEBUG
478 Handle<FixedArray> fixed_array_values =
479 Handle<FixedArray>::cast(copied_elements_values);
480 for (int i = 0; i < fixed_array_values->length(); i++) {
481 ASSERT(!fixed_array_values->get(i)->IsFixedArray());
458 } 482 }
459 }
460 #if DEBUG
461 for (int i = 0; i < content->length(); i++) {
462 ASSERT(!content->get(i)->IsFixedArray());
463 }
464 #endif 483 #endif
465 } else { 484 } else {
466 for (int i = 0; i < content->length(); i++) { 485 Handle<FixedArray> fixed_array_values =
467 Object* current = content->get(i); 486 Handle<FixedArray>::cast(constant_elements_values);
468 if (current->IsFixedArray()) { 487 Handle<FixedArray> fixed_array_values_copy =
469 // The value contains the constant_properties of a 488 isolate->factory()->CopyFixedArray(fixed_array_values);
470 // simple object or array literal. 489 copied_elements_values = fixed_array_values_copy;
471 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); 490 for (int i = 0; i < fixed_array_values->length(); i++) {
472 Handle<Object> result = 491 Object* current = fixed_array_values->get(i);
473 CreateLiteralBoilerplate(isolate, literals, fa); 492 if (current->IsFixedArray()) {
474 if (result.is_null()) return result; 493 // The value contains the constant_properties of a
475 content->set(i, *result); 494 // simple object or array literal.
476 has_non_smi = true; 495 Handle<FixedArray> fa(FixedArray::cast(fixed_array_values->get(i)));
477 } else { 496 Handle<Object> result =
478 if (!current->IsSmi() && !current->IsTheHole()) { 497 CreateLiteralBoilerplate(isolate, literals, fa);
479 has_non_smi = true; 498 if (result.is_null()) return result;
499 fixed_array_values_copy->set(i, *result);
480 } 500 }
481 } 501 }
482 } 502 }
483 } 503 }
484 504 object->set_elements(*copied_elements_values);
485 // Set the elements. 505 object->set_length(Smi::FromInt(copied_elements_values->length()));
486 Handle<JSArray> js_object(Handle<JSArray>::cast(object));
487 isolate->factory()->SetContent(js_object, content);
488
489 if (has_non_smi && js_object->HasFastSmiOnlyElements()) {
490 isolate->factory()->EnsureCanContainNonSmiElements(js_object);
491 }
492
493 return object; 506 return object;
494 } 507 }
495 508
496 509
497 static Handle<Object> CreateLiteralBoilerplate( 510 static Handle<Object> CreateLiteralBoilerplate(
498 Isolate* isolate, 511 Isolate* isolate,
499 Handle<FixedArray> literals, 512 Handle<FixedArray> literals,
500 Handle<FixedArray> array) { 513 Handle<FixedArray> array) {
501 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 514 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
502 const bool kHasNoFunctionLiteral = false; 515 const bool kHasNoFunctionLiteral = false;
(...skipping 1153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1656 ASSERT(args.length() == 2); 1669 ASSERT(args.length() == 2);
1657 CONVERT_ARG_CHECKED(JSObject, object, 0); 1670 CONVERT_ARG_CHECKED(JSObject, object, 0);
1658 CONVERT_SMI_ARG_CHECKED(properties, 1); 1671 CONVERT_SMI_ARG_CHECKED(properties, 1);
1659 if (object->HasFastProperties()) { 1672 if (object->HasFastProperties()) {
1660 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties); 1673 NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties);
1661 } 1674 }
1662 return *object; 1675 return *object;
1663 } 1676 }
1664 1677
1665 1678
1666 RUNTIME_FUNCTION(MaybeObject*, Runtime_NonSmiElementStored) {
1667 ASSERT(args.length() == 1);
1668 CONVERT_ARG_CHECKED(JSObject, object, 0);
1669 if (object->HasFastSmiOnlyElements()) {
1670 MaybeObject* maybe_map = object->GetElementsTransitionMap(FAST_ELEMENTS);
1671 Map* map;
1672 if (!maybe_map->To<Map>(&map)) return maybe_map;
1673 object->set_map(Map::cast(map));
1674 }
1675 return *object;
1676 }
1677
1678
1679 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) { 1679 RUNTIME_FUNCTION(MaybeObject*, Runtime_RegExpExec) {
1680 HandleScope scope(isolate); 1680 HandleScope scope(isolate);
1681 ASSERT(args.length() == 4); 1681 ASSERT(args.length() == 4);
1682 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0); 1682 CONVERT_ARG_CHECKED(JSRegExp, regexp, 0);
1683 CONVERT_ARG_CHECKED(String, subject, 1); 1683 CONVERT_ARG_CHECKED(String, subject, 1);
1684 // Due to the way the JS calls are constructed this must be less than the 1684 // Due to the way the JS calls are constructed this must be less than the
1685 // length of a string, i.e. it is always a Smi. We check anyway for security. 1685 // length of a string, i.e. it is always a Smi. We check anyway for security.
1686 CONVERT_SMI_ARG_CHECKED(index, 2); 1686 CONVERT_SMI_ARG_CHECKED(index, 2);
1687 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3); 1687 CONVERT_ARG_CHECKED(JSArray, last_match_info, 3);
1688 RUNTIME_ASSERT(last_match_info->HasFastElements()); 1688 RUNTIME_ASSERT(last_match_info->HasFastElements());
(...skipping 6039 matching lines...) Expand 10 before | Expand all | Expand 10 after
7728 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) { 7728 RUNTIME_FUNCTION(MaybeObject*, Runtime_DateYMDFromTime) {
7729 NoHandleAllocation ha; 7729 NoHandleAllocation ha;
7730 ASSERT(args.length() == 2); 7730 ASSERT(args.length() == 2);
7731 7731
7732 CONVERT_DOUBLE_ARG_CHECKED(t, 0); 7732 CONVERT_DOUBLE_ARG_CHECKED(t, 0);
7733 CONVERT_CHECKED(JSArray, res_array, args[1]); 7733 CONVERT_CHECKED(JSArray, res_array, args[1]);
7734 7734
7735 int year, month, day; 7735 int year, month, day;
7736 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day); 7736 DateYMDFromTime(static_cast<int>(floor(t / 86400000)), year, month, day);
7737 7737
7738 RUNTIME_ASSERT(res_array->elements()->map() == 7738 FixedArrayBase* elms_base = FixedArrayBase::cast(res_array->elements());
7739 isolate->heap()->fixed_array_map()); 7739 RUNTIME_ASSERT(elms_base->length() == 3);
7740 FixedArray* elms = FixedArray::cast(res_array->elements()); 7740 RUNTIME_ASSERT(res_array->GetElementsKind() <= FAST_DOUBLE_ELEMENTS);
7741 RUNTIME_ASSERT(elms->length() == 3);
7742 7741
7743 elms->set(0, Smi::FromInt(year)); 7742 if (res_array->HasFastDoubleElements()) {
7744 elms->set(1, Smi::FromInt(month)); 7743 FixedDoubleArray* elms = FixedDoubleArray::cast(res_array->elements());
7745 elms->set(2, Smi::FromInt(day)); 7744 elms->set(0, year);
7745 elms->set(1, month);
7746 elms->set(2, day);
7747 } else {
7748 FixedArray* elms = FixedArray::cast(res_array->elements());
7749 elms->set(0, Smi::FromInt(year));
7750 elms->set(1, Smi::FromInt(month));
7751 elms->set(2, Smi::FromInt(day));
7752 }
7746 7753
7747 return isolate->heap()->undefined_value(); 7754 return isolate->heap()->undefined_value();
7748 } 7755 }
7749 7756
7750 7757
7751 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) { 7758 RUNTIME_FUNCTION(MaybeObject*, Runtime_NewArgumentsFast) {
7752 HandleScope scope(isolate); 7759 HandleScope scope(isolate);
7753 ASSERT(args.length() == 3); 7760 ASSERT(args.length() == 3);
7754 7761
7755 Handle<JSFunction> callee = args.at<JSFunction>(0); 7762 Handle<JSFunction> callee = args.at<JSFunction>(0);
(...skipping 5655 matching lines...) Expand 10 before | Expand all | Expand 10 after
13411 } else { 13418 } else {
13412 // Handle last resort GC and make sure to allow future allocations 13419 // Handle last resort GC and make sure to allow future allocations
13413 // to grow the heap without causing GCs (if possible). 13420 // to grow the heap without causing GCs (if possible).
13414 isolate->counters()->gc_last_resort_from_js()->Increment(); 13421 isolate->counters()->gc_last_resort_from_js()->Increment();
13415 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 13422 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13416 } 13423 }
13417 } 13424 }
13418 13425
13419 13426
13420 } } // namespace v8::internal 13427 } } // namespace v8::internal
OLDNEW
« src/arm/full-codegen-arm.cc ('K') | « src/runtime.h ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698