121939df44de1705786c545cd1bf519d47250322dBen Murdoch/* 221939df44de1705786c545cd1bf519d47250322dBen Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved. 321939df44de1705786c545cd1bf519d47250322dBen Murdoch * 421939df44de1705786c545cd1bf519d47250322dBen Murdoch * Redistribution and use in source and binary forms, with or without 521939df44de1705786c545cd1bf519d47250322dBen Murdoch * modification, are permitted provided that the following conditions 621939df44de1705786c545cd1bf519d47250322dBen Murdoch * are met: 721939df44de1705786c545cd1bf519d47250322dBen Murdoch * 1. Redistributions of source code must retain the above copyright 821939df44de1705786c545cd1bf519d47250322dBen Murdoch * notice, this list of conditions and the following disclaimer. 921939df44de1705786c545cd1bf519d47250322dBen Murdoch * 2. Redistributions in binary form must reproduce the above copyright 1021939df44de1705786c545cd1bf519d47250322dBen Murdoch * notice, this list of conditions and the following disclaimer in the 1121939df44de1705786c545cd1bf519d47250322dBen Murdoch * documentation and/or other materials provided with the distribution. 1221939df44de1705786c545cd1bf519d47250322dBen Murdoch * 1321939df44de1705786c545cd1bf519d47250322dBen Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 1421939df44de1705786c545cd1bf519d47250322dBen Murdoch * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1521939df44de1705786c545cd1bf519d47250322dBen Murdoch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 1621939df44de1705786c545cd1bf519d47250322dBen Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 1721939df44de1705786c545cd1bf519d47250322dBen Murdoch * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 1821939df44de1705786c545cd1bf519d47250322dBen Murdoch * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 1921939df44de1705786c545cd1bf519d47250322dBen Murdoch * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 2021939df44de1705786c545cd1bf519d47250322dBen Murdoch * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 2121939df44de1705786c545cd1bf519d47250322dBen Murdoch * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2221939df44de1705786c545cd1bf519d47250322dBen Murdoch * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 2321939df44de1705786c545cd1bf519d47250322dBen Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2421939df44de1705786c545cd1bf519d47250322dBen Murdoch */ 2521939df44de1705786c545cd1bf519d47250322dBen Murdoch 2621939df44de1705786c545cd1bf519d47250322dBen Murdoch#ifndef CachedTranscendentalFunction_h 2721939df44de1705786c545cd1bf519d47250322dBen Murdoch#define CachedTranscendentalFunction_h 2821939df44de1705786c545cd1bf519d47250322dBen Murdoch 2921939df44de1705786c545cd1bf519d47250322dBen Murdoch#include "JSValue.h" 3021939df44de1705786c545cd1bf519d47250322dBen Murdoch 3121939df44de1705786c545cd1bf519d47250322dBen Murdochnamespace JSC { 3221939df44de1705786c545cd1bf519d47250322dBen Murdoch 3321939df44de1705786c545cd1bf519d47250322dBen Murdochextern const double NaN; 3421939df44de1705786c545cd1bf519d47250322dBen Murdoch 3521939df44de1705786c545cd1bf519d47250322dBen Murdochtypedef double (*TranscendentalFunctionPtr)(double); 3621939df44de1705786c545cd1bf519d47250322dBen Murdoch 3721939df44de1705786c545cd1bf519d47250322dBen Murdoch// CachedTranscendentalFunction provides a generic mechanism to cache results 3821939df44de1705786c545cd1bf519d47250322dBen Murdoch// for pure functions with the signature "double func(double)", and where NaN 3921939df44de1705786c545cd1bf519d47250322dBen Murdoch// maps to NaN. 4021939df44de1705786c545cd1bf519d47250322dBen Murdochtemplate<TranscendentalFunctionPtr orignalFunction> 4121939df44de1705786c545cd1bf519d47250322dBen Murdochclass CachedTranscendentalFunction { 4221939df44de1705786c545cd1bf519d47250322dBen Murdoch struct CacheEntry { 4321939df44de1705786c545cd1bf519d47250322dBen Murdoch double operand; 4421939df44de1705786c545cd1bf519d47250322dBen Murdoch double result; 4521939df44de1705786c545cd1bf519d47250322dBen Murdoch }; 4621939df44de1705786c545cd1bf519d47250322dBen Murdoch 4721939df44de1705786c545cd1bf519d47250322dBen Murdochpublic: 4821939df44de1705786c545cd1bf519d47250322dBen Murdoch CachedTranscendentalFunction() 4921939df44de1705786c545cd1bf519d47250322dBen Murdoch : m_cache(0) 5021939df44de1705786c545cd1bf519d47250322dBen Murdoch { 5121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 5221939df44de1705786c545cd1bf519d47250322dBen Murdoch 5321939df44de1705786c545cd1bf519d47250322dBen Murdoch ~CachedTranscendentalFunction() 5421939df44de1705786c545cd1bf519d47250322dBen Murdoch { 5521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (m_cache) 5621939df44de1705786c545cd1bf519d47250322dBen Murdoch fastFree(m_cache); 5721939df44de1705786c545cd1bf519d47250322dBen Murdoch } 5821939df44de1705786c545cd1bf519d47250322dBen Murdoch 59e14391e94c850b8bd03680c23b38978db68687a8John Reck JSValue operator() (double operand) 6021939df44de1705786c545cd1bf519d47250322dBen Murdoch { 6121939df44de1705786c545cd1bf519d47250322dBen Murdoch if (UNLIKELY(!m_cache)) 6221939df44de1705786c545cd1bf519d47250322dBen Murdoch initialize(); 6321939df44de1705786c545cd1bf519d47250322dBen Murdoch CacheEntry* entry = &m_cache[hash(operand)]; 6421939df44de1705786c545cd1bf519d47250322dBen Murdoch 6521939df44de1705786c545cd1bf519d47250322dBen Murdoch if (entry->operand == operand) 66e14391e94c850b8bd03680c23b38978db68687a8John Reck return jsDoubleNumber(entry->result); 6721939df44de1705786c545cd1bf519d47250322dBen Murdoch double result = orignalFunction(operand); 6821939df44de1705786c545cd1bf519d47250322dBen Murdoch entry->operand = operand; 6921939df44de1705786c545cd1bf519d47250322dBen Murdoch entry->result = result; 70e14391e94c850b8bd03680c23b38978db68687a8John Reck return jsDoubleNumber(result); 7121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 7221939df44de1705786c545cd1bf519d47250322dBen Murdoch 7321939df44de1705786c545cd1bf519d47250322dBen Murdochprivate: 7421939df44de1705786c545cd1bf519d47250322dBen Murdoch void initialize() 7521939df44de1705786c545cd1bf519d47250322dBen Murdoch { 7621939df44de1705786c545cd1bf519d47250322dBen Murdoch // Lazily allocate the table, populate with NaN->NaN mapping. 7721939df44de1705786c545cd1bf519d47250322dBen Murdoch m_cache = static_cast<CacheEntry*>(fastMalloc(s_cacheSize * sizeof(CacheEntry))); 7821939df44de1705786c545cd1bf519d47250322dBen Murdoch for (unsigned x = 0; x < s_cacheSize; ++x) { 7921939df44de1705786c545cd1bf519d47250322dBen Murdoch m_cache[x].operand = NaN; 8021939df44de1705786c545cd1bf519d47250322dBen Murdoch m_cache[x].result = NaN; 8121939df44de1705786c545cd1bf519d47250322dBen Murdoch } 8221939df44de1705786c545cd1bf519d47250322dBen Murdoch } 8321939df44de1705786c545cd1bf519d47250322dBen Murdoch 8421939df44de1705786c545cd1bf519d47250322dBen Murdoch static unsigned hash(double d) 8521939df44de1705786c545cd1bf519d47250322dBen Murdoch { 8621939df44de1705786c545cd1bf519d47250322dBen Murdoch union doubleAndUInt64 { 8721939df44de1705786c545cd1bf519d47250322dBen Murdoch double d; 8821939df44de1705786c545cd1bf519d47250322dBen Murdoch uint32_t is[2]; 8921939df44de1705786c545cd1bf519d47250322dBen Murdoch } u; 9021939df44de1705786c545cd1bf519d47250322dBen Murdoch u.d = d; 9121939df44de1705786c545cd1bf519d47250322dBen Murdoch 9221939df44de1705786c545cd1bf519d47250322dBen Murdoch unsigned x = u.is[0] ^ u.is[1]; 9321939df44de1705786c545cd1bf519d47250322dBen Murdoch x = (x >> 20) ^ (x >> 8); 9421939df44de1705786c545cd1bf519d47250322dBen Murdoch return x & (s_cacheSize - 1); 9521939df44de1705786c545cd1bf519d47250322dBen Murdoch } 9621939df44de1705786c545cd1bf519d47250322dBen Murdoch 9721939df44de1705786c545cd1bf519d47250322dBen Murdoch static const unsigned s_cacheSize = 0x1000; 9821939df44de1705786c545cd1bf519d47250322dBen Murdoch CacheEntry* m_cache; 9921939df44de1705786c545cd1bf519d47250322dBen Murdoch}; 10021939df44de1705786c545cd1bf519d47250322dBen Murdoch 10121939df44de1705786c545cd1bf519d47250322dBen Murdoch} 10221939df44de1705786c545cd1bf519d47250322dBen Murdoch 10321939df44de1705786c545cd1bf519d47250322dBen Murdoch#endif // CachedTranscendentalFunction_h 104