blob: c4825fcf734a590dc6dbe114355fa3fc08fede2a [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#ifndef V8_TRANSITIONS_INL_H_
29#define V8_TRANSITIONS_INL_H_
30
31#include "objects-inl.h"
32#include "transitions.h"
33
34namespace v8 {
35namespace internal {
36
37
38#define FIELD_ADDR(p, offset) \
39 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
40
41#define WRITE_FIELD(p, offset, value) \
42 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
43
44#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
45 if (mode == UPDATE_WRITE_BARRIER) { \
46 heap->incremental_marking()->RecordWrite( \
47 object, HeapObject::RawField(object, offset), value); \
48 if (heap->InNewSpace(value)) { \
49 heap->RecordWrite(object->address(), offset); \
50 } \
51 }
52
53
54TransitionArray* TransitionArray::cast(Object* object) {
55 ASSERT(object->IsTransitionArray());
56 return reinterpret_cast<TransitionArray*>(object);
57}
58
59
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000060bool TransitionArray::HasElementsTransition() {
danno@chromium.orgd3c42102013-08-01 16:58:23 +000061 return Search(GetHeap()->elements_transition_symbol()) != kNotFound;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000062}
63
64
verwaest@chromium.orgde64f722012-08-16 15:44:54 +000065Object* TransitionArray::back_pointer_storage() {
66 return get(kBackPointerStorageIndex);
67}
68
69
70void TransitionArray::set_back_pointer_storage(Object* back_pointer,
71 WriteBarrierMode mode) {
72 Heap* heap = GetHeap();
73 WRITE_FIELD(this, kBackPointerStorageOffset, back_pointer);
74 CONDITIONAL_WRITE_BARRIER(
75 heap, this, kBackPointerStorageOffset, back_pointer, mode);
76}
77
78
danno@chromium.org81cac2b2012-07-10 11:28:27 +000079bool TransitionArray::HasPrototypeTransitions() {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000080 return IsFullTransitionArray() &&
81 get(kPrototypeTransitionsIndex) != Smi::FromInt(0);
danno@chromium.org81cac2b2012-07-10 11:28:27 +000082}
83
84
85FixedArray* TransitionArray::GetPrototypeTransitions() {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +000086 ASSERT(IsFullTransitionArray());
danno@chromium.org81cac2b2012-07-10 11:28:27 +000087 Object* prototype_transitions = get(kPrototypeTransitionsIndex);
88 return FixedArray::cast(prototype_transitions);
89}
90
91
92HeapObject* TransitionArray::UncheckedPrototypeTransitions() {
verwaest@chromium.orgde64f722012-08-16 15:44:54 +000093 ASSERT(HasPrototypeTransitions());
94 return reinterpret_cast<HeapObject*>(get(kPrototypeTransitionsIndex));
danno@chromium.org81cac2b2012-07-10 11:28:27 +000095}
96
97
98void TransitionArray::SetPrototypeTransitions(FixedArray* transitions,
99 WriteBarrierMode mode) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000100 ASSERT(IsFullTransitionArray());
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000101 ASSERT(transitions->IsFixedArray());
102 Heap* heap = GetHeap();
103 WRITE_FIELD(this, kPrototypeTransitionsOffset, transitions);
104 CONDITIONAL_WRITE_BARRIER(
105 heap, this, kPrototypeTransitionsOffset, transitions, mode);
106}
107
108
109Object** TransitionArray::GetPrototypeTransitionsSlot() {
110 return HeapObject::RawField(reinterpret_cast<HeapObject*>(this),
111 kPrototypeTransitionsOffset);
112}
113
114
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000115Object** TransitionArray::GetKeySlot(int transition_number) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000116 ASSERT(!IsSimpleTransition());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000117 ASSERT(transition_number < number_of_transitions());
118 return HeapObject::RawField(
119 reinterpret_cast<HeapObject*>(this),
120 OffsetOfElementAt(ToKeyIndex(transition_number)));
121}
122
123
ulan@chromium.org750145a2013-03-07 15:14:13 +0000124Name* TransitionArray::GetKey(int transition_number) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000125 if (IsSimpleTransition()) {
126 Map* target = GetTarget(kSimpleTransitionIndex);
127 int descriptor = target->LastAdded();
ulan@chromium.org750145a2013-03-07 15:14:13 +0000128 Name* key = target->instance_descriptors()->GetKey(descriptor);
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000129 return key;
130 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000131 ASSERT(transition_number < number_of_transitions());
ulan@chromium.org750145a2013-03-07 15:14:13 +0000132 return Name::cast(get(ToKeyIndex(transition_number)));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000133}
134
135
ulan@chromium.org750145a2013-03-07 15:14:13 +0000136void TransitionArray::SetKey(int transition_number, Name* key) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000137 ASSERT(!IsSimpleTransition());
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000138 ASSERT(transition_number < number_of_transitions());
139 set(ToKeyIndex(transition_number), key);
140}
141
142
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000143Map* TransitionArray::GetTarget(int transition_number) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000144 if (IsSimpleTransition()) {
145 ASSERT(transition_number == kSimpleTransitionIndex);
146 return Map::cast(get(kSimpleTransitionTarget));
147 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000148 ASSERT(transition_number < number_of_transitions());
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000149 return Map::cast(get(ToTargetIndex(transition_number)));
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000150}
151
152
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000153void TransitionArray::SetTarget(int transition_number, Map* value) {
verwaest@chromium.org33e09c82012-10-10 17:07:22 +0000154 if (IsSimpleTransition()) {
155 ASSERT(transition_number == kSimpleTransitionIndex);
156 return set(kSimpleTransitionTarget, value);
157 }
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000158 ASSERT(transition_number < number_of_transitions());
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000159 set(ToTargetIndex(transition_number), value);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000160}
161
162
163PropertyDetails TransitionArray::GetTargetDetails(int transition_number) {
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000164 Map* map = GetTarget(transition_number);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000165 DescriptorArray* descriptors = map->instance_descriptors();
yangguo@chromium.org304cc332012-07-24 07:59:48 +0000166 int descriptor = map->LastAdded();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000167 return descriptors->GetDetails(descriptor);
168}
169
170
ulan@chromium.org750145a2013-03-07 15:14:13 +0000171int TransitionArray::Search(Name* name) {
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000172 if (IsSimpleTransition()) {
ulan@chromium.org750145a2013-03-07 15:14:13 +0000173 Name* key = GetKey(kSimpleTransitionIndex);
rossberg@chromium.org89e18f52012-10-22 13:09:53 +0000174 if (key->Equals(name)) return kSimpleTransitionIndex;
175 return kNotFound;
176 }
verwaest@chromium.org06ab2ec2012-10-09 17:00:13 +0000177 return internal::Search<ALL_ENTRIES>(this, name);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000178}
179
180
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000181void TransitionArray::NoIncrementalWriteBarrierSet(int transition_number,
ulan@chromium.org750145a2013-03-07 15:14:13 +0000182 Name* key,
ulan@chromium.org56c14af2012-09-20 12:51:09 +0000183 Map* target) {
184 FixedArray::NoIncrementalWriteBarrierSet(
185 this, ToKeyIndex(transition_number), key);
186 FixedArray::NoIncrementalWriteBarrierSet(
187 this, ToTargetIndex(transition_number), target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000188}
189
190
191#undef FIELD_ADDR
192#undef WRITE_FIELD
193#undef CONDITIONAL_WRITE_BARRIER
194
195
196} } // namespace v8::internal
197
198#endif // V8_TRANSITIONS_INL_H_