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/arm/codegen-arm.cc

Issue 160006: Fix ARM compiler crash in short-circuited boolean expressions.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 11 years, 5 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 | test/mjsunit/regress/regress-406.js » ('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-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 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 3719 matching lines...) Expand 10 before | Expand all | Expand 10 after
3730 __ mov(arg_count.reg(), Operand(0)); // not counting receiver 3730 __ mov(arg_count.reg(), Operand(0)); // not counting receiver
3731 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1); 3731 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, &arg_count, 1);
3732 continue_label.Bind(); 3732 continue_label.Bind();
3733 break; 3733 break;
3734 } 3734 }
3735 default: 3735 default:
3736 UNREACHABLE(); 3736 UNREACHABLE();
3737 } 3737 }
3738 frame_->EmitPush(r0); // r0 has result 3738 frame_->EmitPush(r0); // r0 has result
3739 } 3739 }
3740 ASSERT((has_cc() && frame_->height() == original_height) || 3740 ASSERT(!has_valid_frame() ||
3741 (has_cc() && frame_->height() == original_height) ||
3741 (!has_cc() && frame_->height() == original_height + 1)); 3742 (!has_cc() && frame_->height() == original_height + 1));
3742 } 3743 }
3743 3744
3744 3745
3745 void CodeGenerator::VisitCountOperation(CountOperation* node) { 3746 void CodeGenerator::VisitCountOperation(CountOperation* node) {
3746 #ifdef DEBUG 3747 #ifdef DEBUG
3747 int original_height = frame_->height(); 3748 int original_height = frame_->height();
3748 #endif 3749 #endif
3749 VirtualFrame::SpilledScope spilled_scope; 3750 VirtualFrame::SpilledScope spilled_scope;
3750 Comment cmnt(masm_, "[ CountOperation"); 3751 Comment cmnt(masm_, "[ CountOperation");
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
3864 // semantics), but the compiler must (statically) know if the result 3865 // semantics), but the compiler must (statically) know if the result
3865 // of compiling the binary operation is materialized or not. 3866 // of compiling the binary operation is materialized or not.
3866 3867
3867 if (op == Token::AND) { 3868 if (op == Token::AND) {
3868 JumpTarget is_true; 3869 JumpTarget is_true;
3869 LoadConditionAndSpill(node->left(), 3870 LoadConditionAndSpill(node->left(),
3870 NOT_INSIDE_TYPEOF, 3871 NOT_INSIDE_TYPEOF,
3871 &is_true, 3872 &is_true,
3872 false_target(), 3873 false_target(),
3873 false); 3874 false);
3874 if (has_cc()) { 3875 if (has_valid_frame() && !has_cc()) {
3875 Branch(false, false_target()); 3876 // The left-hand side result is on top of the virtual frame.
3876
3877 // Evaluate right side expression.
3878 is_true.Bind();
3879 LoadConditionAndSpill(node->right(),
3880 NOT_INSIDE_TYPEOF,
3881 true_target(),
3882 false_target(),
3883 false);
3884
3885 } else {
3886 JumpTarget pop_and_continue; 3877 JumpTarget pop_and_continue;
3887 JumpTarget exit; 3878 JumpTarget exit;
3888 3879
3889 __ ldr(r0, frame_->Top()); // dup the stack top 3880 __ ldr(r0, frame_->Top()); // Duplicate the stack top.
3890 frame_->EmitPush(r0); 3881 frame_->EmitPush(r0);
3891 // Avoid popping the result if it converts to 'false' using the 3882 // Avoid popping the result if it converts to 'false' using the
3892 // standard ToBoolean() conversion as described in ECMA-262, 3883 // standard ToBoolean() conversion as described in ECMA-262,
3893 // section 9.2, page 30. 3884 // section 9.2, page 30.
3894 ToBoolean(&pop_and_continue, &exit); 3885 ToBoolean(&pop_and_continue, &exit);
3895 Branch(false, &exit); 3886 Branch(false, &exit);
3896 3887
3897 // Pop the result of evaluating the first part. 3888 // Pop the result of evaluating the first part.
3898 pop_and_continue.Bind(); 3889 pop_and_continue.Bind();
3899 frame_->EmitPop(r0); 3890 frame_->EmitPop(r0);
3900 3891
3901 // Evaluate right side expression. 3892 // Evaluate right side expression.
3902 is_true.Bind(); 3893 is_true.Bind();
3903 LoadAndSpill(node->right()); 3894 LoadAndSpill(node->right());
3904 3895
3905 // Exit (always with a materialized value). 3896 // Exit (always with a materialized value).
3906 exit.Bind(); 3897 exit.Bind();
3898 } else if (has_cc() || is_true.is_linked()) {
3899 // The left-hand side is either (a) partially compiled to
3900 // control flow with a final branch left to emit or (b) fully
3901 // compiled to control flow and possibly true.
3902 if (has_cc()) {
3903 Branch(false, false_target());
3904 }
3905 is_true.Bind();
3906 LoadConditionAndSpill(node->right(),
3907 NOT_INSIDE_TYPEOF,
3908 true_target(),
3909 false_target(),
3910 false);
3911 } else {
3912 // Nothing to do.
3913 ASSERT(!has_valid_frame() && !has_cc() && !is_true.is_linked());
3907 } 3914 }
3908 3915
3909 } else if (op == Token::OR) { 3916 } else if (op == Token::OR) {
3910 JumpTarget is_false; 3917 JumpTarget is_false;
3911 LoadConditionAndSpill(node->left(), 3918 LoadConditionAndSpill(node->left(),
3912 NOT_INSIDE_TYPEOF, 3919 NOT_INSIDE_TYPEOF,
3913 true_target(), 3920 true_target(),
3914 &is_false, 3921 &is_false,
3915 false); 3922 false);
3916 if (has_cc()) { 3923 if (has_valid_frame() && !has_cc()) {
3917 Branch(true, true_target()); 3924 // The left-hand side result is on top of the virtual frame.
3918
3919 // Evaluate right side expression.
3920 is_false.Bind();
3921 LoadConditionAndSpill(node->right(),
3922 NOT_INSIDE_TYPEOF,
3923 true_target(),
3924 false_target(),
3925 false);
3926
3927 } else {
3928 JumpTarget pop_and_continue; 3925 JumpTarget pop_and_continue;
3929 JumpTarget exit; 3926 JumpTarget exit;
3930 3927
3931 __ ldr(r0, frame_->Top()); 3928 __ ldr(r0, frame_->Top());
3932 frame_->EmitPush(r0); 3929 frame_->EmitPush(r0);
3933 // Avoid popping the result if it converts to 'true' using the 3930 // Avoid popping the result if it converts to 'true' using the
3934 // standard ToBoolean() conversion as described in ECMA-262, 3931 // standard ToBoolean() conversion as described in ECMA-262,
3935 // section 9.2, page 30. 3932 // section 9.2, page 30.
3936 ToBoolean(&exit, &pop_and_continue); 3933 ToBoolean(&exit, &pop_and_continue);
3937 Branch(true, &exit); 3934 Branch(true, &exit);
3938 3935
3939 // Pop the result of evaluating the first part. 3936 // Pop the result of evaluating the first part.
3940 pop_and_continue.Bind(); 3937 pop_and_continue.Bind();
3941 frame_->EmitPop(r0); 3938 frame_->EmitPop(r0);
3942 3939
3943 // Evaluate right side expression. 3940 // Evaluate right side expression.
3944 is_false.Bind(); 3941 is_false.Bind();
3945 LoadAndSpill(node->right()); 3942 LoadAndSpill(node->right());
3946 3943
3947 // Exit (always with a materialized value). 3944 // Exit (always with a materialized value).
3948 exit.Bind(); 3945 exit.Bind();
3946 } else if (has_cc() || is_false.is_linked()) {
3947 // The left-hand side is either (a) partially compiled to
3948 // control flow with a final branch left to emit or (b) fully
3949 // compiled to control flow and possibly false.
3950 if (has_cc()) {
3951 Branch(true, true_target());
3952 }
3953 is_false.Bind();
3954 LoadConditionAndSpill(node->right(),
3955 NOT_INSIDE_TYPEOF,
3956 true_target(),
3957 false_target(),
3958 false);
3959 } else {
3960 // Nothing to do.
3961 ASSERT(!has_valid_frame() && !has_cc() && !is_false.is_linked());
3949 } 3962 }
3950 3963
3951 } else { 3964 } else {
3952 // Optimize for the case where (at least) one of the expressions 3965 // Optimize for the case where (at least) one of the expressions
3953 // is a literal small integer. 3966 // is a literal small integer.
3954 Literal* lliteral = node->left()->AsLiteral(); 3967 Literal* lliteral = node->left()->AsLiteral();
3955 Literal* rliteral = node->right()->AsLiteral(); 3968 Literal* rliteral = node->right()->AsLiteral();
3956 // NOTE: The code below assumes that the slow cases (calls to runtime) 3969 // NOTE: The code below assumes that the slow cases (calls to runtime)
3957 // never return a constant/immutable object. 3970 // never return a constant/immutable object.
3958 bool overwrite_left = 3971 bool overwrite_left =
(...skipping 23 matching lines...) Expand all
3982 overwrite_mode = OVERWRITE_LEFT; 3995 overwrite_mode = OVERWRITE_LEFT;
3983 } else if (overwrite_right) { 3996 } else if (overwrite_right) {
3984 overwrite_mode = OVERWRITE_RIGHT; 3997 overwrite_mode = OVERWRITE_RIGHT;
3985 } 3998 }
3986 LoadAndSpill(node->left()); 3999 LoadAndSpill(node->left());
3987 LoadAndSpill(node->right()); 4000 LoadAndSpill(node->right());
3988 GenericBinaryOperation(node->op(), overwrite_mode); 4001 GenericBinaryOperation(node->op(), overwrite_mode);
3989 } 4002 }
3990 frame_->EmitPush(r0); 4003 frame_->EmitPush(r0);
3991 } 4004 }
3992 ASSERT((has_cc() && frame_->height() == original_height) || 4005 ASSERT(!has_valid_frame() ||
4006 (has_cc() && frame_->height() == original_height) ||
3993 (!has_cc() && frame_->height() == original_height + 1)); 4007 (!has_cc() && frame_->height() == original_height + 1));
3994 } 4008 }
3995 4009
3996 4010
3997 void CodeGenerator::VisitThisFunction(ThisFunction* node) { 4011 void CodeGenerator::VisitThisFunction(ThisFunction* node) {
3998 #ifdef DEBUG 4012 #ifdef DEBUG
3999 int original_height = frame_->height(); 4013 int original_height = frame_->height();
4000 #endif 4014 #endif
4001 VirtualFrame::SpilledScope spilled_scope; 4015 VirtualFrame::SpilledScope spilled_scope;
4002 __ ldr(r0, frame_->Function()); 4016 __ ldr(r0, frame_->Function());
(...skipping 2399 matching lines...) Expand 10 before | Expand all | Expand 10 after
6402 int CompareStub::MinorKey() { 6416 int CompareStub::MinorKey() {
6403 // Encode the two parameters in a unique 16 bit value. 6417 // Encode the two parameters in a unique 16 bit value.
6404 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15)); 6418 ASSERT(static_cast<unsigned>(cc_) >> 28 < (1 << 15));
6405 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0); 6419 return (static_cast<unsigned>(cc_) >> 27) | (strict_ ? 1 : 0);
6406 } 6420 }
6407 6421
6408 6422
6409 #undef __ 6423 #undef __
6410 6424
6411 } } // namespace v8::internal 6425 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/regress/regress-406.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698