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

Side by Side Diff: src/scopeinfo.cc

Issue 7523027: Provisional implementation of stack allocated catch variables. Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 9 years, 4 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
« no previous file with comments | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
48 // Consider sorting them according to type as well? 48 // Consider sorting them according to type as well?
49 return x - y; 49 return x - y;
50 } 50 }
51 51
52 52
53 template<class Allocator> 53 template<class Allocator>
54 ScopeInfo<Allocator>::ScopeInfo(Scope* scope) 54 ScopeInfo<Allocator>::ScopeInfo(Scope* scope)
55 : function_name_(FACTORY->empty_symbol()), 55 : function_name_(FACTORY->empty_symbol()),
56 calls_eval_(scope->calls_eval()), 56 calls_eval_(scope->calls_eval()),
57 is_strict_mode_(scope->is_strict_mode()), 57 is_strict_mode_(scope->is_strict_mode()),
58 type_(scope->type()),
59 source_beg_statement_pos_(scope->SourceBegStatementPos()),
60 source_end_statement_pos_(scope->SourceEndStatementPos()),
61 first_stack_index_(-1),
58 parameters_(scope->num_parameters()), 62 parameters_(scope->num_parameters()),
59 stack_slots_(scope->num_stack_slots()), 63 stack_slots_(scope->num_stack_slots()),
60 context_slots_(scope->num_heap_slots()), 64 context_slots_(scope->num_heap_slots()),
61 context_modes_(scope->num_heap_slots()) { 65 context_modes_(scope->num_heap_slots()),
66 inner_scopeinfos_(scope->InnerScopes()->length()) {
62 // Add parameters. 67 // Add parameters.
63 for (int i = 0; i < scope->num_parameters(); i++) { 68 for (int i = 0; i < scope->num_parameters(); i++) {
64 ASSERT(parameters_.length() == i); 69 ASSERT(parameters_.length() == i);
65 parameters_.Add(scope->parameter(i)->name()); 70 parameters_.Add(scope->parameter(i)->name());
66 } 71 }
67 72
68 // Add stack locals and collect heap locals. 73 // Add stack locals and collect heap locals.
69 // We are assuming that the locals' slots are allocated in 74 // We are assuming that the locals' slots are allocated in
70 // increasing order, so we can simply add them to the 75 // increasing order, so we can simply add them to the
71 // ScopeInfo lists. However, due to usage analysis, this is 76 // ScopeInfo lists. However, due to usage analysis, this is
(...skipping 15 matching lines...) Expand all
87 Variable* var = locals[i]; 92 Variable* var = locals[i];
88 if (var->is_used()) { 93 if (var->is_used()) {
89 Slot* slot = var->AsSlot(); 94 Slot* slot = var->AsSlot();
90 if (slot != NULL) { 95 if (slot != NULL) {
91 switch (slot->type()) { 96 switch (slot->type()) {
92 case Slot::PARAMETER: 97 case Slot::PARAMETER:
93 // explicitly added to parameters_ above - ignore 98 // explicitly added to parameters_ above - ignore
94 break; 99 break;
95 100
96 case Slot::LOCAL: 101 case Slot::LOCAL:
97 ASSERT(stack_slots_.length() == slot->index()); 102 if (first_stack_index_ < 0) first_stack_index_ = slot->index();
103 ASSERT(stack_slots_.length() + first_stack_index_ == slot->index());
98 stack_slots_.Add(var->name()); 104 stack_slots_.Add(var->name());
99 break; 105 break;
100 106
101 case Slot::CONTEXT: 107 case Slot::CONTEXT:
102 heap_locals.Add(var); 108 heap_locals.Add(var);
103 break; 109 break;
104 110
105 case Slot::LOOKUP: 111 case Slot::LOOKUP:
106 // This is currently not used. 112 // This is currently not used.
107 UNREACHABLE(); 113 UNREACHABLE();
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 // Contexts::Lookup() function. Thus record an empty symbol here so we 147 // Contexts::Lookup() function. Thus record an empty symbol here so we
142 // get the correct number of context slots. 148 // get the correct number of context slots.
143 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS == 149 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
144 context_slots_.length()); 150 context_slots_.length());
145 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS == 151 ASSERT(var->AsSlot()->index() - Context::MIN_CONTEXT_SLOTS ==
146 context_modes_.length()); 152 context_modes_.length());
147 context_slots_.Add(FACTORY->empty_symbol()); 153 context_slots_.Add(FACTORY->empty_symbol());
148 context_modes_.Add(Variable::INTERNAL); 154 context_modes_.Add(Variable::INTERNAL);
149 } 155 }
150 } 156 }
157
158 // Add inner scope information.
159 ZoneList<Scope*>* inner_scopes = scope->InnerScopes();
160 for (int i = 0; i < inner_scopes->length(); i++) {
161 if (!inner_scopes->at(i)->is_catch_scope() &&
162 !inner_scopes->at(i)->is_with_scope()) continue;
163 inner_scopeinfos_.Add(SerializedScopeInfo::Create(inner_scopes->at(i)));
164 }
151 } 165 }
152 166
153 167
154 // Encoding format in a FixedArray object: 168 // Encoding format in a FixedArray object:
155 // 169 //
156 // - function name 170 // - function name
157 // 171 //
158 // - calls eval boolean flag 172 // - calls eval boolean flag
159 // 173 //
174 // - strict scope boolean flag
175 //
176 // - scope type
177 //
178 // - start statement position
179 //
180 // - end statement position
181 //
182 // - first stack index for stack slots
183 //
160 // - number of variables in the context object (smi) (= function context 184 // - number of variables in the context object (smi) (= function context
161 // slot index + 1) 185 // slot index + 1)
162 // - list of pairs (name, Var mode) of context-allocated variables (starting 186 // - list of pairs (name, Var mode) of context-allocated variables (starting
163 // with context slot 0) 187 // with context slot 0)
164 // 188 //
165 // - number of parameters (smi) 189 // - number of parameters (smi)
166 // - list of parameter names (starting with parameter 0 first) 190 // - list of parameter names (starting with parameter 0 first)
167 // 191 //
168 // - number of variables on the stack (smi) 192 // - number of variables on the stack (smi)
169 // - list of names of stack-allocated variables (starting with stack slot 0) 193 // - list of names of stack-allocated variables (starting with stack slot 0)
194 //
195 // - number of immediate nested scopes (smi)
196 // - list of handles to serialized scope infos for nested scopes
170 197
171 // The ScopeInfo representation could be simplified and the ScopeInfo 198 // The ScopeInfo representation could be simplified and the ScopeInfo
172 // re-implemented (with almost the same interface). Here is a 199 // re-implemented (with almost the same interface). Here is a
173 // suggestion for the new format: 200 // suggestion for the new format:
174 // 201 //
175 // - have a single list with all variable names (parameters, stack locals, 202 // - have a single list with all variable names (parameters, stack locals,
176 // context locals), followed by a list of non-Object* values containing 203 // context locals), followed by a list of non-Object* values containing
177 // the variables information (what kind, index, attributes) 204 // the variables information (what kind, index, attributes)
178 // - searching the linear list of names is fast and yields an index into the 205 // - searching the linear list of names is fast and yields an index into the
179 // list if the variable name is found 206 // list if the variable name is found
180 // - that list index is then used to find the variable information in the 207 // - that list index is then used to find the variable information in the
181 // subsequent list 208 // subsequent list
182 // - the list entries don't have to be in any particular order, so all the 209 // - the list entries don't have to be in any particular order, so all the
183 // current sorting business can go away 210 // current sorting business can go away
184 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup 211 // - the ScopeInfo lookup routines can be reduced to perhaps a single lookup
185 // which returns all information at once 212 // which returns all information at once
186 // - when gathering the information from a Scope, we only need to iterate 213 // - when gathering the information from a Scope, we only need to iterate
187 // through the local variables (parameters and context info is already 214 // through the local variables (parameters and context info is already
188 // present) 215 // present)
189 216
190 217
191 static inline Object** ReadInt(Object** p, int* x) { 218 template <class T>
192 *x = (reinterpret_cast<Smi*>(*p++))->value(); 219 static inline Object** ReadInt(Object** p, T* x) {
220 *x = static_cast<T>((reinterpret_cast<Smi*>(*p++))->value());
193 return p; 221 return p;
194 } 222 }
195 223
196 224
197 static inline Object** ReadBool(Object** p, bool* x) { 225 static inline Object** ReadBool(Object** p, bool* x) {
198 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0; 226 *x = (reinterpret_cast<Smi*>(*p++))->value() != 0;
199 return p; 227 return p;
200 } 228 }
201 229
202 230
203 static inline Object** ReadSymbol(Object** p, Handle<String>* s) { 231 template <class T>
204 *s = Handle<String>(reinterpret_cast<String*>(*p++)); 232 static inline Object** ReadSymbol(Object** p, Handle<T>* s) {
233 *s = Handle<T>(reinterpret_cast<T*>(*p++));
205 return p; 234 return p;
206 } 235 }
207 236
208 237
209 template <class Allocator> 238 template <class Allocator, class T>
210 static Object** ReadList(Object** p, List<Handle<String>, Allocator >* list) { 239 static Object** ReadList(Object** p, List<Handle<T>, Allocator >* list) {
211 ASSERT(list->is_empty()); 240 ASSERT(list->is_empty());
212 int n; 241 int n;
213 p = ReadInt(p, &n); 242 p = ReadInt(p, &n);
214 while (n-- > 0) { 243 while (n-- > 0) {
215 Handle<String> s; 244 Handle<T> s;
216 p = ReadSymbol(p, &s); 245 p = ReadSymbol(p, &s);
217 list->Add(s); 246 list->Add(s);
218 } 247 }
219 return p; 248 return p;
220 } 249 }
221 250
222 251
223 template <class Allocator> 252 template <class Allocator>
224 static Object** ReadList(Object** p, 253 static Object** ReadList(Object** p,
225 List<Handle<String>, Allocator>* list, 254 List<Handle<String>, Allocator>* list,
(...skipping 12 matching lines...) Expand all
238 return p; 267 return p;
239 } 268 }
240 269
241 270
242 template<class Allocator> 271 template<class Allocator>
243 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data) 272 ScopeInfo<Allocator>::ScopeInfo(SerializedScopeInfo* data)
244 : function_name_(FACTORY->empty_symbol()), 273 : function_name_(FACTORY->empty_symbol()),
245 parameters_(4), 274 parameters_(4),
246 stack_slots_(8), 275 stack_slots_(8),
247 context_slots_(8), 276 context_slots_(8),
248 context_modes_(8) { 277 context_modes_(8),
278 inner_scopeinfos_(4) {
249 if (data->length() > 0) { 279 if (data->length() > 0) {
250 Object** p0 = data->data_start(); 280 Object** p0 = data->data_start();
251 Object** p = p0; 281 Object** p = p0;
252 p = ReadSymbol(p, &function_name_); 282 p = ReadSymbol(p, &function_name_);
253 p = ReadBool(p, &calls_eval_); 283 p = ReadBool(p, &calls_eval_);
254 p = ReadBool(p, &is_strict_mode_); 284 p = ReadBool(p, &is_strict_mode_);
285 p = ReadInt(p, &type_);
286 p = ReadInt(p, &source_beg_statement_pos_);
287 p = ReadInt(p, &source_end_statement_pos_);
288 p = ReadInt(p, &first_stack_index_);
255 p = ReadList<Allocator>(p, &context_slots_, &context_modes_); 289 p = ReadList<Allocator>(p, &context_slots_, &context_modes_);
256 p = ReadList<Allocator>(p, &parameters_); 290 p = ReadList<Allocator>(p, &parameters_);
257 p = ReadList<Allocator>(p, &stack_slots_); 291 p = ReadList<Allocator>(p, &stack_slots_);
292 p = ReadList<Allocator>(p, &inner_scopeinfos_);
258 ASSERT((p - p0) == FixedArray::cast(data)->length()); 293 ASSERT((p - p0) == FixedArray::cast(data)->length());
259 } 294 }
260 } 295 }
261 296
262 297
263 static inline Object** WriteInt(Object** p, int x) { 298 static inline Object** WriteInt(Object** p, int x) {
264 *p++ = Smi::FromInt(x); 299 *p++ = Smi::FromInt(x);
265 return p; 300 return p;
266 } 301 }
267 302
268 303
269 static inline Object** WriteBool(Object** p, bool b) { 304 static inline Object** WriteBool(Object** p, bool b) {
270 *p++ = Smi::FromInt(b ? 1 : 0); 305 *p++ = Smi::FromInt(b ? 1 : 0);
271 return p; 306 return p;
272 } 307 }
273 308
274 309
275 static inline Object** WriteSymbol(Object** p, Handle<String> s) { 310 template <class T>
311 static inline Object** WriteSymbol(Object** p, Handle<T> s) {
276 *p++ = *s; 312 *p++ = *s;
277 return p; 313 return p;
278 } 314 }
279 315
280 316
281 template <class Allocator> 317 template <class Allocator, class T>
282 static Object** WriteList(Object** p, List<Handle<String>, Allocator >* list) { 318 static Object** WriteList(Object** p, List<Handle<T>, Allocator >* list) {
283 const int n = list->length(); 319 const int n = list->length();
284 p = WriteInt(p, n); 320 p = WriteInt(p, n);
285 for (int i = 0; i < n; i++) { 321 for (int i = 0; i < n; i++) {
286 p = WriteSymbol(p, list->at(i)); 322 p = WriteSymbol(p, list->at(i));
287 } 323 }
288 return p; 324 return p;
289 } 325 }
290 326
291 327
292 template <class Allocator> 328 template <class Allocator>
293 static Object** WriteList(Object** p, 329 static Object** WriteList(Object** p,
294 List<Handle<String>, Allocator>* list, 330 List<Handle<String>, Allocator>* list,
295 List<Variable::Mode, Allocator>* modes) { 331 List<Variable::Mode, Allocator>* modes) {
296 const int n = list->length(); 332 const int n = list->length();
297 p = WriteInt(p, n); 333 p = WriteInt(p, n);
298 for (int i = 0; i < n; i++) { 334 for (int i = 0; i < n; i++) {
299 p = WriteSymbol(p, list->at(i)); 335 p = WriteSymbol(p, list->at(i));
300 p = WriteInt(p, modes->at(i)); 336 p = WriteInt(p, modes->at(i));
301 } 337 }
302 return p; 338 return p;
303 } 339 }
304 340
305 341
306 template<class Allocator> 342 template<class Allocator>
307 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() { 343 Handle<SerializedScopeInfo> ScopeInfo<Allocator>::Serialize() {
308 // function name, calls eval, is_strict_mode, length for 3 tables: 344 // function name, calls eval, scope type, is_strict_mode, source beg pos,
309 const int extra_slots = 1 + 1 + 1 + 3; 345 // source end pos, first stack slot, length for 4 tables:
346 const int extra_slots = 1 + 1 + 1 + 1 + 1 + 1 + 1 + 4;
310 int length = extra_slots + 347 int length = extra_slots +
311 context_slots_.length() * 2 + 348 context_slots_.length() * 2 +
312 parameters_.length() + 349 parameters_.length() +
313 stack_slots_.length(); 350 stack_slots_.length() +
351 inner_scopeinfos_.length();
314 352
315 Handle<SerializedScopeInfo> data( 353 Handle<SerializedScopeInfo> data(
316 SerializedScopeInfo::cast(*FACTORY->NewFixedArray(length, TENURED))); 354 SerializedScopeInfo::cast(*FACTORY->NewFixedArray(length, TENURED)));
317 AssertNoAllocation nogc; 355 AssertNoAllocation nogc;
318 356
319 Object** p0 = data->data_start(); 357 Object** p0 = data->data_start();
320 Object** p = p0; 358 Object** p = p0;
321 p = WriteSymbol(p, function_name_); 359 p = WriteSymbol(p, function_name_);
322 p = WriteBool(p, calls_eval_); 360 p = WriteBool(p, calls_eval_);
323 p = WriteBool(p, is_strict_mode_); 361 p = WriteBool(p, is_strict_mode_);
362 p = WriteInt(p, type_);
363 p = WriteInt(p, source_beg_statement_pos_);
364 p = WriteInt(p, source_end_statement_pos_);
365 p = WriteInt(p, first_stack_index_);
324 p = WriteList(p, &context_slots_, &context_modes_); 366 p = WriteList(p, &context_slots_, &context_modes_);
325 p = WriteList(p, &parameters_); 367 p = WriteList(p, &parameters_);
326 p = WriteList(p, &stack_slots_); 368 p = WriteList(p, &stack_slots_);
369 p = WriteList(p, &inner_scopeinfos_);
327 ASSERT((p - p0) == length); 370 ASSERT((p - p0) == length);
328 371
329 return data; 372 return data;
330 } 373 }
331 374
332 375
333 template<class Allocator> 376 template<class Allocator>
334 Handle<String> ScopeInfo<Allocator>::LocalName(int i) const { 377 Handle<String> ScopeInfo<Allocator>::LocalName(int i) const {
335 // A local variable can be allocated either on the stack or in the context. 378 // A local variable can be allocated either on the stack or in the context.
336 // For variables allocated in the context they are always preceded by 379 // For variables allocated in the context they are always preceded by
(...skipping 24 matching lines...) Expand all
361 } 404 }
362 405
363 406
364 SerializedScopeInfo* SerializedScopeInfo::Empty() { 407 SerializedScopeInfo* SerializedScopeInfo::Empty() {
365 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array()); 408 return reinterpret_cast<SerializedScopeInfo*>(HEAP->empty_fixed_array());
366 } 409 }
367 410
368 411
369 Object** SerializedScopeInfo::ContextEntriesAddr() { 412 Object** SerializedScopeInfo::ContextEntriesAddr() {
370 ASSERT(length() > 0); 413 ASSERT(length() > 0);
371 // +3 for function name, calls eval, strict mode. 414 // +6 for function name, calls eval, strict mode, scope type, source beg pos,
372 return data_start() + 3; 415 // source end pos, first stack slot.
416 return data_start() + 7;
373 } 417 }
374 418
375 419
376 Object** SerializedScopeInfo::ParameterEntriesAddr() { 420 Object** SerializedScopeInfo::ParameterEntriesAddr() {
377 ASSERT(length() > 0); 421 ASSERT(length() > 0);
378 Object** p = ContextEntriesAddr(); 422 Object** p = ContextEntriesAddr();
379 int number_of_context_slots; 423 int number_of_context_slots;
380 p = ReadInt(p, &number_of_context_slots); 424 p = ReadInt(p, &number_of_context_slots);
381 return p + number_of_context_slots*2; // *2 for pairs 425 return p + number_of_context_slots*2; // *2 for pairs
382 } 426 }
383 427
384 428
385 Object** SerializedScopeInfo::StackSlotEntriesAddr() { 429 Object** SerializedScopeInfo::StackSlotEntriesAddr() {
386 ASSERT(length() > 0); 430 ASSERT(length() > 0);
387 Object** p = ParameterEntriesAddr(); 431 Object** p = ParameterEntriesAddr();
388 int number_of_parameter_slots; 432 int number_of_parameter_slots;
389 p = ReadInt(p, &number_of_parameter_slots); 433 p = ReadInt(p, &number_of_parameter_slots);
390 return p + number_of_parameter_slots; 434 return p + number_of_parameter_slots;
391 } 435 }
392 436
393 437
438 Object** SerializedScopeInfo::NestedScopeEntriesAddr() {
439 ASSERT(length() > 0);
440 Object** p = StackSlotEntriesAddr();
441 int number_of_stack_slots;
442 p = ReadInt(p, &number_of_stack_slots);
443 return p + number_of_stack_slots;
444 }
445
446
447
394 bool SerializedScopeInfo::CallsEval() { 448 bool SerializedScopeInfo::CallsEval() {
395 if (length() > 0) { 449 if (length() > 0) {
396 Object** p = data_start() + 1; // +1 for function name. 450 Object** p = data_start() + 1; // +1 for function name.
397 bool calls_eval; 451 bool calls_eval;
398 p = ReadBool(p, &calls_eval); 452 p = ReadBool(p, &calls_eval);
399 return calls_eval; 453 return calls_eval;
400 } 454 }
401 return false; 455 return false;
402 } 456 }
403 457
404 458
405 bool SerializedScopeInfo::IsStrictMode() { 459 bool SerializedScopeInfo::IsStrictMode() {
406 if (length() > 0) { 460 if (length() > 0) {
407 Object** p = data_start() + 2; // +2 for function name, calls eval. 461 Object** p = data_start() + 2; // +2 for function name, calls eval.
408 bool strict_mode; 462 bool strict_mode;
409 p = ReadBool(p, &strict_mode); 463 p = ReadBool(p, &strict_mode);
410 return strict_mode; 464 return strict_mode;
411 } 465 }
412 return false; 466 return false;
413 } 467 }
414 468
415 469
470 Scope::Type SerializedScopeInfo::ScopeType() {
471 ASSERT(length() > 0);
472 // +3 for function name, calls eval, strict mode.
473 Object** p = data_start() + 3;
474 Scope::Type type;
475 p = ReadInt(p, &type);
476 return type;
477 }
478
479
480 int SerializedScopeInfo::SourceBegStatementPos() {
481 if (length() > 0) {
482 // +4 for function name, calls eval, strict mode, scope type.
483 Object** p = data_start() + 4;
484 int source_beg_statement_pos;
485 p = ReadInt(p, &source_beg_statement_pos);
486 return source_beg_statement_pos;
487 }
488 return -1;
489 }
490
491
492 int SerializedScopeInfo::SourceEndStatementPos() {
493 if (length() > 0) {
494 // +5 for function name, calls eval, strict mode, scope type,
495 // source beg pos.
496 Object** p = data_start() + 5;
497 int source_end_statement_pos;
498 p = ReadInt(p, &source_end_statement_pos);
499 return source_end_statement_pos;
500 }
501 return -1;
502 }
503
504
505 int SerializedScopeInfo::FirstStackSlot() {
506 if (length() > 0) {
507 // +6 for function name, calls eval, strict mode, scope type,
508 // source beg pos, source end pos.
509 Object** p = data_start() + 6;
510 int source_end_pos;
511 p = ReadInt(p, &source_end_pos);
512 return source_end_pos;
513 }
514 return -1;
515 }
516
517
416 int SerializedScopeInfo::NumberOfStackSlots() { 518 int SerializedScopeInfo::NumberOfStackSlots() {
417 if (length() > 0) { 519 if (length() > 0) {
418 Object** p = StackSlotEntriesAddr(); 520 Object** p = StackSlotEntriesAddr();
419 int number_of_stack_slots; 521 int number_of_stack_slots;
420 ReadInt(p, &number_of_stack_slots); 522 ReadInt(p, &number_of_stack_slots);
421 return number_of_stack_slots; 523 return number_of_stack_slots;
422 } 524 }
423 return 0; 525 return 0;
424 } 526 }
425 527
426 528
427 int SerializedScopeInfo::NumberOfContextSlots() { 529 int SerializedScopeInfo::NumberOfContextSlots() {
428 if (length() > 0) { 530 if (length() > 0) {
429 Object** p = ContextEntriesAddr(); 531 Object** p = ContextEntriesAddr();
430 int number_of_context_slots; 532 int number_of_context_slots;
431 ReadInt(p, &number_of_context_slots); 533 ReadInt(p, &number_of_context_slots);
432 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS; 534 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS;
433 } 535 }
434 return 0; 536 return 0;
435 } 537 }
436 538
437 539
540 int SerializedScopeInfo::NumberOfNestedScopes() {
541 if (length() > 0) {
542 Object** p = NestedScopeEntriesAddr();
543 int number_of_nested_scopes;
544 ReadInt(p, &number_of_nested_scopes);
545 return number_of_nested_scopes;
546 }
547 return 0;
548 }
549
550
551 Handle<SerializedScopeInfo> SerializedScopeInfo::NestedScope(int i) {
552 ASSERT(0 <= i && i < NumberOfNestedScopes());
553 Object* p = *(NestedScopeEntriesAddr() + i + 1);
554 return Handle<SerializedScopeInfo>(reinterpret_cast<SerializedScopeInfo*>(p));
555 }
556
557
438 bool SerializedScopeInfo::HasHeapAllocatedLocals() { 558 bool SerializedScopeInfo::HasHeapAllocatedLocals() {
439 if (length() > 0) { 559 if (length() > 0) {
440 Object** p = ContextEntriesAddr(); 560 Object** p = ContextEntriesAddr();
441 int number_of_context_slots; 561 int number_of_context_slots;
442 ReadInt(p, &number_of_context_slots); 562 ReadInt(p, &number_of_context_slots);
443 return number_of_context_slots > 0; 563 return number_of_context_slots > 0;
444 } 564 }
445 return false; 565 return false;
446 } 566 }
447 567
448 568
569 bool SerializedScopeInfo::HasContext() {
570 return ScopeType() == Scope::WITH_SCOPE ||
571 ScopeType() == Scope::GLOBAL_SCOPE ||
572 HasHeapAllocatedLocals();
573 }
574
575
449 int SerializedScopeInfo::StackSlotIndex(String* name) { 576 int SerializedScopeInfo::StackSlotIndex(String* name) {
450 ASSERT(name->IsSymbol()); 577 ASSERT(name->IsSymbol());
451 if (length() > 0) { 578 if (length() > 0) {
452 // Slots start after length entry. 579 // Slots start after length entry.
453 Object** p0 = StackSlotEntriesAddr(); 580 Object** p0 = StackSlotEntriesAddr();
454 int number_of_stack_slots; 581 int number_of_stack_slots;
455 p0 = ReadInt(p0, &number_of_stack_slots); 582 p0 = ReadInt(p0, &number_of_stack_slots);
456 Object** p = p0; 583 Object** p = p0;
457 Object** end = p0 + number_of_stack_slots; 584 Object** end = p0 + number_of_stack_slots;
458 while (p != end) { 585 while (p != end) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
530 ReadInt(p, &number_of_context_slots); 657 ReadInt(p, &number_of_context_slots);
531 ASSERT(number_of_context_slots != 0); 658 ASSERT(number_of_context_slots != 0);
532 // The function context slot is the last entry. 659 // The function context slot is the last entry.
533 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1; 660 return number_of_context_slots + Context::MIN_CONTEXT_SLOTS - 1;
534 } 661 }
535 } 662 }
536 return -1; 663 return -1;
537 } 664 }
538 665
539 666
667 void SerializedScopeInfo::GetLocalScopeChain(
668 List<Handle<SerializedScopeInfo> >* chain,
669 int position) {
670 chain->Add(Handle<SerializedScopeInfo>(this));
671
672 for (int i = 0; i < NumberOfNestedScopes(); i++) {
673 Handle<SerializedScopeInfo> scope = NestedScope(i);
674 int beg_pos = scope->SourceBegStatementPos();
675 int end_pos = scope->SourceEndStatementPos();
676 ASSERT(beg_pos >= 0 && end_pos >= 0);
677 if (beg_pos <= position && position <= end_pos) {
678 scope->GetLocalScopeChain(chain, position);
679 return;
680 }
681 }
682 }
683
684
540 int ContextSlotCache::Hash(Object* data, String* name) { 685 int ContextSlotCache::Hash(Object* data, String* name) {
541 // Uses only lower 32 bits if pointers are larger. 686 // Uses only lower 32 bits if pointers are larger.
542 uintptr_t addr_hash = 687 uintptr_t addr_hash =
543 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; 688 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2;
544 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); 689 return static_cast<int>((addr_hash ^ name->Hash()) % kLength);
545 } 690 }
546 691
547 692
548 int ContextSlotCache::Lookup(Object* data, 693 int ContextSlotCache::Lookup(Object* data,
549 String* name, 694 String* name,
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
639 } 784 }
640 #endif // DEBUG 785 #endif // DEBUG
641 786
642 787
643 // Make sure the classes get instantiated by the template system. 788 // Make sure the classes get instantiated by the template system.
644 template class ScopeInfo<FreeStoreAllocationPolicy>; 789 template class ScopeInfo<FreeStoreAllocationPolicy>;
645 template class ScopeInfo<PreallocatedStorage>; 790 template class ScopeInfo<PreallocatedStorage>;
646 template class ScopeInfo<ZoneListAllocationPolicy>; 791 template class ScopeInfo<ZoneListAllocationPolicy>;
647 792
648 } } // namespace v8::internal 793 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/scopeinfo.h ('k') | src/scopes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698