| 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 |