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