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 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
263 Operand const operand_; | 263 Operand const operand_; |
264 Register const value_; | 264 Register const value_; |
265 Register const scratch0_; | 265 Register const scratch0_; |
266 Register const scratch1_; | 266 Register const scratch1_; |
267 RecordWriteMode const mode_; | 267 RecordWriteMode const mode_; |
268 }; | 268 }; |
269 | 269 |
270 class WasmOutOfLineTrap final : public OutOfLineCode { | 270 class WasmOutOfLineTrap final : public OutOfLineCode { |
271 public: | 271 public: |
272 WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, | 272 WasmOutOfLineTrap(CodeGenerator* gen, int pc, bool frame_elided, |
273 int32_t position) | 273 int32_t position, Instruction* instr) |
274 : OutOfLineCode(gen), | 274 : OutOfLineCode(gen), |
275 gen_(gen), | 275 gen_(gen), |
276 pc_(pc), | 276 pc_(pc), |
277 frame_elided_(frame_elided), | 277 frame_elided_(frame_elided), |
278 position_(position) {} | 278 position_(position), |
| 279 instr_(instr) {} |
279 | 280 |
280 // TODO(eholk): Refactor this method to take the code generator as a | 281 // TODO(eholk): Refactor this method to take the code generator as a |
281 // parameter. | 282 // parameter. |
282 void Generate() final { | 283 void Generate() final { |
283 __ RecordProtectedInstructionLanding(pc_); | 284 __ RecordProtectedInstructionLanding(pc_); |
284 | 285 |
285 if (frame_elided_) { | 286 if (frame_elided_) { |
286 __ EnterFrame(StackFrame::WASM_COMPILED); | 287 __ EnterFrame(StackFrame::WASM_COMPILED); |
287 } | 288 } |
288 | 289 |
289 wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; | 290 wasm::TrapReason trap_id = wasm::kTrapMemOutOfBounds; |
290 int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); | 291 int trap_reason = wasm::WasmOpcodes::TrapReasonToMessageId(trap_id); |
291 __ Push(Smi::FromInt(trap_reason)); | 292 __ Push(Smi::FromInt(trap_reason)); |
292 // TODO(eholk): use AssembleSourcePosition instead of passing in position_ | |
293 // as a parameter. See AssembleArchTrap as an example. Consider sharing code | |
294 // with AssembleArchTrap. | |
295 __ Push(Smi::FromInt(position_)); | 293 __ Push(Smi::FromInt(position_)); |
296 __ Move(rsi, Smi::kZero); | 294 __ Move(rsi, gen_->isolate()->native_context()); |
297 __ CallRuntime(Runtime::kThrowWasmError); | 295 __ CallRuntime(Runtime::kThrowWasmError); |
298 | 296 |
299 ReferenceMap* reference_map = | 297 if (instr_->reference_map() != nullptr) { |
300 new (gen_->code()->zone()) ReferenceMap(gen_->code()->zone()); | 298 gen_->RecordSafepoint(instr_->reference_map(), Safepoint::kSimple, 0, |
301 gen_->RecordSafepoint(reference_map, Safepoint::kSimple, 0, | 299 Safepoint::kNoLazyDeopt); |
302 Safepoint::kNoLazyDeopt); | 300 } |
303 } | 301 } |
304 | 302 |
305 private: | 303 private: |
306 CodeGenerator* gen_; | 304 CodeGenerator* gen_; |
307 int pc_; | 305 int pc_; |
308 bool frame_elided_; | 306 bool frame_elided_; |
309 int32_t position_; | 307 int32_t position_; |
| 308 Instruction* instr_; |
310 }; | 309 }; |
311 | 310 |
312 void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, | 311 void EmitOOLTrapIfNeeded(Zone* zone, CodeGenerator* codegen, |
313 InstructionCode opcode, size_t input_count, | 312 InstructionCode opcode, size_t input_count, |
314 X64OperandConverter& i, int pc) { | 313 X64OperandConverter& i, int pc, Instruction* instr) { |
315 const X64MemoryProtection protection = | 314 const X64MemoryProtection protection = |
316 static_cast<X64MemoryProtection>(MiscField::decode(opcode)); | 315 static_cast<X64MemoryProtection>(MiscField::decode(opcode)); |
317 if (protection == X64MemoryProtection::kProtected) { | 316 if (protection == X64MemoryProtection::kProtected) { |
318 const bool frame_elided = !codegen->frame_access_state()->has_frame(); | 317 const bool frame_elided = !codegen->frame_access_state()->has_frame(); |
319 const int32_t position = i.InputInt32(input_count - 1); | 318 const int32_t position = i.InputInt32(input_count - 1); |
320 new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position); | 319 new (zone) WasmOutOfLineTrap(codegen, pc, frame_elided, position, instr); |
321 } | 320 } |
322 } | 321 } |
323 } // namespace | 322 } // namespace |
324 | 323 |
325 | 324 |
326 #define ASSEMBLE_UNOP(asm_instr) \ | 325 #define ASSEMBLE_UNOP(asm_instr) \ |
327 do { \ | 326 do { \ |
328 if (instr->Output()->IsRegister()) { \ | 327 if (instr->Output()->IsRegister()) { \ |
329 __ asm_instr(i.OutputRegister()); \ | 328 __ asm_instr(i.OutputRegister()); \ |
330 } else { \ | 329 } else { \ |
(...skipping 1517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1848 i.InputOperand(0)); | 1847 i.InputOperand(0)); |
1849 } | 1848 } |
1850 break; | 1849 break; |
1851 } | 1850 } |
1852 case kSSEFloat64SilenceNaN: | 1851 case kSSEFloat64SilenceNaN: |
1853 __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); | 1852 __ Xorpd(kScratchDoubleReg, kScratchDoubleReg); |
1854 __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); | 1853 __ Subsd(i.InputDoubleRegister(0), kScratchDoubleReg); |
1855 break; | 1854 break; |
1856 case kX64Movsxbl: | 1855 case kX64Movsxbl: |
1857 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1856 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1858 __ pc_offset()); | 1857 __ pc_offset(), instr); |
1859 ASSEMBLE_MOVX(movsxbl); | 1858 ASSEMBLE_MOVX(movsxbl); |
1860 __ AssertZeroExtended(i.OutputRegister()); | 1859 __ AssertZeroExtended(i.OutputRegister()); |
1861 break; | 1860 break; |
1862 case kX64Movzxbl: | 1861 case kX64Movzxbl: |
1863 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1862 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1864 __ pc_offset()); | 1863 __ pc_offset(), instr); |
1865 ASSEMBLE_MOVX(movzxbl); | 1864 ASSEMBLE_MOVX(movzxbl); |
1866 __ AssertZeroExtended(i.OutputRegister()); | 1865 __ AssertZeroExtended(i.OutputRegister()); |
1867 break; | 1866 break; |
1868 case kX64Movsxbq: | 1867 case kX64Movsxbq: |
1869 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1868 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1870 __ pc_offset()); | 1869 __ pc_offset(), instr); |
1871 ASSEMBLE_MOVX(movsxbq); | 1870 ASSEMBLE_MOVX(movsxbq); |
1872 break; | 1871 break; |
1873 case kX64Movzxbq: | 1872 case kX64Movzxbq: |
1874 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1873 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1875 __ pc_offset()); | 1874 __ pc_offset(), instr); |
1876 ASSEMBLE_MOVX(movzxbq); | 1875 ASSEMBLE_MOVX(movzxbq); |
1877 __ AssertZeroExtended(i.OutputRegister()); | 1876 __ AssertZeroExtended(i.OutputRegister()); |
1878 break; | 1877 break; |
1879 case kX64Movb: { | 1878 case kX64Movb: { |
1880 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1879 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1881 __ pc_offset()); | 1880 __ pc_offset(), instr); |
1882 size_t index = 0; | 1881 size_t index = 0; |
1883 Operand operand = i.MemoryOperand(&index); | 1882 Operand operand = i.MemoryOperand(&index); |
1884 if (HasImmediateInput(instr, index)) { | 1883 if (HasImmediateInput(instr, index)) { |
1885 __ movb(operand, Immediate(i.InputInt8(index))); | 1884 __ movb(operand, Immediate(i.InputInt8(index))); |
1886 } else { | 1885 } else { |
1887 __ movb(operand, i.InputRegister(index)); | 1886 __ movb(operand, i.InputRegister(index)); |
1888 } | 1887 } |
1889 break; | 1888 break; |
1890 } | 1889 } |
1891 case kX64Movsxwl: | 1890 case kX64Movsxwl: |
1892 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1891 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1893 __ pc_offset()); | 1892 __ pc_offset(), instr); |
1894 ASSEMBLE_MOVX(movsxwl); | 1893 ASSEMBLE_MOVX(movsxwl); |
1895 __ AssertZeroExtended(i.OutputRegister()); | 1894 __ AssertZeroExtended(i.OutputRegister()); |
1896 break; | 1895 break; |
1897 case kX64Movzxwl: | 1896 case kX64Movzxwl: |
1898 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1897 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1899 __ pc_offset()); | 1898 __ pc_offset(), instr); |
1900 ASSEMBLE_MOVX(movzxwl); | 1899 ASSEMBLE_MOVX(movzxwl); |
1901 __ AssertZeroExtended(i.OutputRegister()); | 1900 __ AssertZeroExtended(i.OutputRegister()); |
1902 break; | 1901 break; |
1903 case kX64Movsxwq: | 1902 case kX64Movsxwq: |
1904 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1903 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1905 __ pc_offset()); | 1904 __ pc_offset(), instr); |
1906 ASSEMBLE_MOVX(movsxwq); | 1905 ASSEMBLE_MOVX(movsxwq); |
1907 break; | 1906 break; |
1908 case kX64Movzxwq: | 1907 case kX64Movzxwq: |
1909 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1908 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1910 __ pc_offset()); | 1909 __ pc_offset(), instr); |
1911 ASSEMBLE_MOVX(movzxwq); | 1910 ASSEMBLE_MOVX(movzxwq); |
1912 __ AssertZeroExtended(i.OutputRegister()); | 1911 __ AssertZeroExtended(i.OutputRegister()); |
1913 break; | 1912 break; |
1914 case kX64Movw: { | 1913 case kX64Movw: { |
1915 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1914 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1916 __ pc_offset()); | 1915 __ pc_offset(), instr); |
1917 size_t index = 0; | 1916 size_t index = 0; |
1918 Operand operand = i.MemoryOperand(&index); | 1917 Operand operand = i.MemoryOperand(&index); |
1919 if (HasImmediateInput(instr, index)) { | 1918 if (HasImmediateInput(instr, index)) { |
1920 __ movw(operand, Immediate(i.InputInt16(index))); | 1919 __ movw(operand, Immediate(i.InputInt16(index))); |
1921 } else { | 1920 } else { |
1922 __ movw(operand, i.InputRegister(index)); | 1921 __ movw(operand, i.InputRegister(index)); |
1923 } | 1922 } |
1924 break; | 1923 break; |
1925 } | 1924 } |
1926 case kX64Movl: | 1925 case kX64Movl: |
1927 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1926 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1928 __ pc_offset()); | 1927 __ pc_offset(), instr); |
1929 if (instr->HasOutput()) { | 1928 if (instr->HasOutput()) { |
1930 if (instr->addressing_mode() == kMode_None) { | 1929 if (instr->addressing_mode() == kMode_None) { |
1931 if (instr->InputAt(0)->IsRegister()) { | 1930 if (instr->InputAt(0)->IsRegister()) { |
1932 __ movl(i.OutputRegister(), i.InputRegister(0)); | 1931 __ movl(i.OutputRegister(), i.InputRegister(0)); |
1933 } else { | 1932 } else { |
1934 __ movl(i.OutputRegister(), i.InputOperand(0)); | 1933 __ movl(i.OutputRegister(), i.InputOperand(0)); |
1935 } | 1934 } |
1936 } else { | 1935 } else { |
1937 __ movl(i.OutputRegister(), i.MemoryOperand()); | 1936 __ movl(i.OutputRegister(), i.MemoryOperand()); |
1938 } | 1937 } |
1939 __ AssertZeroExtended(i.OutputRegister()); | 1938 __ AssertZeroExtended(i.OutputRegister()); |
1940 } else { | 1939 } else { |
1941 size_t index = 0; | 1940 size_t index = 0; |
1942 Operand operand = i.MemoryOperand(&index); | 1941 Operand operand = i.MemoryOperand(&index); |
1943 if (HasImmediateInput(instr, index)) { | 1942 if (HasImmediateInput(instr, index)) { |
1944 __ movl(operand, i.InputImmediate(index)); | 1943 __ movl(operand, i.InputImmediate(index)); |
1945 } else { | 1944 } else { |
1946 __ movl(operand, i.InputRegister(index)); | 1945 __ movl(operand, i.InputRegister(index)); |
1947 } | 1946 } |
1948 } | 1947 } |
1949 break; | 1948 break; |
1950 case kX64Movsxlq: | 1949 case kX64Movsxlq: |
1951 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1950 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1952 __ pc_offset()); | 1951 __ pc_offset(), instr); |
1953 ASSEMBLE_MOVX(movsxlq); | 1952 ASSEMBLE_MOVX(movsxlq); |
1954 break; | 1953 break; |
1955 case kX64Movq: | 1954 case kX64Movq: |
1956 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1955 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1957 __ pc_offset()); | 1956 __ pc_offset(), instr); |
1958 if (instr->HasOutput()) { | 1957 if (instr->HasOutput()) { |
1959 __ movq(i.OutputRegister(), i.MemoryOperand()); | 1958 __ movq(i.OutputRegister(), i.MemoryOperand()); |
1960 } else { | 1959 } else { |
1961 size_t index = 0; | 1960 size_t index = 0; |
1962 Operand operand = i.MemoryOperand(&index); | 1961 Operand operand = i.MemoryOperand(&index); |
1963 if (HasImmediateInput(instr, index)) { | 1962 if (HasImmediateInput(instr, index)) { |
1964 __ movq(operand, i.InputImmediate(index)); | 1963 __ movq(operand, i.InputImmediate(index)); |
1965 } else { | 1964 } else { |
1966 __ movq(operand, i.InputRegister(index)); | 1965 __ movq(operand, i.InputRegister(index)); |
1967 } | 1966 } |
1968 } | 1967 } |
1969 break; | 1968 break; |
1970 case kX64Movss: | 1969 case kX64Movss: |
1971 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1970 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1972 __ pc_offset()); | 1971 __ pc_offset(), instr); |
1973 if (instr->HasOutput()) { | 1972 if (instr->HasOutput()) { |
1974 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); | 1973 __ movss(i.OutputDoubleRegister(), i.MemoryOperand()); |
1975 } else { | 1974 } else { |
1976 size_t index = 0; | 1975 size_t index = 0; |
1977 Operand operand = i.MemoryOperand(&index); | 1976 Operand operand = i.MemoryOperand(&index); |
1978 __ movss(operand, i.InputDoubleRegister(index)); | 1977 __ movss(operand, i.InputDoubleRegister(index)); |
1979 } | 1978 } |
1980 break; | 1979 break; |
1981 case kX64Movsd: | 1980 case kX64Movsd: |
1982 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, | 1981 EmitOOLTrapIfNeeded(zone(), this, opcode, instr->InputCount(), i, |
1983 __ pc_offset()); | 1982 __ pc_offset(), instr); |
1984 if (instr->HasOutput()) { | 1983 if (instr->HasOutput()) { |
1985 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); | 1984 __ Movsd(i.OutputDoubleRegister(), i.MemoryOperand()); |
1986 } else { | 1985 } else { |
1987 size_t index = 0; | 1986 size_t index = 0; |
1988 Operand operand = i.MemoryOperand(&index); | 1987 Operand operand = i.MemoryOperand(&index); |
1989 __ Movsd(operand, i.InputDoubleRegister(index)); | 1988 __ Movsd(operand, i.InputDoubleRegister(index)); |
1990 } | 1989 } |
1991 break; | 1990 break; |
1992 case kX64BitcastFI: | 1991 case kX64BitcastFI: |
1993 if (instr->InputAt(0)->IsFPStackSlot()) { | 1992 if (instr->InputAt(0)->IsFPStackSlot()) { |
(...skipping 874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2868 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2867 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2869 __ Nop(padding_size); | 2868 __ Nop(padding_size); |
2870 } | 2869 } |
2871 } | 2870 } |
2872 | 2871 |
2873 #undef __ | 2872 #undef __ |
2874 | 2873 |
2875 } // namespace compiler | 2874 } // namespace compiler |
2876 } // namespace internal | 2875 } // namespace internal |
2877 } // namespace v8 | 2876 } // namespace v8 |
OLD | NEW |