blob: 7acb88fdaf7f4c1a33dda0b548824a5f45020d10 [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_H_
29#define V8_TRANSITIONS_H_
30
31#include "elements-kind.h"
32#include "heap.h"
33#include "isolate.h"
34#include "objects.h"
35#include "v8checks.h"
36
37namespace v8 {
38namespace internal {
39
40
41// TransitionArrays are fixed arrays used to hold map transitions for property,
42// constant, and element changes.
43// The format of the these objects is:
44// [0] Elements transition
45// [1] First transition
46// [length() - kTransitionSize] Last transition
47class TransitionArray: public FixedArray {
48 public:
danno@chromium.org81cac2b2012-07-10 11:28:27 +000049 // Accessors for fetching instance transition at transition number.
50 inline String* GetKey(int transition_number);
51 inline void SetKey(int transition_number, String* value);
52 inline Object** GetKeySlot(int transition_number);
53
verwaest@chromium.org753aee42012-07-17 16:15:42 +000054 inline Map* GetTarget(int transition_number);
55 inline void SetTarget(int transition_number, Map* target);
56 inline Object** GetTargetSlot(int transition_number);
danno@chromium.org81cac2b2012-07-10 11:28:27 +000057
danno@chromium.org81cac2b2012-07-10 11:28:27 +000058 inline PropertyDetails GetTargetDetails(int transition_number);
59
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000060 inline Map* elements_transition();
61 inline void set_elements_transition(
verwaest@chromium.org753aee42012-07-17 16:15:42 +000062 Map* target,
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000063 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
danno@chromium.org81cac2b2012-07-10 11:28:27 +000064 inline Object** GetElementsTransitionSlot();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000065 inline bool HasElementsTransition();
danno@chromium.org81cac2b2012-07-10 11:28:27 +000066 inline void ClearElementsTransition();
67
68 inline FixedArray* GetPrototypeTransitions();
69 inline void SetPrototypeTransitions(
70 FixedArray* prototype_transitions,
71 WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
72 inline Object** GetPrototypeTransitionsSlot();
73 inline bool HasPrototypeTransitions();
74 inline HeapObject* UncheckedPrototypeTransitions();
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000075
76 // Returns the number of transitions in the array.
77 int number_of_transitions() {
78 ASSERT(length() >= kFirstIndex);
79 int len = length();
80 return len <= kFirstIndex ? 0 : (len - kFirstIndex) / kTransitionSize;
81 }
82
83 inline int number_of_entries() { return number_of_transitions(); }
84
85 // Allocate a new transition array with a single entry.
verwaest@chromium.org753aee42012-07-17 16:15:42 +000086 static MUST_USE_RESULT MaybeObject* NewWith(String* name, Map* target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000087
88 // Copy the transition array, inserting a new transition.
89 // TODO(verwaest): This should not cause an existing transition to be
90 // overwritten.
verwaest@chromium.org753aee42012-07-17 16:15:42 +000091 MUST_USE_RESULT MaybeObject* CopyInsert(String* name, Map* target);
yangguo@chromium.org99aa4902012-07-06 16:21:55 +000092
93 // Copy a single transition from the origin array.
94 inline void CopyFrom(TransitionArray* origin,
95 int origin_transition,
96 int target_transition,
97 const WhitenessWitness& witness);
98
99 // Search a transition for a given property name.
100 inline int Search(String* name);
101
102 // Allocates a TransitionArray.
103 MUST_USE_RESULT static MaybeObject* Allocate(int number_of_transitions);
104
105 // Casting.
106 static inline TransitionArray* cast(Object* obj);
107
108 // Constant for denoting key was not found.
109 static const int kNotFound = -1;
110
111 static const int kElementsTransitionIndex = 0;
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000112 static const int kPrototypeTransitionsIndex = 1;
113 static const int kFirstIndex = 2;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000114
115 // Layout transition array header.
116 static const int kElementsTransitionOffset = FixedArray::kHeaderSize;
danno@chromium.org81cac2b2012-07-10 11:28:27 +0000117 static const int kPrototypeTransitionsOffset = kElementsTransitionOffset +
118 kPointerSize;
119 static const int kFirstOffset = kPrototypeTransitionsOffset + kPointerSize;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000120
121 // Layout of map transition.
122 static const int kTransitionKey = 0;
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000123 static const int kTransitionTarget = 1;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000124 static const int kTransitionSize = 2;
125
126#ifdef OBJECT_PRINT
127 // Print all the transitions.
128 inline void PrintTransitions() {
129 PrintTransitions(stdout);
130 }
131 void PrintTransitions(FILE* out);
132#endif
133
134#ifdef DEBUG
135 bool IsSortedNoDuplicates();
136 bool IsConsistentWithBackPointers(Map* current_map);
137 bool IsEqualTo(TransitionArray* other);
138#endif
139
140 // The maximum number of transitions we want in a transition array (should
141 // fit in a page).
142 static const int kMaxNumberOfTransitions = 1024 + 512;
143
144 private:
145 // Conversion from transition number to array indices.
146 static int ToKeyIndex(int transition_number) {
147 return kFirstIndex +
148 (transition_number * kTransitionSize) +
149 kTransitionKey;
150 }
151
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000152 static int ToTargetIndex(int transition_number) {
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000153 return kFirstIndex +
154 (transition_number * kTransitionSize) +
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000155 kTransitionTarget;
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000156 }
157
158 inline void Set(int transition_number,
159 String* key,
verwaest@chromium.org753aee42012-07-17 16:15:42 +0000160 Map* target,
yangguo@chromium.org99aa4902012-07-06 16:21:55 +0000161 const WhitenessWitness&);
162
163 DISALLOW_IMPLICIT_CONSTRUCTORS(TransitionArray);
164};
165
166
167} } // namespace v8::internal
168
169#endif // V8_TRANSITIONS_H_