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

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: Remove whitespace change 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
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 j// Copyright 2012 the V8 project authors. All rights reserved.
Jakob Kummerow 2012/01/23 17:16:55 nit: superfluous "j" (does this compile?)
danno 2012/01/26 21:32:34 Done.
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
11 // with the distribution. 11 // with the distribution.
(...skipping 409 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 // If the ElementsKind of the constant values of the array literal are less
Jakob Kummerow 2012/01/23 17:16:55 This comment is confusing. Suggestion: "Ensure tha
danno 2012/01/26 21:32:34 Done.
519 // specific than the ElementsKind of the boilerplate array object, change
520 // the boilerplate array object's map to reflect that kind.
521 if (!FLAG_smi_only_arrays &&
522 constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) {
523 if (object->GetElementsKind() != FAST_ELEMENTS) {
524 CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure());
525 }
526 }
527
512 return object; 528 return object;
513 } 529 }
514 530
515 531
516 static Handle<Object> CreateLiteralBoilerplate( 532 static Handle<Object> CreateLiteralBoilerplate(
517 Isolate* isolate, 533 Isolate* isolate,
518 Handle<FixedArray> literals, 534 Handle<FixedArray> literals,
519 Handle<FixedArray> array) { 535 Handle<FixedArray> array) {
520 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); 536 Handle<FixedArray> elements = CompileTimeValue::GetElements(array);
521 const bool kHasNoFunctionLiteral = false; 537 const bool kHasNoFunctionLiteral = false;
(...skipping 3673 matching lines...) Expand 10 before | Expand all | Expand 10 after
4195 NoHandleAllocation ha; 4211 NoHandleAllocation ha;
4196 ASSERT(args.length() == 2); 4212 ASSERT(args.length() == 2);
4197 4213
4198 Handle<Object> object = args.at<Object>(0); 4214 Handle<Object> object = args.at<Object>(0);
4199 Handle<Object> key = args.at<Object>(1); 4215 Handle<Object> key = args.at<Object>(1);
4200 4216
4201 return Runtime::GetObjectProperty(isolate, object, key); 4217 return Runtime::GetObjectProperty(isolate, object, key);
4202 } 4218 }
4203 4219
4204 4220
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. 4221 // KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric.
4223 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { 4222 RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) {
4224 NoHandleAllocation ha; 4223 NoHandleAllocation ha;
4225 ASSERT(args.length() == 2); 4224 ASSERT(args.length() == 2);
4226 4225
4227 // Fast cases for getting named properties of the receiver JSObject 4226 // Fast cases for getting named properties of the receiver JSObject
4228 // itself. 4227 // itself.
4229 // 4228 //
4230 // The global proxy objects has to be excluded since LocalLookup on 4229 // The global proxy objects has to be excluded since LocalLookup on
4231 // the global proxy object can return a valid result even though the 4230 // 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; 10223 ElementsKind elements_kind;
10225 if (new_elements->map() == isolate->heap()->fixed_array_map() || 10224 if (new_elements->map() == isolate->heap()->fixed_array_map() ||
10226 new_elements->map() == isolate->heap()->fixed_cow_array_map()) { 10225 new_elements->map() == isolate->heap()->fixed_cow_array_map()) {
10227 elements_kind = FAST_ELEMENTS; 10226 elements_kind = FAST_ELEMENTS;
10228 } else if (new_elements->map() == 10227 } else if (new_elements->map() ==
10229 isolate->heap()->fixed_double_array_map()) { 10228 isolate->heap()->fixed_double_array_map()) {
10230 elements_kind = FAST_DOUBLE_ELEMENTS; 10229 elements_kind = FAST_DOUBLE_ELEMENTS;
10231 } else { 10230 } else {
10232 elements_kind = DICTIONARY_ELEMENTS; 10231 elements_kind = DICTIONARY_ELEMENTS;
10233 } 10232 }
10234 maybe_new_map = to->GetElementsTransitionMap(elements_kind); 10233 maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind);
10235 Object* new_map; 10234 Object* new_map;
10236 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; 10235 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map;
10237 to->set_map(Map::cast(new_map)); 10236 to->set_map(Map::cast(new_map));
10238 to->set_elements(new_elements); 10237 to->set_elements(new_elements);
10239 to->set_length(from->length()); 10238 to->set_length(from->length());
10240 Object* obj; 10239 Object* obj;
10241 { MaybeObject* maybe_obj = from->ResetElements(); 10240 { MaybeObject* maybe_obj = from->ResetElements();
10242 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 10241 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
10243 } 10242 }
10244 from->set_length(Smi::FromInt(0)); 10243 from->set_length(Smi::FromInt(0));
(...skipping 3390 matching lines...) Expand 10 before | Expand all | Expand 10 after
13635 } else { 13634 } else {
13636 // Handle last resort GC and make sure to allow future allocations 13635 // Handle last resort GC and make sure to allow future allocations
13637 // to grow the heap without causing GCs (if possible). 13636 // to grow the heap without causing GCs (if possible).
13638 isolate->counters()->gc_last_resort_from_js()->Increment(); 13637 isolate->counters()->gc_last_resort_from_js()->Increment();
13639 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags); 13638 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags);
13640 } 13639 }
13641 } 13640 }
13642 13641
13643 13642
13644 } } // namespace v8::internal 13643 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698