Reviewers: Søren Gjesse,

Description:
x64: Enable inline smi code patching to reenable the inlined code in
the code generated by the full code generator after my previous
change.

The generated code is the same as on ia32 and so is the patching.

Please review this at http://codereview.chromium.org/6456023/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge/out

Affected files:
  M include/v8.h
  M src/x64/assembler-x64.h
  M src/x64/full-codegen-x64.cc
  M src/x64/ic-x64.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index 44ff2c00e05afa2ad84f44be645e4651506fdd94..83a5744278afe03f7a7869379f17217e74a80ea4 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -462,7 +462,6 @@ class V8EXPORT HandleScope {

   void Leave();

-
   internal::Object** prev_next_;
   internal::Object** prev_limit_;

Index: src/x64/assembler-x64.h
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index 9606e74a6ebf3637ede5ff766968eb7274e88c2b..91e7e6cc61dc74a7d3354559407a3dc339cf6241 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -567,6 +567,15 @@ class Assembler : public Malloced {
   static const byte kTestEaxByte = 0xA9;
   // One byte opcode for test al, 0xXX.
   static const byte kTestAlByte = 0xA8;
+  // One byte opcode for nop.
+  static const byte kNopByte = 0x90;
+
+  // One byte prefix for a short conditional jump.
+  static const byte kJccShortPrefix = 0x70;
+  static const byte kJncShortOpcode = kJccShortPrefix | not_carry;
+  static const byte kJcShortOpcode = kJccShortPrefix | carry;
+
+

// ---------------------------------------------------------------------------
   // Code generation
Index: src/x64/full-codegen-x64.cc
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index d44fabbe3b7321c74f80384ad91789b3c597ba20..2bec6e6cef9717e951cea1bfeac528d9d76ca8d6 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1638,9 +1638,9 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,

 void FullCodeGenerator::EmitBinaryOp(Token::Value op,
                                      OverwriteMode mode) {
-  TypeRecordingBinaryOpStub stub(op, mode);
   __ pop(rdx);
-  __ CallStub(&stub);
+  TypeRecordingBinaryOpStub stub(op, mode);
+  EmitCallIC(stub.GetCode(), NULL);  // NULL signals no inlined smi code.
   context()->Plug(rax);
 }

Index: src/x64/ic-x64.cc
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 25f557baff0c19ba21b70dc6fec389d690605f72..921c86835b133c3c4593bec1dc7b0451fc19ef49 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -1707,11 +1707,43 @@ void CompareIC::UpdateCaches(Handle<Object> x, Handle<Object> y) {
            Token::Name(op_));
   }
 #endif
+
+  // Activate inlined smi code.
+  if (previous_state == UNINITIALIZED) {
+    PatchInlinedSmiCode(address());
+  }
 }

 void PatchInlinedSmiCode(Address address) {
-  // Disabled, then patched inline smi code is not implemented on X64.
-  // So we do nothing in this case.
+  // The address of the instruction following the call.
+  Address test_instruction_address =
+      address + Assembler::kCallTargetAddressOffset;
+
+  // If the instruction following the call is not a test al, nothing
+  // was inlined.
+  if (*test_instruction_address != Assembler::kTestAlByte) {
+    ASSERT(*test_instruction_address == Assembler::kNopByte);
+    return;
+  }
+
+  Address delta_address = test_instruction_address + 1;
+  // The delta to the start of the map check instruction and the
+  // condition code uses at the patched jump.
+  int8_t delta = *reinterpret_cast<int8_t*>(delta_address);
+  if (FLAG_trace_ic) {
+    PrintF("[  patching ic at %p, test=%p, delta=%d\n",
+           address, test_instruction_address, delta);
+  }
+
+  // Patch with a short conditional jump. There must be a
+  // short jump-if-carry/not-carry at this position.
+  Address jmp_address = test_instruction_address - delta;
+  ASSERT(*jmp_address == Assembler::kJncShortOpcode ||
+         *jmp_address == Assembler::kJcShortOpcode);
+  Condition cc = *jmp_address == Assembler::kJncShortOpcode
+      ? not_zero
+      : zero;
+  *jmp_address = static_cast<byte>(Assembler::kJccShortPrefix | cc);
 }




--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to