blob: a884b3b9ed8c03713d12414ca951386016cdebf1 [file] [log] [blame]
karlklose@chromium.org83a47282011-05-11 11:54:09 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// 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_SCOPEINFO_H_
29#define V8_SCOPEINFO_H_
30
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000032#include "variables.h"
ager@chromium.orgce5e87b2010-03-10 10:24:18 +000033#include "zone-inl.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000034
kasperl@chromium.org71affb52009-05-26 05:44:31 +000035namespace v8 {
36namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000038// Cache for mapping (data, property name) into context slot index.
ager@chromium.org5aa501c2009-06-23 07:57:28 +000039// The cache contains both positive and negative results.
40// Slot index equals -1 means the property is absent.
41// Cleared at startup and prior to mark sweep collection.
42class ContextSlotCache {
43 public:
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000044 // Lookup context slot index for (data, name).
ager@chromium.org5aa501c2009-06-23 07:57:28 +000045 // If absent, kNotFound is returned.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000046 int Lookup(Object* data,
47 String* name,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000048 VariableMode* mode,
49 InitializationFlag* init_flag);
ager@chromium.org5aa501c2009-06-23 07:57:28 +000050
51 // Update an element in the cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000052 void Update(Object* data,
53 String* name,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +000054 VariableMode mode,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000055 InitializationFlag init_flag,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000056 int slot_index);
ager@chromium.org5aa501c2009-06-23 07:57:28 +000057
58 // Clear the cache.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000059 void Clear();
ager@chromium.org5aa501c2009-06-23 07:57:28 +000060
61 static const int kNotFound = -2;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +000062
ager@chromium.org5aa501c2009-06-23 07:57:28 +000063 private:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000064 ContextSlotCache() {
65 for (int i = 0; i < kLength; ++i) {
66 keys_[i].data = NULL;
67 keys_[i].name = NULL;
68 values_[i] = kNotFound;
69 }
70 }
71
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000072 inline static int Hash(Object* data, String* name);
ager@chromium.org5aa501c2009-06-23 07:57:28 +000073
74#ifdef DEBUG
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075 void ValidateEntry(Object* data,
76 String* name,
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +000077 VariableMode mode,
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000078 InitializationFlag init_flag,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000079 int slot_index);
ager@chromium.org5aa501c2009-06-23 07:57:28 +000080#endif
81
82 static const int kLength = 256;
83 struct Key {
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +000084 Object* data;
ager@chromium.org5aa501c2009-06-23 07:57:28 +000085 String* name;
86 };
87
88 struct Value {
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000089 Value(VariableMode mode,
90 InitializationFlag init_flag,
91 int index) {
ager@chromium.org5aa501c2009-06-23 07:57:28 +000092 ASSERT(ModeField::is_valid(mode));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000093 ASSERT(InitField::is_valid(init_flag));
ager@chromium.org5aa501c2009-06-23 07:57:28 +000094 ASSERT(IndexField::is_valid(index));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000095 value_ = ModeField::encode(mode) |
96 IndexField::encode(index) |
97 InitField::encode(init_flag);
ager@chromium.org5aa501c2009-06-23 07:57:28 +000098 ASSERT(mode == this->mode());
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +000099 ASSERT(init_flag == this->initialization_flag());
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000100 ASSERT(index == this->index());
101 }
102
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000103 explicit inline Value(uint32_t value) : value_(value) {}
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000104
105 uint32_t raw() { return value_; }
106
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000107 VariableMode mode() { return ModeField::decode(value_); }
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000108
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000109 InitializationFlag initialization_flag() {
110 return InitField::decode(value_);
111 }
112
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000113 int index() { return IndexField::decode(value_); }
114
115 // Bit fields in value_ (type, shift, size). Must be public so the
116 // constants can be embedded in generated code.
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000117 class ModeField: public BitField<VariableMode, 0, 4> {};
118 class InitField: public BitField<InitializationFlag, 4, 1> {};
119 class IndexField: public BitField<int, 5, 32-5> {};
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000120
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000121 private:
122 uint32_t value_;
123 };
124
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000125 Key keys_[kLength];
126 uint32_t values_[kLength];
127
128 friend class Isolate;
129 DISALLOW_COPY_AND_ASSIGN(ContextSlotCache);
ager@chromium.org5aa501c2009-06-23 07:57:28 +0000130};
131
132
ulan@chromium.org8e8d8822012-11-23 14:36:46 +0000133
134
135//---------------------------------------------------------------------------
136// Auxiliary class used for the description of module instances.
137// Used by Runtime_DeclareModules.
138
139class ModuleInfo: public FixedArray {
140 public:
141 static ModuleInfo* cast(Object* description) {
142 return static_cast<ModuleInfo*>(FixedArray::cast(description));
143 }
144
145 static Handle<ModuleInfo> Create(
146 Isolate* isolate, Interface* interface, Scope* scope);
147
148 // Index of module's context in host context.
149 int host_index() { return Smi::cast(get(HOST_OFFSET))->value(); }
150
151 // Name, mode, and index of the i-th export, respectively.
152 // For value exports, the index is the slot of the value in the module
153 // context, for exported modules it is the slot index of the
154 // referred module's context in the host context.
155 // TODO(rossberg): This format cannot yet handle exports of modules declared
156 // in earlier scripts.
157 String* name(int i) { return String::cast(get(name_offset(i))); }
158 VariableMode mode(int i) {
159 return static_cast<VariableMode>(Smi::cast(get(mode_offset(i)))->value());
160 }
161 int index(int i) { return Smi::cast(get(index_offset(i)))->value(); }
162
163 int length() { return (FixedArray::length() - HEADER_SIZE) / ITEM_SIZE; }
164
165 private:
166 // The internal format is: Index, (Name, VariableMode, Index)*
167 enum {
168 HOST_OFFSET,
169 NAME_OFFSET,
170 MODE_OFFSET,
171 INDEX_OFFSET,
172 HEADER_SIZE = NAME_OFFSET,
173 ITEM_SIZE = INDEX_OFFSET - NAME_OFFSET + 1
174 };
175 inline int name_offset(int i) { return NAME_OFFSET + i * ITEM_SIZE; }
176 inline int mode_offset(int i) { return MODE_OFFSET + i * ITEM_SIZE; }
177 inline int index_offset(int i) { return INDEX_OFFSET + i * ITEM_SIZE; }
178
179 static Handle<ModuleInfo> Allocate(Isolate* isolate, int length) {
180 return Handle<ModuleInfo>::cast(
181 isolate->factory()->NewFixedArray(HEADER_SIZE + ITEM_SIZE * length));
182 }
183 void set_host_index(int index) { set(HOST_OFFSET, Smi::FromInt(index)); }
184 void set_name(int i, String* name) { set(name_offset(i), name); }
185 void set_mode(int i, VariableMode mode) {
186 set(mode_offset(i), Smi::FromInt(mode));
187 }
188 void set_index(int i, int index) {
189 set(index_offset(i), Smi::FromInt(index));
190 }
191};
192
193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194} } // namespace v8::internal
195
196#endif // V8_SCOPEINFO_H_