blob: df53178dd3d451bdf5514b2f50599b5755016660 [file] [log] [blame]
yangguo@chromium.org99aa4902012-07-06 16:21:55 +00001// Copyright 2012 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#include "v8.h"
29
30#include "objects.h"
31#include "transitions-inl.h"
32#include "utils.h"
33
34namespace v8 {
35namespace internal {
36
37
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +000038static MaybeObject* AllocateRaw(int length) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000039 Heap* heap = Isolate::Current()->heap();
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +000040
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000041 // Use FixedArray to not use TransitionArray::cast on incomplete object.
ulan@chromium.org56c14af2012-09-20 12:51:09 +000042 FixedArray* array;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000043 MaybeObject* maybe_array = heap->AllocateFixedArray(length);
ulan@chromium.org56c14af2012-09-20 12:51:09 +000044 if (!maybe_array->To(&array)) return maybe_array;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000045 return array;
46}
47
48
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +000049MaybeObject* TransitionArray::Allocate(int number_of_transitions) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000050 FixedArray* array;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +000051 MaybeObject* maybe_array = AllocateRaw(ToKeyIndex(number_of_transitions));
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000052 if (!maybe_array->To(&array)) return maybe_array;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000053 array->set(kElementsTransitionIndex, Smi::FromInt(0));
danno@chromium.org81cac2b2012-07-10 11:28:27 +000054 array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000055 return array;
56}
57
58
ulan@chromium.org56c14af2012-09-20 12:51:09 +000059void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
60 int origin_transition,
61 int target_transition) {
62 NoIncrementalWriteBarrierSet(target_transition,
63 origin->GetKey(origin_transition),
64 origin->GetTarget(origin_transition));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000065}
66
67
ulan@chromium.org750145a2013-03-07 15:14:13 +000068static bool InsertionPointFound(Name* key1, Name* key2) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000069 return key1->Hash() > key2->Hash();
70}
71
72
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000073MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
ulan@chromium.org750145a2013-03-07 15:14:13 +000074 Name* key,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000075 Map* target,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000076 Object* back_pointer) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000077 TransitionArray* result;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000078 MaybeObject* maybe_result;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000079
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000080 if (flag == SIMPLE_TRANSITION) {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +000081 maybe_result = AllocateRaw(kSimpleTransitionSize);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000082 if (!maybe_result->To(&result)) return maybe_result;
83 result->set(kSimpleTransitionTarget, target);
84 } else {
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +000085 maybe_result = Allocate(1);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000086 if (!maybe_result->To(&result)) return maybe_result;
87 result->NoIncrementalWriteBarrierSet(0, key, target);
88 }
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +000089 result->set_back_pointer_storage(back_pointer);
ulan@chromium.org56c14af2012-09-20 12:51:09 +000090 return result;
91}
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000092
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000093
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000094MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
95 ASSERT(!IsFullTransitionArray());
96 int nof = number_of_transitions();
97 TransitionArray* result;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +000098 MaybeObject* maybe_result = Allocate(nof);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000099 if (!maybe_result->To(&result)) return maybe_result;
100
101 if (nof == 1) {
102 result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
103 }
104
105 result->set_back_pointer_storage(back_pointer_storage());
106 return result;
107}
108
109
ulan@chromium.org750145a2013-03-07 15:14:13 +0000110MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000111 TransitionArray* result;
112
113 int number_of_transitions = this->number_of_transitions();
114 int new_size = number_of_transitions;
115
116 int insertion_index = this->Search(name);
117 if (insertion_index == kNotFound) ++new_size;
118
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000119 MaybeObject* maybe_array;
jkummerow@chromium.orgc1956672012-10-11 15:57:38 +0000120 maybe_array = TransitionArray::Allocate(new_size);
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000121 if (!maybe_array->To(&result)) return maybe_array;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000122
123 if (HasElementsTransition()) {
124 result->set_elements_transition(elements_transition());
125 }
126
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000127 if (HasPrototypeTransitions()) {
128 result->SetPrototypeTransitions(GetPrototypeTransitions());
129 }
130
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000131 if (insertion_index != kNotFound) {
132 for (int i = 0; i < number_of_transitions; ++i) {
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000133 if (i != insertion_index) {
134 result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
135 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000136 }
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000137 result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000138 result->set_back_pointer_storage(back_pointer_storage());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000139 return result;
140 }
141
142 insertion_index = 0;
143 for (; insertion_index < number_of_transitions; ++insertion_index) {
144 if (InsertionPointFound(GetKey(insertion_index), name)) break;
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000145 result->NoIncrementalWriteBarrierCopyFrom(
146 this, insertion_index, insertion_index);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000147 }
148
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000149 result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000150
151 for (; insertion_index < number_of_transitions; ++insertion_index) {
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000152 result->NoIncrementalWriteBarrierCopyFrom(
153 this, insertion_index, insertion_index + 1);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000154 }
155
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +0000156 result->set_back_pointer_storage(back_pointer_storage());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000157 return result;
158}
159
160
161} } // namespace v8::internal