blob: 9d3f038947d139694ae7a5563d42a4792484438f [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.org3d00d0a2013-09-04 13:57:32 +000038static MaybeObject* AllocateRaw(Isolate* isolate, int length) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000039 // Use FixedArray to not use TransitionArray::cast on incomplete object.
ulan@chromium.org56c14af2012-09-20 12:51:09 +000040 FixedArray* array;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000041 MaybeObject* maybe_array = isolate->heap()->AllocateFixedArray(length);
ulan@chromium.org56c14af2012-09-20 12:51:09 +000042 if (!maybe_array->To(&array)) return maybe_array;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000043 return array;
44}
45
46
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000047MaybeObject* TransitionArray::Allocate(Isolate* isolate,
48 int number_of_transitions) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000049 FixedArray* array;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000050 MaybeObject* maybe_array =
51 AllocateRaw(isolate, ToKeyIndex(number_of_transitions));
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000052 if (!maybe_array->To(&array)) return maybe_array;
danno@chromium.org81cac2b2012-07-10 11:28:27 +000053 array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000054 return array;
55}
56
57
ulan@chromium.org56c14af2012-09-20 12:51:09 +000058void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
59 int origin_transition,
60 int target_transition) {
61 NoIncrementalWriteBarrierSet(target_transition,
62 origin->GetKey(origin_transition),
63 origin->GetTarget(origin_transition));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000064}
65
66
ulan@chromium.org750145a2013-03-07 15:14:13 +000067static bool InsertionPointFound(Name* key1, Name* key2) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000068 return key1->Hash() > key2->Hash();
69}
70
71
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000072MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
ulan@chromium.org750145a2013-03-07 15:14:13 +000073 Name* key,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000074 Map* target,
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000075 Object* back_pointer) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000076 TransitionArray* result;
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000077 MaybeObject* maybe_result;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000078
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000079 if (flag == SIMPLE_TRANSITION) {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000080 maybe_result = AllocateRaw(target->GetIsolate(), kSimpleTransitionSize);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000081 if (!maybe_result->To(&result)) return maybe_result;
82 result->set(kSimpleTransitionTarget, target);
83 } else {
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000084 maybe_result = Allocate(target->GetIsolate(), 1);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000085 if (!maybe_result->To(&result)) return maybe_result;
86 result->NoIncrementalWriteBarrierSet(0, key, target);
87 }
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +000088 result->set_back_pointer_storage(back_pointer);
ulan@chromium.org56c14af2012-09-20 12:51:09 +000089 return result;
90}
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000091
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000092
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000093MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
94 ASSERT(!IsFullTransitionArray());
95 int nof = number_of_transitions();
96 TransitionArray* result;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +000097 MaybeObject* maybe_result = Allocate(GetIsolate(), nof);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000098 if (!maybe_result->To(&result)) return maybe_result;
99
100 if (nof == 1) {
101 result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
102 }
103
104 result->set_back_pointer_storage(back_pointer_storage());
105 return result;
106}
107
108
ulan@chromium.org750145a2013-03-07 15:14:13 +0000109MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000110 TransitionArray* result;
111
112 int number_of_transitions = this->number_of_transitions();
113 int new_size = number_of_transitions;
114
115 int insertion_index = this->Search(name);
116 if (insertion_index == kNotFound) ++new_size;
117
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000118 MaybeObject* maybe_array;
jkummerow@chromium.org3d00d0a2013-09-04 13:57:32 +0000119 maybe_array = TransitionArray::Allocate(GetIsolate(), new_size);
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000120 if (!maybe_array->To(&result)) return maybe_array;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000121
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000122 if (HasPrototypeTransitions()) {
123 result->SetPrototypeTransitions(GetPrototypeTransitions());
124 }
125
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000126 if (insertion_index != kNotFound) {
127 for (int i = 0; i < number_of_transitions; ++i) {
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000128 if (i != insertion_index) {
129 result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
130 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000131 }
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000132 result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
danno@chromium.orgf005df62013-04-30 16:36:45 +0000133 result->set_back_pointer_storage(back_pointer_storage());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000134 return result;
135 }
136
137 insertion_index = 0;
138 for (; insertion_index < number_of_transitions; ++insertion_index) {
139 if (InsertionPointFound(GetKey(insertion_index), name)) break;
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000140 result->NoIncrementalWriteBarrierCopyFrom(
141 this, insertion_index, insertion_index);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000142 }
143
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000144 result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000145
146 for (; insertion_index < number_of_transitions; ++insertion_index) {
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000147 result->NoIncrementalWriteBarrierCopyFrom(
148 this, insertion_index, insertion_index + 1);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000149 }
150
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +0000151 result->set_back_pointer_storage(back_pointer_storage());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000152 return result;
153}
154
155
156} } // namespace v8::internal