Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |