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

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 717093002: Perform receiver patching for sloppy mode in high-level IR. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Minor fix. Created 6 years, 1 month 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/compiler/ast-graph-builder.h ('k') | src/compiler/ia32/code-generator-ia32.cc » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/compiler.h" 7 #include "src/compiler.h"
8 #include "src/compiler/ast-loop-assignment-analyzer.h" 8 #include "src/compiler/ast-loop-assignment-analyzer.h"
9 #include "src/compiler/control-builders.h" 9 #include "src/compiler/control-builders.h"
10 #include "src/compiler/machine-operator.h" 10 #include "src/compiler/machine-operator.h"
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 if (FLAG_loop_assignment_analysis) { 65 if (FLAG_loop_assignment_analysis) {
66 // TODO(turbofan): use a temporary zone for the loop assignment analysis. 66 // TODO(turbofan): use a temporary zone for the loop assignment analysis.
67 AstLoopAssignmentAnalyzer analyzer(zone(), info()); 67 AstLoopAssignmentAnalyzer analyzer(zone(), info());
68 loop_assignment_analysis_ = analyzer.Analyze(); 68 loop_assignment_analysis_ = analyzer.Analyze();
69 } 69 }
70 70
71 // Initialize the top-level environment. 71 // Initialize the top-level environment.
72 Environment env(this, scope, graph()->start()); 72 Environment env(this, scope, graph()->start());
73 set_environment(&env); 73 set_environment(&env);
74 74
75 // Initialize the incoming context.
76 Node* outer_context = GetFunctionContext();
77 set_current_context(outer_context);
78
79 // Build receiver check for sloppy mode if necessary.
80 // TODO(mstarzinger/verwaest): Should this be moved back into the CallIC?
81 Node* original_receiver = env.Lookup(scope->receiver());
82 Node* patched_receiver = BuildPatchReceiverToGlobalProxy(original_receiver);
83 env.Bind(scope->receiver(), patched_receiver);
84
75 // Build node to initialize local function context. 85 // Build node to initialize local function context.
76 Node* closure = GetFunctionClosure(); 86 Node* closure = GetFunctionClosure();
77 Node* outer = GetFunctionContext(); 87 Node* inner_context = BuildLocalFunctionContext(outer_context, closure);
78 Node* inner = BuildLocalFunctionContext(outer, closure);
79 88
80 // Push top-level function scope for the function body. 89 // Push top-level function scope for the function body.
81 ContextScope top_context(this, scope, inner); 90 ContextScope top_context(this, scope, inner_context);
82 91
83 // Build the arguments object if it is used. 92 // Build the arguments object if it is used.
84 BuildArgumentsObject(scope->arguments()); 93 BuildArgumentsObject(scope->arguments());
85 94
86 // Emit tracing call if requested to do so. 95 // Emit tracing call if requested to do so.
87 if (FLAG_trace) { 96 if (FLAG_trace) {
88 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0)); 97 NewNode(javascript()->CallRuntime(Runtime::kTraceEnter, 0));
89 } 98 }
90 99
91 // Visit implicit declaration of the function name. 100 // Visit implicit declaration of the function name.
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after
1766 DCHECK(environment()->stack_height() >= arity); 1775 DCHECK(environment()->stack_height() >= arity);
1767 Node** all = info()->zone()->NewArray<Node*>(arity); 1776 Node** all = info()->zone()->NewArray<Node*>(arity);
1768 for (int i = arity - 1; i >= 0; --i) { 1777 for (int i = arity - 1; i >= 0; --i) {
1769 all[i] = environment()->Pop(); 1778 all[i] = environment()->Pop();
1770 } 1779 }
1771 Node* value = NewNode(op, arity, all); 1780 Node* value = NewNode(op, arity, all);
1772 return value; 1781 return value;
1773 } 1782 }
1774 1783
1775 1784
1785 Node* AstGraphBuilder::BuildPatchReceiverToGlobalProxy(Node* receiver) {
1786 // Sloppy mode functions and builtins need to replace the receiver with the
1787 // global proxy when called as functions (without an explicit receiver
1788 // object). Otherwise there is nothing left to do here.
1789 if (info()->strict_mode() != SLOPPY || info()->is_native()) return receiver;
1790
1791 // There is no need to perform patching if the receiver is never used. Note
1792 // that scope predicates are purely syntactical, a call to eval might still
1793 // inspect the receiver value.
1794 if (!info()->scope()->uses_this() && !info()->scope()->inner_uses_this() &&
1795 !info()->scope()->calls_sloppy_eval()) {
1796 return receiver;
1797 }
1798
1799 IfBuilder receiver_check(this);
1800 Node* undefined = jsgraph()->UndefinedConstant();
1801 Node* check = NewNode(javascript()->StrictEqual(), receiver, undefined);
1802 receiver_check.If(check);
1803 receiver_check.Then();
1804 environment()->Push(BuildLoadGlobalProxy());
1805 receiver_check.Else();
1806 environment()->Push(receiver);
1807 receiver_check.End();
1808 return environment()->Pop();
1809 }
1810
1811
1776 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) { 1812 Node* AstGraphBuilder::BuildLocalFunctionContext(Node* context, Node* closure) {
1777 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; 1813 int heap_slots = info()->num_heap_slots() - Context::MIN_CONTEXT_SLOTS;
1778 if (heap_slots <= 0) return context; 1814 if (heap_slots <= 0) return context;
1779 set_current_context(context);
1780 1815
1781 // Allocate a new local context. 1816 // Allocate a new local context.
1782 const Operator* op = javascript()->CreateFunctionContext(); 1817 const Operator* op = javascript()->CreateFunctionContext();
1783 Node* local_context = NewNode(op, closure); 1818 Node* local_context = NewNode(op, closure);
1784 set_current_context(local_context); 1819 set_current_context(local_context);
1785 1820
1786 // Copy parameters into context if necessary. 1821 // Copy parameters into context if necessary.
1787 int num_parameters = info()->scope()->num_parameters(); 1822 int num_parameters = info()->scope()->num_parameters();
1788 for (int i = 0; i < num_parameters; i++) { 1823 for (int i = 0; i < num_parameters; i++) {
1789 Variable* variable = info()->scope()->parameter(i); 1824 Variable* variable = info()->scope()->parameter(i);
(...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after
2062 2097
2063 2098
2064 Node* AstGraphBuilder::BuildLoadGlobalObject() { 2099 Node* AstGraphBuilder::BuildLoadGlobalObject() {
2065 Node* context = GetFunctionContext(); 2100 Node* context = GetFunctionContext();
2066 const Operator* load_op = 2101 const Operator* load_op =
2067 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true); 2102 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
2068 return NewNode(load_op, context); 2103 return NewNode(load_op, context);
2069 } 2104 }
2070 2105
2071 2106
2107 Node* AstGraphBuilder::BuildLoadGlobalProxy() {
2108 Node* global = BuildLoadGlobalObject();
2109 Node* proxy =
2110 BuildLoadObjectField(global, JSGlobalObject::kGlobalProxyOffset);
2111 return proxy;
2112 }
2113
2114
2072 Node* AstGraphBuilder::BuildToBoolean(Node* input) { 2115 Node* AstGraphBuilder::BuildToBoolean(Node* input) {
2073 // TODO(titzer): this should be in a JSOperatorReducer. 2116 // TODO(titzer): this should be in a JSOperatorReducer.
2074 switch (input->opcode()) { 2117 switch (input->opcode()) {
2075 case IrOpcode::kInt32Constant: 2118 case IrOpcode::kInt32Constant:
2076 return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0)); 2119 return jsgraph_->BooleanConstant(!Int32Matcher(input).Is(0));
2077 case IrOpcode::kFloat64Constant: 2120 case IrOpcode::kFloat64Constant:
2078 return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0)); 2121 return jsgraph_->BooleanConstant(!Float64Matcher(input).Is(0));
2079 case IrOpcode::kNumberConstant: 2122 case IrOpcode::kNumberConstant:
2080 return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0)); 2123 return jsgraph_->BooleanConstant(!NumberMatcher(input).Is(0));
2081 case IrOpcode::kHeapConstant: { 2124 case IrOpcode::kHeapConstant: {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
2184 2227
2185 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop( 2228 BitVector* AstGraphBuilder::GetVariablesAssignedInLoop(
2186 IterationStatement* stmt) { 2229 IterationStatement* stmt) {
2187 if (loop_assignment_analysis_ == NULL) return NULL; 2230 if (loop_assignment_analysis_ == NULL) return NULL;
2188 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt); 2231 return loop_assignment_analysis_->GetVariablesAssignedInLoop(stmt);
2189 } 2232 }
2190 2233
2191 } // namespace compiler 2234 } // namespace compiler
2192 } // namespace internal 2235 } // namespace internal
2193 } // namespace v8 2236 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/ia32/code-generator-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698