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

Side by Side Diff: src/codegen-arm.cc

Issue 28027: Speed up access to global variables from eval scopes. Traverse the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 10 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 | « no previous file | src/codegen-ia32.cc » ('j') | src/compilation-cache.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2004 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 // eval-introduced variables. Eval is used a lot without 2015 // eval-introduced variables. Eval is used a lot without
2016 // introducing variables. In those cases, we do not want to 2016 // introducing variables. In those cases, we do not want to
2017 // perform a runtime call for all variables in the scope 2017 // perform a runtime call for all variables in the scope
2018 // containing the eval. 2018 // containing the eval.
2019 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { 2019 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) {
2020 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, r1, r2, &slow); 2020 LoadFromGlobalSlotCheckExtensions(slot, typeof_state, r1, r2, &slow);
2021 __ b(&done); 2021 __ b(&done);
2022 2022
2023 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { 2023 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) {
2024 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); 2024 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot();
2025 __ ldr(r0, 2025 // Only generate the fast case for locals that rewrite to slots.
2026 ContextSlotOperandCheckExtensions(potential_slot, 2026 // This rules out argument loads.
2027 r1, 2027 if (potential_slot != NULL) {
2028 r2, 2028 __ ldr(r0,
2029 &slow)); 2029 ContextSlotOperandCheckExtensions(potential_slot,
2030 __ b(&done); 2030 r1,
2031 r2,
2032 &slow));
2033 __ b(&done);
2034 }
2031 } 2035 }
2032 2036
2033 __ bind(&slow); 2037 __ bind(&slow);
2034 frame_->Push(cp); 2038 frame_->Push(cp);
2035 __ mov(r0, Operand(slot->var()->name())); 2039 __ mov(r0, Operand(slot->var()->name()));
2036 frame_->Push(r0); 2040 frame_->Push(r0);
2037 2041
2038 if (typeof_state == INSIDE_TYPEOF) { 2042 if (typeof_state == INSIDE_TYPEOF) {
2039 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); 2043 __ CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2);
2040 } else { 2044 } else {
(...skipping 26 matching lines...) Expand all
2067 2071
2068 2072
2069 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot, 2073 void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot,
2070 TypeofState typeof_state, 2074 TypeofState typeof_state,
2071 Register tmp, 2075 Register tmp,
2072 Register tmp2, 2076 Register tmp2,
2073 Label* slow) { 2077 Label* slow) {
2074 // Check that no extension objects have been created by calls to 2078 // Check that no extension objects have been created by calls to
2075 // eval from the current scope to the global scope. 2079 // eval from the current scope to the global scope.
2076 Register context = cp; 2080 Register context = cp;
2077 for (Scope* s = scope(); s != NULL; s = s->outer_scope()) { 2081 Scope* s = scope();
2082 while (s != NULL) {
2078 if (s->num_heap_slots() > 0) { 2083 if (s->num_heap_slots() > 0) {
2079 if (s->calls_eval()) { 2084 if (s->calls_eval()) {
2080 // Check that extension is NULL. 2085 // Check that extension is NULL.
2081 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX)); 2086 __ ldr(tmp2, ContextOperand(context, Context::EXTENSION_INDEX));
2082 __ tst(tmp2, tmp2); 2087 __ tst(tmp2, tmp2);
2083 __ b(ne, slow); 2088 __ b(ne, slow);
2084 } 2089 }
2085 // Load next context in chain. 2090 // Load next context in chain.
2086 __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX)); 2091 __ ldr(tmp, ContextOperand(context, Context::CLOSURE_INDEX));
2087 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset)); 2092 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
2088 context = tmp; 2093 context = tmp;
2089 } 2094 }
2090 // If no outer scope calls eval, we do not need to check more 2095 // If no outer scope calls eval, we do not need to check more
2091 // context extensions. 2096 // context extensions.
2092 if (!s->outer_scope_calls_eval()) break; 2097 if (!s->outer_scope_calls_eval() || s->is_eval_scope()) break;
2098 s = s->outer_scope();
2099 }
2100
2101 if (s->is_eval_scope()) {
2102 Label next, fast;
2103 if (!context.is(tmp)) __ mov(tmp, Operand(context));
2104 __ bind(&next);
2105 // Terminate at global context.
2106 __ ldr(tmp2, FieldMemOperand(tmp, HeapObject::kMapOffset));
2107 __ cmp(tmp2, Operand(Factory::global_context_map()));
2108 __ b(eq, &fast);
2109 // Check that extension is NULL.
2110 __ ldr(tmp2, ContextOperand(tmp, Context::EXTENSION_INDEX));
2111 __ tst(tmp2, tmp2);
2112 __ b(ne, slow);
2113 // Load next context in chain.
2114 __ ldr(tmp, ContextOperand(tmp, Context::CLOSURE_INDEX));
2115 __ ldr(tmp, FieldMemOperand(tmp, JSFunction::kContextOffset));
2116 __ b(&next);
2117 __ bind(&fast);
2093 } 2118 }
2094 2119
2095 // All extension objects were empty and it is safe to use a global 2120 // All extension objects were empty and it is safe to use a global
2096 // load IC call. 2121 // load IC call.
2097 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize)); 2122 Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
2098 // Load the global object. 2123 // Load the global object.
2099 LoadGlobal(); 2124 LoadGlobal();
2100 // Setup the name register. 2125 // Setup the name register.
2101 __ mov(r2, Operand(slot->var()->name())); 2126 __ mov(r2, Operand(slot->var()->name()));
2102 // Call IC stub. 2127 // Call IC stub.
(...skipping 2350 matching lines...) Expand 10 before | Expand all | Expand 10 after
4453 __ mov(r2, Operand(0)); 4478 __ mov(r2, Operand(0));
4454 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION); 4479 __ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
4455 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)), 4480 __ Jump(Handle<Code>(Builtins::builtin(Builtins::ArgumentsAdaptorTrampoline)),
4456 RelocInfo::CODE_TARGET); 4481 RelocInfo::CODE_TARGET);
4457 } 4482 }
4458 4483
4459 4484
4460 #undef __ 4485 #undef __
4461 4486
4462 } } // namespace v8::internal 4487 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/codegen-ia32.cc » ('j') | src/compilation-cache.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698