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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/arm/codegen-arm.cc
===================================================================
--- src/arm/codegen-arm.cc (revision 5606)
+++ src/arm/codegen-arm.cc (working copy)
@@ -6048,6 +6048,69 @@
}
+class DeferredCountOperation: public DeferredCode {
+ public:
+ DeferredCountOperation(Register value,
+ bool is_increment,
+ bool is_postfix,
+ int target_size)
+ : value_(value),
+ is_increment_(is_increment),
+ is_postfix_(is_postfix),
+ target_size_(target_size) {}
+
+ virtual void Generate() {
+ VirtualFrame copied_frame(*frame_state()->frame());
+
+ Label slow;
+ // Check for smi operand.
+ __ tst(value_, Operand(kSmiTagMask));
+ __ b(ne, &slow);
+
+ // Revert optimistic increment/decrement.
+ if (is_increment_) {
+ __ sub(value_, value_, Operand(Smi::FromInt(1)));
+ } else {
+ __ add(value_, value_, Operand(Smi::FromInt(1)));
+ }
+
+ // Slow case: Convert to number. At this point the
+ // value to be incremented is in the value register..
+ __ bind(&slow);
+
+ // Convert the operand to a number.
+ copied_frame.EmitPush(value_);
+
+ copied_frame.InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
+
+ if (is_postfix_) {
+ // Postfix: store to result (on the stack).
+ __ str(r0, MemOperand(sp, target_size_ * kPointerSize));
+ }
+
+ copied_frame.EmitPush(r0);
+ copied_frame.EmitPush(Operand(Smi::FromInt(1)));
+
+ if (is_increment_) {
+ copied_frame.CallRuntime(Runtime::kNumberAdd, 2);
+ } else {
+ copied_frame.CallRuntime(Runtime::kNumberSub, 2);
+ }
+
+ if (!value_.is(r0))
Erik Corry 2010/11/24 09:56:33 The 'if' is not needed. I corrected this.
+ __ Move(value_, r0);
+
+ copied_frame.MergeTo(frame_state()->frame());
+ }
+
+ private:
+ Register value_;
+ bool is_increment_;
+ bool is_postfix_;
+ int target_size_;
+};
+
+
void CodeGenerator::VisitCountOperation(CountOperation* node) {
#ifdef DEBUG
int original_height = frame_->height();
@@ -6107,9 +6170,6 @@
// the target. It also pushes the current value of the target.
target.GetValue();
- JumpTarget slow;
- JumpTarget exit;
-
Register value = frame_->PopToRegister();
// Postfix: Store the old value as the result.
@@ -6123,8 +6183,14 @@
// Check for smi operand.
__ tst(value, Operand(kSmiTagMask));
- slow.Branch(ne);
+ DeferredCode* deferred =
+ new DeferredCountOperation(value,
+ is_increment,
+ is_postfix,
+ target.size());
+ deferred->Branch(ne);
+
// Perform optimistic increment/decrement.
if (is_increment) {
__ add(value, value, Operand(Smi::FromInt(1)), SetCC);
@@ -6132,46 +6198,13 @@
__ sub(value, value, Operand(Smi::FromInt(1)), SetCC);
}
- // If the increment/decrement didn't overflow, we're done.
- exit.Branch(vc);
+ // If increment/decrement overflows, go to deferred code.
+ deferred->Branch(vs);
- // Revert optimistic increment/decrement.
- if (is_increment) {
- __ sub(value, value, Operand(Smi::FromInt(1)));
- } else {
- __ add(value, value, Operand(Smi::FromInt(1)));
- }
+ deferred->BindExit();
- // Slow case: Convert to number. At this point the
- // value to be incremented is in the value register..
- slow.Bind();
-
- // Convert the operand to a number.
- frame_->EmitPush(value);
-
- {
- VirtualFrame::SpilledScope spilled(frame_);
- frame_->InvokeBuiltin(Builtins::TO_NUMBER, CALL_JS, 1);
-
- if (is_postfix) {
- // Postfix: store to result (on the stack).
- __ str(r0, frame_->ElementAt(target.size()));
- }
-
- // Compute the new value.
- frame_->EmitPush(r0);
- frame_->EmitPush(Operand(Smi::FromInt(1)));
- if (is_increment) {
- frame_->CallRuntime(Runtime::kNumberAdd, 2);
- } else {
- frame_->CallRuntime(Runtime::kNumberSub, 2);
- }
- }
-
- __ Move(value, r0);
// Store the new value in the target if not const.
// At this point the answer is in the value register.
- exit.Bind();
frame_->EmitPush(value);
// Set the target with the result, leaving the result on
// top of the stack. Removes the target from the stack if
« 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