OLD | NEW |
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 Loading... |
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(TERMINAL_FAST_ELEMENTS_KIND); | 2472 new_neander_map->set_elements_kind(FAST_ELEMENTS); |
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 Loading... |
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(); | |
3054 message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); | 3053 message->set_elements(Heap::empty_fixed_array(), SKIP_WRITE_BARRIER); |
3055 message->set_type(type); | 3054 message->set_type(type); |
3056 message->set_arguments(arguments); | 3055 message->set_arguments(arguments); |
3057 message->set_start_position(start_position); | 3056 message->set_start_position(start_position); |
3058 message->set_end_position(end_position); | 3057 message->set_end_position(end_position); |
3059 message->set_script(script); | 3058 message->set_script(script); |
3060 message->set_stack_trace(stack_trace); | 3059 message->set_stack_trace(stack_trace); |
3061 message->set_stack_frames(stack_frames); | 3060 message->set_stack_frames(stack_frames); |
3062 return result; | 3061 return result; |
3063 } | 3062 } |
(...skipping 683 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3747 Smi::FromInt(length), | 3746 Smi::FromInt(length), |
3748 SKIP_WRITE_BARRIER); | 3747 SKIP_WRITE_BARRIER); |
3749 // Set the callee property for non-strict mode arguments object only. | 3748 // Set the callee property for non-strict mode arguments object only. |
3750 if (!strict_mode_callee) { | 3749 if (!strict_mode_callee) { |
3751 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex, | 3750 JSObject::cast(result)->InObjectPropertyAtPut(kArgumentsCalleeIndex, |
3752 callee); | 3751 callee); |
3753 } | 3752 } |
3754 | 3753 |
3755 // Check the state of the object | 3754 // Check the state of the object |
3756 ASSERT(JSObject::cast(result)->HasFastProperties()); | 3755 ASSERT(JSObject::cast(result)->HasFastProperties()); |
3757 ASSERT(JSObject::cast(result)->HasFastObjectElements()); | 3756 ASSERT(JSObject::cast(result)->HasFastElements()); |
3758 | 3757 |
3759 return result; | 3758 return result; |
3760 } | 3759 } |
3761 | 3760 |
3762 | 3761 |
3763 static bool HasDuplicates(DescriptorArray* descriptors) { | 3762 static bool HasDuplicates(DescriptorArray* descriptors) { |
3764 int count = descriptors->number_of_descriptors(); | 3763 int count = descriptors->number_of_descriptors(); |
3765 if (count > 1) { | 3764 if (count > 1) { |
3766 String* prev_key = descriptors->GetKey(0); | 3765 String* prev_key = descriptors->GetKey(0); |
3767 for (int i = 1; i != count; i++) { | 3766 for (int i = 1; i != count; i++) { |
(...skipping 24 matching lines...) Expand all Loading... |
3792 prototype = fun->instance_prototype(); | 3791 prototype = fun->instance_prototype(); |
3793 } else { | 3792 } else { |
3794 { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); | 3793 { MaybeObject* maybe_prototype = AllocateFunctionPrototype(fun); |
3795 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; | 3794 if (!maybe_prototype->ToObject(&prototype)) return maybe_prototype; |
3796 } | 3795 } |
3797 } | 3796 } |
3798 Map* map = Map::cast(map_obj); | 3797 Map* map = Map::cast(map_obj); |
3799 map->set_inobject_properties(in_object_properties); | 3798 map->set_inobject_properties(in_object_properties); |
3800 map->set_unused_property_fields(in_object_properties); | 3799 map->set_unused_property_fields(in_object_properties); |
3801 map->set_prototype(prototype); | 3800 map->set_prototype(prototype); |
3802 ASSERT(map->has_fast_object_elements()); | 3801 ASSERT(map->has_fast_elements()); |
3803 | 3802 |
3804 // If the function has only simple this property assignments add | 3803 // If the function has only simple this property assignments add |
3805 // field descriptors for these to the initial map as the object | 3804 // field descriptors for these to the initial map as the object |
3806 // cannot be constructed without having these properties. Guard by | 3805 // cannot be constructed without having these properties. Guard by |
3807 // the inline_new flag so we only change the map if we generate a | 3806 // the inline_new flag so we only change the map if we generate a |
3808 // specialized construct stub. | 3807 // specialized construct stub. |
3809 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); | 3808 ASSERT(in_object_properties <= Map::kMaxPreAllocatedPropertyFields); |
3810 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { | 3809 if (fun->shared()->CanGenerateInlineConstructor(prototype)) { |
3811 int count = fun->shared()->this_property_assignments_count(); | 3810 int count = fun->shared()->this_property_assignments_count(); |
3812 if (count > in_object_properties) { | 3811 if (count > in_object_properties) { |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3909 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; | 3908 if (map->instance_size() > Page::kMaxNonCodeHeapObjectSize) space = LO_SPACE; |
3910 Object* obj; | 3909 Object* obj; |
3911 { MaybeObject* maybe_obj = Allocate(map, space); | 3910 { MaybeObject* maybe_obj = Allocate(map, space); |
3912 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3911 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3913 } | 3912 } |
3914 | 3913 |
3915 // Initialize the JSObject. | 3914 // Initialize the JSObject. |
3916 InitializeJSObjectFromMap(JSObject::cast(obj), | 3915 InitializeJSObjectFromMap(JSObject::cast(obj), |
3917 FixedArray::cast(properties), | 3916 FixedArray::cast(properties), |
3918 map); | 3917 map); |
3919 ASSERT(JSObject::cast(obj)->HasFastSmiOrObjectElements()); | 3918 ASSERT(JSObject::cast(obj)->HasFastSmiOnlyElements() || |
| 3919 JSObject::cast(obj)->HasFastElements()); |
3920 return obj; | 3920 return obj; |
3921 } | 3921 } |
3922 | 3922 |
3923 | 3923 |
3924 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, | 3924 MaybeObject* Heap::AllocateJSObject(JSFunction* constructor, |
3925 PretenureFlag pretenure) { | 3925 PretenureFlag pretenure) { |
3926 // Allocate the initial map if absent. | 3926 // Allocate the initial map if absent. |
3927 if (!constructor->has_initial_map()) { | 3927 if (!constructor->has_initial_map()) { |
3928 Object* initial_map; | 3928 Object* initial_map; |
3929 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); | 3929 { MaybeObject* maybe_initial_map = AllocateInitialMap(constructor); |
(...skipping 24 matching lines...) Expand all Loading... |
3954 } | 3954 } |
3955 | 3955 |
3956 | 3956 |
3957 MaybeObject* Heap::AllocateJSArrayAndStorage( | 3957 MaybeObject* Heap::AllocateJSArrayAndStorage( |
3958 ElementsKind elements_kind, | 3958 ElementsKind elements_kind, |
3959 int length, | 3959 int length, |
3960 int capacity, | 3960 int capacity, |
3961 ArrayStorageAllocationMode mode, | 3961 ArrayStorageAllocationMode mode, |
3962 PretenureFlag pretenure) { | 3962 PretenureFlag pretenure) { |
3963 ASSERT(capacity >= length); | 3963 ASSERT(capacity >= length); |
3964 if (length != 0 && mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE) { | |
3965 elements_kind = GetHoleyElementsKind(elements_kind); | |
3966 } | |
3967 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); | 3964 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); |
3968 JSArray* array; | 3965 JSArray* array; |
3969 if (!maybe_array->To(&array)) return maybe_array; | 3966 if (!maybe_array->To(&array)) return maybe_array; |
3970 | 3967 |
3971 if (capacity == 0) { | 3968 if (capacity == 0) { |
3972 array->set_length(Smi::FromInt(0)); | 3969 array->set_length(Smi::FromInt(0)); |
3973 array->set_elements(empty_fixed_array()); | 3970 array->set_elements(empty_fixed_array()); |
3974 return array; | 3971 return array; |
3975 } | 3972 } |
3976 | 3973 |
3977 FixedArrayBase* elms; | 3974 FixedArrayBase* elms; |
3978 MaybeObject* maybe_elms = NULL; | 3975 MaybeObject* maybe_elms = NULL; |
3979 if (elements_kind == FAST_DOUBLE_ELEMENTS) { | 3976 if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
3980 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { | 3977 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { |
3981 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity); | 3978 maybe_elms = AllocateUninitializedFixedDoubleArray(capacity); |
3982 } else { | 3979 } else { |
3983 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 3980 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
3984 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity); | 3981 maybe_elms = AllocateFixedDoubleArrayWithHoles(capacity); |
3985 } | 3982 } |
3986 } else { | 3983 } else { |
3987 ASSERT(IsFastSmiOrObjectElementsKind(elements_kind)); | 3984 ASSERT(elements_kind == FAST_ELEMENTS || |
| 3985 elements_kind == FAST_SMI_ONLY_ELEMENTS); |
3988 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { | 3986 if (mode == DONT_INITIALIZE_ARRAY_ELEMENTS) { |
3989 maybe_elms = AllocateUninitializedFixedArray(capacity); | 3987 maybe_elms = AllocateUninitializedFixedArray(capacity); |
3990 } else { | 3988 } else { |
3991 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); | 3989 ASSERT(mode == INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
3992 maybe_elms = AllocateFixedArrayWithHoles(capacity); | 3990 maybe_elms = AllocateFixedArrayWithHoles(capacity); |
3993 } | 3991 } |
3994 } | 3992 } |
3995 if (!maybe_elms->To(&elms)) return maybe_elms; | 3993 if (!maybe_elms->To(&elms)) return maybe_elms; |
3996 | 3994 |
3997 array->set_elements(elms); | 3995 array->set_elements(elms); |
3998 array->set_length(Smi::FromInt(length)); | 3996 array->set_length(Smi::FromInt(length)); |
3999 return array; | 3997 return array; |
4000 } | 3998 } |
4001 | 3999 |
4002 | 4000 |
4003 MaybeObject* Heap::AllocateJSArrayWithElements( | 4001 MaybeObject* Heap::AllocateJSArrayWithElements( |
4004 FixedArrayBase* elements, | 4002 FixedArrayBase* elements, |
4005 ElementsKind elements_kind, | 4003 ElementsKind elements_kind, |
4006 PretenureFlag pretenure) { | 4004 PretenureFlag pretenure) { |
4007 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); | 4005 MaybeObject* maybe_array = AllocateJSArray(elements_kind, pretenure); |
4008 JSArray* array; | 4006 JSArray* array; |
4009 if (!maybe_array->To(&array)) return maybe_array; | 4007 if (!maybe_array->To(&array)) return maybe_array; |
4010 | 4008 |
4011 array->set_elements(elements); | 4009 array->set_elements(elements); |
4012 array->set_length(Smi::FromInt(elements->length())); | 4010 array->set_length(Smi::FromInt(elements->length())); |
4013 array->ValidateElements(); | |
4014 return array; | 4011 return array; |
4015 } | 4012 } |
4016 | 4013 |
4017 | 4014 |
4018 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { | 4015 MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) { |
4019 // Allocate map. | 4016 // Allocate map. |
4020 // TODO(rossberg): Once we optimize proxies, think about a scheme to share | 4017 // TODO(rossberg): Once we optimize proxies, think about a scheme to share |
4021 // maps. Will probably depend on the identity of the handler object, too. | 4018 // maps. Will probably depend on the identity of the handler object, too. |
4022 Map* map; | 4019 Map* map; |
4023 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize); | 4020 MaybeObject* maybe_map_obj = AllocateMap(JS_PROXY_TYPE, JSProxy::kSize); |
(...skipping 520 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4544 return result; | 4541 return result; |
4545 } | 4542 } |
4546 | 4543 |
4547 | 4544 |
4548 MaybeObject* Heap::AllocateJSArray( | 4545 MaybeObject* Heap::AllocateJSArray( |
4549 ElementsKind elements_kind, | 4546 ElementsKind elements_kind, |
4550 PretenureFlag pretenure) { | 4547 PretenureFlag pretenure) { |
4551 Context* global_context = isolate()->context()->global_context(); | 4548 Context* global_context = isolate()->context()->global_context(); |
4552 JSFunction* array_function = global_context->array_function(); | 4549 JSFunction* array_function = global_context->array_function(); |
4553 Map* map = array_function->initial_map(); | 4550 Map* map = array_function->initial_map(); |
4554 Object* maybe_map_array = global_context->js_array_maps(); | 4551 if (elements_kind == FAST_DOUBLE_ELEMENTS) { |
4555 if (!maybe_map_array->IsUndefined()) { | 4552 map = Map::cast(global_context->double_js_array_map()); |
4556 Object* maybe_transitioned_map = | 4553 } else if (elements_kind == FAST_ELEMENTS || !FLAG_smi_only_arrays) { |
4557 FixedArray::cast(maybe_map_array)->get(elements_kind); | 4554 map = Map::cast(global_context->object_js_array_map()); |
4558 if (!maybe_transitioned_map->IsUndefined()) { | 4555 } else { |
4559 map = Map::cast(maybe_transitioned_map); | 4556 ASSERT(elements_kind == FAST_SMI_ONLY_ELEMENTS); |
4560 } | 4557 ASSERT(map == global_context->smi_js_array_map()); |
4561 } | 4558 } |
4562 | 4559 |
4563 return AllocateJSObjectFromMap(map, pretenure); | 4560 return AllocateJSObjectFromMap(map, pretenure); |
4564 } | 4561 } |
4565 | 4562 |
4566 | 4563 |
4567 MaybeObject* Heap::AllocateEmptyFixedArray() { | 4564 MaybeObject* Heap::AllocateEmptyFixedArray() { |
4568 int size = FixedArray::SizeFor(0); | 4565 int size = FixedArray::SizeFor(0); |
4569 Object* result; | 4566 Object* result; |
4570 { MaybeObject* maybe_result = | 4567 { MaybeObject* maybe_result = |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4835 | 4832 |
4836 | 4833 |
4837 MaybeObject* Heap::AllocateGlobalContext() { | 4834 MaybeObject* Heap::AllocateGlobalContext() { |
4838 Object* result; | 4835 Object* result; |
4839 { MaybeObject* maybe_result = | 4836 { MaybeObject* maybe_result = |
4840 AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); | 4837 AllocateFixedArray(Context::GLOBAL_CONTEXT_SLOTS); |
4841 if (!maybe_result->ToObject(&result)) return maybe_result; | 4838 if (!maybe_result->ToObject(&result)) return maybe_result; |
4842 } | 4839 } |
4843 Context* context = reinterpret_cast<Context*>(result); | 4840 Context* context = reinterpret_cast<Context*>(result); |
4844 context->set_map_no_write_barrier(global_context_map()); | 4841 context->set_map_no_write_barrier(global_context_map()); |
4845 context->set_js_array_maps(undefined_value()); | 4842 context->set_smi_js_array_map(undefined_value()); |
| 4843 context->set_double_js_array_map(undefined_value()); |
| 4844 context->set_object_js_array_map(undefined_value()); |
4846 ASSERT(context->IsGlobalContext()); | 4845 ASSERT(context->IsGlobalContext()); |
4847 ASSERT(result->IsContext()); | 4846 ASSERT(result->IsContext()); |
4848 return result; | 4847 return result; |
4849 } | 4848 } |
4850 | 4849 |
4851 | 4850 |
4852 MaybeObject* Heap::AllocateModuleContext(Context* previous, | 4851 MaybeObject* Heap::AllocateModuleContext(Context* previous, |
4853 ScopeInfo* scope_info) { | 4852 ScopeInfo* scope_info) { |
4854 Object* result; | 4853 Object* result; |
4855 { MaybeObject* maybe_result = | 4854 { MaybeObject* maybe_result = |
(...skipping 2289 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7145 } else { | 7144 } else { |
7146 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. | 7145 p ^= 0x1d1ed & (Page::kPageSize - 1); // I died. |
7147 } | 7146 } |
7148 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = | 7147 remembered_unmapped_pages_[remembered_unmapped_pages_index_] = |
7149 reinterpret_cast<Address>(p); | 7148 reinterpret_cast<Address>(p); |
7150 remembered_unmapped_pages_index_++; | 7149 remembered_unmapped_pages_index_++; |
7151 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; | 7150 remembered_unmapped_pages_index_ %= kRememberedUnmappedPages; |
7152 } | 7151 } |
7153 | 7152 |
7154 } } // namespace v8::internal | 7153 } } // namespace v8::internal |
OLD | NEW |