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

Side by Side Diff: src/heap.cc

Issue 10170030: Implement tracking and optimizations of packed arrays (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Platforms ports and 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
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 2448 matching lines...) Expand 10 before | Expand all | Expand 10 after
2459 Object* obj; 2459 Object* obj;
2460 2460
2461 { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize); 2461 { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
2462 if (!maybe_obj->ToObject(&obj)) return false; 2462 if (!maybe_obj->ToObject(&obj)) return false;
2463 } 2463 }
2464 // Don't use Smi-only elements optimizations for objects with the neander 2464 // Don't use Smi-only elements optimizations for objects with the neander
2465 // map. There are too many cases where element values are set directly with a 2465 // map. There are too many cases where element values are set directly with a
2466 // bottleneck to trap the Smi-only -> fast elements transition, and there 2466 // bottleneck to trap the Smi-only -> fast elements transition, and there
2467 // appears to be no benefit for optimize this case. 2467 // appears to be no benefit for optimize this case.
2468 Map* new_neander_map = Map::cast(obj); 2468 Map* new_neander_map = Map::cast(obj);
2469 new_neander_map->set_elements_kind(FAST_ELEMENTS); 2469 new_neander_map->set_elements_kind(TERMINAL_FAST_ELEMENTS_KIND);
2470 set_neander_map(new_neander_map); 2470 set_neander_map(new_neander_map);
2471 2471
2472 { MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map()); 2472 { MaybeObject* maybe_obj = AllocateJSObjectFromMap(neander_map());
2473 if (!maybe_obj->ToObject(&obj)) return false; 2473 if (!maybe_obj->ToObject(&obj)) return false;
2474 } 2474 }
2475 Object* elements; 2475 Object* elements;
2476 { MaybeObject* maybe_elements = AllocateFixedArray(2); 2476 { MaybeObject* maybe_elements = AllocateFixedArray(2);
2477 if (!maybe_elements->ToObject(&elements)) return false; 2477 if (!maybe_elements->ToObject(&elements)) return false;
2478 } 2478 }
2479 FixedArray::cast(elements)->set(0, Smi::FromInt(0)); 2479 FixedArray::cast(elements)->set(0, Smi::FromInt(0));
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after
3040 int end_position, 3040 int end_position,
3041 Object* script, 3041 Object* script,
3042 Object* stack_trace, 3042 Object* stack_trace,
3043 Object* stack_frames) { 3043 Object* stack_frames) {
3044 Object* result; 3044 Object* result;
3045 { MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE); 3045 { MaybeObject* maybe_result = Allocate(message_object_map(), NEW_SPACE);
3046 if (!maybe_result->ToObject(&result)) return maybe_result; 3046 if (!maybe_result->ToObject(&result)) return maybe_result;
3047 } 3047 }
3048 JSMessageObject* message = JSMessageObject::cast(result); 3048 JSMessageObject* message = JSMessageObject::cast(result);
3049 message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); 3049 message->set_properties(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
3050 message->initialize_elements();
3050 message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); 3051 message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER);
3051 message->set_type(type); 3052 message->set_type(type);
3052 message->set_arguments(arguments); 3053 message->set_arguments(arguments);
3053 message->set_start_position(start_position); 3054 message->set_start_position(start_position);
3054 message->set_end_position(end_position); 3055 message->set_end_position(end_position);
3055 message->set_script(script); 3056 message->set_script(script);
3056 message->set_stack_trace(stack_trace); 3057 message->set_stack_trace(stack_trace);
3057 message->set_stack_frames(stack_frames); 3058 message->set_stack_frames(stack_frames);
3058 return result; 3059 return result;
3059 } 3060 }
(...skipping 681 matching lines...) Expand 10 before | Expand all | Expand 10 after
3741 Smi::FromInt(length), 3742 Smi::FromInt(length),
3742 SKIP_WRITE_BARRIER); 3743 SKIP_WRITE_BARRIER);
3743 // Set the callee property for non-strict mode arguments object only. 3744 // Set the callee property for non-strict mode arguments object only.
3744 if (!strict_mode_callee) { 3745 if (!strict_mode_callee) {
3745 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex, 3746 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex,
3746 callee); 3747 callee);
3747 } 3748 }
3748 3749
3749 // Check the state of the object 3750 // Check the state of the object
3750 ASSERT(JSObject::cast(result)->HasFastProperties()); 3751 ASSERT(JSObject::cast(result)->HasFastProperties());
3751 ASSERT(JSObject::cast(result)->HasFastElements()); 3752 ASSERT(JSObject::cast(result)->HasFastObjectElements());
3752 3753
3753 return result; 3754 return result;
3754 } 3755 }
3755 3756
3756 3757
3757 static bool HasDuplicates(DescriptorArray* descriptors) { 3758 static bool HasDuplicates(DescriptorArray* descriptors) {
3758 int count = descriptors->number_of_descriptors(); 3759 int count = descriptors->number_of_descriptors();
3759 if (count > 1) { 3760 if (count > 1) {
3760 String* prev_key = descriptors->GetKey(0); 3761 String* prev_key = descriptors->GetKey(0);
3761 for (int i = 1; i != count; i++) { 3762 for (int i = 1; i != count; i++) {
(...skipping 24 matching lines...) Expand all
3786 prototype = fun->instance_prototype(); 3787 prototype = fun->instance_prototype();
3787 } else { 3788 } else {
3788 { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); 3789 { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun);
3789 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; 3790 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype;
3790 } 3791 }
3791 } 3792 }
3792 Map* map = Map::cast(map_obj); 3793 Map* map = Map::cast(map_obj);
3793 map->set_inobject_properties(in_object_properties); 3794 map->set_inobject_properties(in_object_properties);
3794 map->set_unused_property_fields(in_object_properties); 3795 map->set_unused_property_fields(in_object_properties);
3795 map->set_prototype(prototype); 3796 map->set_prototype(prototype);
3796 ASSERT(map->has_fast_elements()); 3797 ASSERT(map->has_fast_object_elements());
3797 3798
3798 // If the function has only simple this property assignments add 3799 // If the function has only simple this property assignments add
3799 // field descriptors for these to the initial map as the object 3800 // field descriptors for these to the initial map as the object
3800 // cannot be constructed without having these properties. Guard by 3801 // cannot be constructed without having these properties. Guard by
3801 // the inline_new flag so we only change the map if we generate a 3802 // the inline_new flag so we only change the map if we generate a
3802 // specialized construct stub. 3803 // specialized construct stub.
3803 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); 3804 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields);
3804 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { 3805 if (fun->shared()->CanGenerateInlineConstructor(prototype)) {
3805 int count = fun->shared()->this_property_assignments_count(); 3806 int count = fun->shared()->this_property_assignments_count();
3806 if (count > in_object_properties) { 3807 if (count > in_object_properties) {
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
3903 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; 3904 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE;
3904 Object* obj; 3905 Object* obj;
3905 { MaybeObject* maybe_obj = Allocate(map, space); 3906 { MaybeObject* maybe_obj = Allocate(map, space);
3906 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 3907 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3907 } 3908 }
3908 3909
3909 // Initialize the JSObject. 3910 // Initialize the JSObject.
3910 InitializeJSObjectFromMap(JSObject::cast(obj), 3911 InitializeJSObjectFromMap(JSObject::cast(obj),
3911 FixedArray::cast(properties), 3912 FixedArray::cast(properties),
3912 map); 3913 map);
3913 ASSERT(JSObject::cast(obj)->HasFastSmiOnlyElements() || 3914 ASSERT(JSObject::cast(obj)->HasFastSmiOrObjectElements());
3914 JSObject::cast(obj)->HasFastElements());
3915 return obj; 3915 return obj;
3916 } 3916 }
3917 3917
3918 3918
3919 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, 3919 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor,
3920 PretenureFlag pretenure) { 3920 PretenureFlag pretenure) {
3921 // Allocate the initial map if absent. 3921 // Allocate the initial map if absent.
3922 if (!constructor->has_initial_map()) { 3922 if (!constructor->has_initial_map()) {
3923 Object* initial_map; 3923 Object* initial_map;
3924 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); 3924 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor);
(...skipping 24 matching lines...) Expand all
3949 } 3949 }
3950 3950
3951 3951
3952 MaybeObject* Heap::AllocateJSArrayAndStorage( 3952 MaybeObject* Heap::AllocateJSArrayAndStorage(
3953 ElementsKind elements_kind, 3953 ElementsKind elements_kind,
3954 int length, 3954 int length,
3955 int capacity, 3955 int capacity,
3956 ArrayStorageAllocationMode mode, 3956 ArrayStorageAllocationMode mode,
3957 PretenureFlag pretenure) { 3957 PretenureFlag pretenure) {
3958 ASSERT(capacity >= length); 3958 ASSERT(capacity >= length);
3959 if (length != 0 && mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE) {
3960 elements_kind = GetHoleyElementsKind(elements_kind);
3961 }
3959 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); 3962 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure);
3960 JSArray* array; 3963 JSArray* array;
3961 if (!maybe_array->To(&array)) return maybe_array; 3964 if (!maybe_array->To(&array)) return maybe_array;
3962 3965
3963 if (capacity == 0) { 3966 if (capacity == 0) {
3964 array->set_length(Smi::FromInt(0)); 3967 array->set_length(Smi::FromInt(0));
3965 array->set_elements(empty_fixed_array()); 3968 array->set_elements(empty_fixed_array());
3966 return array; 3969 return array;
3967 } 3970 }
3968 3971
3969 FixedArrayBase* elms; 3972 FixedArrayBase* elms;
3970 MaybeObject* maybe_elms = NULL; 3973 MaybeObject* maybe_elms = NULL;
3971 if (elements_kind == FAST_DOUBLE_ELEMENTS) { 3974 if (elements_kind == FAST_DOUBLE_ELEMENTS) {
3972 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 3975 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
3973 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity); 3976 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity);
3974 } else { 3977 } else {
3975 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 3978 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
3976 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity); 3979 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity);
3977 } 3980 }
3978 } else { 3981 } else {
3979 ASSERT(elements_kind == FAST_ELEMENTS || 3982 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind));
3980 elements_kind == FAST_SMI_ONLY_ELEMENTS);
3981 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { 3983 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) {
3982 maybe_elms = AllocateUninitializedFixedArray(capacity); 3984 maybe_elms = AllocateUninitializedFixedArray(capacity);
3983 } else { 3985 } else {
3984 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 3986 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
3985 maybe_elms = AllocateFixedArrayWithHoles(capacity); 3987 maybe_elms = AllocateFixedArrayWithHoles(capacity);
3986 } 3988 }
3987 } 3989 }
3988 if (!maybe_elms->To(&elms)) return maybe_elms; 3990 if (!maybe_elms->To(&elms)) return maybe_elms;
3989 3991
3990 array->set_elements(elms); 3992 array->set_elements(elms);
3991 array->set_length(Smi::FromInt(length)); 3993 array->set_length(Smi::FromInt(length));
3992 return array; 3994 return array;
3993 } 3995 }
3994 3996
3995 3997
3996 MaybeObject* Heap::AllocateJSArrayWithElements( 3998 MaybeObject* Heap::AllocateJSArrayWithElements(
3997 FixedArrayBase* elements, 3999 FixedArrayBase* elements,
3998 ElementsKind elements_kind, 4000 ElementsKind elements_kind,
3999 PretenureFlag pretenure) { 4001 PretenureFlag pretenure) {
4000 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); 4002 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure);
4001 JSArray* array; 4003 JSArray* array;
4002 if (!maybe_array->To(&array)) return maybe_array; 4004 if (!maybe_array->To(&array)) return maybe_array;
4003 4005
4004 array->set_elements(elements); 4006 array->set_elements(elements);
4005 array->set_length(Smi::FromInt(elements->length())); 4007 array->set_length(Smi::FromInt(elements->length()));
4008 array->ValidateElements();
4006 return array; 4009 return array;
4007 } 4010 }
4008 4011
4009 4012
4010 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { 4013 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) {
4011 // Allocate map. 4014 // Allocate map.
4012 // TODO(rossberg): Once we optimize proxies, think about a scheme to share 4015 // TODO(rossberg): Once we optimize proxies, think about a scheme to share
4013 // maps. Will probably depend on the identity of the handler object, too. 4016 // maps. Will probably depend on the identity of the handler object, too.
4014 Map* map; 4017 Map* map;
4015 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize); 4018 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize);
(...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after
4526 return result; 4529 return result;
4527 } 4530 }
4528 4531
4529 4532
4530 MaybeObject* Heap::AllocateJSArray( 4533 MaybeObject* Heap::AllocateJSArray(
4531 ElementsKind elements_kind, 4534 ElementsKind elements_kind,
4532 PretenureFlag pretenure) { 4535 PretenureFlag pretenure) {
4533 Context* global_context = isolate()->context()->global_context(); 4536 Context* global_context = isolate()->context()->global_context();
4534 JSFunction* array_function = global_context->array_function(); 4537 JSFunction* array_function = global_context->array_function();
4535 Map* map = array_function->initial_map(); 4538 Map* map = array_function->initial_map();
4536 if (elements_kind == FAST_DOUBLE_ELEMENTS) { 4539 Object* maybe_map_array = global_context->js_array_maps();
4537 map = Map::cast(global_context->double_js_array_map()); 4540 if (!maybe_map_array->IsUndefined()) {
4538 } else if (elements_kind == FAST_ELEMENTS || !FLAG_smi_only_arrays) { 4541 Object* maybe_transitioned_map =
4539 map = Map::cast(global_context->object_js_array_map()); 4542 FixedArray::cast(maybe_map_array)->get(elements_kind);
4540 } else { 4543 if (!maybe_transitioned_map->IsUndefined()) {
4541 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); 4544 map = Map::cast(maybe_transitioned_map);
4542 ASSERT(map == global_context->smi_js_array_map()); 4545 }
4543 } 4546 }
4544 4547
4545 return AllocateJSObjectFromMap(map, pretenure); 4548 return AllocateJSObjectFromMap(map, pretenure);
4546 } 4549 }
4547 4550
4548 4551
4549 MaybeObject* Heap::AllocateEmptyFixedArray() { 4552 MaybeObject* Heap::AllocateEmptyFixedArray() {
4550 int size = FixedArray::SizeFor(0); 4553 int size = FixedArray::SizeFor(0);
4551 Object* result; 4554 Object* result;
4552 { MaybeObject* maybe_result = 4555 { MaybeObject* maybe_result =
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
4817 4820
4818 4821
4819 MaybeObject* Heap::AllocateGlobalContext() { 4822 MaybeObject* Heap::AllocateGlobalContext() {
4820 Object* result; 4823 Object* result;
4821 { MaybeObject* maybe_result = 4824 { MaybeObject* maybe_result =
4822 AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); 4825 AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS);
4823 if (!maybe_result->ToObject(&result)) return maybe_result; 4826 if (!maybe_result->ToObject(&result)) return maybe_result;
4824 } 4827 }
4825 Context* context = reinterpret_cast<Context*>(result); 4828 Context* context = reinterpret_cast<Context*>(result);
4826 context->set_map_no_write_barrier(global_context_map()); 4829 context->set_map_no_write_barrier(global_context_map());
4827 context->set_smi_js_array_map(undefined_value()); 4830 context->set_js_array_maps(undefined_value());
4828 context->set_double_js_array_map(undefined_value());
4829 context->set_object_js_array_map(undefined_value());
4830 ASSERT(context->IsGlobalContext()); 4831 ASSERT(context->IsGlobalContext());
4831 ASSERT(result->IsContext()); 4832 ASSERT(result->IsContext());
4832 return result; 4833 return result;
4833 } 4834 }
4834 4835
4835 4836
4836 MaybeObject* Heap::AllocateModuleContext(Context* previous, 4837 MaybeObject* Heap::AllocateModuleContext(Context* previous,
4837 ScopeInfo* scope_info) { 4838 ScopeInfo* scope_info) {
4838 Object* result; 4839 Object* result;
4839 { MaybeObject* maybe_result = 4840 { MaybeObject* maybe_result =
(...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after
7129 } else { 7130 } else {
7130 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. 7131 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died.
7131 } 7132 }
7132 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = 7133 remembered_unmapped_pages_[remembered_unmapped_pages_index_] =
7133 reinterpret_cast<Address>(p); 7134 reinterpret_cast<Address>(p);
7134 remembered_unmapped_pages_index_++; 7135 remembered_unmapped_pages_index_++;
7135 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; 7136 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages;
7136 } 7137 }
7137 7138
7138 } } // namespace v8::internal 7139 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698