| OLD | NEW |
| 1 // Copyright 2006-2008 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2008 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 2387 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2398 // If there was no control flow to slow, we can exit early. | 2398 // If there was no control flow to slow, we can exit early. |
| 2399 if (!slow.is_linked()) { | 2399 if (!slow.is_linked()) { |
| 2400 frame_->EmitPush(r0); | 2400 frame_->EmitPush(r0); |
| 2401 return; | 2401 return; |
| 2402 } | 2402 } |
| 2403 | 2403 |
| 2404 done.Jump(); | 2404 done.Jump(); |
| 2405 | 2405 |
| 2406 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { | 2406 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { |
| 2407 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); | 2407 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); |
| 2408 __ ldr(r0, | 2408 // Only generate the fast case for locals that rewrite to slots. |
| 2409 ContextSlotOperandCheckExtensions(potential_slot, | 2409 // This rules out argument loads. |
| 2410 r1, | 2410 if (potential_slot != NULL) { |
| 2411 r2, | 2411 __ ldr(r0, |
| 2412 &slow)); | 2412 ContextSlotOperandCheckExtensions(potential_slot, |
| 2413 // There is always control flow to slow from | 2413 r1, |
| 2414 // ContextSlotOperandCheckExtensions. | 2414 r2, |
| 2415 done.Jump(); | 2415 &slow)); |
| 2416 // There is always control flow to slow from |
| 2417 // ContextSlotOperandCheckExtensions. |
| 2418 done.Jump(); |
| 2419 } |
| 2416 } | 2420 } |
| 2417 | 2421 |
| 2418 slow.Bind(); | 2422 slow.Bind(); |
| 2419 frame_->EmitPush(cp); | 2423 frame_->EmitPush(cp); |
| 2420 __ mov(r0, Operand(slot->var()->name())); | 2424 __ mov(r0, Operand(slot->var()->name())); |
| 2421 frame_->EmitPush(r0); | 2425 frame_->EmitPush(r0); |
| 2422 | 2426 |
| 2423 if (typeof_state == INSIDE_TYPEOF) { | 2427 if (typeof_state == INSIDE_TYPEOF) { |
| 2424 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 2428 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
| 2425 } else { | 2429 } else { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 2452 | 2456 |
| 2453 | 2457 |
| 2454 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot, | 2458 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot, |
| 2455 TypeofState typeof_state, | 2459 TypeofState typeof_state, |
| 2456 Register tmp, | 2460 Register tmp, |
| 2457 Register tmp2, | 2461 Register tmp2, |
| 2458 JumpTarget* slow) { | 2462 JumpTarget* slow) { |
| 2459 // Check that no extension objects have been created by calls to | 2463 // Check that no extension objects have been created by calls to |
| 2460 // eval from the current scope to the global scope. | 2464 // eval from the current scope to the global scope. |
| 2461 Register context = cp; | 2465 Register context = cp; |
| 2462 for (Scope* s = scope(); s != NULL; s = s->outer_scope()) { | 2466 Scope* s = scope(); |
| 2467 while (s != NULL) { |
| 2463 if (s->num_heap_slots() > 0) { | 2468 if (s->num_heap_slots() > 0) { |
| 2464 if (s->calls_eval()) { | 2469 if (s->calls_eval()) { |
| 2465 // Check that extension is NULL. | 2470 // Check that extension is NULL. |
| 2466 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); | 2471 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); |
| 2467 __ tst(tmp2, tmp2); | 2472 __ tst(tmp2, tmp2); |
| 2468 slow->Branch(ne); | 2473 slow->Branch(ne); |
| 2469 } | 2474 } |
| 2470 // Load next context in chain. | 2475 // Load next context in chain. |
| 2471 __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); | 2476 __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); |
| 2472 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); | 2477 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); |
| 2473 context = tmp; | 2478 context = tmp; |
| 2474 } | 2479 } |
| 2475 // If no outer scope calls eval, we do not need to check more | 2480 // If no outer scope calls eval, we do not need to check more |
| 2476 // context extensions. | 2481 // context extensions. |
| 2477 if (!s->outer_scope_calls_eval()) break; | 2482 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break; |
| 2483 s = s->outer_scope(); |
| 2484 } |
| 2485 |
| 2486 if (s->is_eval_scope()) { |
| 2487 Label next, fast; |
| 2488 if (!context.is(tmp)) __ mov(tmp, Operand(context)); |
| 2489 __ bind(&next); |
| 2490 // Terminate at global context. |
| 2491 __ ldr(tmp2, FieldMemOperand(tmp, HeapObject::kMapOffset)); |
| 2492 __ cmp(tmp2, Operand(Factory::global_context_map())); |
| 2493 __ b(eq, &fast); |
| 2494 // Check that extension is NULL. |
| 2495 __ ldr(tmp2, ContextOperand(tmp, Context::EXTENSION_INDEX)); |
| 2496 __ tst(tmp2, tmp2); |
| 2497 __ b(ne, slow); |
| 2498 // Load next context in chain. |
| 2499 __ ldr(tmp, ContextOperand(tmp, Context::CLOSURE_INDEX)); |
| 2500 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); |
| 2501 __ b(&next); |
| 2502 __ bind(&fast); |
| 2478 } | 2503 } |
| 2479 | 2504 |
| 2480 // All extension objects were empty and it is safe to use a global | 2505 // All extension objects were empty and it is safe to use a global |
| 2481 // load IC call. | 2506 // load IC call. |
| 2482 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); | 2507 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); |
| 2483 // Load the global object. | 2508 // Load the global object. |
| 2484 LoadGlobal(); | 2509 LoadGlobal(); |
| 2485 // Setup the name register. | 2510 // Setup the name register. |
| 2486 Result name = allocator_->Allocate(r2); | 2511 Result name = allocator_->Allocate(r2); |
| 2487 ASSERT(name.is_valid()); // We are in spilled code. | 2512 ASSERT(name.is_valid()); // We are in spilled code. |
| (...skipping 2571 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5059 __ mov(r2, Operand(0)); | 5084 __ mov(r2, Operand(0)); |
| 5060 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); | 5085 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); |
| 5061 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), | 5086 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), |
| 5062 RelocInfo::CODE_TARGET); | 5087 RelocInfo::CODE_TARGET); |
| 5063 } | 5088 } |
| 5064 | 5089 |
| 5065 | 5090 |
| 5066 #undef __ | 5091 #undef __ |
| 5067 | 5092 |
| 5068 } } // namespace v8::internal | 5093 } } // namespace v8::internal |
| OLD | NEW |