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

Side by Side Diff: src/rewriter.cc

Issue 1148007: Merge bleeding_edge from version 2.1.3 up to revision 4205... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 years, 9 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
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 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 } 213 }
214 214
215 215
216 void AstOptimizer::VisitFunctionBoilerplateLiteral( 216 void AstOptimizer::VisitFunctionBoilerplateLiteral(
217 FunctionBoilerplateLiteral* node) { 217 FunctionBoilerplateLiteral* node) {
218 USE(node); 218 USE(node);
219 } 219 }
220 220
221 221
222 void AstOptimizer::VisitConditional(Conditional* node) { 222 void AstOptimizer::VisitConditional(Conditional* node) {
223 node->condition()->set_no_negative_zero(true);
223 Visit(node->condition()); 224 Visit(node->condition());
224 Visit(node->then_expression()); 225 Visit(node->then_expression());
225 Visit(node->else_expression()); 226 Visit(node->else_expression());
226 } 227 }
227 228
228 229
229 void AstOptimizer::VisitSlot(Slot* node) { 230 void AstOptimizer::VisitSlot(Slot* node) {
230 USE(node); 231 USE(node);
231 } 232 }
232 233
233 234
234 void AstOptimizer::VisitVariableProxy(VariableProxy* node) { 235 void AstOptimizer::VisitVariableProxy(VariableProxy* node) {
235 Variable* var = node->AsVariable(); 236 Variable* var = node->AsVariable();
236 if (var != NULL) { 237 if (var != NULL) {
237 if (var->type()->IsKnown()) { 238 if (var->type()->IsKnown()) {
238 node->type()->CopyFrom(var->type()); 239 node->type()->CopyFrom(var->type());
239 } else if (node->type()->IsLikelySmi()) { 240 } else if (node->type()->IsLikelySmi()) {
240 var->type()->SetAsLikelySmi(); 241 var->type()->SetAsLikelySmi();
241 } 242 }
242 243
243 if (!var->is_this() && 244 if (!var->is_this() &&
244 !Heap::result_symbol()->Equals(*var->name())) { 245 !Heap::result_symbol()->Equals(*var->name())) {
245 func_name_inferrer_.PushName(var->name()); 246 func_name_inferrer_.PushName(var->name());
246 } 247 }
247 248
248 if (FLAG_safe_int32_compiler) { 249 if (FLAG_safe_int32_compiler) {
249 if (var->IsStackAllocated() && !var->is_arguments()) { 250 if (var->IsStackAllocated() &&
251 !var->is_arguments() &&
252 var->mode() != Variable::CONST) {
250 node->set_side_effect_free(true); 253 node->set_side_effect_free(true);
251 } 254 }
252 } 255 }
253 } 256 }
254 } 257 }
255 258
256 259
257 void AstOptimizer::VisitLiteral(Literal* node) { 260 void AstOptimizer::VisitLiteral(Literal* node) {
258 Handle<Object> literal = node->handle(); 261 Handle<Object> literal = node->handle();
259 if (literal->IsSmi()) { 262 if (literal->IsSmi()) {
260 node->type()->SetAsLikelySmi(); 263 node->type()->SetAsLikelySmi();
261 node->set_side_effect_free(true); 264 node->set_side_effect_free(true);
262 } else if (literal->IsString()) { 265 } else if (literal->IsString()) {
263 Handle<String> lit_str(Handle<String>::cast(literal)); 266 Handle<String> lit_str(Handle<String>::cast(literal));
264 if (!Heap::prototype_symbol()->Equals(*lit_str)) { 267 if (!Heap::prototype_symbol()->Equals(*lit_str)) {
265 func_name_inferrer_.PushName(lit_str); 268 func_name_inferrer_.PushName(lit_str);
266 } 269 }
267 } else if (literal->IsHeapNumber()) { 270 } else if (literal->IsHeapNumber()) {
268 node->set_side_effect_free(true); 271 if (node->to_int32()) {
272 // Any HeapNumber has an int32 value if it is the input to a bit op.
273 node->set_side_effect_free(true);
274 } else {
275 double double_value = HeapNumber::cast(*literal)->value();
276 int32_t int32_value = DoubleToInt32(double_value);
277 node->set_side_effect_free(double_value == int32_value);
278 }
269 } 279 }
270 } 280 }
271 281
272 282
273 void AstOptimizer::VisitRegExpLiteral(RegExpLiteral* node) { 283 void AstOptimizer::VisitRegExpLiteral(RegExpLiteral* node) {
274 USE(node); 284 USE(node);
275 } 285 }
276 286
277 287
278 void AstOptimizer::VisitArrayLiteral(ArrayLiteral* node) { 288 void AstOptimizer::VisitArrayLiteral(ArrayLiteral* node) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
312 break; 322 break;
313 case Token::ASSIGN_BIT_OR: 323 case Token::ASSIGN_BIT_OR:
314 case Token::ASSIGN_BIT_XOR: 324 case Token::ASSIGN_BIT_XOR:
315 case Token::ASSIGN_BIT_AND: 325 case Token::ASSIGN_BIT_AND:
316 case Token::ASSIGN_SHL: 326 case Token::ASSIGN_SHL:
317 case Token::ASSIGN_SAR: 327 case Token::ASSIGN_SAR:
318 case Token::ASSIGN_SHR: 328 case Token::ASSIGN_SHR:
319 node->type()->SetAsLikelySmiIfUnknown(); 329 node->type()->SetAsLikelySmiIfUnknown();
320 node->target()->type()->SetAsLikelySmiIfUnknown(); 330 node->target()->type()->SetAsLikelySmiIfUnknown();
321 node->value()->type()->SetAsLikelySmiIfUnknown(); 331 node->value()->type()->SetAsLikelySmiIfUnknown();
332 node->value()->set_to_int32(true);
333 node->value()->set_no_negative_zero(true);
322 break; 334 break;
323 case Token::ASSIGN_ADD: 335 case Token::ASSIGN_ADD:
324 case Token::ASSIGN_SUB: 336 case Token::ASSIGN_SUB:
325 case Token::ASSIGN_MUL: 337 case Token::ASSIGN_MUL:
326 case Token::ASSIGN_DIV: 338 case Token::ASSIGN_DIV:
327 case Token::ASSIGN_MOD: 339 case Token::ASSIGN_MOD:
328 if (node->type()->IsLikelySmi()) { 340 if (node->type()->IsLikelySmi()) {
329 node->target()->type()->SetAsLikelySmiIfUnknown(); 341 node->target()->type()->SetAsLikelySmiIfUnknown();
330 node->value()->type()->SetAsLikelySmiIfUnknown(); 342 node->value()->type()->SetAsLikelySmiIfUnknown();
331 } 343 }
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 } 398 }
387 } 399 }
388 400
389 401
390 void AstOptimizer::VisitThrow(Throw* node) { 402 void AstOptimizer::VisitThrow(Throw* node) {
391 Visit(node->exception()); 403 Visit(node->exception());
392 } 404 }
393 405
394 406
395 void AstOptimizer::VisitProperty(Property* node) { 407 void AstOptimizer::VisitProperty(Property* node) {
408 node->key()->set_no_negative_zero(true);
396 Visit(node->obj()); 409 Visit(node->obj());
397 Visit(node->key()); 410 Visit(node->key());
398 } 411 }
399 412
400 413
401 void AstOptimizer::VisitCall(Call* node) { 414 void AstOptimizer::VisitCall(Call* node) {
402 Visit(node->expression()); 415 Visit(node->expression());
403 OptimizeArguments(node->arguments()); 416 OptimizeArguments(node->arguments());
404 } 417 }
405 418
406 419
407 void AstOptimizer::VisitCallNew(CallNew* node) { 420 void AstOptimizer::VisitCallNew(CallNew* node) {
408 Visit(node->expression()); 421 Visit(node->expression());
409 OptimizeArguments(node->arguments()); 422 OptimizeArguments(node->arguments());
410 } 423 }
411 424
412 425
413 void AstOptimizer::VisitCallRuntime(CallRuntime* node) { 426 void AstOptimizer::VisitCallRuntime(CallRuntime* node) {
414 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_); 427 ScopedFuncNameInferrer scoped_fni(&func_name_inferrer_);
415 if (Factory::InitializeVarGlobal_symbol()->Equals(*node->name()) && 428 if (Factory::InitializeVarGlobal_symbol()->Equals(*node->name()) &&
416 node->arguments()->length() >= 2 && 429 node->arguments()->length() >= 2 &&
417 node->arguments()->at(1)->AsFunctionLiteral() != NULL) { 430 node->arguments()->at(1)->AsFunctionLiteral() != NULL) {
418 scoped_fni.Enter(); 431 scoped_fni.Enter();
419 } 432 }
420 OptimizeArguments(node->arguments()); 433 OptimizeArguments(node->arguments());
421 } 434 }
422 435
423 436
424 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) { 437 void AstOptimizer::VisitUnaryOperation(UnaryOperation* node) {
438 if (node->op() == Token::ADD || node->op() == Token::SUB) {
439 node->expression()->set_no_negative_zero(node->no_negative_zero());
440 } else {
441 node->expression()->set_no_negative_zero(true);
442 }
425 Visit(node->expression()); 443 Visit(node->expression());
426 if (FLAG_safe_int32_compiler) { 444 if (FLAG_safe_int32_compiler) {
427 switch (node->op()) { 445 switch (node->op()) {
428 case Token::BIT_NOT: 446 case Token::BIT_NOT:
429 node->expression()->set_to_int32(true); 447 node->expression()->set_to_int32(true);
430 // Fall through. 448 // Fall through.
431 case Token::ADD: 449 case Token::ADD:
432 case Token::SUB: 450 case Token::SUB:
433 case Token::NOT:
434 node->set_side_effect_free(node->expression()->side_effect_free()); 451 node->set_side_effect_free(node->expression()->side_effect_free());
435 break; 452 break;
453 case Token::NOT:
436 case Token::DELETE: 454 case Token::DELETE:
437 case Token::TYPEOF: 455 case Token::TYPEOF:
438 case Token::VOID: 456 case Token::VOID:
439 break; 457 break;
440 default: 458 default:
441 UNREACHABLE(); 459 UNREACHABLE();
442 break; 460 break;
443 } 461 }
444 } else if (node->op() == Token::BIT_NOT) { 462 } else if (node->op() == Token::BIT_NOT) {
445 node->expression()->set_to_int32(true); 463 node->expression()->set_to_int32(true);
446 } 464 }
447 } 465 }
448 466
449 467
450 void AstOptimizer::VisitCountOperation(CountOperation* node) { 468 void AstOptimizer::VisitCountOperation(CountOperation* node) {
451 // Count operations assume that they work on Smis. 469 // Count operations assume that they work on Smis.
470 node->expression()->set_no_negative_zero(node->is_prefix() ?
471 true :
472 node->no_negative_zero());
452 node->type()->SetAsLikelySmiIfUnknown(); 473 node->type()->SetAsLikelySmiIfUnknown();
453 node->expression()->type()->SetAsLikelySmiIfUnknown(); 474 node->expression()->type()->SetAsLikelySmiIfUnknown();
454 Visit(node->expression()); 475 Visit(node->expression());
455 } 476 }
456 477
457 478
458 void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) { 479 void AstOptimizer::VisitBinaryOperation(BinaryOperation* node) {
459 // Depending on the operation we can propagate this node's type down the 480 // Depending on the operation we can propagate this node's type down the
460 // AST nodes. 481 // AST nodes.
461 switch (node->op()) { 482 switch (node->op()) {
462 case Token::COMMA: 483 case Token::COMMA:
463 case Token::OR: 484 case Token::OR:
485 node->left()->set_no_negative_zero(true);
486 node->right()->set_no_negative_zero(node->no_negative_zero());
487 break;
464 case Token::AND: 488 case Token::AND:
489 node->left()->set_no_negative_zero(node->no_negative_zero());
490 node->right()->set_no_negative_zero(node->no_negative_zero());
465 break; 491 break;
466 case Token::BIT_OR: 492 case Token::BIT_OR:
467 case Token::BIT_XOR: 493 case Token::BIT_XOR:
468 case Token::BIT_AND: 494 case Token::BIT_AND:
469 case Token::SHL: 495 case Token::SHL:
470 case Token::SAR: 496 case Token::SAR:
471 case Token::SHR: 497 case Token::SHR:
472 node->type()->SetAsLikelySmiIfUnknown(); 498 node->type()->SetAsLikelySmiIfUnknown();
473 node->left()->type()->SetAsLikelySmiIfUnknown(); 499 node->left()->type()->SetAsLikelySmiIfUnknown();
474 node->right()->type()->SetAsLikelySmiIfUnknown(); 500 node->right()->type()->SetAsLikelySmiIfUnknown();
475 node->left()->set_to_int32(true); 501 node->left()->set_to_int32(true);
476 node->right()->set_to_int32(true); 502 node->right()->set_to_int32(true);
503 node->left()->set_no_negative_zero(true);
504 node->right()->set_no_negative_zero(true);
477 break; 505 break;
478 case Token::ADD: 506 case Token::ADD:
479 case Token::SUB: 507 case Token::SUB:
480 case Token::MUL: 508 case Token::MUL:
481 case Token::DIV: 509 case Token::DIV:
482 case Token::MOD: 510 case Token::MOD:
483 if (node->type()->IsLikelySmi()) { 511 if (node->type()->IsLikelySmi()) {
484 node->left()->type()->SetAsLikelySmiIfUnknown(); 512 node->left()->type()->SetAsLikelySmiIfUnknown();
485 node->right()->type()->SetAsLikelySmiIfUnknown(); 513 node->right()->type()->SetAsLikelySmiIfUnknown();
486 } 514 }
515 node->left()->set_no_negative_zero(node->no_negative_zero());
516 node->right()->set_no_negative_zero(node->no_negative_zero());
517 if (node->op() == Token::DIV) {
518 node->right()->set_no_negative_zero(false);
519 } else if (node->op() == Token::MOD) {
520 node->right()->set_no_negative_zero(true);
521 }
487 break; 522 break;
488 default: 523 default:
489 UNREACHABLE(); 524 UNREACHABLE();
490 break; 525 break;
491 } 526 }
492 527
493 Visit(node->left()); 528 Visit(node->left());
494 Visit(node->right()); 529 Visit(node->right());
495 530
496 // After visiting the operand nodes we have to check if this node's type 531 // After visiting the operand nodes we have to check if this node's type
(...skipping 24 matching lines...) Expand all
521 case Token::COMMA: 556 case Token::COMMA:
522 case Token::OR: 557 case Token::OR:
523 case Token::AND: 558 case Token::AND:
524 break; 559 break;
525 case Token::BIT_OR: 560 case Token::BIT_OR:
526 case Token::BIT_XOR: 561 case Token::BIT_XOR:
527 case Token::BIT_AND: 562 case Token::BIT_AND:
528 case Token::SHL: 563 case Token::SHL:
529 case Token::SAR: 564 case Token::SAR:
530 case Token::SHR: 565 case Token::SHR:
566 // Add one to the number of bit operations in this expression.
567 node->set_num_bit_ops(1);
568 // Fall through.
531 case Token::ADD: 569 case Token::ADD:
532 case Token::SUB: 570 case Token::SUB:
533 case Token::MUL: 571 case Token::MUL:
534 case Token::DIV: 572 case Token::DIV:
535 case Token::MOD: 573 case Token::MOD:
536 node->set_side_effect_free(node->left()->side_effect_free() && 574 node->set_side_effect_free(node->left()->side_effect_free() &&
537 node->right()->side_effect_free()); 575 node->right()->side_effect_free());
576 node->set_num_bit_ops(node->num_bit_ops() +
577 node->left()->num_bit_ops() +
578 node->right()->num_bit_ops());
579 if (!node->no_negative_zero() && node->op() == Token::MUL) {
580 node->set_side_effect_free(false);
581 }
538 break; 582 break;
539 default: 583 default:
540 UNREACHABLE(); 584 UNREACHABLE();
541 break; 585 break;
542 } 586 }
543 } 587 }
544 } 588 }
545 589
546 590
547 void AstOptimizer::VisitCompareOperation(CompareOperation* node) { 591 void AstOptimizer::VisitCompareOperation(CompareOperation* node) {
548 if (node->type()->IsKnown()) { 592 if (node->type()->IsKnown()) {
549 // Propagate useful information down towards the leafs. 593 // Propagate useful information down towards the leafs.
550 node->left()->type()->SetAsLikelySmiIfUnknown(); 594 node->left()->type()->SetAsLikelySmiIfUnknown();
551 node->right()->type()->SetAsLikelySmiIfUnknown(); 595 node->right()->type()->SetAsLikelySmiIfUnknown();
552 } 596 }
553 597
598 node->left()->set_no_negative_zero(true);
599 // Only [[HasInstance]] has the right argument passed unchanged to it.
600 node->right()->set_no_negative_zero(true);
601
554 Visit(node->left()); 602 Visit(node->left());
555 Visit(node->right()); 603 Visit(node->right());
556 604
557 // After visiting the operand nodes we have to check if this node's type 605 // After visiting the operand nodes we have to check if this node's type
558 // can be updated. If it does, then we can push that information down 606 // can be updated. If it does, then we can push that information down
559 // towards the leafs again if the new information is an upgrade over the 607 // towards the leafs again if the new information is an upgrade over the
560 // previous type of the operand nodes. 608 // previous type of the operand nodes.
561 if (node->type()->IsUnknown()) { 609 if (node->type()->IsUnknown()) {
562 if (node->left()->type()->IsLikelySmi() || 610 if (node->left()->type()->IsLikelySmi() ||
563 node->right()->type()->IsLikelySmi()) { 611 node->right()->type()->IsLikelySmi()) {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
904 optimizer.Optimize(body); 952 optimizer.Optimize(body);
905 if (optimizer.HasStackOverflow()) { 953 if (optimizer.HasStackOverflow()) {
906 return false; 954 return false;
907 } 955 }
908 } 956 }
909 return true; 957 return true;
910 } 958 }
911 959
912 960
913 } } // namespace v8::internal 961 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698