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

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

Issue 2041010: ARM: Fix jumptargets to actually merge virtual frames.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 10 years, 7 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/arm/virtual-frame-arm.h » ('j') | src/arm/virtual-frame-arm.h » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 4940 matching lines...) Expand 10 before | Expand all | Expand 10 after
4951 ASSERT(!has_valid_frame() || 4951 ASSERT(!has_valid_frame() ||
4952 (has_cc() && frame_->height() == original_height) || 4952 (has_cc() && frame_->height() == original_height) ||
4953 (!has_cc() && frame_->height() == original_height + 1)); 4953 (!has_cc() && frame_->height() == original_height + 1));
4954 } 4954 }
4955 4955
4956 4956
4957 void CodeGenerator::VisitCountOperation(CountOperation* node) { 4957 void CodeGenerator::VisitCountOperation(CountOperation* node) {
4958 #ifdef DEBUG 4958 #ifdef DEBUG
4959 int original_height = frame_->height(); 4959 int original_height = frame_->height();
4960 #endif 4960 #endif
4961 VirtualFrame::SpilledScope spilled_scope(frame_);
4962 Comment cmnt(masm_, "[ CountOperation"); 4961 Comment cmnt(masm_, "[ CountOperation");
4963 4962
4964 bool is_postfix = node->is_postfix(); 4963 bool is_postfix = node->is_postfix();
4965 bool is_increment = node->op() == Token::INC; 4964 bool is_increment = node->op() == Token::INC;
4966 4965
4967 Variable* var = node->expression()->AsVariableProxy()->AsVariable(); 4966 Variable* var = node->expression()->AsVariableProxy()->AsVariable();
4968 bool is_const = (var != NULL && var->mode() == Variable::CONST); 4967 bool is_const = (var != NULL && var->mode() == Variable::CONST);
4969 4968
4970 // Postfix: Make room for the result.
4971 if (is_postfix) { 4969 if (is_postfix) {
4972 __ mov(r0, Operand(0)); 4970 frame_->EmitPush(Operand(Smi::FromInt(0)));
4973 frame_->EmitPush(r0);
4974 } 4971 }
4975 4972
4976 // A constant reference is not saved to, so a constant reference is not a 4973 // A constant reference is not saved to, so a constant reference is not a
4977 // compound assignment reference. 4974 // compound assignment reference.
4978 { Reference target(this, node->expression(), !is_const); 4975 { Reference target(this, node->expression(), !is_const);
4979 if (target.is_illegal()) { 4976 if (target.is_illegal()) {
4980 // Spoof the virtual frame to have the expected height (one higher 4977 // Spoof the virtual frame to have the expected height (one higher
4981 // than on entry). 4978 // than on entry).
4982 if (!is_postfix) { 4979 if (!is_postfix) {
4983 __ mov(r0, Operand(Smi::FromInt(0))); 4980 frame_->EmitPush(Operand(Smi::FromInt(0)));
4984 frame_->EmitPush(r0);
4985 } 4981 }
4986 ASSERT_EQ(original_height + 1, frame_->height()); 4982 ASSERT_EQ(original_height + 1, frame_->height());
4987 return; 4983 return;
4988 } 4984 }
4985 // This pushes 0, 1 or 2 words on the object to be used later when updating
4986 // the target. It also pushes the current value of the target.
4989 target.GetValue(); 4987 target.GetValue();
4990 frame_->EmitPop(r0);
4991 4988
4992 JumpTarget slow; 4989 JumpTarget slow;
4993 JumpTarget exit; 4990 JumpTarget exit;
4994 4991
4995 // Load the value (1) into register r1.
4996 __ mov(r1, Operand(Smi::FromInt(1)));
4997
4998 // Check for smi operand. 4992 // Check for smi operand.
4999 __ tst(r0, Operand(kSmiTagMask)); 4993 Register tos = frame_->PopToRegister();
4994 __ tst(tos, Operand(kSmiTagMask));
5000 slow.Branch(ne); 4995 slow.Branch(ne);
5001 4996
5002 // Postfix: Store the old value as the result. 4997 // Postfix: Store the old value as the result.
5003 if (is_postfix) { 4998 if (is_postfix) {
5004 __ str(r0, frame_->ElementAt(target.size())); 4999 frame_->OverwriteStackPosition(tos, target.size());
5005 } 5000 }
5006 5001
5007 // Perform optimistic increment/decrement. 5002 // Perform optimistic increment/decrement.
5008 if (is_increment) { 5003 if (is_increment) {
5009 __ add(r0, r0, Operand(r1), SetCC); 5004 __ add(tos, tos, Operand(Smi::FromInt(1)), SetCC);
5010 } else { 5005 } else {
5011 __ sub(r0, r0, Operand(r1), SetCC); 5006 __ sub(tos, tos, Operand(Smi::FromInt(1)), SetCC);
5012 } 5007 }
5013 5008
5014 // If the increment/decrement didn't overflow, we're done. 5009 // If the increment/decrement didn't overflow, we're done.
5015 exit.Branch(vc); 5010 exit.Branch(vc);
5016 5011
5017 // Revert optimistic increment/decrement. 5012 // Revert optimistic increment/decrement.
5018 if (is_increment) { 5013 if (is_increment) {
5019 __ sub(r0, r0, Operand(r1)); 5014 __ sub(tos, tos, Operand(Smi::FromInt(1)));
5020 } else { 5015 } else {
5021 __ add(r0, r0, Operand(r1)); 5016 __ add(tos, tos, Operand(Smi::FromInt(1)));
5022 } 5017 }
5023 5018
5024 // Slow case: Convert to number. 5019 // Slow case: Convert to number. At this point the
5020 // value to be incremented is in the tos register..
5025 slow.Bind(); 5021 slow.Bind();
5026 { 5022
5027 // Convert the operand to a number. 5023 // Convert the operand to a number.
5028 frame_->EmitPush(r0); 5024 frame_->EmitPush(tos);
5029 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1); 5025
5030 } 5026 // Work with a spilled frame from here.
5027 frame_->SpillAll();
5028 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
5029
5031 if (is_postfix) { 5030 if (is_postfix) {
5032 // Postfix: store to result (on the stack). 5031 // Postfix: store to result (on the stack).
5033 __ str(r0, frame_->ElementAt(target.size())); 5032 __ str(r0, frame_->ElementAt(target.size()));
5034 } 5033 }
5035 5034
5036 // Compute the new value. 5035 // Compute the new value.
5037 __ mov(r1, Operand(Smi::FromInt(1)));
5038 frame_->EmitPush(r0); 5036 frame_->EmitPush(r0);
5039 frame_->EmitPush(r1); 5037 frame_->EmitPush(Operand(Smi::FromInt(1)));
5040 if (is_increment) { 5038 if (is_increment) {
5041 frame_->CallRuntime(Runtime::kNumberAdd, 2); 5039 frame_->CallRuntime(Runtime::kNumberAdd, 2);
5042 } else { 5040 } else {
5043 frame_->CallRuntime(Runtime::kNumberSub, 2); 5041 frame_->CallRuntime(Runtime::kNumberSub, 2);
5044 } 5042 }
5045 5043
5044 __ Move(tos, r0);
Søren Thygesen Gjesse 2010/05/11 13:46:12 Perhaps make a spill scope from SpillAll above to
Erik Corry 2010/05/12 09:00:32 Done.
5046 // Store the new value in the target if not const. 5045 // Store the new value in the target if not const.
5046 // At this point the answer is in the tos register.
5047 exit.Bind(); 5047 exit.Bind();
5048 frame_->EmitPush(r0); 5048 frame_->EmitPush(tos);
5049 // Set the target with the result, leaving the result on
5050 // top of the stack. Removes the target from the stack if
5051 // it has a non-zero size.
5049 if (!is_const) target.SetValue(NOT_CONST_INIT); 5052 if (!is_const) target.SetValue(NOT_CONST_INIT);
5050 } 5053 }
5051 5054
5052 // Postfix: Discard the new value and use the old. 5055 // Postfix: Discard the new value and use the old.
5053 if (is_postfix) frame_->EmitPop(r0); 5056 if (is_postfix) frame_->Pop();
5054 ASSERT_EQ(original_height + 1, frame_->height()); 5057 ASSERT_EQ(original_height + 1, frame_->height());
5055 } 5058 }
5056 5059
5057 5060
5058 void CodeGenerator::GenerateLogicalBooleanOperation(BinaryOperation* node) { 5061 void CodeGenerator::GenerateLogicalBooleanOperation(BinaryOperation* node) {
5059 // According to ECMA-262 section 11.11, page 58, the binary logical 5062 // According to ECMA-262 section 11.11, page 58, the binary logical
5060 // operators must yield the result of one of the two expressions 5063 // operators must yield the result of one of the two expressions
5061 // before any ToBoolean() conversions. This means that the value 5064 // before any ToBoolean() conversions. This means that the value
5062 // produced by a && or || operator is not necessarily a boolean. 5065 // produced by a && or || operator is not necessarily a boolean.
5063 5066
(...skipping 4972 matching lines...) Expand 10 before | Expand all | Expand 10 after
10036 10039
10037 // Just jump to runtime to add the two strings. 10040 // Just jump to runtime to add the two strings.
10038 __ bind(&string_add_runtime); 10041 __ bind(&string_add_runtime);
10039 __ TailCallRuntime(Runtime::kStringAdd, 2, 1); 10042 __ TailCallRuntime(Runtime::kStringAdd, 2, 1);
10040 } 10043 }
10041 10044
10042 10045
10043 #undef __ 10046 #undef __
10044 10047
10045 } } // namespace v8::internal 10048 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/arm/virtual-frame-arm.h » ('j') | src/arm/virtual-frame-arm.h » ('J')

Powered by Google App Engine
This is Rietveld 408576698