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

Side by Side Diff: src/rewriter.cc

Issue 62146: Add name inference for anonymous functions to facilitate debugging and profiling of JS code. (Closed)
Patch Set: updated v8_base_arm project Created 11 years, 8 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
« no previous file with comments | « src/prettyprinter.cc ('k') | src/runtime.h » ('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 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 10 matching lines...) Expand all
21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 27
28 #include "v8.h" 28 #include "v8.h"
29 29
30 #include "ast.h" 30 #include "ast.h"
31 #include "func-name-inferrer.h"
31 #include "scopes.h" 32 #include "scopes.h"
32 #include "rewriter.h" 33 #include "rewriter.h"
33 34
34 namespace v8 { namespace internal { 35 namespace v8 { namespace internal {
35 36
36 37
37 class AstOptimizer: public AstVisitor { 38 class AstOptimizer: public AstVisitor {
38 public: 39 public:
39 explicit AstOptimizer() { 40 explicit AstOptimizer() {}
41 explicit AstOptimizer(Handle<String> enclosing_name) {
42 func_name_inferrer_.PushEnclosingName(enclosing_name);
40 } 43 }
41 44
42 void Optimize(ZoneList<Statement*>* statements); 45 void Optimize(ZoneList<Statement*>* statements);
43 46
44 private: 47 private:
45 // Used for loop condition analysis. Cleared before visiting a loop 48 // Used for loop condition analysis. Cleared before visiting a loop
46 // condition, set when a function literal is visited. 49 // condition, set when a function literal is visited.
47 bool has_function_literal_; 50 bool has_function_literal_;
51 // Helper object for function name inferring.
52 FuncNameInferrer func_name_inferrer_;
48 53
49 // Helpers 54 // Helpers
50 void OptimizeArguments(ZoneList<Expression*>* arguments); 55 void OptimizeArguments(ZoneList<Expression*>* arguments);
51 56
52 // Node visitors. 57 // Node visitors.
53 #define DEF_VISIT(type) \ 58 #define DEF_VISIT(type) \
54 virtual void Visit##type(type* node); 59 virtual void Visit##type(type* node);
55 NODE_LIST(DEF_VISIT) 60 NODE_LIST(DEF_VISIT)
56 #undef DEF_VISIT 61 #undef DEF_VISIT
57 62
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after
178 USE(node); 183 USE(node);
179 } 184 }
180 185
181 186
182 void AstOptimizer::VisitDebuggerStatement(DebuggerStatement* node) { 187 void AstOptimizer::VisitDebuggerStatement(DebuggerStatement* node) {
183 USE(node); 188 USE(node);
184 } 189 }
185 190
186 191
187 void AstOptimizer::VisitFunctionLiteral(FunctionLiteral* node) { 192 void AstOptimizer::VisitFunctionLiteral(FunctionLiteral* node) {
188 USE(node);
189 has_function_literal_ = true; 193 has_function_literal_ = true;
194
195 if (node->name()->length() == 0) {
196 // Anonymous function.
197 func_name_inferrer_.SetFuncToInfer(node);
198 }
190 } 199 }
191 200
192 201
193 void AstOptimizer::VisitFunctionBoilerplateLiteral( 202 void AstOptimizer::VisitFunctionBoilerplateLiteral(
194 FunctionBoilerplateLiteral* node) { 203 FunctionBoilerplateLiteral* node) {
195 USE(node); 204 USE(node);
196 } 205 }
197 206
198 207
199 void AstOptimizer::VisitConditional(Conditional* node) { 208 void AstOptimizer::VisitConditional(Conditional* node) {
200 Visit(node->condition()); 209 Visit(node->condition());
201 Visit(node->then_expression()); 210 Visit(node->then_expression());
202 Visit(node->else_expression()); 211 Visit(node->else_expression());
203 } 212 }
204 213
205 214
206 void AstOptimizer::VisitSlot(Slot* node) { 215 void AstOptimizer::VisitSlot(Slot* node) {
207 USE(node); 216 USE(node);
208 } 217 }
209 218
210 219
211 void AstOptimizer::VisitVariableProxy(VariableProxy* node) { 220 void AstOptimizer::VisitVariableProxy(VariableProxy* node) {
212 Variable* var = node->AsVariable(); 221 Variable* var = node->AsVariable();
213 if (var != NULL) { 222 if (var != NULL) {
214 if (var->type()->IsKnown()) { 223 if (var->type()->IsKnown()) {
215 node->type()->CopyFrom(var->type()); 224 node->type()->CopyFrom(var->type());
216 } else if (node->type()->IsLikelySmi()) { 225 } else if (node->type()->IsLikelySmi()) {
217 var->type()->SetAsLikelySmi(); 226 var->type()->SetAsLikelySmi();
218 } 227 }
228
229 if (!var->is_this() &&
230 !Heap::result_symbol()->Equals(*var->name())) {
231 func_name_inferrer_.PushName(var->name());
232 }
219 } 233 }
220 } 234 }
221 235
222 236
223 void AstOptimizer::VisitLiteral(Literal* node) { 237 void AstOptimizer::VisitLiteral(Literal* node) {
224 Handle<Object> literal = node->handle(); 238 Handle<Object> literal = node->handle();
225 if (literal->IsSmi()) { 239 if (literal->IsSmi()) {
226 node->type()->SetAsLikelySmi(); 240 node->type()->SetAsLikelySmi();
241 } else if (literal->IsString()) {
242 Handle<String> lit_str(Handle<String>::cast(literal));
243 if (!Heap::prototype_symbol()->Equals(*lit_str)) {
244 func_name_inferrer_.PushName(lit_str);
245 }
227 } 246 }
228 } 247 }
229 248
230 249
231 void AstOptimizer::VisitRegExpLiteral(RegExpLiteral* node) { 250 void AstOptimizer::VisitRegExpLiteral(RegExpLiteral* node) {
232 USE(node); 251 USE(node);
233 } 252 }
234 253
235 254
236 void AstOptimizer::VisitArrayLiteral(ArrayLiteral* node) { 255 void AstOptimizer::VisitArrayLiteral(ArrayLiteral* node) {
237 for (int i = 0; i < node->values()->length(); i++) { 256 for (int i = 0; i < node->values()->length(); i++) {
238 Visit(node->values()->at(i)); 257 Visit(node->values()->at(i));
239 } 258 }
240 } 259 }
241 260
242
243 void AstOptimizer::VisitObjectLiteral(ObjectLiteral* node) { 261 void AstOptimizer::VisitObjectLiteral(ObjectLiteral* node) {
244 for (int i = 0; i < node->properties()->length(); i++) { 262 for (int i = 0; i < node->properties()->length(); i++) {
263 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
264 scoped_fni.Enter();
245 Visit(node->properties()->at(i)->key()); 265 Visit(node->properties()->at(i)->key());
246 Visit(node->properties()->at(i)->value()); 266 Visit(node->properties()->at(i)->value());
247 } 267 }
248 } 268 }
249 269
250 270
251 void AstOptimizer::VisitCatchExtensionObject(CatchExtensionObject* node) { 271 void AstOptimizer::VisitCatchExtensionObject(CatchExtensionObject* node) {
252 Visit(node->key()); 272 Visit(node->key());
253 Visit(node->value()); 273 Visit(node->value());
254 } 274 }
255 275
256 276
257 void AstOptimizer::VisitAssignment(Assignment* node) { 277 void AstOptimizer::VisitAssignment(Assignment* node) {
278 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
258 switch (node->op()) { 279 switch (node->op()) {
259 case Token::INIT_VAR: 280 case Token::INIT_VAR:
260 case Token::INIT_CONST: 281 case Token::INIT_CONST:
261 case Token::ASSIGN: 282 case Token::ASSIGN:
262 // No type can be infered from the general assignment. 283 // No type can be infered from the general assignment.
284
285 if (node->value()->AsFunctionLiteral() != NULL ||
286 node->value()->AsObjectLiteral() != NULL) {
287 scoped_fni.Enter();
288 }
263 break; 289 break;
264 case Token::ASSIGN_BIT_OR: 290 case Token::ASSIGN_BIT_OR:
265 case Token::ASSIGN_BIT_XOR: 291 case Token::ASSIGN_BIT_XOR:
266 case Token::ASSIGN_BIT_AND: 292 case Token::ASSIGN_BIT_AND:
267 case Token::ASSIGN_SHL: 293 case Token::ASSIGN_SHL:
268 case Token::ASSIGN_SAR: 294 case Token::ASSIGN_SAR:
269 case Token::ASSIGN_SHR: 295 case Token::ASSIGN_SHR:
270 node->type()->SetAsLikelySmiIfUnknown(); 296 node->type()->SetAsLikelySmiIfUnknown();
271 node->target()->type()->SetAsLikelySmiIfUnknown(); 297 node->target()->type()->SetAsLikelySmiIfUnknown();
272 node->value()->type()->SetAsLikelySmiIfUnknown(); 298 node->value()->type()->SetAsLikelySmiIfUnknown();
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
361 } 387 }
362 388
363 389
364 void AstOptimizer::VisitCallNew(CallNew* node) { 390 void AstOptimizer::VisitCallNew(CallNew* node) {
365 Visit(node->expression()); 391 Visit(node->expression());
366 OptimizeArguments(node->arguments()); 392 OptimizeArguments(node->arguments());
367 } 393 }
368 394
369 395
370 void AstOptimizer::VisitCallRuntime(CallRuntime* node) { 396 void AstOptimizer::VisitCallRuntime(CallRuntime* node) {
397 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
398 if (Factory::InitializeVarGlobal_symbol()->Equals(*node->name()) &&
399 node->arguments()->length() >= 2 &&
400 node->arguments()->at(1)->AsFunctionLiteral() != NULL) {
401 scoped_fni.Enter();
402 }
371 OptimizeArguments(node->arguments()); 403 OptimizeArguments(node->arguments());
372 } 404 }
373 405
374 406
375 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) { 407 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
376 Visit(node->expression()); 408 Visit(node->expression());
377 } 409 }
378 410
379 411
380 void AstOptimizer::VisitCountOperation(CountOperation* node) { 412 void AstOptimizer::VisitCountOperation(CountOperation* node) {
(...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after
787 819
788 if (processor.result_assigned()) body->Add(new ReturnStatement(result)); 820 if (processor.result_assigned()) body->Add(new ReturnStatement(result));
789 return true; 821 return true;
790 } 822 }
791 823
792 824
793 bool Rewriter::Optimize(FunctionLiteral* function) { 825 bool Rewriter::Optimize(FunctionLiteral* function) {
794 ZoneList<Statement*>* body = function->body(); 826 ZoneList<Statement*>* body = function->body();
795 827
796 if (FLAG_optimize_ast && !body->is_empty()) { 828 if (FLAG_optimize_ast && !body->is_empty()) {
797 Scope* scope = function->scope(); 829 AstOptimizer optimizer(function->name());
798 if (!scope->is_global_scope()) { 830 optimizer.Optimize(body);
799 AstOptimizer optimizer; 831 if (optimizer.HasStackOverflow()) {
800 optimizer.Optimize(body); 832 return false;
801 if (optimizer.HasStackOverflow()) {
802 return false;
803 }
804 } 833 }
805 } 834 }
806 return true; 835 return true;
807 } 836 }
808 837
809 838
810 } } // namespace v8::internal 839 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/prettyprinter.cc ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698