Update V8 to version 4.1.0.21
This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.
Original commit message:
Version 4.1.0.21 (cherry-pick)
Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412
Unlink pages from the space page list after evacuation.
BUG=430201
LOG=N
R=jkummerow@chromium.org
Review URL: https://codereview.chromium.org/953813002
Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}
---
FPIIM-449
Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/src/ia32/disasm-ia32.cc b/src/ia32/disasm-ia32.cc
index 22c2a55..bf88f69 100644
--- a/src/ia32/disasm-ia32.cc
+++ b/src/ia32/disasm-ia32.cc
@@ -246,6 +246,9 @@
DisassemblerIA32(const NameConverter& converter,
bool abort_on_unimplemented = true)
: converter_(converter),
+ vex_byte0_(0),
+ vex_byte1_(0),
+ vex_byte2_(0),
instruction_table_(InstructionTable::get_instance()),
tmp_buffer_pos_(0),
abort_on_unimplemented_(abort_on_unimplemented) {
@@ -260,6 +263,9 @@
private:
const NameConverter& converter_;
+ byte vex_byte0_; // 0xc4 or 0xc5
+ byte vex_byte1_;
+ byte vex_byte2_; // only for 3 bytes vex prefix
InstructionTable* instruction_table_;
v8::internal::EmbeddedVector<char, 128> tmp_buffer_;
unsigned int tmp_buffer_pos_;
@@ -287,6 +293,57 @@
kSAR = 7
};
+ bool vex_128() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 4) != 1;
+ }
+
+ bool vex_66() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 3) == 1;
+ }
+
+ bool vex_f3() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 3) == 2;
+ }
+
+ bool vex_f2() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return (checked & 3) == 3;
+ }
+
+ bool vex_w() {
+ if (vex_byte0_ == 0xc5) return false;
+ return (vex_byte2_ & 0x80) != 0;
+ }
+
+ bool vex_0f() {
+ if (vex_byte0_ == 0xc5) return true;
+ return (vex_byte1_ & 3) == 1;
+ }
+
+ bool vex_0f38() {
+ if (vex_byte0_ == 0xc5) return false;
+ return (vex_byte1_ & 3) == 2;
+ }
+
+ bool vex_0f3a() {
+ if (vex_byte0_ == 0xc5) return false;
+ return (vex_byte1_ & 3) == 3;
+ }
+
+ int vex_vreg() {
+ DCHECK(vex_byte0_ == 0xc4 || vex_byte0_ == 0xc5);
+ byte checked = vex_byte0_ == 0xc4 ? vex_byte2_ : vex_byte1_;
+ return ~(checked >> 3) & 0xf;
+ }
+
+ char float_size_code() { return "sd"[vex_w()]; }
const char* NameOfCPURegister(int reg) const {
return converter_.NameOfCPURegister(reg);
@@ -340,6 +397,7 @@
int FPUInstruction(byte* data);
int MemoryFPUInstruction(int escape_opcode, int regop, byte* modrm_start);
int RegisterFPUInstruction(int escape_opcode, byte modrm_byte);
+ int AVXInstruction(byte* data);
void AppendToBuffer(const char* format, ...);
@@ -679,6 +737,111 @@
}
+int DisassemblerIA32::AVXInstruction(byte* data) {
+ byte opcode = *data;
+ byte* current = data + 1;
+ if (vex_66() && vex_0f38()) {
+ int mod, regop, rm, vvvv = vex_vreg();
+ get_modrm(*current, &mod, ®op, &rm);
+ switch (opcode) {
+ case 0x99:
+ AppendToBuffer("vfmadd132s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xa9:
+ AppendToBuffer("vfmadd213s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xb9:
+ AppendToBuffer("vfmadd231s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x9b:
+ AppendToBuffer("vfmsub132s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xab:
+ AppendToBuffer("vfmsub213s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xbb:
+ AppendToBuffer("vfmsub231s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x9d:
+ AppendToBuffer("vfnmadd132s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xad:
+ AppendToBuffer("vfnmadd213s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xbd:
+ AppendToBuffer("vfnmadd231s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x9f:
+ AppendToBuffer("vfnmsub132s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xaf:
+ AppendToBuffer("vfnmsub213s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0xbf:
+ AppendToBuffer("vfnmsub231s%c %s,%s,", float_size_code(),
+ NameOfXMMRegister(regop), NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ default:
+ UnimplementedInstruction();
+ }
+ } else if (vex_f2() && vex_0f()) {
+ int mod, regop, rm, vvvv = vex_vreg();
+ get_modrm(*current, &mod, ®op, &rm);
+ switch (opcode) {
+ case 0x58:
+ AppendToBuffer("vaddsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x59:
+ AppendToBuffer("vmulsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x5c:
+ AppendToBuffer("vsubsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ case 0x5e:
+ AppendToBuffer("vdivsd %s,%s,", NameOfXMMRegister(regop),
+ NameOfXMMRegister(vvvv));
+ current += PrintRightXMMOperand(current);
+ break;
+ default:
+ UnimplementedInstruction();
+ }
+ } else {
+ UnimplementedInstruction();
+ }
+
+ return static_cast<int>(current - data);
+}
+
+
// Returns number of bytes used, including *data.
int DisassemblerIA32::FPUInstruction(byte* data) {
byte escape_opcode = *data;
@@ -903,65 +1066,81 @@
} else if (*data == 0x2E /*cs*/) {
branch_hint = "predicted not taken";
data++;
+ } else if (*data == 0xC4 && *(data + 1) >= 0xc0) {
+ vex_byte0_ = *data;
+ vex_byte1_ = *(data + 1);
+ vex_byte2_ = *(data + 2);
+ data += 3;
+ } else if (*data == 0xC5 && *(data + 1) >= 0xc0) {
+ vex_byte0_ = *data;
+ vex_byte1_ = *(data + 1);
+ data += 2;
}
+
bool processed = true; // Will be set to false if the current instruction
// is not in 'instructions' table.
- const InstructionDesc& idesc = instruction_table_->Get(*data);
- switch (idesc.type) {
- case ZERO_OPERANDS_INSTR:
- AppendToBuffer(idesc.mnem);
- data++;
- break;
+ // Decode AVX instructions.
+ if (vex_byte0_ != 0) {
+ data += AVXInstruction(data);
+ } else {
+ const InstructionDesc& idesc = instruction_table_->Get(*data);
+ switch (idesc.type) {
+ case ZERO_OPERANDS_INSTR:
+ AppendToBuffer(idesc.mnem);
+ data++;
+ break;
- case TWO_OPERANDS_INSTR:
- data++;
- data += PrintOperands(idesc.mnem, idesc.op_order_, data);
- break;
+ case TWO_OPERANDS_INSTR:
+ data++;
+ data += PrintOperands(idesc.mnem, idesc.op_order_, data);
+ break;
- case JUMP_CONDITIONAL_SHORT_INSTR:
- data += JumpConditionalShort(data, branch_hint);
- break;
+ case JUMP_CONDITIONAL_SHORT_INSTR:
+ data += JumpConditionalShort(data, branch_hint);
+ break;
- case REGISTER_INSTR:
- AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
- data++;
- break;
+ case REGISTER_INSTR:
+ AppendToBuffer("%s %s", idesc.mnem, NameOfCPURegister(*data & 0x07));
+ data++;
+ break;
- case MOVE_REG_INSTR: {
- byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
- AppendToBuffer("mov %s,%s",
- NameOfCPURegister(*data & 0x07),
- NameOfAddress(addr));
- data += 5;
- break;
+ case MOVE_REG_INSTR: {
+ byte* addr =
+ reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+ AppendToBuffer("mov %s,%s", NameOfCPURegister(*data & 0x07),
+ NameOfAddress(addr));
+ data += 5;
+ break;
+ }
+
+ case CALL_JUMP_INSTR: {
+ byte* addr = data + *reinterpret_cast<int32_t*>(data + 1) + 5;
+ AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
+ data += 5;
+ break;
+ }
+
+ case SHORT_IMMEDIATE_INSTR: {
+ byte* addr =
+ reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data + 1));
+ AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
+ data += 5;
+ break;
+ }
+
+ case BYTE_IMMEDIATE_INSTR: {
+ AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
+ data += 2;
+ break;
+ }
+
+ case NO_INSTR:
+ processed = false;
+ break;
+
+ default:
+ UNIMPLEMENTED(); // This type is not implemented.
}
-
- case CALL_JUMP_INSTR: {
- byte* addr = data + *reinterpret_cast<int32_t*>(data+1) + 5;
- AppendToBuffer("%s %s", idesc.mnem, NameOfAddress(addr));
- data += 5;
- break;
- }
-
- case SHORT_IMMEDIATE_INSTR: {
- byte* addr = reinterpret_cast<byte*>(*reinterpret_cast<int32_t*>(data+1));
- AppendToBuffer("%s eax,%s", idesc.mnem, NameOfAddress(addr));
- data += 5;
- break;
- }
-
- case BYTE_IMMEDIATE_INSTR: {
- AppendToBuffer("%s al,0x%x", idesc.mnem, data[1]);
- data += 2;
- break;
- }
-
- case NO_INSTR:
- processed = false;
- break;
-
- default:
- UNIMPLEMENTED(); // This type is not implemented.
}
//----------------------------
if (!processed) {
@@ -1047,6 +1226,12 @@
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
+ } else if (f0byte == 0x2e) {
+ data += 2;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("ucomiss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
} else if (f0byte >= 0x53 && f0byte <= 0x5F) {
const char* const pseudo_op[] = {
"rcpps",
@@ -1386,6 +1571,15 @@
NameOfXMMRegister(regop),
NameOfXMMRegister(rm));
data++;
+ } else if (*data == 0x72) {
+ data++;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ int8_t imm8 = static_cast<int8_t>(data[1]);
+ DCHECK(regop == esi || regop == edx);
+ AppendToBuffer("%s %s,%d", (regop == esi) ? "pslld" : "psrld",
+ NameOfXMMRegister(rm), static_cast<int>(imm8));
+ data += 2;
} else if (*data == 0x73) {
data++;
int mod, regop, rm;
@@ -1608,12 +1802,36 @@
get_modrm(*data, &mod, ®op, &rm);
AppendToBuffer("cvttss2si %s,", NameOfCPURegister(regop));
data += PrintRightXMMOperand(data);
+ } else if (b2 == 0x58) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("addss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
+ } else if (b2 == 0x59) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("mulss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
} else if (b2 == 0x5A) {
data += 3;
int mod, regop, rm;
get_modrm(*data, &mod, ®op, &rm);
AppendToBuffer("cvtss2sd %s,", NameOfXMMRegister(regop));
data += PrintRightXMMOperand(data);
+ } else if (b2 == 0x5c) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("subss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
+ } else if (b2 == 0x5e) {
+ data += 3;
+ int mod, regop, rm;
+ get_modrm(*data, &mod, ®op, &rm);
+ AppendToBuffer("divss %s,", NameOfXMMRegister(regop));
+ data += PrintRightXMMOperand(data);
} else if (b2 == 0x6F) {
data += 3;
int mod, regop, rm;
@@ -1681,17 +1899,17 @@
//------------------------------------------------------------------------------
-static const char* cpu_regs[8] = {
+static const char* const cpu_regs[8] = {
"eax", "ecx", "edx", "ebx", "esp", "ebp", "esi", "edi"
};
-static const char* byte_cpu_regs[8] = {
+static const char* const byte_cpu_regs[8] = {
"al", "cl", "dl", "bl", "ah", "ch", "dh", "bh"
};
-static const char* xmm_regs[8] = {
+static const char* const xmm_regs[8] = {
"xmm0", "xmm1", "xmm2", "xmm3", "xmm4", "xmm5", "xmm6", "xmm7"
};