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

Side by Side Diff: src/runtime.cc

Issue 15094018: Create AllocationSite objects, pointed to by AllocationSiteInfo. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platform ports and perf bugfix Created 7 years, 5 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 // 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 482 matching lines...) Expand 10 before | Expand all | Expand 10 after
493 should_have_fast_elements, 493 should_have_fast_elements,
494 has_function_literal); 494 has_function_literal);
495 if (boilerplate.is_null()) return Failure::Exception(); 495 if (boilerplate.is_null()) return Failure::Exception();
496 // Update the functions literal and return the boilerplate. 496 // Update the functions literal and return the boilerplate.
497 literals->set(literals_index, *boilerplate); 497 literals->set(literals_index, *boilerplate);
498 } 498 }
499 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate)); 499 return isolate->heap()->CopyJSObject(JSObject::cast(*boilerplate));
500 } 500 }
501 501
502 502
503 static Handle<AllocationSite> GetLiteralAllocationSite(
504 Isolate* isolate,
505 Handle<FixedArray> literals,
506 int literals_index,
507 Handle<FixedArray> elements) {
508 // Check if boilerplate exists. If not, create it first.
509 Handle<Object> literal_site(literals->get(literals_index), isolate);
510 Handle<AllocationSite> site;
511 if (*literal_site == isolate->heap()->undefined_value()) {
512 ASSERT(*elements != isolate->heap()->empty_fixed_array());
513 Handle<Object> boilerplate =
514 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
515 if (boilerplate.is_null()) return site;
516 site = isolate->factory()->NewAllocationSite();
517 site->set_payload(*boilerplate);
518 literals->set(literals_index, *site);
519 } else {
520 site = Handle<AllocationSite>::cast(literal_site);
521 }
522
523 return site;
524 }
525
526
503 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) { 527 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteral) {
504 HandleScope scope(isolate); 528 HandleScope scope(isolate);
505 ASSERT(args.length() == 3); 529 ASSERT(args.length() == 3);
506 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); 530 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
507 CONVERT_SMI_ARG_CHECKED(literals_index, 1); 531 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
508 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); 532 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
509 533
510 // Check if boilerplate exists. If not, create it first. 534 Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
511 Handle<Object> boilerplate(literals->get(literals_index), isolate); 535 literals_index, elements);
512 if (*boilerplate == isolate->heap()->undefined_value()) { 536 if (site.is_null()) {
513 ASSERT(*elements != isolate->heap()->empty_fixed_array()); 537 return Failure::Exception();
514 boilerplate =
515 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
516 if (boilerplate.is_null()) return Failure::Exception();
517 // Update the functions literal and return the boilerplate.
518 literals->set(literals_index, *boilerplate);
519 } 538 }
520 return JSObject::cast(*boilerplate)->DeepCopy(isolate); 539
540 JSObject* boilerplate = JSObject::cast(site->payload());
541 return boilerplate->DeepCopy(isolate);
521 } 542 }
522 543
523 544
524 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) { 545 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateArrayLiteralShallow) {
525 HandleScope scope(isolate); 546 HandleScope scope(isolate);
526 ASSERT(args.length() == 3); 547 ASSERT(args.length() == 3);
527 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0); 548 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 0);
528 CONVERT_SMI_ARG_CHECKED(literals_index, 1); 549 CONVERT_SMI_ARG_CHECKED(literals_index, 1);
529 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2); 550 CONVERT_ARG_HANDLE_CHECKED(FixedArray, elements, 2);
530 551
531 // Check if boilerplate exists. If not, create it first. 552 Handle<AllocationSite> site = GetLiteralAllocationSite(isolate, literals,
532 Handle<Object> boilerplate(literals->get(literals_index), isolate); 553 literals_index, elements);
533 if (*boilerplate == isolate->heap()->undefined_value()) { 554 if (site.is_null()) {
534 ASSERT(*elements != isolate->heap()->empty_fixed_array()); 555 return Failure::Exception();
535 boilerplate =
536 Runtime::CreateArrayLiteralBoilerplate(isolate, literals, elements);
537 if (boilerplate.is_null()) return Failure::Exception();
538 // Update the functions literal and return the boilerplate.
539 literals->set(literals_index, *boilerplate);
540 } 556 }
541 if (JSObject::cast(*boilerplate)->elements()->map() == 557
558 JSObject* boilerplate = JSObject::cast(site->payload());
559 if (boilerplate->elements()->map() ==
542 isolate->heap()->fixed_cow_array_map()) { 560 isolate->heap()->fixed_cow_array_map()) {
543 isolate->counters()->cow_arrays_created_runtime()->Increment(); 561 isolate->counters()->cow_arrays_created_runtime()->Increment();
544 } 562 }
545 563
546 JSObject* boilerplate_object = JSObject::cast(*boilerplate); 564 AllocationSiteMode mode = AllocationSite::GetMode(
547 AllocationSiteMode mode = AllocationSiteInfo::GetMode( 565 boilerplate->GetElementsKind());
548 boilerplate_object->GetElementsKind());
549 if (mode == TRACK_ALLOCATION_SITE) { 566 if (mode == TRACK_ALLOCATION_SITE) {
550 return isolate->heap()->CopyJSObjectWithAllocationSite(boilerplate_object); 567 return isolate->heap()->CopyJSObjectWithAllocationSite(
568 boilerplate, *site);
551 } 569 }
552 570
553 return isolate->heap()->CopyJSObject(boilerplate_object); 571 return isolate->heap()->CopyJSObject(boilerplate);
554 } 572 }
555 573
556 574
557 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) { 575 RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateSymbol) {
558 HandleScope scope(isolate); 576 HandleScope scope(isolate);
559 ASSERT(args.length() == 1); 577 ASSERT(args.length() == 1);
560 Handle<Object> name(args[0], isolate); 578 Handle<Object> name(args[0], isolate);
561 RUNTIME_ASSERT(name->IsString() || name->IsUndefined()); 579 RUNTIME_ASSERT(name->IsString() || name->IsUndefined());
562 Symbol* symbol; 580 Symbol* symbol;
563 MaybeObject* maybe = isolate->heap()->AllocateSymbol(); 581 MaybeObject* maybe = isolate->heap()->AllocateSymbol();
(...skipping 4618 matching lines...) Expand 10 before | Expand all | Expand 10 after
5182 5200
5183 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) { 5201 RUNTIME_FUNCTION(MaybeObject*, Runtime_StoreArrayLiteralElement) {
5184 HandleScope scope(isolate); 5202 HandleScope scope(isolate);
5185 RUNTIME_ASSERT(args.length() == 5); 5203 RUNTIME_ASSERT(args.length() == 5);
5186 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5204 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5187 CONVERT_SMI_ARG_CHECKED(store_index, 1); 5205 CONVERT_SMI_ARG_CHECKED(store_index, 1);
5188 Handle<Object> value = args.at<Object>(2); 5206 Handle<Object> value = args.at<Object>(2);
5189 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3); 5207 CONVERT_ARG_HANDLE_CHECKED(FixedArray, literals, 3);
5190 CONVERT_SMI_ARG_CHECKED(literal_index, 4); 5208 CONVERT_SMI_ARG_CHECKED(literal_index, 4);
5191 5209
5192 Object* raw_boilerplate_object = literals->get(literal_index); 5210 Object* raw_literal_cell = literals->get(literal_index);
5193 Handle<JSArray> boilerplate_object(JSArray::cast(raw_boilerplate_object)); 5211 JSArray* boilerplate = NULL;
5212 if (raw_literal_cell->IsAllocationSite()) {
5213 AllocationSite* site = AllocationSite::cast(raw_literal_cell);
5214 boilerplate = JSArray::cast(site->payload());
5215 } else {
5216 boilerplate = JSArray::cast(raw_literal_cell);
5217 }
5218 Handle<JSArray> boilerplate_object(boilerplate);
5194 ElementsKind elements_kind = object->GetElementsKind(); 5219 ElementsKind elements_kind = object->GetElementsKind();
5195 ASSERT(IsFastElementsKind(elements_kind)); 5220 ASSERT(IsFastElementsKind(elements_kind));
5196 // Smis should never trigger transitions. 5221 // Smis should never trigger transitions.
5197 ASSERT(!value->IsSmi()); 5222 ASSERT(!value->IsSmi());
5198 5223
5199 if (value->IsNumber()) { 5224 if (value->IsNumber()) {
5200 ASSERT(IsFastSmiElementsKind(elements_kind)); 5225 ASSERT(IsFastSmiElementsKind(elements_kind));
5201 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind) 5226 ElementsKind transitioned_kind = IsFastHoleyElementsKind(elements_kind)
5202 ? FAST_HOLEY_DOUBLE_ELEMENTS 5227 ? FAST_HOLEY_DOUBLE_ELEMENTS
5203 : FAST_DOUBLE_ELEMENTS; 5228 : FAST_DOUBLE_ELEMENTS;
(...skipping 8582 matching lines...) Expand 10 before | Expand all | Expand 10 after
13786 } else { 13811 } else {
13787 // Non-smi length argument produces a dictionary 13812 // Non-smi length argument produces a dictionary
13788 can_use_type_feedback = false; 13813 can_use_type_feedback = false;
13789 } 13814 }
13790 } 13815 }
13791 13816
13792 JSArray* array; 13817 JSArray* array;
13793 MaybeObject* maybe_array; 13818 MaybeObject* maybe_array;
13794 if (!type_info.is_null() && 13819 if (!type_info.is_null() &&
13795 *type_info != isolate->heap()->undefined_value() && 13820 *type_info != isolate->heap()->undefined_value() &&
13796 Cell::cast(*type_info)->value()->IsSmi() && 13821 Cell::cast(*type_info)->value()->IsAllocationSite() &&
13797 can_use_type_feedback) { 13822 can_use_type_feedback) {
13798 Cell* cell = Cell::cast(*type_info); 13823 Handle<Cell> cell = Handle<Cell>::cast(type_info);
13799 Smi* smi = Smi::cast(cell->value()); 13824 Handle<AllocationSite> site = Handle<AllocationSite>(
13800 ElementsKind to_kind = static_cast<ElementsKind>(smi->value()); 13825 AllocationSite::cast(cell->value()), isolate);
13826 ASSERT(!site->IsLiteralSite());
13827 ElementsKind to_kind = site->GetElementsKindPayload();
13801 if (holey && !IsFastHoleyElementsKind(to_kind)) { 13828 if (holey && !IsFastHoleyElementsKind(to_kind)) {
13802 to_kind = GetHoleyElementsKind(to_kind); 13829 to_kind = GetHoleyElementsKind(to_kind);
13803 // Update the allocation site info to reflect the advice alteration. 13830 // Update the allocation site info to reflect the advice alteration.
13804 cell->set_value(Smi::FromInt(to_kind)); 13831 site->SetElementsKindPayload(to_kind);
13805 } 13832 }
13806 13833
13807 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite( 13834 maybe_array = isolate->heap()->AllocateJSObjectWithAllocationSite(
13808 *constructor, type_info); 13835 *constructor, site);
13809 if (!maybe_array->To(&array)) return maybe_array; 13836 if (!maybe_array->To(&array)) return maybe_array;
13810 } else { 13837 } else {
13811 maybe_array = isolate->heap()->AllocateJSObject(*constructor); 13838 maybe_array = isolate->heap()->AllocateJSObject(*constructor);
13812 if (!maybe_array->To(&array)) return maybe_array; 13839 if (!maybe_array->To(&array)) return maybe_array;
13813 // We might need to transition to holey 13840 // We might need to transition to holey
13814 ElementsKind kind = constructor->initial_map()->elements_kind(); 13841 ElementsKind kind = constructor->initial_map()->elements_kind();
13815 if (holey && !IsFastHoleyElementsKind(kind)) { 13842 if (holey && !IsFastHoleyElementsKind(kind)) {
13816 kind = GetHoleyElementsKind(kind); 13843 kind = GetHoleyElementsKind(kind);
13817 maybe_array = array->TransitionElementsKind(kind); 13844 maybe_array = array->TransitionElementsKind(kind);
13818 if (maybe_array->IsFailure()) return maybe_array; 13845 if (maybe_array->IsFailure()) return maybe_array;
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
13947 // Handle last resort GC and make sure to allow future allocations 13974 // Handle last resort GC and make sure to allow future allocations
13948 // to grow the heap without causing GCs (if possible). 13975 // to grow the heap without causing GCs (if possible).
13949 isolate->counters()->gc_last_resort_from_js()->Increment(); 13976 isolate->counters()->gc_last_resort_from_js()->Increment();
13950 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13977 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13951 "Runtime::PerformGC"); 13978 "Runtime::PerformGC");
13952 } 13979 }
13953 } 13980 }
13954 13981
13955 13982
13956 } } // namespace v8::internal 13983 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698