Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(540)

Side by Side Diff: src/scopeinfo.cc

Issue 7979001: Scope tree serialization and ScopeIterator cleanup. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 // Consider sorting them according to type as well? 44 // Consider sorting them according to type as well?
45 return x - y; 45 return x - y;
46 } 46 }
47 47
48 48
49 template<class Allocator> 49 template<class Allocator>
50 ScopeInfo<Allocator>::ScopeInfo(Scope* scope) 50 ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
51 : function_name_(FACTORY->empty_symbol()), 51 : function_name_(FACTORY->empty_symbol()),
52 calls_eval_(scope->calls_eval()), 52 calls_eval_(scope->calls_eval()),
53 is_strict_mode_(scope->is_strict_mode()), 53 is_strict_mode_(scope->is_strict_mode()),
54 type_(scope->type()),
55 source_beg_statement_pos_(scope->SourceBegStatementPos()),
56 source_end_statement_pos_(scope->SourceEndStatementPos()),
54 parameters_(scope->num_parameters()), 57 parameters_(scope->num_parameters()),
55 stack_slots_(scope->num_stack_slots()), 58 stack_slots_(scope->num_stack_slots()),
56 context_slots_(scope->num_heap_slots()), 59 context_slots_(scope->num_heap_slots()),
57 context_modes_(scope->num_heap_slots()) { 60 context_modes_(scope->num_heap_slots()),
61 inner_scopeinfos_(scope->InnerScopes()->length()) {
58 // Add parameters. 62 // Add parameters.
59 for (int i = 0; i < scope->num_parameters(); i++) { 63 for (int i = 0; i < scope->num_parameters(); i++) {
60 ASSERT(parameters_.length() == i); 64 ASSERT(parameters_.length() == i);
61 parameters_.Add(scope->parameter(i)->name()); 65 parameters_.Add(scope->parameter(i)->name());
62 } 66 }
63 67
64 // Add stack locals and collect heap locals. 68 // Add stack locals and collect heap locals.
65 // We are assuming that the locals' slots are allocated in 69 // We are assuming that the locals' slots are allocated in
66 // increasing order, so we can simply add them to the 70 // increasing order, so we can simply add them to the
67 // ScopeInfo lists. However, due to usage analysis, this is 71 // ScopeInfo lists. However, due to usage analysis, this is
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
134 // Contexts::Lookup() function. Thus record an empty symbol here so we 138 // Contexts::Lookup() function. Thus record an empty symbol here so we
135 // get the correct number of context slots. 139 // get the correct number of context slots.
136 ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS == 140 ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS ==
137 context_slots_.length()); 141 context_slots_.length());
138 ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS == 142 ASSERT(proxy->var()->index() - Context::MIN_CONTEXT_SLOTS ==
139 context_modes_.length()); 143 context_modes_.length());
140 context_slots_.Add(FACTORY->empty_symbol()); 144 context_slots_.Add(FACTORY->empty_symbol());
141 context_modes_.Add(Variable::INTERNAL); 145 context_modes_.Add(Variable::INTERNAL);
142 } 146 }
143 } 147 }
148
149 // Add nested scope information. Only nested block, catch or with scopes are
150 // tracked, but no inner function scopes.
151 ZoneList<Scope*>* inner_scopes = scope->InnerScopes();
152 for (int i = 0; i < inner_scopes->length(); i++) {
153 if (!inner_scopes->at(i)->is_declaration_scope()) {
154 inner_scopeinfos_.Add(SerializedScopeInfo::Create(inner_scopes->at(i)));
155 }
156 }
144 } 157 }
145 158
146 159
147 // Encoding format in a FixedArray object: 160 // Encoding format in a FixedArray object:
148 // 161 //
149 // - function name 162 // - function name
150 // 163 //
151 // - calls eval boolean flag 164 // - calls eval boolean flag
Kevin Millikin (Chromium) 2011/10/05 08:43:36 This is a separate change, but this class should b
Steven 2011/10/06 19:09:27 Yes I agree. We will talk about this cleanup later
152 // 165 //
166 // - is strict mode scope
167 //
168 // - scope type
169 //
170 // - start statement position
171 //
172 // - end statement position
173 //
153 // - number of variables in the context object (smi) (= function context 174 // - number of variables in the context object (smi) (= function context
154 // slot index + 1) 175 // slot index + 1)
155 // - list of pairs (name, Var mode) of context-allocated variables (starting 176 // - list of pairs (name, Var mode) of context-allocated variables (starting
156 // with context slot 0) 177 // with context slot 0)
157 // 178 //
158 // - number of parameters (smi) 179 // - number of parameters (smi)
159 // - list of parameter names (starting with parameter 0 first) 180 // - list of parameter names (starting with parameter 0 first)
160 // 181 //
161 // - number of variables on the stack (smi) 182 // - number of variables on the stack (smi)
162 // - list of names of stack-allocated variables (starting with stack slot 0) 183 // - list of names of stack-allocated variables (starting with stack slot 0)
184 //
185 // - number of immediate nested scopes (smi)
186 // - list of handles to serialized scope infos for nested scopes
163 187
164 // The ScopeInfo representation could be simplified and the ScopeInfo 188 // The ScopeInfo representation could be simplified and the ScopeInfo
165 // re-implemented (with almost the same interface). Here is a 189 // re-implemented (with almost the same interface). Here is a
166 // suggestion for the new format: 190 // suggestion for the new format:
167 // 191 //
168 // - have a single list with all variable names (parameters, stack locals, 192 // - have a single list with all variable names (parameters, stack locals,
169 // context locals), followed by a list of non-Object* values containing 193 // context locals), followed by a list of non-Object* values containing
170 // the variables information (what kind, index, attributes) 194 // the variables information (what kind, index, attributes)
171 // - searching the linear list of names is fast and yields an index into the 195 // - searching the linear list of names is fast and yields an index into the
172 // list if the variable name is found 196 // list if the variable name is found
173 // - that list index is then used to find the variable information in the 197 // - that list index is then used to find the variable information in the
174 // subsequent list 198 // subsequent list
175 // - the list entries don't have to be in any particular order, so all the 199 // - the list entries don't have to be in any particular order, so all the
176 // current sorting business can go away 200 // current sorting business can go away
177 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup 201 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup
178 // which returns all information at once 202 // which returns all information at once
179 // - when gathering the information from a Scope, we only need to iterate 203 // - when gathering the information from a Scope, we only need to iterate
180 // through the local variables (parameters and context info is already 204 // through the local variables (parameters and context info is already
181 // present) 205 // present)
182 206
183 207
184 static inline Object** ReadInt(Object** p, int* x) { 208 template <class T>
185 *x = (reinterpret_cast<Smi*>(*p++))->value(); 209 static inline Object** ReadInt(Object** p, T* x) {
210 *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value());
186 return p; 211 return p;
187 } 212 }
188 213
189 214
190 static inline Object** ReadBool(Object** p, bool* x) { 215 static inline Object** ReadBool(Object** p, bool* x) {
191 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0; 216 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0;
192 return p; 217 return p;
193 } 218 }
194 219
195 220
196 static inline Object** ReadSymbol(Object** p, Handle<String>* s) { 221 template <class T>
197 *s = Handle<String>(reinterpret_cast<String*>(*p++)); 222 static inline Object** ReadObject(Object** p, Handle<T>* s) {
223 *s = Handle<T>::cast(Handle<Object>(*p++));
198 return p; 224 return p;
199 } 225 }
200 226
201 227
202 template <class Allocator> 228 template <class Allocator, class T>
203 static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) { 229 static Object** ReadList(Object** p, List<Handle<T>, Allocator >* list) {
204 ASSERT(list->is_empty()); 230 ASSERT(list->is_empty());
205 int n; 231 int n;
206 p = ReadInt(p, &n); 232 p = ReadInt(p, &n);
207 while (n-- > 0) { 233 while (n-- > 0) {
208 Handle<String> s; 234 Handle<T> s;
209 p = ReadSymbol(p, &s); 235 p = ReadObject(p, &s);
210 list->Add(s); 236 list->Add(s);
211 } 237 }
212 return p; 238 return p;
213 } 239 }
214 240
215 241
216 template <class Allocator> 242 template <class Allocator>
217 static Object** ReadList(Object** p, 243 static Object** ReadList(Object** p,
218 List<Handle<String>, Allocator>* list, 244 List<Handle<String>, Allocator>* list,
219 List<Variable::Mode, Allocator>* modes) { 245 List<Variable::Mode, Allocator>* modes) {
220 ASSERT(list->is_empty()); 246 ASSERT(list->is_empty());
221 int n; 247 int n;
222 p = ReadInt(p, &n); 248 p = ReadInt(p, &n);
223 while (n-- > 0) { 249 while (n-- > 0) {
224 Handle<String> s; 250 Handle<String> s;
225 int m; 251 int m;
226 p = ReadSymbol(p, &s); 252 p = ReadObject(p, &s);
227 p = ReadInt(p, &m); 253 p = ReadInt(p, &m);
228 list->Add(s); 254 list->Add(s);
229 modes->Add(static_cast<Variable::Mode>(m)); 255 modes->Add(static_cast<Variable::Mode>(m));
230 } 256 }
231 return p; 257 return p;
232 } 258 }
233 259
234 260
235 template<class Allocator> 261 template<class Allocator>
236 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) 262 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
Kevin Millikin (Chromium) 2011/10/05 08:43:36 Also, for future refactoring. Do we need the abil
Steven 2011/10/06 19:09:27 No we can unify those classes, they only differ sl
237 : function_name_(FACTORY->empty_symbol()), 263 : function_name_(FACTORY->empty_symbol()),
238 parameters_(4), 264 parameters_(4),
239 stack_slots_(8), 265 stack_slots_(8),
240 context_slots_(8), 266 context_slots_(8),
241 context_modes_(8) { 267 context_modes_(8),
268 inner_scopeinfos_(4) {
242 if (data->length() > 0) { 269 if (data->length() > 0) {
243 Object** p0 = data->data_start(); 270 Object** p0 = data->data_start();
244 Object** p = p0; 271 Object** p = p0;
245 p = ReadSymbol(p, &function_name_); 272 p = ReadObject(p, &function_name_);
246 p = ReadBool(p, &calls_eval_); 273 p = ReadBool(p, &calls_eval_);
247 p = ReadBool(p, &is_strict_mode_); 274 p = ReadBool(p, &is_strict_mode_);
275 p = ReadInt(p, &type_);
276 p = ReadInt(p, &source_beg_statement_pos_);
277 p = ReadInt(p, &source_end_statement_pos_);
248 p = ReadList<Allocator>(p, &context_slots_, &context_modes_); 278 p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
249 p = ReadList<Allocator>(p, &parameters_); 279 p = ReadList<Allocator>(p, &parameters_);
250 p = ReadList<Allocator>(p, &stack_slots_); 280 p = ReadList<Allocator>(p, &stack_slots_);
281 p = ReadList<Allocator>(p, &inner_scopeinfos_);
251 ASSERT((p - p0) == FixedArray::cast(data)->length()); 282 ASSERT((p - p0) == FixedArray::cast(data)->length());
252 } 283 }
253 } 284 }
254 285
255 286
256 static inline Object** WriteInt(Object** p, int x) { 287 static inline Object** WriteInt(Object** p, int x) {
257 *p++ = Smi::FromInt(x); 288 *p++ = Smi::FromInt(x);
258 return p; 289 return p;
259 } 290 }
260 291
261 292
262 static inline Object** WriteBool(Object** p, bool b) { 293 static inline Object** WriteBool(Object** p, bool b) {
263 *p++ = Smi::FromInt(b ? 1 : 0); 294 *p++ = Smi::FromInt(b ? 1 : 0);
264 return p; 295 return p;
265 } 296 }
266 297
267 298
268 static inline Object** WriteSymbol(Object** p, Handle<String> s) { 299 template <class T>
300 static inline Object** WriteObject(Object** p, Handle<T> s) {
269 *p++ = *s; 301 *p++ = *s;
270 return p; 302 return p;
271 } 303 }
272 304
273 305
274 template <class Allocator> 306 template <class Allocator, class T>
275 static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) { 307 static Object** WriteList(Object** p, List<Handle<T>, Allocator >* list) {
276 const int n = list->length(); 308 const int n = list->length();
277 p = WriteInt(p, n); 309 p = WriteInt(p, n);
278 for (int i = 0; i < n; i++) { 310 for (int i = 0; i < n; i++) {
279 p = WriteSymbol(p, list->at(i)); 311 p = WriteObject(p, list->at(i));
280 } 312 }
281 return p; 313 return p;
282 } 314 }
283 315
284 316
285 template <class Allocator> 317 template <class Allocator>
286 static Object** WriteList(Object** p, 318 static Object** WriteList(Object** p,
287 List<Handle<String>, Allocator>* list, 319 List<Handle<String>, Allocator>* list,
288 List<Variable::Mode, Allocator>* modes) { 320 List<Variable::Mode, Allocator>* modes) {
289 const int n = list->length(); 321 const int n = list->length();
290 p = WriteInt(p, n); 322 p = WriteInt(p, n);
291 for (int i = 0; i < n; i++) { 323 for (int i = 0; i < n; i++) {
292 p = WriteSymbol(p, list->at(i)); 324 p = WriteObject(p, list->at(i));
293 p = WriteInt(p, modes->at(i)); 325 p = WriteInt(p, modes->at(i));
294 } 326 }
295 return p; 327 return p;
296 } 328 }
297 329
298 330
299 template<class Allocator> 331 template<class Allocator>
300 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { 332 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
301 // function name, calls eval, is_strict_mode, length for 3 tables: 333 // function name, calls eval, is_strict_mode, scope type, source beg pos,
302 const int extra_slots = 1 + 1 + 1 + 3; 334 // source end pos, length for 4 tables:
335 const int extra_slots = 1 + 1 + 1 + 1 + 1 + 1 + 4;
303 int length = extra_slots + 336 int length = extra_slots +
304 context_slots_.length() * 2 + 337 context_slots_.length() * 2 +
305 parameters_.length() + 338 parameters_.length() +
306 stack_slots_.length(); 339 stack_slots_.length() +
340 inner_scopeinfos_.length();
307 341
308 Handle<SerializedScopeInfo> data( 342 Handle<SerializedScopeInfo> data(
309 SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length))); 343 SerializedScopeInfo::cast(*FACTORY->NewSerializedScopeInfo(length)));
310 AssertNoAllocation nogc; 344 AssertNoAllocation nogc;
311 345
312 Object** p0 = data->data_start(); 346 Object** p0 = data->data_start();
313 Object** p = p0; 347 Object** p = p0;
314 p = WriteSymbol(p, function_name_); 348 p = WriteObject(p, function_name_);
315 p = WriteBool(p, calls_eval_); 349 p = WriteBool(p, calls_eval_);
316 p = WriteBool(p, is_strict_mode_); 350 p = WriteBool(p, is_strict_mode_);
351 p = WriteInt(p, type_);
352 p = WriteInt(p, source_beg_statement_pos_);
353 p = WriteInt(p, source_end_statement_pos_);
317 p = WriteList(p, &context_slots_, &context_modes_); 354 p = WriteList(p, &context_slots_, &context_modes_);
318 p = WriteList(p, &parameters_); 355 p = WriteList(p, &parameters_);
319 p = WriteList(p, &stack_slots_); 356 p = WriteList(p, &stack_slots_);
357 p = WriteList(p, &inner_scopeinfos_);
320 ASSERT((p - p0) == length); 358 ASSERT((p - p0) == length);
321 359
322 return data; 360 return data;
323 } 361 }
324 362
325 363
326 template<class Allocator> 364 template<class Allocator>
327 Handle<String> ScopeInfo<Allocator>::LocalName(int i) const { 365 Handle<String> ScopeInfo<Allocator>::LocalName(int i) const {
328 // A local variable can be allocated either on the stack or in the context. 366 // A local variable can be allocated either on the stack or in the context.
329 // For variables allocated in the context they are always preceded by 367 // For variables allocated in the context they are always preceded by
(...skipping 24 matching lines...) Expand all
354 } 392 }
355 393
356 394
357 SerializedScopeInfo* SerializedScopeInfo::Empty() { 395 SerializedScopeInfo* SerializedScopeInfo::Empty() {
358 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array()); 396 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array());
359 } 397 }
360 398
361 399
362 Object** SerializedScopeInfo::ContextEntriesAddr() { 400 Object** SerializedScopeInfo::ContextEntriesAddr() {
363 ASSERT(length() > 0); 401 ASSERT(length() > 0);
364 // +3 for function name, calls eval, strict mode. 402 // +6 for function name, calls eval, strict mode, scope type, source beg pos,
365 return data_start() + 3; 403 // source end pos.
404 return data_start() + 6;
366 } 405 }
367 406
368 407
369 Object** SerializedScopeInfo::ParameterEntriesAddr() { 408 Object** SerializedScopeInfo::ParameterEntriesAddr() {
370 ASSERT(length() > 0); 409 ASSERT(length() > 0);
371 Object** p = ContextEntriesAddr(); 410 Object** p = ContextEntriesAddr();
372 int number_of_context_slots; 411 int number_of_context_slots;
373 p = ReadInt(p, &number_of_context_slots); 412 p = ReadInt(p, &number_of_context_slots);
374 return p + number_of_context_slots*2; // *2 for pairs 413 return p + number_of_context_slots*2; // *2 for pairs
375 } 414 }
376 415
377 416
378 Object** SerializedScopeInfo::StackSlotEntriesAddr() { 417 Object** SerializedScopeInfo::StackSlotEntriesAddr() {
379 ASSERT(length() > 0); 418 ASSERT(length() > 0);
380 Object** p = ParameterEntriesAddr(); 419 Object** p = ParameterEntriesAddr();
381 int number_of_parameter_slots; 420 int number_of_parameter_slots;
382 p = ReadInt(p, &number_of_parameter_slots); 421 p = ReadInt(p, &number_of_parameter_slots);
383 return p + number_of_parameter_slots; 422 return p + number_of_parameter_slots;
384 } 423 }
385 424
386 425
426 Object** SerializedScopeInfo::NestedScopeEntriesAddr() {
427 ASSERT(length() > 0);
428 Object** p = StackSlotEntriesAddr();
429 int number_of_stack_slots;
430 p = ReadInt(p, &number_of_stack_slots);
431 return p + number_of_stack_slots;
432 }
433
434
387 bool SerializedScopeInfo::CallsEval() { 435 bool SerializedScopeInfo::CallsEval() {
388 if (length() > 0) { 436 if (length() > 0) {
389 Object** p = data_start() + 1; // +1 for function name. 437 Object** p = data_start() + 1; // +1 for function name.
390 bool calls_eval; 438 bool calls_eval;
391 p = ReadBool(p, &calls_eval); 439 p = ReadBool(p, &calls_eval);
392 return calls_eval; 440 return calls_eval;
393 } 441 }
394 return false; 442 return false;
395 } 443 }
396 444
397 445
398 bool SerializedScopeInfo::IsStrictMode() { 446 bool SerializedScopeInfo::IsStrictMode() {
399 if (length() > 0) { 447 if (length() > 0) {
400 Object** p = data_start() + 2; // +2 for function name, calls eval. 448 Object** p = data_start() + 2; // +2 for function name, calls eval.
401 bool strict_mode; 449 bool strict_mode;
402 p = ReadBool(p, &strict_mode); 450 p = ReadBool(p, &strict_mode);
403 return strict_mode; 451 return strict_mode;
404 } 452 }
405 return false; 453 return false;
406 } 454 }
407 455
408 456
457 Scope::Type SerializedScopeInfo::ScopeType() {
458 ASSERT(length() > 0);
459 // +3 for function name, calls eval, strict mode.
460 Object** p = data_start() + 3;
461 Scope::Type type;
462 p = ReadInt(p, &type);
Kevin Millikin (Chromium) 2011/10/05 08:43:36 Future refactoring: if you decide to keep the stre
463 return type;
464 }
465
466
467 int SerializedScopeInfo::SourceBegStatementPos() {
468 if (length() > 0) {
469 // +4 for function name, calls eval, strict mode, scope type.
470 Object** p = data_start() + 4;
471 int source_beg_statement_pos;
472 p = ReadInt(p, &source_beg_statement_pos);
473 return source_beg_statement_pos;
474 }
475 return -1;
Kevin Millikin (Chromium) 2011/10/05 08:43:36 -1 is RelocInfo::kNoPosition?
Steven 2011/10/06 19:09:27 Yes it is. Using the named constant now. On 2011/1
476 }
477
478
479 int SerializedScopeInfo::SourceEndStatementPos() {
480 if (length() > 0) {
481 // +5 for function name, calls eval, strict mode, scope type,
482 // source beg pos.
483 Object** p = data_start() + 5;
484 int source_end_statement_pos;
485 p = ReadInt(p, &source_end_statement_pos);
486 return source_end_statement_pos;
487 }
488 return -1;
489 }
490
491
409 int SerializedScopeInfo::NumberOfStackSlots() { 492 int SerializedScopeInfo::NumberOfStackSlots() {
410 if (length() > 0) { 493 if (length() > 0) {
411 Object** p = StackSlotEntriesAddr(); 494 Object** p = StackSlotEntriesAddr();
412 int number_of_stack_slots; 495 int number_of_stack_slots;
413 ReadInt(p, &number_of_stack_slots); 496 ReadInt(p, &number_of_stack_slots);
414 return number_of_stack_slots; 497 return number_of_stack_slots;
415 } 498 }
416 return 0; 499 return 0;
417 } 500 }
418 501
419 502
420 int SerializedScopeInfo::NumberOfContextSlots() { 503 int SerializedScopeInfo::NumberOfContextSlots() {
421 if (length() > 0) { 504 if (length() > 0) {
422 Object** p = ContextEntriesAddr(); 505 Object** p = ContextEntriesAddr();
423 int number_of_context_slots; 506 int number_of_context_slots;
424 ReadInt(p, &number_of_context_slots); 507 ReadInt(p, &number_of_context_slots);
425 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS; 508 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS;
426 } 509 }
427 return 0; 510 return 0;
428 } 511 }
429 512
430 513
514 int SerializedScopeInfo::NumberOfNestedScopes() {
515 if (length() > 0) {
516 Object** p = NestedScopeEntriesAddr();
517 int number_of_nested_scopes;
518 ReadInt(p, &number_of_nested_scopes);
519 return number_of_nested_scopes;
520 }
521 return 0;
522 }
523
524
525 Handle<SerializedScopeInfo> SerializedScopeInfo::NestedScope(int i) {
526 ASSERT(0 <= i && i < NumberOfNestedScopes());
527 Object* p = *(NestedScopeEntriesAddr() + i + 1);
528 return Handle<SerializedScopeInfo>(reinterpret_cast<SerializedScopeInfo*>(p));
529 }
530
531
431 bool SerializedScopeInfo::HasHeapAllocatedLocals() { 532 bool SerializedScopeInfo::HasHeapAllocatedLocals() {
432 if (length() > 0) { 533 if (length() > 0) {
433 Object** p = ContextEntriesAddr(); 534 Object** p = ContextEntriesAddr();
434 int number_of_context_slots; 535 int number_of_context_slots;
435 ReadInt(p, &number_of_context_slots); 536 ReadInt(p, &number_of_context_slots);
436 return number_of_context_slots > 0; 537 return number_of_context_slots > 0;
437 } 538 }
438 return false; 539 return false;
439 } 540 }
440 541
441 542
543 bool SerializedScopeInfo::HasContext() {
544 return HasHeapAllocatedLocals() ||
545 ScopeType() == Scope::WITH_SCOPE;
546 }
547
548
442 int SerializedScopeInfo::StackSlotIndex(String* name) { 549 int SerializedScopeInfo::StackSlotIndex(String* name) {
443 ASSERT(name->IsSymbol()); 550 ASSERT(name->IsSymbol());
444 if (length() > 0) { 551 if (length() > 0) {
445 // Slots start after length entry. 552 // Slots start after length entry.
446 Object** p0 = StackSlotEntriesAddr(); 553 Object** p0 = StackSlotEntriesAddr();
447 int number_of_stack_slots; 554 int number_of_stack_slots;
448 p0 = ReadInt(p0, &number_of_stack_slots); 555 p0 = ReadInt(p0, &number_of_stack_slots);
449 Object** p = p0; 556 Object** p = p0;
450 Object** end = p0 + number_of_stack_slots; 557 Object** end = p0 + number_of_stack_slots;
451 while (p != end) { 558 while (p != end) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
523 ReadInt(p, &number_of_context_slots); 630 ReadInt(p, &number_of_context_slots);
524 ASSERT(number_of_context_slots != 0); 631 ASSERT(number_of_context_slots != 0);
525 // The function context slot is the last entry. 632 // The function context slot is the last entry.
526 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1; 633 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1;
527 } 634 }
528 } 635 }
529 return -1; 636 return -1;
530 } 637 }
531 638
532 639
640 void SerializedScopeInfo::GetNestedScopeChain(
641 List<Handle<SerializedScopeInfo> >* chain,
642 int position) {
643 chain->Add(Handle<SerializedScopeInfo>(this));
644
645 for (int i = 0; i < NumberOfNestedScopes(); i++) {
646 Handle<SerializedScopeInfo> scope = NestedScope(i);
647 int beg_pos = scope->SourceBegStatementPos();
648 int end_pos = scope->SourceEndStatementPos();
649 ASSERT(beg_pos >= 0 && end_pos >= 0);
650 if (beg_pos <= position && position <= end_pos) {
651 scope->GetNestedScopeChain(chain, position);
652 return;
653 }
654 }
655 }
656
657
533 int ContextSlotCache::Hash(Object* data, String* name) { 658 int ContextSlotCache::Hash(Object* data, String* name) {
534 // Uses only lower 32 bits if pointers are larger. 659 // Uses only lower 32 bits if pointers are larger.
535 uintptr_t addr_hash = 660 uintptr_t addr_hash =
536 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 661 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
537 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 662 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
538 } 663 }
539 664
540 665
541 int ContextSlotCache::Lookup(Object* data, 666 int ContextSlotCache::Lookup(Object* data,
542 String* name, 667 String* name,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
632 } 757 }
633 #endif // DEBUG 758 #endif // DEBUG
634 759
635 760
636 // Make sure the classes get instantiated by the template system. 761 // Make sure the classes get instantiated by the template system.
637 template class ScopeInfo<FreeStoreAllocationPolicy>; 762 template class ScopeInfo<FreeStoreAllocationPolicy>;
638 template class ScopeInfo<PreallocatedStorage>; 763 template class ScopeInfo<PreallocatedStorage>;
639 template class ScopeInfo<ZoneListAllocationPolicy>; 764 template class ScopeInfo<ZoneListAllocationPolicy>;
640 765
641 } } // namespace v8::internal 766 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698