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

Unified Diff: runtime/vm/code_patcher_x64.cc

Issue 1192103004: VM: New calling convention for generated code. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 5 years, 6 months 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
Index: runtime/vm/code_patcher_x64.cc
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 1f3f8e18aae25f6667fa7818dbef9e6f2b4d28f1..eacc6bec6a7d764a46f21aa8bb2ca04cc5314df0 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -16,6 +16,19 @@
namespace dart {
+
+static bool MatchesPattern(uword addr, int16_t* pattern, intptr_t size) {
+ uint8_t* bytes = reinterpret_cast<uint8_t*>(addr);
+ for (intptr_t i = 0; i < size; i++) {
+ int16_t val = pattern[i];
+ if ((val >= 0) && (val != bytes[i])) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
// The expected pattern of a Dart unoptimized call (static and instance):
// 0: 49 8b 9f imm32 mov RBX, [PP + off]
// 7: 41 ff 97 imm32 call [PP + off]
srdjan 2015/06/18 21:29:47 You may need to update this comment.
Florian Schneider 2015/06/29 14:50:24 Done.
@@ -25,19 +38,21 @@ class UnoptimizedCall : public ValueObject {
UnoptimizedCall(uword return_address, const Code& code)
: start_(return_address - kCallPatternSize),
object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
- ASSERT(IsValid(return_address));
ASSERT((kCallPatternSize - 7) == Assembler::kCallExternalLabelSize);
+ ASSERT(IsValid());
}
- static const int kCallPatternSize = 14;
-
- static bool IsValid(uword return_address) {
- uint8_t* code_bytes =
- reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
- return (code_bytes[0] == 0x49) && (code_bytes[1] == 0x8B) &&
- (code_bytes[2] == 0x9F) &&
- (code_bytes[7] == 0x41) && (code_bytes[8] == 0xFF) &&
- (code_bytes[9] == 0x97);
+ static const int kCallPatternSize = 26;
+
+ bool IsValid() const {
+ static int16_t pattern[kCallPatternSize] = {
+ 0x49, 0x8b, 0x9f, -1, -1, -1, -1, // movq RBX, [PP + offs]
+ 0x4d, 0x8b, 0xa7, -1, -1, -1, -1, // movq CR, [PP + offs]
+ 0x4d, 0x8b, 0x5c, 0x24, 0x07, // movq TMP, [CR + insns_offs]
+ 0x49, 0x83, 0xc3, 0x1f, // addq TMP, entry_offs
+ 0x41, 0xff, 0xd3 // callq TMP
+ };
+ return MatchesPattern(start_, pattern, kCallPatternSize);
}
RawObject* ic_data() const {
@@ -45,14 +60,16 @@ class UnoptimizedCall : public ValueObject {
return object_pool_.ObjectAt(index);
}
- uword target() const {
+ RawCode* target() const {
intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10);
- return object_pool_.RawValueAt(index);
+ Code& code = Code::Handle();
+ code ^= object_pool_.ObjectAt(index);
+ return code.raw();
}
- void set_target(uword target) const {
+ void set_target(const Code& target) const {
intptr_t index = InstructionPattern::IndexFromPPLoad(start_ + 10);
- object_pool_.SetRawValueAt(index, target);
+ object_pool_.SetObjectAt(index, target);
// No need to flush the instruction cache, since the code is not modified.
}
@@ -97,35 +114,43 @@ class UnoptimizedStaticCall : public UnoptimizedCall {
// The expected pattern of a call where the target is loaded from
// the object pool:
-// 0: 41 ff 97 imm32 call [PP + off]
-// 7: <- return address
+// 0: 4d 8b a7 imm32 movq CR, [PP + offs]
+// 7: 4d 8b 5c 24 07 movq TMP, [CR + insns_offs]
+// 12: 49 83 c3 1f addq TMP, entry_offs
+// 16: 41 ff d3 callq TMP
+// 19: <- return address
class PoolPointerCall : public ValueObject {
public:
explicit PoolPointerCall(uword return_address, const Code& code)
: start_(return_address - kCallPatternSize),
object_pool_(ObjectPool::Handle(code.GetObjectPool())) {
- ASSERT(IsValid(return_address));
+ ASSERT(IsValid());
}
- static const int kCallPatternSize = 7;
+ static const int kCallPatternSize = 19;
- static bool IsValid(uword return_address) {
- uint8_t* code_bytes =
- reinterpret_cast<uint8_t*>(return_address - kCallPatternSize);
- return (code_bytes[0] == 0x41) && (code_bytes[1] == 0xFF) &&
- (code_bytes[2] == 0x97);
+ bool IsValid() const {
+ static int16_t pattern[kCallPatternSize] = {
+ 0x4d, 0x8b, 0xa7, -1, -1, -1, -1, // movq CR, [PP + offs]
+ 0x4d, 0x8b, 0x5c, 0x24, 0x07, // movq TMP, [CR + insns_offs]
+ 0x49, 0x83, 0xc3, 0x1f, // addq TMP, entry_offs
+ 0x41, 0xff, 0xd3 // callq TMP
+ };
+ return MatchesPattern(start_, pattern, kCallPatternSize);
}
intptr_t pp_index() const {
return InstructionPattern::IndexFromPPLoad(start_ + 3);
}
- uword Target() const {
- return object_pool_.RawValueAt(pp_index());
+ RawCode* Target() const {
+ Code& code = Code::Handle();
+ code ^= object_pool_.ObjectAt(pp_index());
+ return code.raw();
}
- void SetTarget(uword target) const {
- object_pool_.SetRawValueAt(pp_index(), target);
+ void SetTarget(const Code& target) const {
+ object_pool_.SetObjectAt(pp_index(), target);
// No need to flush the instruction cache, since the code is not modified.
}
@@ -138,8 +163,8 @@ class PoolPointerCall : public ValueObject {
};
-uword CodePatcher::GetStaticCallTargetAt(uword return_address,
- const Code& code) {
+RawCode* CodePatcher::GetStaticCallTargetAt(uword return_address,
+ const Code& code) {
ASSERT(code.ContainsInstructionAt(return_address));
PoolPointerCall call(return_address, code);
return call.Target();
@@ -148,14 +173,14 @@ uword CodePatcher::GetStaticCallTargetAt(uword return_address,
void CodePatcher::PatchStaticCallAt(uword return_address,
const Code& code,
- uword new_target) {
+ const Code& new_target) {
PatchPoolPointerCallAt(return_address, code, new_target);
}
void CodePatcher::PatchPoolPointerCallAt(uword return_address,
const Code& code,
- uword new_target) {
+ const Code& new_target) {
ASSERT(code.ContainsInstructionAt(return_address));
PoolPointerCall call(return_address, code);
call.SetTarget(new_target);
@@ -164,16 +189,16 @@ void CodePatcher::PatchPoolPointerCallAt(uword return_address,
void CodePatcher::PatchInstanceCallAt(uword return_address,
const Code& code,
- uword new_target) {
+ const Code& new_target) {
ASSERT(code.ContainsInstructionAt(return_address));
InstanceCall call(return_address, code);
call.set_target(new_target);
}
-uword CodePatcher::GetInstanceCallAt(uword return_address,
- const Code& code,
- ICData* ic_data) {
+RawCode* CodePatcher::GetInstanceCallAt(uword return_address,
+ const Code& code,
+ ICData* ic_data) {
ASSERT(code.ContainsInstructionAt(return_address));
InstanceCall call(return_address, code);
if (ic_data != NULL) {

Powered by Google App Engine
This is Rietveld 408576698