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

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 | 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 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 copied_frame.SpillAll();
Erik Corry 2010/11/05 22:04:36 Actually I think you don't need this, though the b
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: Done.
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: Done.
6065
6066 Label slow;
6067 // Check for smi operand.
6068 __ tst(value_, Operand(kSmiTagMask));
6069 __ b(ne, &slow);
6070
6071 // Revert optimistic increment/decrement.
6072 if (is_increment_) {
6073 __ sub(value_, value_, Operand(Smi::FromInt(1)), LeaveCC, vs);
6074 } else {
6075 __ add(value_, value_, Operand(Smi::FromInt(1)), LeaveCC, vs);
6076 }
6077
6078 // Slow case: Convert to number. At this point the
6079 // value to be incremented is in the value register..
6080 __ bind(&slow);
6081
6082 // Convert the operand to a number.
6083 __ push(value_);
6084 copied_frame.RaiseHeight(1, 0);
Erik Corry 2010/11/05 22:04:36 Instead of doing a "__ push" followed by RaiseHeig
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: Done.
6085
6086 copied_frame.InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
6087
6088 if (is_postfix_) {
6089 // Postfix: store to result (on the stack).
6090 __ str(r0, MemOperand(sp, target_size_ * kPointerSize));
6091 }
6092
6093 // Compute the new value.
6094 __ push(r0);
6095 copied_frame.RaiseHeight(1, 0);
6096 __ mov(r0, Operand(Smi::FromInt(1)));
Erik Corry 2010/11/05 22:04:36 If you use EmitPush you will have to get a new reg
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: Done.
6097 __ push(r0);
6098 copied_frame.RaiseHeight(1, 0);
6099 if (is_increment_) {
6100 copied_frame.CallRuntime(Runtime::kNumberAdd, 2);
6101 } else {
6102 copied_frame.CallRuntime(Runtime::kNumberSub, 2);
6103 }
6104
6105 if (!value_.is(r0))
6106 __ mov(value_, r0);
Erik Corry 2010/11/05 22:04:36 We have __ Move(value_, r0) for this purpose.
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: Done.
6107
6108 copied_frame.MergeTo(frame_state()->frame());
6109 }
6110
6111 private:
6112 Register value_;
6113 bool is_increment_;
6114 bool is_postfix_;
6115 int target_size_;
6116 };
6117
6118
6051 void CodeGenerator::VisitCountOperation(CountOperation* node) { 6119 void CodeGenerator::VisitCountOperation(CountOperation* node) {
6052 #ifdef DEBUG 6120 #ifdef DEBUG
6053 int original_height = frame_->height(); 6121 int original_height = frame_->height();
6054 #endif 6122 #endif
6055 Comment cmnt(masm_, "[ CountOperation"); 6123 Comment cmnt(masm_, "[ CountOperation");
6056 VirtualFrame::RegisterAllocationScope scope(this); 6124 VirtualFrame::RegisterAllocationScope scope(this);
6057 6125
6058 bool is_postfix = node->is_postfix(); 6126 bool is_postfix = node->is_postfix();
6059 bool is_increment = node->op() == Token::INC; 6127 bool is_increment = node->op() == Token::INC;
6060 6128
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
6100 // than on entry). 6168 // than on entry).
6101 if (!placeholder_pushed) frame_->EmitPush(Operand(Smi::FromInt(0))); 6169 if (!placeholder_pushed) frame_->EmitPush(Operand(Smi::FromInt(0)));
6102 ASSERT_EQ(original_height + 1, frame_->height()); 6170 ASSERT_EQ(original_height + 1, frame_->height());
6103 return; 6171 return;
6104 } 6172 }
6105 6173
6106 // This pushes 0, 1 or 2 words on the object to be used later when updating 6174 // 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. 6175 // the target. It also pushes the current value of the target.
6108 target.GetValue(); 6176 target.GetValue();
6109 6177
6110 JumpTarget slow;
6111 JumpTarget exit;
6112
6113 Register value = frame_->PopToRegister(); 6178 Register value = frame_->PopToRegister();
6114 6179
6115 // Postfix: Store the old value as the result. 6180 // Postfix: Store the old value as the result.
6116 if (placeholder_pushed) { 6181 if (placeholder_pushed) {
6117 frame_->SetElementAt(value, target.size()); 6182 frame_->SetElementAt(value, target.size());
6118 } else if (is_postfix) { 6183 } else if (is_postfix) {
6119 frame_->EmitPush(value); 6184 frame_->EmitPush(value);
6120 __ mov(VirtualFrame::scratch0(), value); 6185 __ mov(VirtualFrame::scratch0(), value);
6121 value = VirtualFrame::scratch0(); 6186 value = VirtualFrame::scratch0();
6122 } 6187 }
6123 6188
6124 // Check for smi operand. 6189 // Check for smi operand.
6125 __ tst(value, Operand(kSmiTagMask)); 6190 __ tst(value, Operand(kSmiTagMask));
6126 slow.Branch(ne); 6191
6192 DeferredCode* deferred =
6193 new DeferredCountOperation(value,
6194 is_increment,
6195 is_postfix,
6196 target.size());
6197 deferred->Branch(ne);
Erik Corry 2010/11/05 22:04:36 It looks like you still have a bug here. The tst
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: I agree
6127 6198
6128 // Perform optimistic increment/decrement. 6199 // Perform optimistic increment/decrement.
6129 if (is_increment) { 6200 if (is_increment) {
6130 __ add(value, value, Operand(Smi::FromInt(1)), SetCC); 6201 __ add(value, value, Operand(Smi::FromInt(1)), SetCC);
6131 } else { 6202 } else {
6132 __ sub(value, value, Operand(Smi::FromInt(1)), SetCC); 6203 __ sub(value, value, Operand(Smi::FromInt(1)), SetCC);
6133 } 6204 }
6134 6205
6135 // If the increment/decrement didn't overflow, we're done. 6206 // If increment/decrement overflows, go to deferred code.
6136 exit.Branch(vc); 6207 deferred->Branch(vs);
6137
6138 // Revert optimistic increment/decrement.
6139 if (is_increment) {
6140 __ sub(value, value, Operand(Smi::FromInt(1)));
6141 } else {
6142 __ add(value, value, Operand(Smi::FromInt(1)));
6143 }
6144 6208
6145 // Slow case: Convert to number. At this point the 6209 // Slow case: Convert to number. At this point the
Erik Corry 2010/11/05 22:04:36 This comment should be moved to the deferred code,
zhangk 2010/11/09 23:07:53 On 2010/11/05 22:04:36, Erik Corry wrote: Done.
6146 // value to be incremented is in the value register.. 6210 // value to be incremented is in the value register..
6147 slow.Bind(); 6211 deferred->BindExit();
6148 6212
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. 6213 // Store the new value in the target if not const.
6173 // At this point the answer is in the value register. 6214 // At this point the answer is in the value register.
6174 exit.Bind();
6175 frame_->EmitPush(value); 6215 frame_->EmitPush(value);
6176 // Set the target with the result, leaving the result on 6216 // Set the target with the result, leaving the result on
6177 // top of the stack. Removes the target from the stack if 6217 // top of the stack. Removes the target from the stack if
6178 // it has a non-zero size. 6218 // it has a non-zero size.
6179 if (!is_const) target.SetValue(NOT_CONST_INIT, LIKELY_SMI); 6219 if (!is_const) target.SetValue(NOT_CONST_INIT, LIKELY_SMI);
6180 } 6220 }
6181 6221
6182 // Postfix: Discard the new value and use the old. 6222 // Postfix: Discard the new value and use the old.
6183 if (is_postfix) frame_->Pop(); 6223 if (is_postfix) frame_->Pop();
6184 ASSERT_EQ(original_height + 1, frame_->height()); 6224 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_)); 7344 BinaryOpIC::GetName(runtime_operands_type_));
7305 return name_; 7345 return name_;
7306 } 7346 }
7307 7347
7308 7348
7309 #undef __ 7349 #undef __
7310 7350
7311 } } // namespace v8::internal 7351 } } // namespace v8::internal
7312 7352
7313 #endif // V8_TARGET_ARCH_ARM 7353 #endif // V8_TARGET_ARCH_ARM
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