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

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

Powered by Google App Engine
This is Rietveld 408576698