OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/compilation-info.h" | 9 #include "src/compilation-info.h" |
10 #include "src/compiler/code-generator-impl.h" | 10 #include "src/compiler/code-generator-impl.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 Operand const operand_; | 264 Operand const operand_; |
265 Register const value_; | 265 Register const value_; |
266 Register const scratch0_; | 266 Register const scratch0_; |
267 Register const scratch1_; | 267 Register const scratch1_; |
268 RecordWriteMode const mode_; | 268 RecordWriteMode const mode_; |
269 }; | 269 }; |
270 | 270 |
271 class WasmOutOfLineTrap final : public OutOfLineCode { | 271 class WasmOutOfLineTrap final : public OutOfLineCode { |
272 public: | 272 public: |
273 WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, | 273 WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, |
274 Register context, int32_t position) | 274 int32_t position, Instruction* instr) |
275 : OutOfLineCode(gen), | 275 : OutOfLineCode(gen), |
276 gen_(gen), | 276 gen_(gen), |
277 pc_(pc), | 277 pc_(pc), |
278 frame_elided_(frame_elided), | 278 frame_elided_(frame_elided), |
279 context_(context), | 279 position_(position), |
280 position_(position) {} | 280 instr_(instr) {} |
281 | 281 |
282 // TODO(eholk): Refactor this method to take the code generator as a | 282 // TODO(eholk): Refactor this method to take the code generator as a |
283 // parameter. | 283 // parameter. |
284 void Generate() final { | 284 void Generate() final { |
285 int current_pc = __ pc_offset(); | 285 int current_pc = __ pc_offset(); |
286 | 286 |
287 gen_->AddProtectedInstruction(pc_, current_pc); | 287 gen_->AddProtectedInstruction(pc_, current_pc); |
288 | 288 |
289 if (frame_elided_) { | 289 if (frame_elided_) { |
290 __ EnterFrame(StackFrame::WASM); | 290 __ EnterFrame(StackFrame::WASM); |
291 } | 291 } |
292 | 292 |
293 wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; | 293 wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; |
294 int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); | 294 int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); |
295 __ Push(Smi::FromInt(trap_reason)); | 295 __ Push(Smi::FromInt(trap_reason)); |
296 __ Push(Smi::FromInt(position_)); | 296 __ Push(Smi::FromInt(position_)); |
297 __ Move(rsi, context_); | 297 __ Move(rsi, gen_->isolate()->native_context()); |
298 __ CallRuntime(Runtime::kThrowWasmError); | 298 __ CallRuntime(Runtime::kThrowWasmError); |
| 299 |
| 300 if (instr_->reference_map() != nullptr) { |
| 301 gen_->RecordSafepoint(instr_->reference_map(), Safepoint::kSimple, 0, |
| 302 Safepoint::kNoLazyDeopt); |
| 303 } |
299 } | 304 } |
300 | 305 |
301 private: | 306 private: |
302 CodeGenerator* gen_; | 307 CodeGenerator* gen_; |
303 int pc_; | 308 int pc_; |
304 bool frame_elided_; | 309 bool frame_elided_; |
305 Register context_; | |
306 int32_t position_; | 310 int32_t position_; |
| 311 Instruction* instr_; |
307 }; | 312 }; |
308 | 313 |
309 void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, | 314 void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, |
310 InstructionCode opcode, X64OperandConverter& i, | 315 InstructionCode opcode, size_t input_count, |
311 int pc) { | 316 X64OperandConverter& i, int pc, Instruction* instr) { |
312 X64MemoryProtection protection = | 317 const X64MemoryProtection protection = |
313 static_cast<X64MemoryProtection>(MiscField::decode(opcode)); | 318 static_cast<X64MemoryProtection>(MiscField::decode(opcode)); |
314 if (protection == X64MemoryProtection::kProtected) { | 319 if (protection == X64MemoryProtection::kProtected) { |
315 bool frame_elided = !codegen->frame_access_state()->has_frame(); | 320 const bool frame_elided = !codegen->frame_access_state()->has_frame(); |
316 new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, i.InputRegister(2), | 321 const int32_t position = i.InputInt32(input_count - 1); |
317 i.InputInt32(3)); | 322 new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position, instr); |
318 } | 323 } |
319 } | 324 } |
320 } // namespace | 325 } // namespace |
321 | 326 |
322 | 327 |
323 #define ASSEMBLE_UNOP(asm_instr) \ | 328 #define ASSEMBLE_UNOP(asm_instr) \ |
324 do { \ | 329 do { \ |
325 if (instr->Output()->IsRegister()) { \ | 330 if (instr->Output()->IsRegister()) { \ |
326 __ asm_instr(i.OutputRegister()); \ | 331 __ asm_instr(i.OutputRegister()); \ |
327 } else { \ | 332 } else { \ |
(...skipping 1518 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1846 __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, | 1851 __ vxorpd(i.OutputDoubleRegister(), kScratchDoubleReg, |
1847 i.InputOperand(0)); | 1852 i.InputOperand(0)); |
1848 } | 1853 } |
1849 break; | 1854 break; |
1850 } | 1855 } |
1851 case kSSEFloat64SilenceNaN: | 1856 case kSSEFloat64SilenceNaN: |
1852 __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); | 1857 __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); |
1853 __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); | 1858 __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); |
1854 break; | 1859 break; |
1855 case kX64Movsxbl: | 1860 case kX64Movsxbl: |
| 1861 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1862 __ pc_offset(), instr); |
1856 ASSEMBLE_MOVX(movsxbl); | 1863 ASSEMBLE_MOVX(movsxbl); |
1857 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1858 __ AssertZeroExtended(i.OutputRegister()); | 1864 __ AssertZeroExtended(i.OutputRegister()); |
1859 break; | 1865 break; |
1860 case kX64Movzxbl: | 1866 case kX64Movzxbl: |
| 1867 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1868 __ pc_offset(), instr); |
1861 ASSEMBLE_MOVX(movzxbl); | 1869 ASSEMBLE_MOVX(movzxbl); |
1862 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1863 __ AssertZeroExtended(i.OutputRegister()); | 1870 __ AssertZeroExtended(i.OutputRegister()); |
1864 break; | 1871 break; |
1865 case kX64Movsxbq: | 1872 case kX64Movsxbq: |
| 1873 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1874 __ pc_offset(), instr); |
1866 ASSEMBLE_MOVX(movsxbq); | 1875 ASSEMBLE_MOVX(movsxbq); |
1867 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1868 break; | 1876 break; |
1869 case kX64Movzxbq: | 1877 case kX64Movzxbq: |
| 1878 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1879 __ pc_offset(), instr); |
1870 ASSEMBLE_MOVX(movzxbq); | 1880 ASSEMBLE_MOVX(movzxbq); |
1871 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1872 __ AssertZeroExtended(i.OutputRegister()); | 1881 __ AssertZeroExtended(i.OutputRegister()); |
1873 break; | 1882 break; |
1874 case kX64Movb: { | 1883 case kX64Movb: { |
| 1884 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1885 __ pc_offset(), instr); |
1875 size_t index = 0; | 1886 size_t index = 0; |
1876 Operand operand = i.MemoryOperand(&index); | 1887 Operand operand = i.MemoryOperand(&index); |
1877 if (HasImmediateInput(instr, index)) { | 1888 if (HasImmediateInput(instr, index)) { |
1878 __ movb(operand, Immediate(i.InputInt8(index))); | 1889 __ movb(operand, Immediate(i.InputInt8(index))); |
1879 } else { | 1890 } else { |
1880 __ movb(operand, i.InputRegister(index)); | 1891 __ movb(operand, i.InputRegister(index)); |
1881 } | 1892 } |
1882 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1883 break; | 1893 break; |
1884 } | 1894 } |
1885 case kX64Movsxwl: | 1895 case kX64Movsxwl: |
| 1896 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1897 __ pc_offset(), instr); |
1886 ASSEMBLE_MOVX(movsxwl); | 1898 ASSEMBLE_MOVX(movsxwl); |
1887 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1888 __ AssertZeroExtended(i.OutputRegister()); | 1899 __ AssertZeroExtended(i.OutputRegister()); |
1889 break; | 1900 break; |
1890 case kX64Movzxwl: | 1901 case kX64Movzxwl: |
| 1902 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1903 __ pc_offset(), instr); |
1891 ASSEMBLE_MOVX(movzxwl); | 1904 ASSEMBLE_MOVX(movzxwl); |
1892 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1893 __ AssertZeroExtended(i.OutputRegister()); | 1905 __ AssertZeroExtended(i.OutputRegister()); |
1894 break; | 1906 break; |
1895 case kX64Movsxwq: | 1907 case kX64Movsxwq: |
| 1908 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1909 __ pc_offset(), instr); |
1896 ASSEMBLE_MOVX(movsxwq); | 1910 ASSEMBLE_MOVX(movsxwq); |
1897 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1898 break; | 1911 break; |
1899 case kX64Movzxwq: | 1912 case kX64Movzxwq: |
| 1913 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1914 __ pc_offset(), instr); |
1900 ASSEMBLE_MOVX(movzxwq); | 1915 ASSEMBLE_MOVX(movzxwq); |
1901 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1902 __ AssertZeroExtended(i.OutputRegister()); | 1916 __ AssertZeroExtended(i.OutputRegister()); |
1903 break; | 1917 break; |
1904 case kX64Movw: { | 1918 case kX64Movw: { |
| 1919 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1920 __ pc_offset(), instr); |
1905 size_t index = 0; | 1921 size_t index = 0; |
1906 Operand operand = i.MemoryOperand(&index); | 1922 Operand operand = i.MemoryOperand(&index); |
1907 if (HasImmediateInput(instr, index)) { | 1923 if (HasImmediateInput(instr, index)) { |
1908 __ movw(operand, Immediate(i.InputInt16(index))); | 1924 __ movw(operand, Immediate(i.InputInt16(index))); |
1909 } else { | 1925 } else { |
1910 __ movw(operand, i.InputRegister(index)); | 1926 __ movw(operand, i.InputRegister(index)); |
1911 } | 1927 } |
1912 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1913 break; | 1928 break; |
1914 } | 1929 } |
1915 case kX64Movl: | 1930 case kX64Movl: |
| 1931 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1932 __ pc_offset(), instr); |
1916 if (instr->HasOutput()) { | 1933 if (instr->HasOutput()) { |
1917 if (instr->addressing_mode() == kMode_None) { | 1934 if (instr->addressing_mode() == kMode_None) { |
1918 if (instr->InputAt(0)->IsRegister()) { | 1935 if (instr->InputAt(0)->IsRegister()) { |
1919 __ movl(i.OutputRegister(), i.InputRegister(0)); | 1936 __ movl(i.OutputRegister(), i.InputRegister(0)); |
1920 } else { | 1937 } else { |
1921 __ movl(i.OutputRegister(), i.InputOperand(0)); | 1938 __ movl(i.OutputRegister(), i.InputOperand(0)); |
1922 } | 1939 } |
1923 } else { | 1940 } else { |
1924 __ movl(i.OutputRegister(), i.MemoryOperand()); | 1941 __ movl(i.OutputRegister(), i.MemoryOperand()); |
1925 } | 1942 } |
1926 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1927 __ AssertZeroExtended(i.OutputRegister()); | 1943 __ AssertZeroExtended(i.OutputRegister()); |
1928 } else { | 1944 } else { |
1929 size_t index = 0; | 1945 size_t index = 0; |
1930 Operand operand = i.MemoryOperand(&index); | 1946 Operand operand = i.MemoryOperand(&index); |
1931 if (HasImmediateInput(instr, index)) { | 1947 if (HasImmediateInput(instr, index)) { |
1932 __ movl(operand, i.InputImmediate(index)); | 1948 __ movl(operand, i.InputImmediate(index)); |
1933 } else { | 1949 } else { |
1934 __ movl(operand, i.InputRegister(index)); | 1950 __ movl(operand, i.InputRegister(index)); |
1935 } | 1951 } |
1936 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1937 } | 1952 } |
1938 break; | 1953 break; |
1939 case kX64Movsxlq: | 1954 case kX64Movsxlq: |
| 1955 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1956 __ pc_offset(), instr); |
1940 ASSEMBLE_MOVX(movsxlq); | 1957 ASSEMBLE_MOVX(movsxlq); |
1941 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1942 break; | 1958 break; |
1943 case kX64Movq: | 1959 case kX64Movq: |
| 1960 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1961 __ pc_offset(), instr); |
1944 if (instr->HasOutput()) { | 1962 if (instr->HasOutput()) { |
1945 __ movq(i.OutputRegister(), i.MemoryOperand()); | 1963 __ movq(i.OutputRegister(), i.MemoryOperand()); |
1946 } else { | 1964 } else { |
1947 size_t index = 0; | 1965 size_t index = 0; |
1948 Operand operand = i.MemoryOperand(&index); | 1966 Operand operand = i.MemoryOperand(&index); |
1949 if (HasImmediateInput(instr, index)) { | 1967 if (HasImmediateInput(instr, index)) { |
1950 __ movq(operand, i.InputImmediate(index)); | 1968 __ movq(operand, i.InputImmediate(index)); |
1951 } else { | 1969 } else { |
1952 __ movq(operand, i.InputRegister(index)); | 1970 __ movq(operand, i.InputRegister(index)); |
1953 } | 1971 } |
1954 } | 1972 } |
1955 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1956 break; | 1973 break; |
1957 case kX64Movss: | 1974 case kX64Movss: |
| 1975 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1976 __ pc_offset(), instr); |
1958 if (instr->HasOutput()) { | 1977 if (instr->HasOutput()) { |
1959 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); | 1978 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); |
1960 } else { | 1979 } else { |
1961 size_t index = 0; | 1980 size_t index = 0; |
1962 Operand operand = i.MemoryOperand(&index); | 1981 Operand operand = i.MemoryOperand(&index); |
1963 __ movss(operand, i.InputDoubleRegister(index)); | 1982 __ movss(operand, i.InputDoubleRegister(index)); |
1964 } | 1983 } |
1965 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1966 break; | 1984 break; |
1967 case kX64Movsd: | 1985 case kX64Movsd: |
| 1986 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
| 1987 __ pc_offset(), instr); |
1968 if (instr->HasOutput()) { | 1988 if (instr->HasOutput()) { |
1969 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); | 1989 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); |
1970 } else { | 1990 } else { |
1971 size_t index = 0; | 1991 size_t index = 0; |
1972 Operand operand = i.MemoryOperand(&index); | 1992 Operand operand = i.MemoryOperand(&index); |
1973 __ Movsd(operand, i.InputDoubleRegister(index)); | 1993 __ Movsd(operand, i.InputDoubleRegister(index)); |
1974 } | 1994 } |
1975 EmitOOLTrapIfNeeded(zone(), this, opcode, i, __ pc_offset()); | |
1976 break; | 1995 break; |
1977 case kX64BitcastFI: | 1996 case kX64BitcastFI: |
1978 if (instr->InputAt(0)->IsFPStackSlot()) { | 1997 if (instr->InputAt(0)->IsFPStackSlot()) { |
1979 __ movl(i.OutputRegister(), i.InputOperand(0)); | 1998 __ movl(i.OutputRegister(), i.InputOperand(0)); |
1980 } else { | 1999 } else { |
1981 __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); | 2000 __ Movd(i.OutputRegister(), i.InputDoubleRegister(0)); |
1982 } | 2001 } |
1983 break; | 2002 break; |
1984 case kX64BitcastDL: | 2003 case kX64BitcastDL: |
1985 if (instr->InputAt(0)->IsFPStackSlot()) { | 2004 if (instr->InputAt(0)->IsFPStackSlot()) { |
(...skipping 853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2839 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2858 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2840 __ Nop(padding_size); | 2859 __ Nop(padding_size); |
2841 } | 2860 } |
2842 } | 2861 } |
2843 | 2862 |
2844 #undef __ | 2863 #undef __ |
2845 | 2864 |
2846 } // namespace compiler | 2865 } // namespace compiler |
2847 } // namespace internal | 2866 } // namespace internal |
2848 } // namespace v8 | 2867 } // namespace v8 |
OLD | NEW |