From 5ce562cda8a3a304ef6559fdf1a0c88fe9a6e8b7 Mon Sep 17 00:00:00 2001 From: "yangguo@chromium.org" Date: Mon, 5 Mar 2012 08:17:16 +0000 Subject: [PATCH] Reland r10908 (Ensure consistent result of transcendental function0.) BUG= TEST= Review URL: https://chromiumcodereview.appspot.com/9583037 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10915 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/arm/codegen-arm.cc | 13 ++++++++++ src/arm/lithium-arm.cc | 2 +- src/codegen.h | 9 +++++++ src/heap-inl.h | 9 +++---- src/hydrogen-instructions.h | 2 ++ src/hydrogen.cc | 2 ++ src/ia32/code-stubs-ia32.cc | 17 ++++++------- src/ia32/code-stubs-ia32.h | 3 ++- src/ia32/codegen-ia32.cc | 48 +++++++++++++++++++++++++++++++++++++ src/ia32/lithium-ia32.cc | 2 +- src/mips/codegen-mips.cc | 13 ++++++++++ src/mips/lithium-mips.cc | 2 +- src/platform-nullos.cc | 24 +++++++++++++++++++ src/platform-posix.cc | 24 +++++++++++++++++++ src/platform-win32.cc | 25 +++++++++++++++++++ src/platform.h | 6 +++++ src/x64/code-stubs-x64.cc | 25 +++++++++++-------- src/x64/code-stubs-x64.h | 3 ++- src/x64/codegen-x64.cc | 46 +++++++++++++++++++++++++++++++++++ src/x64/lithium-x64.cc | 2 +- 20 files changed, 249 insertions(+), 28 deletions(-) diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc index 506f9b2d5..6e1827778 100644 --- a/src/arm/codegen-arm.cc +++ b/src/arm/codegen-arm.cc @@ -37,6 +37,19 @@ namespace internal { #define __ ACCESS_MASM(masm) +TranscendentalFunction CreateTranscendentalFunction( + TranscendentalCache::Type type) { + switch (type) { + case TranscendentalCache::SIN: return &sin; + case TranscendentalCache::COS: return &cos; + case TranscendentalCache::TAN: return &tan; + case TranscendentalCache::LOG: return &log; + default: UNIMPLEMENTED(); + } + return NULL; +} + + // ------------------------------------------------------------------------- // Platform-specific RuntimeCallHelper functions. diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index b747ab815..108a6de62 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -1170,7 +1170,7 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); - if (op == kMathLog || op == kMathSin || op == kMathCos) { + if (op == kMathLog || op == kMathSin || op == kMathCos || op == kMathTan) { LOperand* input = UseFixedDouble(instr->value(), d2); LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, NULL); return MarkAsCall(DefineFixedDouble(result, d2), instr); diff --git a/src/codegen.h b/src/codegen.h index 5360d3ef3..28a3006e1 100644 --- a/src/codegen.h +++ b/src/codegen.h @@ -84,6 +84,15 @@ enum TypeofState { INSIDE_TYPEOF, NOT_INSIDE_TYPEOF }; namespace v8 { namespace internal { +// Results of the library implementation of transcendental functions may differ +// from the one we use in our generated code. Therefore we use the same +// generated code both in runtime and compiled code. +typedef double (*TranscendentalFunction)(double x); + +TranscendentalFunction CreateTranscendentalFunction( + TranscendentalCache::Type type); + + class ElementsTransitionGenerator : public AllStatic { public: static void GenerateSmiOnlyToObject(MacroAssembler* masm); diff --git a/src/heap-inl.h b/src/heap-inl.h index 81ed448a1..706d2886b 100644 --- a/src/heap-inl.h +++ b/src/heap-inl.h @@ -32,6 +32,7 @@ #include "isolate.h" #include "list-inl.h" #include "objects.h" +#include "platform.h" #include "v8-counters.h" #include "store-buffer.h" #include "store-buffer-inl.h" @@ -658,15 +659,15 @@ double TranscendentalCache::SubCache::Calculate(double input) { case ATAN: return atan(input); case COS: - return cos(input); + return fast_cos(input); case EXP: return exp(input); case LOG: - return log(input); + return fast_log(input); case SIN: - return sin(input); + return fast_sin(input); case TAN: - return tan(input); + return fast_tan(input); default: return 0.0; // Never happens. } diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h index eb0e0fd7d..a05fc776f 100644 --- a/src/hydrogen-instructions.h +++ b/src/hydrogen-instructions.h @@ -1886,6 +1886,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { case kMathLog: case kMathSin: case kMathCos: + case kMathTan: set_representation(Representation::Double()); break; default: @@ -1916,6 +1917,7 @@ class HUnaryMathOperation: public HTemplateInstruction<2> { case kMathLog: case kMathSin: case kMathCos: + case kMathTan: return Representation::Double(); case kMathAbs: return representation(); diff --git a/src/hydrogen.cc b/src/hydrogen.cc index ccddd8869..9c8338049 100644 --- a/src/hydrogen.cc +++ b/src/hydrogen.cc @@ -5420,6 +5420,7 @@ bool HGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, bool drop_extra) { case kMathLog: case kMathSin: case kMathCos: + case kMathTan: if (expr->arguments()->length() == 1) { HValue* argument = Pop(); HValue* context = environment()->LookupContext(); @@ -5480,6 +5481,7 @@ bool HGraphBuilder::TryInlineBuiltinMethodCall(Call* expr, case kMathLog: case kMathSin: case kMathCos: + case kMathTan: if (argument_count == 2 && check_type == RECEIVER_MAP_CHECK) { AddCheckConstantFunction(expr, receiver, receiver_map, true); HValue* argument = Pop(); diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index b89cc14c6..5b6f6873c 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -2510,7 +2510,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { __ fld_d(Operand(esp, 0)); __ add(esp, Immediate(kDoubleSize)); } - GenerateOperation(masm); + GenerateOperation(masm, type_); __ mov(Operand(ecx, 0), ebx); __ mov(Operand(ecx, kIntSize), edx); __ mov(Operand(ecx, 2 * kIntSize), eax); @@ -2526,7 +2526,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { __ sub(esp, Immediate(kDoubleSize)); __ movdbl(Operand(esp, 0), xmm1); __ fld_d(Operand(esp, 0)); - GenerateOperation(masm); + GenerateOperation(masm, type_); __ fstp_d(Operand(esp, 0)); __ movdbl(xmm1, Operand(esp, 0)); __ add(esp, Immediate(kDoubleSize)); @@ -2578,14 +2578,15 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { } -void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { +void TranscendentalCacheStub::GenerateOperation( + MacroAssembler* masm, TranscendentalCache::Type type) { // Only free register is edi. // Input value is on FP stack, and also in ebx/edx. // Input value is possibly in xmm1. // Address of result (a newly allocated HeapNumber) may be in eax. - if (type_ == TranscendentalCache::SIN || - type_ == TranscendentalCache::COS || - type_ == TranscendentalCache::TAN) { + if (type == TranscendentalCache::SIN || + type == TranscendentalCache::COS || + type == TranscendentalCache::TAN) { // Both fsin and fcos require arguments in the range +/-2^63 and // return NaN for infinities and NaN. They can share all code except // the actual fsin/fcos operation. @@ -2649,7 +2650,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { // FPU Stack: input % 2*pi __ bind(&in_range); - switch (type_) { + switch (type) { case TranscendentalCache::SIN: __ fsin(); break; @@ -2667,7 +2668,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { } __ bind(&done); } else { - ASSERT(type_ == TranscendentalCache::LOG); + ASSERT(type == TranscendentalCache::LOG); __ fldln2(); __ fxch(); __ fyl2x(); diff --git a/src/ia32/code-stubs-ia32.h b/src/ia32/code-stubs-ia32.h index 4d23c3a17..803a711de 100644 --- a/src/ia32/code-stubs-ia32.h +++ b/src/ia32/code-stubs-ia32.h @@ -49,6 +49,8 @@ class TranscendentalCacheStub: public CodeStub { ArgumentType argument_type) : type_(type), argument_type_(argument_type) {} void Generate(MacroAssembler* masm); + static void GenerateOperation(MacroAssembler* masm, + TranscendentalCache::Type type); private: TranscendentalCache::Type type_; ArgumentType argument_type_; @@ -56,7 +58,6 @@ class TranscendentalCacheStub: public CodeStub { Major MajorKey() { return TranscendentalCache; } int MinorKey() { return type_ | argument_type_; } Runtime::FunctionId RuntimeFunction(); - void GenerateOperation(MacroAssembler* masm); }; diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc index 3e085a245..de6901f9c 100644 --- a/src/ia32/codegen-ia32.cc +++ b/src/ia32/codegen-ia32.cc @@ -30,6 +30,7 @@ #if defined(V8_TARGET_ARCH_IA32) #include "codegen.h" +#include "heap.h" #include "macro-assembler.h" namespace v8 { @@ -55,6 +56,53 @@ void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { #define __ masm. + +TranscendentalFunction CreateTranscendentalFunction( + TranscendentalCache::Type type) { + size_t actual_size; + // Allocate buffer in executable space. + byte* buffer = static_cast(OS::Allocate(1 * KB, + &actual_size, + true)); + if (buffer == NULL) { + // Fallback to library function if function cannot be created. + switch (type) { + case TranscendentalCache::SIN: return &sin; + case TranscendentalCache::COS: return &cos; + case TranscendentalCache::TAN: return &tan; + case TranscendentalCache::LOG: return &log; + default: UNIMPLEMENTED(); + } + } + + MacroAssembler masm(NULL, buffer, static_cast(actual_size)); + // esp[1 * kPointerSize]: raw double input + // esp[0 * kPointerSize]: return address + // Move double input into registers. + + __ push(ebx); + __ push(edx); + __ push(edi); + __ fld_d(Operand(esp, 4 * kPointerSize)); + __ mov(ebx, Operand(esp, 4 * kPointerSize)); + __ mov(edx, Operand(esp, 5 * kPointerSize)); + TranscendentalCacheStub::GenerateOperation(&masm, type); + // The return value is expected to be on ST(0) of the FPU stack. + __ pop(edi); + __ pop(edx); + __ pop(ebx); + __ Ret(); + + CodeDesc desc; + masm.GetCode(&desc); + ASSERT(desc.reloc_size == 0); + + CPU::FlushICache(buffer, actual_size); + OS::ProtectCode(buffer, actual_size); + return FUNCTION_CAST(buffer); +} + + static void MemCopyWrapper(void* dest, const void* src, size_t size) { memcpy(dest, src, size); } diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 6db041319..758701652 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -1195,7 +1195,7 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(context, input); return DefineSameAsFirst(result); - } else if (op == kMathSin || op == kMathCos) { + } else if (op == kMathSin || op == kMathCos || op == kMathTan) { LOperand* context = UseFixed(instr->context(), esi); LOperand* input = UseFixedDouble(instr->value(), xmm1); LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(context, diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc index d7bddaf12..8cbb77195 100644 --- a/src/mips/codegen-mips.cc +++ b/src/mips/codegen-mips.cc @@ -37,6 +37,19 @@ namespace internal { #define __ ACCESS_MASM(masm) +TranscendentalFunction CreateTranscendentalFunction( + TranscendentalCache::Type type) { + switch (type) { + case TranscendentalCache::SIN: return &sin; + case TranscendentalCache::COS: return &cos; + case TranscendentalCache::TAN: return &tan; + case TranscendentalCache::LOG: return &log; + default: UNIMPLEMENTED(); + } + return NULL; +} + + // ------------------------------------------------------------------------- // Platform-specific RuntimeCallHelper functions. diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc index ae07c1e45..1c4e1da3f 100644 --- a/src/mips/lithium-mips.cc +++ b/src/mips/lithium-mips.cc @@ -1169,7 +1169,7 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); - if (op == kMathLog || op == kMathSin || op == kMathCos) { + if (op == kMathLog || op == kMathSin || op == kMathCos || op == kMathTan) { LOperand* input = UseFixedDouble(instr->value(), f4); LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input, NULL); return MarkAsCall(DefineFixedDouble(result, f4), instr); diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc index 918327a98..e05345c80 100644 --- a/src/platform-nullos.cc +++ b/src/platform-nullos.cc @@ -55,6 +55,30 @@ double modulo(double x, double y) { } +double fast_sin(double x) { + UNIMPLEMENTED(); + return 0; +} + + +double fast_cos(double x) { + UNIMPLEMENTED(); + return 0; +} + + +double fast_tan(double x) { + UNIMPLEMENTED(); + return 0; +} + + +double fast_log(double x) { + UNIMPLEMENTED(); + return 0; +} + + // Initialize OS class early in the V8 startup. void OS::SetUp() { // Seed the random number generator. diff --git a/src/platform-posix.cc b/src/platform-posix.cc index 34fd5c449..4543a66e8 100644 --- a/src/platform-posix.cc +++ b/src/platform-posix.cc @@ -53,6 +53,7 @@ #include "v8.h" +#include "codegen.h" #include "platform.h" namespace v8 { @@ -126,6 +127,29 @@ double modulo(double x, double y) { } +static Mutex* transcendental_function_mutex = OS::CreateMutex(); + +#define TRANSCENDENTAL_FUNCTION(name, type) \ +static TranscendentalFunction fast_##name##_function = NULL; \ +double fast_##name(double x) { \ + if (fast_##name##_function == NULL) { \ + ScopedLock lock(transcendental_function_mutex); \ + TranscendentalFunction temp = \ + CreateTranscendentalFunction(type); \ + MemoryBarrier(); \ + fast_##name##_function = temp; \ + } \ + return (*fast_##name##_function)(x); \ +} + +TRANSCENDENTAL_FUNCTION(sin, TranscendentalCache::SIN) +TRANSCENDENTAL_FUNCTION(cos, TranscendentalCache::COS) +TRANSCENDENTAL_FUNCTION(tan, TranscendentalCache::TAN) +TRANSCENDENTAL_FUNCTION(log, TranscendentalCache::LOG) + +#undef TRANSCENDENTAL_FUNCTION + + double OS::nan_value() { // NAN from math.h is defined in C99 and not in POSIX. return NAN; diff --git a/src/platform-win32.cc b/src/platform-win32.cc index 115a6c946..064a449e0 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -32,6 +32,7 @@ #include "v8.h" +#include "codegen.h" #include "platform.h" #include "vm-state-inl.h" @@ -206,6 +207,30 @@ double modulo(double x, double y) { #endif // _WIN64 + +static Mutex* transcendental_function_mutex = OS::CreateMutex(); + +#define TRANSCENDENTAL_FUNCTION(name, type) \ +static TranscendentalFunction fast_##name##_function = NULL; \ +double fast_##name(double x) { \ + if (fast_##name##_function == NULL) { \ + ScopedLock lock(transcendental_function_mutex); \ + TranscendentalFunction temp = \ + CreateTranscendentalFunction(type); \ + MemoryBarrier(); \ + fast_##name##_function = temp; \ + } \ + return (*fast_##name##_function)(x); \ +} + +TRANSCENDENTAL_FUNCTION(sin, TranscendentalCache::SIN) +TRANSCENDENTAL_FUNCTION(cos, TranscendentalCache::COS) +TRANSCENDENTAL_FUNCTION(tan, TranscendentalCache::TAN) +TRANSCENDENTAL_FUNCTION(log, TranscendentalCache::LOG) + +#undef TRANSCENDENTAL_FUNCTION + + // ---------------------------------------------------------------------------- // The Time class represents time on win32. A timestamp is represented as // a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript diff --git a/src/platform.h b/src/platform.h index 38e633a38..ccb4109b2 100644 --- a/src/platform.h +++ b/src/platform.h @@ -96,6 +96,12 @@ class Mutex; double ceiling(double x); double modulo(double x, double y); +// Custom implementation of sin, cos, tan and log. +double fast_sin(double input); +double fast_cos(double input); +double fast_tan(double input); +double fast_log(double input); + // Forward declarations. class Socket; diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 982639e9a..2bfb0043b 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -1628,7 +1628,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { __ movsd(FieldOperand(rax, HeapNumber::kValueOffset), xmm1); __ fld_d(FieldOperand(rax, HeapNumber::kValueOffset)); } - GenerateOperation(masm); + GenerateOperation(masm, type_); __ movq(Operand(rcx, 0), rbx); __ movq(Operand(rcx, 2 * kIntSize), rax); __ fstp_d(FieldOperand(rax, HeapNumber::kValueOffset)); @@ -1643,7 +1643,7 @@ void TranscendentalCacheStub::Generate(MacroAssembler* masm) { __ subq(rsp, Immediate(kDoubleSize)); __ movsd(Operand(rsp, 0), xmm1); __ fld_d(Operand(rsp, 0)); - GenerateOperation(masm); + GenerateOperation(masm, type_); __ fstp_d(Operand(rsp, 0)); __ movsd(xmm1, Operand(rsp, 0)); __ addq(rsp, Immediate(kDoubleSize)); @@ -1695,16 +1695,17 @@ Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() { } -void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { +void TranscendentalCacheStub::GenerateOperation( + MacroAssembler* masm, TranscendentalCache::Type type) { // Registers: // rax: Newly allocated HeapNumber, which must be preserved. // rbx: Bits of input double. Must be preserved. // rcx: Pointer to cache entry. Must be preserved. // st(0): Input double Label done; - if (type_ == TranscendentalCache::SIN || - type_ == TranscendentalCache::COS || - type_ == TranscendentalCache::TAN) { + if (type == TranscendentalCache::SIN || + type == TranscendentalCache::COS || + type == TranscendentalCache::TAN) { // Both fsin and fcos require arguments in the range +/-2^63 and // return NaN for infinities and NaN. They can share all code except // the actual fsin/fcos operation. @@ -1725,8 +1726,12 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { __ j(not_equal, &non_nan_result, Label::kNear); // Input is +/-Infinity or NaN. Result is NaN. __ fstp(0); - __ LoadRoot(kScratchRegister, Heap::kNanValueRootIndex); - __ fld_d(FieldOperand(kScratchRegister, HeapNumber::kValueOffset)); + // NaN is represented by 0x7ff8000000000000. + __ subq(rsp, Immediate(kPointerSize)); + __ movl(Operand(rsp, 4), Immediate(0x7ff80000)); + __ movl(Operand(rsp, 0), Immediate(0x00000000)); + __ fld_d(Operand(rsp, 0)); + __ addq(rsp, Immediate(kPointerSize)); __ jmp(&done); __ bind(&non_nan_result); @@ -1767,7 +1772,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { // FPU Stack: input % 2*pi __ movq(rax, rdi); // Restore rax, pointer to the new HeapNumber. __ bind(&in_range); - switch (type_) { + switch (type) { case TranscendentalCache::SIN: __ fsin(); break; @@ -1785,7 +1790,7 @@ void TranscendentalCacheStub::GenerateOperation(MacroAssembler* masm) { } __ bind(&done); } else { - ASSERT(type_ == TranscendentalCache::LOG); + ASSERT(type == TranscendentalCache::LOG); __ fldln2(); __ fxch(); __ fyl2x(); diff --git a/src/x64/code-stubs-x64.h b/src/x64/code-stubs-x64.h index 30ef3e8c5..6a1a18f83 100644 --- a/src/x64/code-stubs-x64.h +++ b/src/x64/code-stubs-x64.h @@ -48,6 +48,8 @@ class TranscendentalCacheStub: public CodeStub { ArgumentType argument_type) : type_(type), argument_type_(argument_type) {} void Generate(MacroAssembler* masm); + static void GenerateOperation(MacroAssembler* masm, + TranscendentalCache::Type type); private: TranscendentalCache::Type type_; ArgumentType argument_type_; @@ -55,7 +57,6 @@ class TranscendentalCacheStub: public CodeStub { Major MajorKey() { return TranscendentalCache; } int MinorKey() { return type_ | argument_type_; } Runtime::FunctionId RuntimeFunction(); - void GenerateOperation(MacroAssembler* masm); }; diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc index 8947f7005..2584889f0 100644 --- a/src/x64/codegen-x64.cc +++ b/src/x64/codegen-x64.cc @@ -54,6 +54,52 @@ void StubRuntimeCallHelper::AfterCall(MacroAssembler* masm) const { #define __ masm. + +TranscendentalFunction CreateTranscendentalFunction( + TranscendentalCache::Type type) { + size_t actual_size; + // Allocate buffer in executable space. + byte* buffer = static_cast(OS::Allocate(1 * KB, + &actual_size, + true)); + if (buffer == NULL) { + // Fallback to library function if function cannot be created. + switch (type) { + case TranscendentalCache::SIN: return &sin; + case TranscendentalCache::COS: return &cos; + case TranscendentalCache::TAN: return &tan; + case TranscendentalCache::LOG: return &log; + default: UNIMPLEMENTED(); + } + } + + MacroAssembler masm(NULL, buffer, static_cast(actual_size)); + // xmm0: raw double input. + // Move double input into registers. + __ push(rbx); + __ push(rdi); + __ movq(rbx, xmm0); + __ push(rbx); + __ fld_d(Operand(rsp, 0)); + TranscendentalCacheStub::GenerateOperation(&masm, type); + // The return value is expected to be in xmm0. + __ fstp_d(Operand(rsp, 0)); + __ pop(rbx); + __ movq(xmm0, rbx); + __ pop(rdi); + __ pop(rbx); + __ Ret(); + + CodeDesc desc; + masm.GetCode(&desc); + ASSERT(desc.reloc_size == 0); + + CPU::FlushICache(buffer, actual_size); + OS::ProtectCode(buffer, actual_size); + return FUNCTION_CAST(buffer); +} + + #ifdef _WIN64 typedef double (*ModuloFunction)(double, double); // Define custom fmod implementation. diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index 19bb58ae6..79ca5f59e 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -1163,7 +1163,7 @@ LInstruction* LChunkBuilder::DoInvokeFunction(HInvokeFunction* instr) { LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) { BuiltinFunctionId op = instr->op(); - if (op == kMathLog || op == kMathSin || op == kMathCos) { + if (op == kMathLog || op == kMathSin || op == kMathCos || op == kMathTan) { LOperand* input = UseFixedDouble(instr->value(), xmm1); LUnaryMathOperation* result = new(zone()) LUnaryMathOperation(input); return MarkAsCall(DefineFixedDouble(result, xmm1), instr); -- 2.34.1