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

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

Issue 3666001: Defer the prefix/postfix code generation. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 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 | « no previous file | no next file » | no next file with comments »
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 6030 matching lines...) Expand 10 before | Expand all | Expand 10 after
6041 default: 6041 default:
6042 UNREACHABLE(); 6042 UNREACHABLE();
6043 } 6043 }
6044 } 6044 }
6045 ASSERT(!has_valid_frame() || 6045 ASSERT(!has_valid_frame() ||
6046 (has_cc() && frame_->height() == original_height) || 6046 (has_cc() && frame_->height() == original_height) ||
6047 (!has_cc() && frame_->height() == original_height + 1)); 6047 (!has_cc() && frame_->height() == original_height + 1));
6048 } 6048 }
6049 6049
6050 6050
6051 class DeferredCountOperation: public DeferredCode {
6052 public:
6053 DeferredCountOperation(Register value,
6054 bool is_increment,
6055 bool is_postfix,
6056 int target_size)
6057 : value_(value),
6058 is_increment_(is_increment),
6059 is_postfix_(is_postfix),
6060 target_size_(target_size) {}
6061
6062 virtual void Generate() {
6063 VirtualFrame copied_frame(*frame_state()->frame());
6064
6065 Label slow;
6066 // Check for smi operand.
6067 __ tst(value_, Operand(kSmiTagMask));
6068 __ b(ne, &slow);
6069
6070 // Revert optimistic increment/decrement.
6071 if (is_increment_) {
6072 __ sub(value_, value_, Operand(Smi::FromInt(1)));
6073 } else {
6074 __ add(value_, value_, Operand(Smi::FromInt(1)));
6075 }
6076
6077 // Slow case: Convert to number. At this point the
6078 // value to be incremented is in the value register..
6079 __ bind(&slow);
6080
6081 // Convert the operand to a number.
6082 copied_frame.EmitPush(value_);
6083
6084 copied_frame.InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
6085
6086 if (is_postfix_) {
6087 // Postfix: store to result (on the stack).
6088 __ str(r0, MemOperand(sp, target_size_ * kPointerSize));
6089 }
6090
6091 copied_frame.EmitPush(r0);
6092 copied_frame.EmitPush(Operand(Smi::FromInt(1)));
6093
6094 if (is_increment_) {
6095 copied_frame.CallRuntime(Runtime::kNumberAdd, 2);
6096 } else {
6097 copied_frame.CallRuntime(Runtime::kNumberSub, 2);
6098 }
6099
6100 if (!value_.is(r0))
Erik Corry 2010/11/24 09:56:33 The 'if' is not needed. I corrected this.
6101 __ Move(value_, r0);
6102
6103 copied_frame.MergeTo(frame_state()->frame());
6104 }
6105
6106 private:
6107 Register value_;
6108 bool is_increment_;
6109 bool is_postfix_;
6110 int target_size_;
6111 };
6112
6113
6051 void CodeGenerator::VisitCountOperation(CountOperation* node) { 6114 void CodeGenerator::VisitCountOperation(CountOperation* node) {
6052 #ifdef DEBUG 6115 #ifdef DEBUG
6053 int original_height = frame_->height(); 6116 int original_height = frame_->height();
6054 #endif 6117 #endif
6055 Comment cmnt(masm_, "[ CountOperation"); 6118 Comment cmnt(masm_, "[ CountOperation");
6056 VirtualFrame::RegisterAllocationScope scope(this); 6119 VirtualFrame::RegisterAllocationScope scope(this);
6057 6120
6058 bool is_postfix = node->is_postfix(); 6121 bool is_postfix = node->is_postfix();
6059 bool is_increment = node->op() == Token::INC; 6122 bool is_increment = node->op() == Token::INC;
6060 6123
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6100 // than on entry). 6163 // than on entry).
6101 if (!placeholder_pushed) frame_->EmitPush(Operand(Smi::FromInt(0))); 6164 if (!placeholder_pushed) frame_->EmitPush(Operand(Smi::FromInt(0)));
6102 ASSERT_EQ(original_height + 1, frame_->height()); 6165 ASSERT_EQ(original_height + 1, frame_->height());
6103 return; 6166 return;
6104 } 6167 }
6105 6168
6106 // This pushes 0, 1 or 2 words on the object to be used later when updating 6169 // This pushes 0, 1 or 2 words on the object to be used later when updating
6107 // the target. It also pushes the current value of the target. 6170 // the target. It also pushes the current value of the target.
6108 target.GetValue(); 6171 target.GetValue();
6109 6172
6110 JumpTarget slow;
6111 JumpTarget exit;
6112
6113 Register value = frame_->PopToRegister(); 6173 Register value = frame_->PopToRegister();
6114 6174
6115 // Postfix: Store the old value as the result. 6175 // Postfix: Store the old value as the result.
6116 if (placeholder_pushed) { 6176 if (placeholder_pushed) {
6117 frame_->SetElementAt(value, target.size()); 6177 frame_->SetElementAt(value, target.size());
6118 } else if (is_postfix) { 6178 } else if (is_postfix) {
6119 frame_->EmitPush(value); 6179 frame_->EmitPush(value);
6120 __ mov(VirtualFrame::scratch0(), value); 6180 __ mov(VirtualFrame::scratch0(), value);
6121 value = VirtualFrame::scratch0(); 6181 value = VirtualFrame::scratch0();
6122 } 6182 }
6123 6183
6124 // Check for smi operand. 6184 // Check for smi operand.
6125 __ tst(value, Operand(kSmiTagMask)); 6185 __ tst(value, Operand(kSmiTagMask));
6126 slow.Branch(ne); 6186
6187 DeferredCode* deferred =
6188 new DeferredCountOperation(value,
6189 is_increment,
6190 is_postfix,
6191 target.size());
6192 deferred->Branch(ne);
6127 6193
6128 // Perform optimistic increment/decrement. 6194 // Perform optimistic increment/decrement.
6129 if (is_increment) { 6195 if (is_increment) {
6130 __ add(value, value, Operand(Smi::FromInt(1)), SetCC); 6196 __ add(value, value, Operand(Smi::FromInt(1)), SetCC);
6131 } else { 6197 } else {
6132 __ sub(value, value, Operand(Smi::FromInt(1)), SetCC); 6198 __ sub(value, value, Operand(Smi::FromInt(1)), SetCC);
6133 } 6199 }
6134 6200
6135 // If the increment/decrement didn't overflow, we're done. 6201 // If increment/decrement overflows, go to deferred code.
6136 exit.Branch(vc); 6202 deferred->Branch(vs);
6137 6203
6138 // Revert optimistic increment/decrement. 6204 deferred->BindExit();
6139 if (is_increment) {
6140 __ sub(value, value, Operand(Smi::FromInt(1)));
6141 } else {
6142 __ add(value, value, Operand(Smi::FromInt(1)));
6143 }
6144 6205
6145 // Slow case: Convert to number. At this point the
6146 // value to be incremented is in the value register..
6147 slow.Bind();
6148
6149 // Convert the operand to a number.
6150 frame_->EmitPush(value);
6151
6152 {
6153 VirtualFrame::SpilledScope spilled(frame_);
6154 frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
6155
6156 if (is_postfix) {
6157 // Postfix: store to result (on the stack).
6158 __ str(r0, frame_->ElementAt(target.size()));
6159 }
6160
6161 // Compute the new value.
6162 frame_->EmitPush(r0);
6163 frame_->EmitPush(Operand(Smi::FromInt(1)));
6164 if (is_increment) {
6165 frame_->CallRuntime(Runtime::kNumberAdd, 2);
6166 } else {
6167 frame_->CallRuntime(Runtime::kNumberSub, 2);
6168 }
6169 }
6170
6171 __ Move(value, r0);
6172 // Store the new value in the target if not const. 6206 // Store the new value in the target if not const.
6173 // At this point the answer is in the value register. 6207 // At this point the answer is in the value register.
6174 exit.Bind();
6175 frame_->EmitPush(value); 6208 frame_->EmitPush(value);
6176 // Set the target with the result, leaving the result on 6209 // Set the target with the result, leaving the result on
6177 // top of the stack. Removes the target from the stack if 6210 // top of the stack. Removes the target from the stack if
6178 // it has a non-zero size. 6211 // it has a non-zero size.
6179 if (!is_const) target.SetValue(NOT_CONST_INIT, LIKELY_SMI); 6212 if (!is_const) target.SetValue(NOT_CONST_INIT, LIKELY_SMI);
6180 } 6213 }
6181 6214
6182 // Postfix: Discard the new value and use the old. 6215 // Postfix: Discard the new value and use the old.
6183 if (is_postfix) frame_->Pop(); 6216 if (is_postfix) frame_->Pop();
6184 ASSERT_EQ(original_height + 1, frame_->height()); 6217 ASSERT_EQ(original_height + 1, frame_->height());
(...skipping 1119 matching lines...) Expand 10 before | Expand all | Expand 10 after
7304 BinaryOpIC::GetName(runtime_operands_type_)); 7337 BinaryOpIC::GetName(runtime_operands_type_));
7305 return name_; 7338 return name_;
7306 } 7339 }
7307 7340
7308 7341
7309 #undef __ 7342 #undef __
7310 7343
7311 } } // namespace v8::internal 7344 } } // namespace v8::internal
7312 7345
7313 #endif // V8_TARGET_ARCH_ARM 7346 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698