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

Side by Side Diff: src/runtime.cc

Issue 9073007: Store transitioned JSArray maps in global context (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 8 years, 11 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/parser.cc ('k') | src/x64/builtins-x64.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 410 matching lines...) Expand 10 before | Expand all | Expand 10 after
421 // constant function properties. 421 // constant function properties.
422 if (should_transform && !has_function_literal) { 422 if (should_transform && !has_function_literal) {
423 JSObject::TransformToFastProperties( 423 JSObject::TransformToFastProperties(
424 boilerplate, boilerplate->map()->unused_property_fields()); 424 boilerplate, boilerplate->map()->unused_property_fields());
425 } 425 }
426 426
427 return boilerplate; 427 return boilerplate;
428 } 428 }
429 429
430 430
431 MaybeObject* TransitionElements(Handle<Object> object,
432 ElementsKind to_kind,
433 Isolate* isolate) {
434 HandleScope scope(isolate);
435 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
436 ElementsKind from_kind =
437 Handle<JSObject>::cast(object)->map()->elements_kind();
438 if (Map::IsValidElementsTransition(from_kind, to_kind)) {
439 Handle<Object> result = JSObject::TransitionElementsKind(
440 Handle<JSObject>::cast(object), to_kind);
441 if (result.is_null()) return isolate->ThrowIllegalOperation();
442 return *result;
443 }
444 return isolate->ThrowIllegalOperation();
445 }
446
447
431 static const int kSmiOnlyLiteralMinimumLength = 1024; 448 static const int kSmiOnlyLiteralMinimumLength = 1024;
432 449
433 450
434 Handle<Object> Runtime::CreateArrayLiteralBoilerplate( 451 Handle<Object> Runtime::CreateArrayLiteralBoilerplate(
435 Isolate* isolate, 452 Isolate* isolate,
436 Handle<FixedArray> literals, 453 Handle<FixedArray> literals,
437 Handle<FixedArray> elements) { 454 Handle<FixedArray> elements) {
438 // Create the JSArray. 455 // Create the JSArray.
439 Handle<JSFunction> constructor( 456 Handle<JSFunction> constructor(
440 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); 457 JSFunction::GlobalContextFromLiterals(*literals)->array_function());
441 Handle<JSArray> object = 458 Handle<JSArray> object =
442 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor)); 459 Handle<JSArray>::cast(isolate->factory()->NewJSObject(constructor));
443 460
444 ElementsKind constant_elements_kind = 461 ElementsKind constant_elements_kind =
445 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value()); 462 static_cast<ElementsKind>(Smi::cast(elements->get(0))->value());
446 Handle<FixedArrayBase> constant_elements_values( 463 Handle<FixedArrayBase> constant_elements_values(
447 FixedArrayBase::cast(elements->get(1))); 464 FixedArrayBase::cast(elements->get(1)));
448 465
449 ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS || 466 Context* global_context = isolate->context()->global_context();
450 constant_elements_kind == FAST_SMI_ONLY_ELEMENTS); 467 if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) {
451 bool allow_literal_kind_transition = FLAG_smi_only_arrays && 468 object->set_map(Map::cast(global_context->smi_js_array_map()));
452 constant_elements_kind > object->GetElementsKind(); 469 } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
453 470 object->set_map(Map::cast(global_context->double_js_array_map()));
454 if (!FLAG_smi_only_arrays && 471 } else {
455 constant_elements_values->length() > kSmiOnlyLiteralMinimumLength && 472 object->set_map(Map::cast(global_context->object_js_array_map()));
456 constant_elements_kind != object->GetElementsKind()) {
457 allow_literal_kind_transition = true;
458 }
459
460 // If the ElementsKind of the constant values of the array literal are less
461 // specific than the ElementsKind of the boilerplate array object, change the
462 // boilerplate array object's map to reflect that kind.
463 if (allow_literal_kind_transition) {
464 Handle<Map> transitioned_array_map =
465 isolate->factory()->GetElementsTransitionMap(object,
466 constant_elements_kind);
467 object->set_map(*transitioned_array_map);
468 } 473 }
469 474
470 Handle<FixedArrayBase> copied_elements_values; 475 Handle<FixedArrayBase> copied_elements_values;
471 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { 476 if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) {
472 ASSERT(FLAG_smi_only_arrays); 477 ASSERT(FLAG_smi_only_arrays);
473 copied_elements_values = isolate->factory()->CopyFixedDoubleArray( 478 copied_elements_values = isolate->factory()->CopyFixedDoubleArray(
474 Handle<FixedDoubleArray>::cast(constant_elements_values)); 479 Handle<FixedDoubleArray>::cast(constant_elements_values));
475 } else { 480 } else {
476 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS || 481 ASSERT(constant_elements_kind == FAST_SMI_ONLY_ELEMENTS ||
477 constant_elements_kind == FAST_ELEMENTS); 482 constant_elements_kind == FAST_ELEMENTS);
(...skipping 24 matching lines...) Expand all
502 Handle<Object> result = 507 Handle<Object> result =
503 CreateLiteralBoilerplate(isolate, literals, fa); 508 CreateLiteralBoilerplate(isolate, literals, fa);
504 if (result.is_null()) return result; 509 if (result.is_null()) return result;
505 fixed_array_values_copy->set(i, *result); 510 fixed_array_values_copy->set(i, *result);
506 } 511 }
507 } 512 }
508 } 513 }
509 } 514 }
510 object->set_elements(*copied_elements_values); 515 object->set_elements(*copied_elements_values);
511 object->set_length(Smi::FromInt(copied_elements_values->length())); 516 object->set_length(Smi::FromInt(copied_elements_values->length()));
517
518 // Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is
519 // on or the object is larger than the threshold.
520 if (!FLAG_smi_only_arrays &&
521 constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) {
522 if (object->GetElementsKind() != FAST_ELEMENTS) {
523 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
524 }
525 }
526
512 return object; 527 return object;
513 } 528 }
514 529
515 530
516 static Handle<Object> CreateLiteralBoilerplate( 531 static Handle<Object> CreateLiteralBoilerplate(
517 Isolate* isolate, 532 Isolate* isolate,
518 Handle<FixedArray> literals, 533 Handle<FixedArray> literals,
519 Handle<FixedArray> array) { 534 Handle<FixedArray> array) {
520 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 535 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
521 const bool kHasNoFunctionLiteral = false; 536 const bool kHasNoFunctionLiteral = false;
(...skipping 3673 matching lines...) Expand 10 before | Expand all | Expand 10 after
4195 NoHandleAllocation ha; 4210 NoHandleAllocation ha;
4196 ASSERT(args.length() == 2); 4211 ASSERT(args.length() == 2);
4197 4212
4198 Handle<Object> object = args.at<Object>(0); 4213 Handle<Object> object = args.at<Object>(0);
4199 Handle<Object> key = args.at<Object>(1); 4214 Handle<Object> key = args.at<Object>(1);
4200 4215
4201 return Runtime::GetObjectProperty(isolate, object, key); 4216 return Runtime::GetObjectProperty(isolate, object, key);
4202 } 4217 }
4203 4218
4204 4219
4205 MaybeObject* TransitionElements(Handle<Object> object,
4206 ElementsKind to_kind,
4207 Isolate* isolate) {
4208 HandleScope scope(isolate);
4209 if (!object->IsJSObject()) return isolate->ThrowIllegalOperation();
4210 ElementsKind from_kind =
4211 Handle<JSObject>::cast(object)->map()->elements_kind();
4212 if (Map::IsValidElementsTransition(from_kind, to_kind)) {
4213 Handle<Object> result = JSObject::TransitionElementsKind(
4214 Handle<JSObject>::cast(object), to_kind);
4215 if (result.is_null()) return isolate->ThrowIllegalOperation();
4216 return *result;
4217 }
4218 return isolate->ThrowIllegalOperation();
4219 }
4220
4221
4222 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. 4220 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric.
4223 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { 4221 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
4224 NoHandleAllocation ha; 4222 NoHandleAllocation ha;
4225 ASSERT(args.length() == 2); 4223 ASSERT(args.length() == 2);
4226 4224
4227 // Fast cases for getting named properties of the receiver JSObject 4225 // Fast cases for getting named properties of the receiver JSObject
4228 // itself. 4226 // itself.
4229 // 4227 //
4230 // The global proxy objects has to be excluded since LocalLookup on 4228 // The global proxy objects has to be excluded since LocalLookup on
4231 // the global proxy object can return a valid result even though the 4229 // the global proxy object can return a valid result even though the
(...skipping 5992 matching lines...) Expand 10 before | Expand all | Expand 10 after
10224 ElementsKind elements_kind; 10222 ElementsKind elements_kind;
10225 if (new_elements->map() == isolate->heap()->fixed_array_map() || 10223 if (new_elements->map() == isolate->heap()->fixed_array_map() ||
10226 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { 10224 new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
10227 elements_kind = FAST_ELEMENTS; 10225 elements_kind = FAST_ELEMENTS;
10228 } else if (new_elements->map() == 10226 } else if (new_elements->map() ==
10229 isolate->heap()->fixed_double_array_map()) { 10227 isolate->heap()->fixed_double_array_map()) {
10230 elements_kind = FAST_DOUBLE_ELEMENTS; 10228 elements_kind = FAST_DOUBLE_ELEMENTS;
10231 } else { 10229 } else {
10232 elements_kind = DICTIONARY_ELEMENTS; 10230 elements_kind = DICTIONARY_ELEMENTS;
10233 } 10231 }
10234 maybe_new_map = to->GetElementsTransitionMap(elements_kind); 10232 maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind);
10235 Object* new_map; 10233 Object* new_map;
10236 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 10234 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
10237 to->set_map(Map::cast(new_map)); 10235 to->set_map(Map::cast(new_map));
10238 to->set_elements(new_elements); 10236 to->set_elements(new_elements);
10239 to->set_length(from->length()); 10237 to->set_length(from->length());
10240 Object* obj; 10238 Object* obj;
10241 { MaybeObject* maybe_obj = from->ResetElements(); 10239 { MaybeObject* maybe_obj = from->ResetElements();
10242 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10240 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10243 } 10241 }
10244 from->set_length(Smi::FromInt(0)); 10242 from->set_length(Smi::FromInt(0));
(...skipping 3390 matching lines...) Expand 10 before | Expand all | Expand 10 after
13635 } else { 13633 } else {
13636 // Handle last resort GC and make sure to allow future allocations 13634 // Handle last resort GC and make sure to allow future allocations
13637 // to grow the heap without causing GCs (if possible). 13635 // to grow the heap without causing GCs (if possible).
13638 isolate->counters()->gc_last_resort_from_js()->Increment(); 13636 isolate->counters()->gc_last_resort_from_js()->Increment();
13639 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 13637 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13640 } 13638 }
13641 } 13639 }
13642 13640
13643 13641
13644 } } // namespace v8::internal 13642 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/x64/builtins-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698