OLD | NEW |
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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 // order with the variable list anymore. Thus, we first need to sort them by | 141 // order with the variable list anymore. Thus, we first need to sort them by |
142 // context slot index before adding them to the ScopeInfo object. | 142 // context slot index before adding them to the ScopeInfo object. |
143 context_locals.Sort(&CompareLocal); | 143 context_locals.Sort(&CompareLocal); |
144 | 144 |
145 // Add context locals' names. | 145 // Add context locals' names. |
146 ASSERT(index == scope_info->ContextLocalNameEntriesIndex()); | 146 ASSERT(index == scope_info->ContextLocalNameEntriesIndex()); |
147 for (int i = 0; i < num_context_locals; ++i) { | 147 for (int i = 0; i < num_context_locals; ++i) { |
148 scope_info->set(index++, *context_locals[i]->name()); | 148 scope_info->set(index++, *context_locals[i]->name()); |
149 } | 149 } |
150 | 150 |
151 // Add context locals' modes. | 151 // Add context locals' info. |
152 ASSERT(index == scope_info->ContextLocalModeEntriesIndex()); | 152 ASSERT(index == scope_info->ContextLocalInfoEntriesIndex()); |
153 for (int i = 0; i < num_context_locals; ++i) { | 153 for (int i = 0; i < num_context_locals; ++i) { |
154 scope_info->set(index++, Smi::FromInt(context_locals[i]->mode())); | 154 Variable* var = context_locals[i]; |
| 155 uint32_t value = ContextLocalMode::encode(var->mode()) | |
| 156 ContextLocalInitFlag::encode(var->initialization_flag()); |
| 157 scope_info->set(index++, Smi::FromInt(value)); |
155 } | 158 } |
156 | 159 |
157 // If present, add the function variable name and its index. | 160 // If present, add the function variable name and its index. |
158 ASSERT(index == scope_info->FunctionNameEntryIndex()); | 161 ASSERT(index == scope_info->FunctionNameEntryIndex()); |
159 if (has_function_name) { | 162 if (has_function_name) { |
160 int var_index = scope->function()->var()->index(); | 163 int var_index = scope->function()->var()->index(); |
161 scope_info->set(index++, *scope->function()->name()); | 164 scope_info->set(index++, *scope->function()->name()); |
162 scope_info->set(index++, Smi::FromInt(var_index)); | 165 scope_info->set(index++, Smi::FromInt(var_index)); |
163 ASSERT(function_name_info != STACK || | 166 ASSERT(function_name_info != STACK || |
164 (var_index == scope_info->num_stack_locals() && | 167 (var_index == scope_info->num_stack_locals() && |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 | 301 |
299 Handle<String> ScopeInfo::context_local_name(int var) { | 302 Handle<String> ScopeInfo::context_local_name(int var) { |
300 ASSERT(0 <= var && var < num_context_locals()); | 303 ASSERT(0 <= var && var < num_context_locals()); |
301 int info_index = ContextLocalNameEntriesIndex() + var; | 304 int info_index = ContextLocalNameEntriesIndex() + var; |
302 return Handle<String>(String::cast(get(info_index))); | 305 return Handle<String>(String::cast(get(info_index))); |
303 } | 306 } |
304 | 307 |
305 | 308 |
306 VariableMode ScopeInfo::context_local_mode(int var) { | 309 VariableMode ScopeInfo::context_local_mode(int var) { |
307 ASSERT(0 <= var && var < num_context_locals()); | 310 ASSERT(0 <= var && var < num_context_locals()); |
308 int info_index = ContextLocalModeEntriesIndex() + var; | 311 int info_index = ContextLocalInfoEntriesIndex() + var; |
309 return static_cast<VariableMode>(Smi::cast(get(info_index))->value()); | 312 int value = Smi::cast(get(info_index))->value(); |
| 313 return ContextLocalMode::decode(value); |
310 } | 314 } |
311 | 315 |
312 | 316 |
| 317 InitializationFlag ScopeInfo::context_local_init_flag(int var) { |
| 318 ASSERT(0 <= var && var < num_context_locals()); |
| 319 int info_index = ContextLocalInfoEntriesIndex() + var; |
| 320 int value = Smi::cast(get(info_index))->value(); |
| 321 return ContextLocalInitFlag::decode(value); |
| 322 } |
| 323 |
| 324 |
313 int ScopeInfo::StackSlotIndex(String* name) { | 325 int ScopeInfo::StackSlotIndex(String* name) { |
314 ASSERT(name->IsSymbol()); | 326 ASSERT(name->IsSymbol()); |
315 if (length() > 0) { | 327 if (length() > 0) { |
316 int start = StackLocalEntriesIndex(); | 328 int start = StackLocalEntriesIndex(); |
317 int end = StackLocalEntriesIndex() + num_stack_locals(); | 329 int end = StackLocalEntriesIndex() + num_stack_locals(); |
318 for (int i = start; i < end; ++i) { | 330 for (int i = start; i < end; ++i) { |
319 if (name == get(i)) { | 331 if (name == get(i)) { |
320 return i - start; | 332 return i - start; |
321 } | 333 } |
322 } | 334 } |
323 } | 335 } |
324 return -1; | 336 return -1; |
325 } | 337 } |
326 | 338 |
327 | 339 |
328 int ScopeInfo::ContextSlotIndex(String* name, VariableMode* mode) { | 340 int ScopeInfo::ContextSlotIndex(String* name, |
| 341 VariableMode* mode, |
| 342 InitializationFlag* init_flag) { |
329 ASSERT(name->IsSymbol()); | 343 ASSERT(name->IsSymbol()); |
330 if (length() > 0) { | 344 if (length() > 0) { |
331 ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache(); | 345 ContextSlotCache* context_slot_cache = GetIsolate()->context_slot_cache(); |
332 int result = context_slot_cache->Lookup(this, name, mode); | 346 int result = context_slot_cache->Lookup(this, name, mode, init_flag); |
333 if (result != ContextSlotCache::kNotFound) { | 347 if (result != ContextSlotCache::kNotFound) { |
334 ASSERT(result < NumberOfContextSlots()); | 348 ASSERT(result < NumberOfContextSlots()); |
335 return result; | 349 return result; |
336 } | 350 } |
337 | 351 |
338 int start = ContextLocalNameEntriesIndex(); | 352 int start = ContextLocalNameEntriesIndex(); |
339 int end = ContextLocalNameEntriesIndex() + num_context_locals(); | 353 int end = ContextLocalNameEntriesIndex() + num_context_locals(); |
340 for (int i = start; i < end; ++i) { | 354 for (int i = start; i < end; ++i) { |
341 if (name == get(i)) { | 355 if (name == get(i)) { |
342 int var = i - start; | 356 int var = i - start; |
343 VariableMode mode_value = context_local_mode(var); | 357 VariableMode mode_value = context_local_mode(var); |
| 358 InitializationFlag init_flag_value = context_local_init_flag(var); |
344 if (mode != NULL) *mode = mode_value; | 359 if (mode != NULL) *mode = mode_value; |
| 360 if (init_flag != NULL) *init_flag = init_flag_value; |
345 result = Context::MIN_CONTEXT_SLOTS + var; | 361 result = Context::MIN_CONTEXT_SLOTS + var; |
346 context_slot_cache->Update(this, name, mode_value, result); | 362 context_slot_cache->Update( |
| 363 this, name, mode_value, init_flag_value, result); |
347 ASSERT(result < NumberOfContextSlots()); | 364 ASSERT(result < NumberOfContextSlots()); |
348 return result; | 365 return result; |
349 } | 366 } |
350 } | 367 } |
351 context_slot_cache->Update(this, name, INTERNAL, -1); | 368 context_slot_cache->Update(this, name, INTERNAL, NEEDS_INITIALIZATION, -1); |
352 } | 369 } |
353 return -1; | 370 return -1; |
354 } | 371 } |
355 | 372 |
356 | 373 |
357 int ScopeInfo::ParameterIndex(String* name) { | 374 int ScopeInfo::ParameterIndex(String* name) { |
358 ASSERT(name->IsSymbol()); | 375 ASSERT(name->IsSymbol()); |
359 if (length() > 0) { | 376 if (length() > 0) { |
360 // We must read parameters from the end since for | 377 // We must read parameters from the end since for |
361 // multiply declared parameters the value of the | 378 // multiply declared parameters the value of the |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 int ScopeInfo::StackLocalEntriesIndex() { | 413 int ScopeInfo::StackLocalEntriesIndex() { |
397 return ParameterEntriesIndex() + num_parameters(); | 414 return ParameterEntriesIndex() + num_parameters(); |
398 } | 415 } |
399 | 416 |
400 | 417 |
401 int ScopeInfo::ContextLocalNameEntriesIndex() { | 418 int ScopeInfo::ContextLocalNameEntriesIndex() { |
402 return StackLocalEntriesIndex() + num_stack_locals(); | 419 return StackLocalEntriesIndex() + num_stack_locals(); |
403 } | 420 } |
404 | 421 |
405 | 422 |
406 int ScopeInfo::ContextLocalModeEntriesIndex() { | 423 int ScopeInfo::ContextLocalInfoEntriesIndex() { |
407 return ContextLocalNameEntriesIndex() + num_context_locals(); | 424 return ContextLocalNameEntriesIndex() + num_context_locals(); |
408 } | 425 } |
409 | 426 |
410 | 427 |
411 int ScopeInfo::FunctionNameEntryIndex() { | 428 int ScopeInfo::FunctionNameEntryIndex() { |
412 return ContextLocalModeEntriesIndex() + num_context_locals(); | 429 return ContextLocalInfoEntriesIndex() + num_context_locals(); |
413 } | 430 } |
414 | 431 |
415 | 432 |
416 int ContextSlotCache::Hash(Object* data, String* name) { | 433 int ContextSlotCache::Hash(Object* data, String* name) { |
417 // Uses only lower 32 bits if pointers are larger. | 434 // Uses only lower 32 bits if pointers are larger. |
418 uintptr_t addr_hash = | 435 uintptr_t addr_hash = |
419 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; | 436 static_cast<uint32_t>(reinterpret_cast<uintptr_t>(data)) >> 2; |
420 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); | 437 return static_cast<int>((addr_hash ^ name->Hash()) % kLength); |
421 } | 438 } |
422 | 439 |
423 | 440 |
424 int ContextSlotCache::Lookup(Object* data, | 441 int ContextSlotCache::Lookup(Object* data, |
425 String* name, | 442 String* name, |
426 VariableMode* mode) { | 443 VariableMode* mode, |
| 444 InitializationFlag* init_flag) { |
427 int index = Hash(data, name); | 445 int index = Hash(data, name); |
428 Key& key = keys_[index]; | 446 Key& key = keys_[index]; |
429 if ((key.data == data) && key.name->Equals(name)) { | 447 if ((key.data == data) && key.name->Equals(name)) { |
430 Value result(values_[index]); | 448 Value result(values_[index]); |
431 if (mode != NULL) *mode = result.mode(); | 449 if (mode != NULL) *mode = result.mode(); |
| 450 if (init_flag != NULL) *init_flag = result.initialization_flag(); |
432 return result.index() + kNotFound; | 451 return result.index() + kNotFound; |
433 } | 452 } |
434 return kNotFound; | 453 return kNotFound; |
435 } | 454 } |
436 | 455 |
437 | 456 |
438 void ContextSlotCache::Update(Object* data, | 457 void ContextSlotCache::Update(Object* data, |
439 String* name, | 458 String* name, |
440 VariableMode mode, | 459 VariableMode mode, |
| 460 InitializationFlag init_flag, |
441 int slot_index) { | 461 int slot_index) { |
442 String* symbol; | 462 String* symbol; |
443 ASSERT(slot_index > kNotFound); | 463 ASSERT(slot_index > kNotFound); |
444 if (HEAP->LookupSymbolIfExists(name, &symbol)) { | 464 if (HEAP->LookupSymbolIfExists(name, &symbol)) { |
445 int index = Hash(data, symbol); | 465 int index = Hash(data, symbol); |
446 Key& key = keys_[index]; | 466 Key& key = keys_[index]; |
447 key.data = data; | 467 key.data = data; |
448 key.name = symbol; | 468 key.name = symbol; |
449 // Please note value only takes a uint as index. | 469 // Please note value only takes a uint as index. |
450 values_[index] = Value(mode, slot_index - kNotFound).raw(); | 470 values_[index] = Value(mode, init_flag, slot_index - kNotFound).raw(); |
451 #ifdef DEBUG | 471 #ifdef DEBUG |
452 ValidateEntry(data, name, mode, slot_index); | 472 ValidateEntry(data, name, mode, init_flag, slot_index); |
453 #endif | 473 #endif |
454 } | 474 } |
455 } | 475 } |
456 | 476 |
457 | 477 |
458 void ContextSlotCache::Clear() { | 478 void ContextSlotCache::Clear() { |
459 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; | 479 for (int index = 0; index < kLength; index++) keys_[index].data = NULL; |
460 } | 480 } |
461 | 481 |
462 | 482 |
463 #ifdef DEBUG | 483 #ifdef DEBUG |
464 | 484 |
465 void ContextSlotCache::ValidateEntry(Object* data, | 485 void ContextSlotCache::ValidateEntry(Object* data, |
466 String* name, | 486 String* name, |
467 VariableMode mode, | 487 VariableMode mode, |
| 488 InitializationFlag init_flag, |
468 int slot_index) { | 489 int slot_index) { |
469 String* symbol; | 490 String* symbol; |
470 if (HEAP->LookupSymbolIfExists(name, &symbol)) { | 491 if (HEAP->LookupSymbolIfExists(name, &symbol)) { |
471 int index = Hash(data, name); | 492 int index = Hash(data, name); |
472 Key& key = keys_[index]; | 493 Key& key = keys_[index]; |
473 ASSERT(key.data == data); | 494 ASSERT(key.data == data); |
474 ASSERT(key.name->Equals(name)); | 495 ASSERT(key.name->Equals(name)); |
475 Value result(values_[index]); | 496 Value result(values_[index]); |
476 ASSERT(result.mode() == mode); | 497 ASSERT(result.mode() == mode); |
| 498 ASSERT(result.initialization_flag() == init_flag); |
477 ASSERT(result.index() + kNotFound == slot_index); | 499 ASSERT(result.index() + kNotFound == slot_index); |
478 } | 500 } |
479 } | 501 } |
480 | 502 |
481 | 503 |
482 static void PrintList(const char* list_name, | 504 static void PrintList(const char* list_name, |
483 int nof_internal_slots, | 505 int nof_internal_slots, |
484 int start, | 506 int start, |
485 int end, | 507 int end, |
486 ScopeInfo* scope_info) { | 508 ScopeInfo* scope_info) { |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
519 Context::MIN_CONTEXT_SLOTS, | 541 Context::MIN_CONTEXT_SLOTS, |
520 ContextLocalNameEntriesIndex(), | 542 ContextLocalNameEntriesIndex(), |
521 ContextLocalNameEntriesIndex() + num_context_locals(), | 543 ContextLocalNameEntriesIndex() + num_context_locals(), |
522 this); | 544 this); |
523 | 545 |
524 PrintF("}\n"); | 546 PrintF("}\n"); |
525 } | 547 } |
526 #endif // DEBUG | 548 #endif // DEBUG |
527 | 549 |
528 } } // namespace v8::internal | 550 } } // namespace v8::internal |
OLD | NEW |