diff options
Diffstat (limited to 'JavaScriptCore/wtf')
200 files changed, 0 insertions, 42406 deletions
diff --git a/JavaScriptCore/wtf/ASCIICType.h b/JavaScriptCore/wtf/ASCIICType.h deleted file mode 100644 index c19b85a..0000000 --- a/JavaScriptCore/wtf/ASCIICType.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_ASCIICType_h -#define WTF_ASCIICType_h - -#include <wtf/Assertions.h> - -// The behavior of many of the functions in the <ctype.h> header is dependent -// on the current locale. But in the WebKit project, all uses of those functions -// are in code processing something that's not locale-specific. These equivalents -// for some of the <ctype.h> functions are named more explicitly, not dependent -// on the C library locale, and we should also optimize them as needed. - -// All functions return false or leave the character unchanged if passed a character -// that is outside the range 0-7F. So they can be used on Unicode strings or -// characters if the intent is to do processing only if the character is ASCII. - -namespace WTF { - - inline bool isASCII(char c) { return !(c & ~0x7F); } - inline bool isASCII(unsigned short c) { return !(c & ~0x7F); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCII(wchar_t c) { return !(c & ~0x7F); } -#endif - inline bool isASCII(int c) { return !(c & ~0x7F); } - inline bool isASCII(unsigned c) { return !(c & ~0x7F); } - - inline bool isASCIIAlpha(char c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; } - inline bool isASCIIAlpha(unsigned short c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIAlpha(wchar_t c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; } -#endif - inline bool isASCIIAlpha(int c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; } - inline bool isASCIIAlpha(unsigned c) { return (c | 0x20) >= 'a' && (c | 0x20) <= 'z'; } - - inline bool isASCIIAlphanumeric(char c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); } - inline bool isASCIIAlphanumeric(unsigned short c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIAlphanumeric(wchar_t c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); } -#endif - inline bool isASCIIAlphanumeric(int c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); } - inline bool isASCIIAlphanumeric(unsigned c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'z'); } - - inline bool isASCIIDigit(char c) { return (c >= '0') & (c <= '9'); } - inline bool isASCIIDigit(unsigned short c) { return (c >= '0') & (c <= '9'); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIDigit(wchar_t c) { return (c >= '0') & (c <= '9'); } -#endif - inline bool isASCIIDigit(int c) { return (c >= '0') & (c <= '9'); } - inline bool isASCIIDigit(unsigned c) { return (c >= '0') & (c <= '9'); } - - inline bool isASCIIHexDigit(char c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); } - inline bool isASCIIHexDigit(unsigned short c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIHexDigit(wchar_t c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); } -#endif - inline bool isASCIIHexDigit(int c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); } - inline bool isASCIIHexDigit(unsigned c) { return (c >= '0' && c <= '9') || ((c | 0x20) >= 'a' && (c | 0x20) <= 'f'); } - - inline bool isASCIIOctalDigit(char c) { return (c >= '0') & (c <= '7'); } - inline bool isASCIIOctalDigit(unsigned short c) { return (c >= '0') & (c <= '7'); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIOctalDigit(wchar_t c) { return (c >= '0') & (c <= '7'); } -#endif - inline bool isASCIIOctalDigit(int c) { return (c >= '0') & (c <= '7'); } - inline bool isASCIIOctalDigit(unsigned c) { return (c >= '0') & (c <= '7'); } - - inline bool isASCIILower(char c) { return c >= 'a' && c <= 'z'; } - inline bool isASCIILower(unsigned short c) { return c >= 'a' && c <= 'z'; } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIILower(wchar_t c) { return c >= 'a' && c <= 'z'; } -#endif - inline bool isASCIILower(int c) { return c >= 'a' && c <= 'z'; } - inline bool isASCIILower(unsigned c) { return c >= 'a' && c <= 'z'; } - - inline bool isASCIIUpper(char c) { return c >= 'A' && c <= 'Z'; } - inline bool isASCIIUpper(unsigned short c) { return c >= 'A' && c <= 'Z'; } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIUpper(wchar_t c) { return c >= 'A' && c <= 'Z'; } -#endif - inline bool isASCIIUpper(int c) { return c >= 'A' && c <= 'Z'; } - inline bool isASCIIUpper(unsigned c) { return c >= 'A' && c <= 'Z'; } - - /* - Statistics from a run of Apple's page load test for callers of isASCIISpace: - - character count - --------- ----- - non-spaces 689383 - 20 space 294720 - 0A \n 89059 - 09 \t 28320 - 0D \r 0 - 0C \f 0 - 0B \v 0 - */ - inline bool isASCIISpace(char c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); } - inline bool isASCIISpace(unsigned short c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIISpace(wchar_t c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); } -#endif - inline bool isASCIISpace(int c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); } - inline bool isASCIISpace(unsigned c) { return c <= ' ' && (c == ' ' || (c <= 0xD && c >= 0x9)); } - - inline char toASCIILower(char c) { return c | ((c >= 'A' && c <= 'Z') << 5); } - inline unsigned short toASCIILower(unsigned short c) { return c | ((c >= 'A' && c <= 'Z') << 5); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline wchar_t toASCIILower(wchar_t c) { return c | ((c >= 'A' && c <= 'Z') << 5); } -#endif - inline int toASCIILower(int c) { return c | ((c >= 'A' && c <= 'Z') << 5); } - inline unsigned toASCIILower(unsigned c) { return c | ((c >= 'A' && c <= 'Z') << 5); } - - // FIXME: Why do these need static_cast? - inline char toASCIIUpper(char c) { return static_cast<char>(c & ~((c >= 'a' && c <= 'z') << 5)); } - inline unsigned short toASCIIUpper(unsigned short c) { return static_cast<unsigned short>(c & ~((c >= 'a' && c <= 'z') << 5)); } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline wchar_t toASCIIUpper(wchar_t c) { return static_cast<wchar_t>(c & ~((c >= 'a' && c <= 'z') << 5)); } -#endif - inline int toASCIIUpper(int c) { return static_cast<int>(c & ~((c >= 'a' && c <= 'z') << 5)); } - inline unsigned toASCIIUpper(unsigned c) { return static_cast<unsigned>(c & ~((c >= 'a' && c <= 'z') << 5)); } - - inline int toASCIIHexValue(char c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; } - inline int toASCIIHexValue(unsigned short c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline int toASCIIHexValue(wchar_t c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; } -#endif - inline int toASCIIHexValue(int c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; } - inline int toASCIIHexValue(unsigned c) { ASSERT(isASCIIHexDigit(c)); return c < 'A' ? c - '0' : (c - 'A' + 10) & 0xF; } - - inline bool isASCIIPrintable(char c) { return c >= ' ' && c <= '~'; } - inline bool isASCIIPrintable(unsigned short c) { return c >= ' ' && c <= '~'; } -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - inline bool isASCIIPrintable(wchar_t c) { return c >= ' ' && c <= '~'; } -#endif - inline bool isASCIIPrintable(int c) { return c >= ' ' && c <= '~'; } - inline bool isASCIIPrintable(unsigned c) { return c >= ' ' && c <= '~'; } -} - -using WTF::isASCII; -using WTF::isASCIIAlpha; -using WTF::isASCIIAlphanumeric; -using WTF::isASCIIDigit; -using WTF::isASCIIHexDigit; -using WTF::isASCIILower; -using WTF::isASCIIOctalDigit; -using WTF::isASCIIPrintable; -using WTF::isASCIISpace; -using WTF::isASCIIUpper; -using WTF::toASCIIHexValue; -using WTF::toASCIILower; -using WTF::toASCIIUpper; - -#endif diff --git a/JavaScriptCore/wtf/AVLTree.h b/JavaScriptCore/wtf/AVLTree.h deleted file mode 100644 index ec8a639..0000000 --- a/JavaScriptCore/wtf/AVLTree.h +++ /dev/null @@ -1,960 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Based on Abstract AVL Tree Template v1.5 by Walt Karas - * <http://geocities.com/wkaras/gen_cpp/avl_tree.html>. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AVL_TREE_H_ -#define AVL_TREE_H_ - -#include "Assertions.h" -#include <wtf/FixedArray.h> - -namespace WTF { - -// Here is the reference class for BSet. -// -// class BSet -// { -// public: -// -// class ANY_bitref -// { -// public: -// operator bool (); -// void operator = (bool b); -// }; -// -// // Does not have to initialize bits. -// BSet(); -// -// // Must return a valid value for index when 0 <= index < maxDepth -// ANY_bitref operator [] (unsigned index); -// -// // Set all bits to 1. -// void set(); -// -// // Set all bits to 0. -// void reset(); -// }; - -template<unsigned maxDepth> -class AVLTreeDefaultBSet { -public: - bool& operator[](unsigned i) { ASSERT(i < maxDepth); return m_data[i]; } - void set() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = true; } - void reset() { for (unsigned i = 0; i < maxDepth; ++i) m_data[i] = false; } - -private: - FixedArray<bool, maxDepth> m_data; -}; - -// How to determine maxDepth: -// d Minimum number of nodes -// 2 2 -// 3 4 -// 4 7 -// 5 12 -// 6 20 -// 7 33 -// 8 54 -// 9 88 -// 10 143 -// 11 232 -// 12 376 -// 13 609 -// 14 986 -// 15 1,596 -// 16 2,583 -// 17 4,180 -// 18 6,764 -// 19 10,945 -// 20 17,710 -// 21 28,656 -// 22 46,367 -// 23 75,024 -// 24 121,392 -// 25 196,417 -// 26 317,810 -// 27 514,228 -// 28 832,039 -// 29 1,346,268 -// 30 2,178,308 -// 31 3,524,577 -// 32 5,702,886 -// 33 9,227,464 -// 34 14,930,351 -// 35 24,157,816 -// 36 39,088,168 -// 37 63,245,985 -// 38 102,334,154 -// 39 165,580,140 -// 40 267,914,295 -// 41 433,494,436 -// 42 701,408,732 -// 43 1,134,903,169 -// 44 1,836,311,902 -// 45 2,971,215,072 -// -// E.g., if, in a particular instantiation, the maximum number of nodes in a tree instance is 1,000,000, the maximum depth should be 28. -// You pick 28 because MN(28) is 832,039, which is less than or equal to 1,000,000, and MN(29) is 1,346,268, which is strictly greater than 1,000,000. - -template <class Abstractor, unsigned maxDepth = 32, class BSet = AVLTreeDefaultBSet<maxDepth> > -class AVLTree { -public: - - typedef typename Abstractor::key key; - typedef typename Abstractor::handle handle; - typedef typename Abstractor::size size; - - enum SearchType { - EQUAL = 1, - LESS = 2, - GREATER = 4, - LESS_EQUAL = EQUAL | LESS, - GREATER_EQUAL = EQUAL | GREATER - }; - - - Abstractor& abstractor() { return abs; } - - inline handle insert(handle h); - - inline handle search(key k, SearchType st = EQUAL); - inline handle search_least(); - inline handle search_greatest(); - - inline handle remove(key k); - - inline handle subst(handle new_node); - - void purge() { abs.root = null(); } - - bool is_empty() { return abs.root == null(); } - - AVLTree() { abs.root = null(); } - - class Iterator { - public: - - // Initialize depth to invalid value, to indicate iterator is - // invalid. (Depth is zero-base.) - Iterator() { depth = ~0U; } - - void start_iter(AVLTree &tree, key k, SearchType st = EQUAL) - { - // Mask of high bit in an int. - const int MASK_HIGH_BIT = (int) ~ ((~ (unsigned) 0) >> 1); - - // Save the tree that we're going to iterate through in a - // member variable. - tree_ = &tree; - - int cmp, target_cmp; - handle h = tree_->abs.root; - unsigned d = 0; - - depth = ~0U; - - if (h == null()) - // Tree is empty. - return; - - if (st & LESS) - // Key can be greater than key of starting node. - target_cmp = 1; - else if (st & GREATER) - // Key can be less than key of starting node. - target_cmp = -1; - else - // Key must be same as key of starting node. - target_cmp = 0; - - for (;;) { - cmp = cmp_k_n(k, h); - if (cmp == 0) { - if (st & EQUAL) { - // Equal node was sought and found as starting node. - depth = d; - break; - } - cmp = -target_cmp; - } else if (target_cmp != 0) { - if (!((cmp ^ target_cmp) & MASK_HIGH_BIT)) { - // cmp and target_cmp are both negative or both positive. - depth = d; - } - } - h = cmp < 0 ? get_lt(h) : get_gt(h); - if (h == null()) - break; - branch[d] = cmp > 0; - path_h[d++] = h; - } - } - - void start_iter_least(AVLTree &tree) - { - tree_ = &tree; - - handle h = tree_->abs.root; - - depth = ~0U; - - branch.reset(); - - while (h != null()) { - if (depth != ~0U) - path_h[depth] = h; - depth++; - h = get_lt(h); - } - } - - void start_iter_greatest(AVLTree &tree) - { - tree_ = &tree; - - handle h = tree_->abs.root; - - depth = ~0U; - - branch.set(); - - while (h != null()) { - if (depth != ~0U) - path_h[depth] = h; - depth++; - h = get_gt(h); - } - } - - handle operator*() - { - if (depth == ~0U) - return null(); - - return depth == 0 ? tree_->abs.root : path_h[depth - 1]; - } - - void operator++() - { - if (depth != ~0U) { - handle h = get_gt(**this); - if (h == null()) { - do { - if (depth == 0) { - depth = ~0U; - break; - } - depth--; - } while (branch[depth]); - } else { - branch[depth] = true; - path_h[depth++] = h; - for (;;) { - h = get_lt(h); - if (h == null()) - break; - branch[depth] = false; - path_h[depth++] = h; - } - } - } - } - - void operator--() - { - if (depth != ~0U) { - handle h = get_lt(**this); - if (h == null()) - do { - if (depth == 0) { - depth = ~0U; - break; - } - depth--; - } while (!branch[depth]); - else { - branch[depth] = false; - path_h[depth++] = h; - for (;;) { - h = get_gt(h); - if (h == null()) - break; - branch[depth] = true; - path_h[depth++] = h; - } - } - } - } - - void operator++(int) { ++(*this); } - void operator--(int) { --(*this); } - - protected: - - // Tree being iterated over. - AVLTree *tree_; - - // Records a path into the tree. If branch[n] is true, indicates - // take greater branch from the nth node in the path, otherwise - // take the less branch. branch[0] gives branch from root, and - // so on. - BSet branch; - - // Zero-based depth of path into tree. - unsigned depth; - - // Handles of nodes in path from root to current node (returned by *). - handle path_h[maxDepth - 1]; - - int cmp_k_n(key k, handle h) { return tree_->abs.compare_key_node(k, h); } - int cmp_n_n(handle h1, handle h2) { return tree_->abs.compare_node_node(h1, h2); } - handle get_lt(handle h) { return tree_->abs.get_less(h); } - handle get_gt(handle h) { return tree_->abs.get_greater(h); } - handle null() { return tree_->abs.null(); } - }; - - template<typename fwd_iter> - bool build(fwd_iter p, size num_nodes) - { - if (num_nodes == 0) { - abs.root = null(); - return true; - } - - // Gives path to subtree being built. If branch[N] is false, branch - // less from the node at depth N, if true branch greater. - BSet branch; - - // If rem[N] is true, then for the current subtree at depth N, it's - // greater subtree has one more node than it's less subtree. - BSet rem; - - // Depth of root node of current subtree. - unsigned depth = 0; - - // Number of nodes in current subtree. - size num_sub = num_nodes; - - // The algorithm relies on a stack of nodes whose less subtree has - // been built, but whose right subtree has not yet been built. The - // stack is implemented as linked list. The nodes are linked - // together by having the "greater" handle of a node set to the - // next node in the list. "less_parent" is the handle of the first - // node in the list. - handle less_parent = null(); - - // h is root of current subtree, child is one of its children. - handle h, child; - - for (;;) { - while (num_sub > 2) { - // Subtract one for root of subtree. - num_sub--; - rem[depth] = !!(num_sub & 1); - branch[depth++] = false; - num_sub >>= 1; - } - - if (num_sub == 2) { - // Build a subtree with two nodes, slanting to greater. - // I arbitrarily chose to always have the extra node in the - // greater subtree when there is an odd number of nodes to - // split between the two subtrees. - - h = *p; - p++; - child = *p; - p++; - set_lt(child, null()); - set_gt(child, null()); - set_bf(child, 0); - set_gt(h, child); - set_lt(h, null()); - set_bf(h, 1); - } else { // num_sub == 1 - // Build a subtree with one node. - - h = *p; - p++; - set_lt(h, null()); - set_gt(h, null()); - set_bf(h, 0); - } - - while (depth) { - depth--; - if (!branch[depth]) - // We've completed a less subtree. - break; - - // We've completed a greater subtree, so attach it to - // its parent (that is less than it). We pop the parent - // off the stack of less parents. - child = h; - h = less_parent; - less_parent = get_gt(h); - set_gt(h, child); - // num_sub = 2 * (num_sub - rem[depth]) + rem[depth] + 1 - num_sub <<= 1; - num_sub += 1 - rem[depth]; - if (num_sub & (num_sub - 1)) - // num_sub is not a power of 2 - set_bf(h, 0); - else - // num_sub is a power of 2 - set_bf(h, 1); - } - - if (num_sub == num_nodes) - // We've completed the full tree. - break; - - // The subtree we've completed is the less subtree of the - // next node in the sequence. - - child = h; - h = *p; - p++; - set_lt(h, child); - - // Put h into stack of less parents. - set_gt(h, less_parent); - less_parent = h; - - // Proceed to creating greater than subtree of h. - branch[depth] = true; - num_sub += rem[depth++]; - - } // end for (;;) - - abs.root = h; - - return true; - } - -protected: - - friend class Iterator; - - // Create a class whose sole purpose is to take advantage of - // the "empty member" optimization. - struct abs_plus_root : public Abstractor { - // The handle of the root element in the AVL tree. - handle root; - }; - - abs_plus_root abs; - - - handle get_lt(handle h) { return abs.get_less(h); } - void set_lt(handle h, handle lh) { abs.set_less(h, lh); } - - handle get_gt(handle h) { return abs.get_greater(h); } - void set_gt(handle h, handle gh) { abs.set_greater(h, gh); } - - int get_bf(handle h) { return abs.get_balance_factor(h); } - void set_bf(handle h, int bf) { abs.set_balance_factor(h, bf); } - - int cmp_k_n(key k, handle h) { return abs.compare_key_node(k, h); } - int cmp_n_n(handle h1, handle h2) { return abs.compare_node_node(h1, h2); } - - handle null() { return abs.null(); } - -private: - - // Balances subtree, returns handle of root node of subtree - // after balancing. - handle balance(handle bal_h) - { - handle deep_h; - - // Either the "greater than" or the "less than" subtree of - // this node has to be 2 levels deeper (or else it wouldn't - // need balancing). - - if (get_bf(bal_h) > 0) { - // "Greater than" subtree is deeper. - - deep_h = get_gt(bal_h); - - if (get_bf(deep_h) < 0) { - handle old_h = bal_h; - bal_h = get_lt(deep_h); - - set_gt(old_h, get_lt(bal_h)); - set_lt(deep_h, get_gt(bal_h)); - set_lt(bal_h, old_h); - set_gt(bal_h, deep_h); - - int bf = get_bf(bal_h); - if (bf != 0) { - if (bf > 0) { - set_bf(old_h, -1); - set_bf(deep_h, 0); - } else { - set_bf(deep_h, 1); - set_bf(old_h, 0); - } - set_bf(bal_h, 0); - } else { - set_bf(old_h, 0); - set_bf(deep_h, 0); - } - } else { - set_gt(bal_h, get_lt(deep_h)); - set_lt(deep_h, bal_h); - if (get_bf(deep_h) == 0) { - set_bf(deep_h, -1); - set_bf(bal_h, 1); - } else { - set_bf(deep_h, 0); - set_bf(bal_h, 0); - } - bal_h = deep_h; - } - } else { - // "Less than" subtree is deeper. - - deep_h = get_lt(bal_h); - - if (get_bf(deep_h) > 0) { - handle old_h = bal_h; - bal_h = get_gt(deep_h); - set_lt(old_h, get_gt(bal_h)); - set_gt(deep_h, get_lt(bal_h)); - set_gt(bal_h, old_h); - set_lt(bal_h, deep_h); - - int bf = get_bf(bal_h); - if (bf != 0) { - if (bf < 0) { - set_bf(old_h, 1); - set_bf(deep_h, 0); - } else { - set_bf(deep_h, -1); - set_bf(old_h, 0); - } - set_bf(bal_h, 0); - } else { - set_bf(old_h, 0); - set_bf(deep_h, 0); - } - } else { - set_lt(bal_h, get_gt(deep_h)); - set_gt(deep_h, bal_h); - if (get_bf(deep_h) == 0) { - set_bf(deep_h, 1); - set_bf(bal_h, -1); - } else { - set_bf(deep_h, 0); - set_bf(bal_h, 0); - } - bal_h = deep_h; - } - } - - return bal_h; - } - -}; - -template <class Abstractor, unsigned maxDepth, class BSet> -inline typename AVLTree<Abstractor, maxDepth, BSet>::handle -AVLTree<Abstractor, maxDepth, BSet>::insert(handle h) -{ - set_lt(h, null()); - set_gt(h, null()); - set_bf(h, 0); - - if (abs.root == null()) - abs.root = h; - else { - // Last unbalanced node encountered in search for insertion point. - handle unbal = null(); - // Parent of last unbalanced node. - handle parent_unbal = null(); - // Balance factor of last unbalanced node. - int unbal_bf; - - // Zero-based depth in tree. - unsigned depth = 0, unbal_depth = 0; - - // Records a path into the tree. If branch[n] is true, indicates - // take greater branch from the nth node in the path, otherwise - // take the less branch. branch[0] gives branch from root, and - // so on. - BSet branch; - - handle hh = abs.root; - handle parent = null(); - int cmp; - - do { - if (get_bf(hh) != 0) { - unbal = hh; - parent_unbal = parent; - unbal_depth = depth; - } - cmp = cmp_n_n(h, hh); - if (cmp == 0) - // Duplicate key. - return hh; - parent = hh; - hh = cmp < 0 ? get_lt(hh) : get_gt(hh); - branch[depth++] = cmp > 0; - } while (hh != null()); - - // Add node to insert as leaf of tree. - if (cmp < 0) - set_lt(parent, h); - else - set_gt(parent, h); - - depth = unbal_depth; - - if (unbal == null()) - hh = abs.root; - else { - cmp = branch[depth++] ? 1 : -1; - unbal_bf = get_bf(unbal); - if (cmp < 0) - unbal_bf--; - else // cmp > 0 - unbal_bf++; - hh = cmp < 0 ? get_lt(unbal) : get_gt(unbal); - if ((unbal_bf != -2) && (unbal_bf != 2)) { - // No rebalancing of tree is necessary. - set_bf(unbal, unbal_bf); - unbal = null(); - } - } - - if (hh != null()) - while (h != hh) { - cmp = branch[depth++] ? 1 : -1; - if (cmp < 0) { - set_bf(hh, -1); - hh = get_lt(hh); - } else { // cmp > 0 - set_bf(hh, 1); - hh = get_gt(hh); - } - } - - if (unbal != null()) { - unbal = balance(unbal); - if (parent_unbal == null()) - abs.root = unbal; - else { - depth = unbal_depth - 1; - cmp = branch[depth] ? 1 : -1; - if (cmp < 0) - set_lt(parent_unbal, unbal); - else // cmp > 0 - set_gt(parent_unbal, unbal); - } - } - } - - return h; -} - -template <class Abstractor, unsigned maxDepth, class BSet> -inline typename AVLTree<Abstractor, maxDepth, BSet>::handle -AVLTree<Abstractor, maxDepth, BSet>::search(key k, typename AVLTree<Abstractor, maxDepth, BSet>::SearchType st) -{ - const int MASK_HIGH_BIT = (int) ~ ((~ (unsigned) 0) >> 1); - - int cmp, target_cmp; - handle match_h = null(); - handle h = abs.root; - - if (st & LESS) - target_cmp = 1; - else if (st & GREATER) - target_cmp = -1; - else - target_cmp = 0; - - while (h != null()) { - cmp = cmp_k_n(k, h); - if (cmp == 0) { - if (st & EQUAL) { - match_h = h; - break; - } - cmp = -target_cmp; - } else if (target_cmp != 0) - if (!((cmp ^ target_cmp) & MASK_HIGH_BIT)) - // cmp and target_cmp are both positive or both negative. - match_h = h; - h = cmp < 0 ? get_lt(h) : get_gt(h); - } - - return match_h; -} - -template <class Abstractor, unsigned maxDepth, class BSet> -inline typename AVLTree<Abstractor, maxDepth, BSet>::handle -AVLTree<Abstractor, maxDepth, BSet>::search_least() -{ - handle h = abs.root, parent = null(); - - while (h != null()) { - parent = h; - h = get_lt(h); - } - - return parent; -} - -template <class Abstractor, unsigned maxDepth, class BSet> -inline typename AVLTree<Abstractor, maxDepth, BSet>::handle -AVLTree<Abstractor, maxDepth, BSet>::search_greatest() -{ - handle h = abs.root, parent = null(); - - while (h != null()) { - parent = h; - h = get_gt(h); - } - - return parent; -} - -template <class Abstractor, unsigned maxDepth, class BSet> -inline typename AVLTree<Abstractor, maxDepth, BSet>::handle -AVLTree<Abstractor, maxDepth, BSet>::remove(key k) -{ - // Zero-based depth in tree. - unsigned depth = 0, rm_depth; - - // Records a path into the tree. If branch[n] is true, indicates - // take greater branch from the nth node in the path, otherwise - // take the less branch. branch[0] gives branch from root, and - // so on. - BSet branch; - - handle h = abs.root; - handle parent = null(), child; - int cmp, cmp_shortened_sub_with_path = 0; - - for (;;) { - if (h == null()) - // No node in tree with given key. - return null(); - cmp = cmp_k_n(k, h); - if (cmp == 0) - // Found node to remove. - break; - parent = h; - h = cmp < 0 ? get_lt(h) : get_gt(h); - branch[depth++] = cmp > 0; - cmp_shortened_sub_with_path = cmp; - } - handle rm = h; - handle parent_rm = parent; - rm_depth = depth; - - // If the node to remove is not a leaf node, we need to get a - // leaf node, or a node with a single leaf as its child, to put - // in the place of the node to remove. We will get the greatest - // node in the less subtree (of the node to remove), or the least - // node in the greater subtree. We take the leaf node from the - // deeper subtree, if there is one. - - if (get_bf(h) < 0) { - child = get_lt(h); - branch[depth] = false; - cmp = -1; - } else { - child = get_gt(h); - branch[depth] = true; - cmp = 1; - } - depth++; - - if (child != null()) { - cmp = -cmp; - do { - parent = h; - h = child; - if (cmp < 0) { - child = get_lt(h); - branch[depth] = false; - } else { - child = get_gt(h); - branch[depth] = true; - } - depth++; - } while (child != null()); - - if (parent == rm) - // Only went through do loop once. Deleted node will be replaced - // in the tree structure by one of its immediate children. - cmp_shortened_sub_with_path = -cmp; - else - cmp_shortened_sub_with_path = cmp; - - // Get the handle of the opposite child, which may not be null. - child = cmp > 0 ? get_lt(h) : get_gt(h); - } - - if (parent == null()) - // There were only 1 or 2 nodes in this tree. - abs.root = child; - else if (cmp_shortened_sub_with_path < 0) - set_lt(parent, child); - else - set_gt(parent, child); - - // "path" is the parent of the subtree being eliminated or reduced - // from a depth of 2 to 1. If "path" is the node to be removed, we - // set path to the node we're about to poke into the position of the - // node to be removed. - handle path = parent == rm ? h : parent; - - if (h != rm) { - // Poke in the replacement for the node to be removed. - set_lt(h, get_lt(rm)); - set_gt(h, get_gt(rm)); - set_bf(h, get_bf(rm)); - if (parent_rm == null()) - abs.root = h; - else { - depth = rm_depth - 1; - if (branch[depth]) - set_gt(parent_rm, h); - else - set_lt(parent_rm, h); - } - } - - if (path != null()) { - // Create a temporary linked list from the parent of the path node - // to the root node. - h = abs.root; - parent = null(); - depth = 0; - while (h != path) { - if (branch[depth++]) { - child = get_gt(h); - set_gt(h, parent); - } else { - child = get_lt(h); - set_lt(h, parent); - } - parent = h; - h = child; - } - - // Climb from the path node to the root node using the linked - // list, restoring the tree structure and rebalancing as necessary. - bool reduced_depth = true; - int bf; - cmp = cmp_shortened_sub_with_path; - for (;;) { - if (reduced_depth) { - bf = get_bf(h); - if (cmp < 0) - bf++; - else // cmp > 0 - bf--; - if ((bf == -2) || (bf == 2)) { - h = balance(h); - bf = get_bf(h); - } else - set_bf(h, bf); - reduced_depth = (bf == 0); - } - if (parent == null()) - break; - child = h; - h = parent; - cmp = branch[--depth] ? 1 : -1; - if (cmp < 0) { - parent = get_lt(h); - set_lt(h, child); - } else { - parent = get_gt(h); - set_gt(h, child); - } - } - abs.root = h; - } - - return rm; -} - -template <class Abstractor, unsigned maxDepth, class BSet> -inline typename AVLTree<Abstractor, maxDepth, BSet>::handle -AVLTree<Abstractor, maxDepth, BSet>::subst(handle new_node) -{ - handle h = abs.root; - handle parent = null(); - int cmp, last_cmp; - - /* Search for node already in tree with same key. */ - for (;;) { - if (h == null()) - /* No node in tree with same key as new node. */ - return null(); - cmp = cmp_n_n(new_node, h); - if (cmp == 0) - /* Found the node to substitute new one for. */ - break; - last_cmp = cmp; - parent = h; - h = cmp < 0 ? get_lt(h) : get_gt(h); - } - - /* Copy tree housekeeping fields from node in tree to new node. */ - set_lt(new_node, get_lt(h)); - set_gt(new_node, get_gt(h)); - set_bf(new_node, get_bf(h)); - - if (parent == null()) - /* New node is also new root. */ - abs.root = new_node; - else { - /* Make parent point to new node. */ - if (last_cmp < 0) - set_lt(parent, new_node); - else - set_gt(parent, new_node); - } - - return h; -} - -} - -#endif diff --git a/JavaScriptCore/wtf/AlwaysInline.h b/JavaScriptCore/wtf/AlwaysInline.h deleted file mode 100644 index 34f8b74..0000000 --- a/JavaScriptCore/wtf/AlwaysInline.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2005, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "Platform.h" - -#ifndef ALWAYS_INLINE -#if COMPILER(GCC) && defined(NDEBUG) && !COMPILER(MINGW) -#define ALWAYS_INLINE inline __attribute__((__always_inline__)) -#elif (COMPILER(MSVC) || COMPILER(RVCT)) && defined(NDEBUG) -#define ALWAYS_INLINE __forceinline -#else -#define ALWAYS_INLINE inline -#endif -#endif - -#ifndef NEVER_INLINE -#if COMPILER(GCC) -#define NEVER_INLINE __attribute__((__noinline__)) -#elif COMPILER(RVCT) -#define NEVER_INLINE __declspec(noinline) -#else -#define NEVER_INLINE -#endif -#endif - -#ifndef UNLIKELY -#if COMPILER(GCC) -#define UNLIKELY(x) __builtin_expect((x), 0) -#else -#define UNLIKELY(x) (x) -#endif -#endif - -#ifndef LIKELY -#if COMPILER(GCC) -#define LIKELY(x) __builtin_expect((x), 1) -#else -#define LIKELY(x) (x) -#endif -#endif - -#ifndef NO_RETURN -#if COMPILER(GCC) -#define NO_RETURN __attribute((__noreturn__)) -#elif COMPILER(MSVC) || COMPILER(RVCT) -#define NO_RETURN __declspec(noreturn) -#else -#define NO_RETURN -#endif -#endif - -#ifndef NO_RETURN_WITH_VALUE -#if !COMPILER(MSVC) -#define NO_RETURN_WITH_VALUE NO_RETURN -#else -#define NO_RETURN_WITH_VALUE -#endif -#endif diff --git a/JavaScriptCore/wtf/Assertions.cpp b/JavaScriptCore/wtf/Assertions.cpp deleted file mode 100644 index 1841150..0000000 --- a/JavaScriptCore/wtf/Assertions.cpp +++ /dev/null @@ -1,249 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Assertions.h" - -#include <stdio.h> -#include <stdarg.h> -#include <string.h> - -#if PLATFORM(MAC) -#include <CoreFoundation/CFString.h> -#endif - -#if COMPILER(MSVC) && !OS(WINCE) && !PLATFORM(BREWMP) -#ifndef WINVER -#define WINVER 0x0500 -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0500 -#endif -#include <crtdbg.h> -#endif - -#if OS(WINDOWS) -#include <windows.h> -#endif - -#if PLATFORM(BREWMP) -#include <AEEdbg.h> -#include <wtf/Vector.h> -#endif - -extern "C" { - -#if PLATFORM(BREWMP) - -static void printLog(const Vector<char>& buffer) -{ - // Each call to DBGPRINTF generates at most 128 bytes of output on the Windows SDK. - // On Qualcomm chipset targets, DBGPRINTF() comes out the diag port (though this may change). - // The length of each output string is constrained even more than on the Windows SDK. -#if COMPILER(MSVC) - const int printBufferSize = 128; -#else - const int printBufferSize = 32; -#endif - - char printBuffer[printBufferSize + 1]; - printBuffer[printBufferSize] = 0; // to guarantee null termination - - const char* p = buffer.data(); - const char* end = buffer.data() + buffer.size(); - while (p < end) { - strncpy(printBuffer, p, printBufferSize); - dbg_Message(printBuffer, DBG_MSG_LEVEL_HIGH, __FILE__, __LINE__); - p += printBufferSize; - } -} - -#endif - -WTF_ATTRIBUTE_PRINTF(1, 0) -static void vprintf_stderr_common(const char* format, va_list args) -{ -#if PLATFORM(MAC) - if (strstr(format, "%@")) { - CFStringRef cfFormat = CFStringCreateWithCString(NULL, format, kCFStringEncodingUTF8); - CFStringRef str = CFStringCreateWithFormatAndArguments(NULL, NULL, cfFormat, args); - - int length = CFStringGetMaximumSizeForEncoding(CFStringGetLength(str), kCFStringEncodingUTF8); - char* buffer = (char*)malloc(length + 1); - - CFStringGetCString(str, buffer, length, kCFStringEncodingUTF8); - - fputs(buffer, stderr); - - free(buffer); - CFRelease(str); - CFRelease(cfFormat); - } else -#elif PLATFORM(BREWMP) - // When str is 0, the return value is the number of bytes needed - // to accept the result including null termination. - int size = vsnprintf(0, 0, format, args); - if (size > 0) { - Vector<char> buffer(size); - vsnprintf(buffer.data(), size, format, args); - printLog(buffer); - } - -#elif HAVE(ISDEBUGGERPRESENT) - if (IsDebuggerPresent()) { - size_t size = 1024; - - do { - char* buffer = (char*)malloc(size); - - if (buffer == NULL) - break; - - if (_vsnprintf(buffer, size, format, args) != -1) { -#if OS(WINCE) - // WinCE only supports wide chars - wchar_t* wideBuffer = (wchar_t*)malloc(size * sizeof(wchar_t)); - if (wideBuffer == NULL) - break; - for (unsigned int i = 0; i < size; ++i) { - if (!(wideBuffer[i] = buffer[i])) - break; - } - OutputDebugStringW(wideBuffer); - free(wideBuffer); -#else - OutputDebugStringA(buffer); -#endif - free(buffer); - break; - } - - free(buffer); - size *= 2; - } while (size > 1024); - } -#endif -#if OS(SYMBIAN) - vfprintf(stdout, format, args); -#else - vfprintf(stderr, format, args); -#endif -} - -WTF_ATTRIBUTE_PRINTF(1, 2) -static void printf_stderr_common(const char* format, ...) -{ - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); -} - -static void printCallSite(const char* file, int line, const char* function) -{ -#if OS(WIN) && !OS(WINCE) && defined _DEBUG - _CrtDbgReport(_CRT_WARN, file, line, NULL, "%s\n", function); -#else - printf_stderr_common("(%s:%d %s)\n", file, line, function); -#endif -} - -void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion) -{ - if (assertion) - printf_stderr_common("ASSERTION FAILED: %s\n", assertion); - else - printf_stderr_common("SHOULD NEVER BE REACHED\n"); - printCallSite(file, line, function); -} - -void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) -{ - printf_stderr_common("ASSERTION FAILED: "); - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - printf_stderr_common("\n%s\n", assertion); - printCallSite(file, line, function); -} - -void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion) -{ - printf_stderr_common("ARGUMENT BAD: %s, %s\n", argName, assertion); - printCallSite(file, line, function); -} - -void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) -{ - printf_stderr_common("FATAL ERROR: "); - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - printf_stderr_common("\n"); - printCallSite(file, line, function); -} - -void WTFReportError(const char* file, int line, const char* function, const char* format, ...) -{ - printf_stderr_common("ERROR: "); - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - printf_stderr_common("\n"); - printCallSite(file, line, function); -} - -void WTFLog(WTFLogChannel* channel, const char* format, ...) -{ - if (channel->state != WTFLogChannelOn) - return; - - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - if (format[strlen(format) - 1] != '\n') - printf_stderr_common("\n"); -} - -void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) -{ - if (channel->state != WTFLogChannelOn) - return; - - va_list args; - va_start(args, format); - vprintf_stderr_common(format, args); - va_end(args); - if (format[strlen(format) - 1] != '\n') - printf_stderr_common("\n"); - printCallSite(file, line, function); -} - -} // extern "C" diff --git a/JavaScriptCore/wtf/Assertions.h b/JavaScriptCore/wtf/Assertions.h deleted file mode 100644 index 3f3af72..0000000 --- a/JavaScriptCore/wtf/Assertions.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_Assertions_h -#define WTF_Assertions_h - -/* - no namespaces because this file has to be includable from C and Objective-C - - Note, this file uses many GCC extensions, but it should be compatible with - C, Objective C, C++, and Objective C++. - - For non-debug builds, everything is disabled by default. - Defining any of the symbols explicitly prevents this from having any effect. - - MSVC7 note: variadic macro support was added in MSVC8, so for now we disable - those macros in MSVC7. For more info, see the MSDN document on variadic - macros here: - - http://msdn2.microsoft.com/en-us/library/ms177415(VS.80).aspx -*/ - -#include "Platform.h" - -#include <stddef.h> - -#if !COMPILER(MSVC) -#include <inttypes.h> -#endif - -#if OS(SYMBIAN) -#include <e32def.h> -#include <e32debug.h> -#endif - -#if PLATFORM(BREWMP) -#include <AEEError.h> -#include <AEEdbg.h> -#endif - -#ifdef NDEBUG -/* Disable ASSERT* macros in release mode. */ -#define ASSERTIONS_DISABLED_DEFAULT 1 -#else -#define ASSERTIONS_DISABLED_DEFAULT 0 -#endif - -#if COMPILER(MSVC7_OR_LOWER) || COMPILER(WINSCW) -#define HAVE_VARIADIC_MACRO 0 -#else -#define HAVE_VARIADIC_MACRO 1 -#endif - -#ifndef ASSERT_DISABLED -#define ASSERT_DISABLED ASSERTIONS_DISABLED_DEFAULT -#endif - -#ifndef ASSERT_MSG_DISABLED -#if HAVE(VARIADIC_MACRO) -#define ASSERT_MSG_DISABLED ASSERTIONS_DISABLED_DEFAULT -#else -#define ASSERT_MSG_DISABLED 1 -#endif -#endif - -#ifndef ASSERT_ARG_DISABLED -#define ASSERT_ARG_DISABLED ASSERTIONS_DISABLED_DEFAULT -#endif - -#ifndef FATAL_DISABLED -#if HAVE(VARIADIC_MACRO) -#define FATAL_DISABLED ASSERTIONS_DISABLED_DEFAULT -#else -#define FATAL_DISABLED 1 -#endif -#endif - -#ifndef ERROR_DISABLED -#if HAVE(VARIADIC_MACRO) -#define ERROR_DISABLED ASSERTIONS_DISABLED_DEFAULT -#else -#define ERROR_DISABLED 1 -#endif -#endif - -#ifndef LOG_DISABLED -#if HAVE(VARIADIC_MACRO) -#define LOG_DISABLED ASSERTIONS_DISABLED_DEFAULT -#else -#define LOG_DISABLED 1 -#endif -#endif - -#if COMPILER(GCC) -#define WTF_PRETTY_FUNCTION __PRETTY_FUNCTION__ -#else -#define WTF_PRETTY_FUNCTION __FUNCTION__ -#endif - -/* WTF logging functions can process %@ in the format string to log a NSObject* but the printf format attribute - emits a warning when %@ is used in the format string. Until <rdar://problem/5195437> is resolved we can't include - the attribute when being used from Objective-C code in case it decides to use %@. */ -#if COMPILER(GCC) && !defined(__OBJC__) -#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) __attribute__((__format__(printf, formatStringArgument, extraArguments))) -#else -#define WTF_ATTRIBUTE_PRINTF(formatStringArgument, extraArguments) -#endif - -/* These helper functions are always declared, but not necessarily always defined if the corresponding function is disabled. */ - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { WTFLogChannelOff, WTFLogChannelOn } WTFLogChannelState; - -typedef struct { - unsigned mask; - const char *defaultName; - WTFLogChannelState state; -} WTFLogChannel; - -void WTFReportAssertionFailure(const char* file, int line, const char* function, const char* assertion); -void WTFReportAssertionFailureWithMessage(const char* file, int line, const char* function, const char* assertion, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); -void WTFReportArgumentAssertionFailure(const char* file, int line, const char* function, const char* argName, const char* assertion); -void WTFReportFatalError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5); -void WTFReportError(const char* file, int line, const char* function, const char* format, ...) WTF_ATTRIBUTE_PRINTF(4, 5); -void WTFLog(WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(2, 3); -void WTFLogVerbose(const char* file, int line, const char* function, WTFLogChannel* channel, const char* format, ...) WTF_ATTRIBUTE_PRINTF(5, 6); - -#ifdef __cplusplus -} -#endif - -/* CRASH() - Raises a fatal error resulting in program termination and triggering either the debugger or the crash reporter. - - Use CRASH() in response to known, unrecoverable errors like out-of-memory. - Macro is enabled in both debug and release mode. - To test for unknown errors and verify assumptions, use ASSERT instead, to avoid impacting performance in release builds. - - Signals are ignored by the crash reporter on OS X so we must do better. -*/ -#ifndef CRASH -#if OS(SYMBIAN) -#define CRASH() do { \ - __DEBUGGER(); \ - User::Panic(_L("Webkit CRASH"),0); \ - } while(false) -#elif PLATFORM(BREWMP) -#define CRASH() do { \ - dbg_Message("WebKit CRASH", DBG_MSG_LEVEL_FATAL, __FILE__, __LINE__); \ - *(int *)(uintptr_t)0xbbadbeef = 0; \ - ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ -} while(false) -#else -#define CRASH() do { \ - *(int *)(uintptr_t)0xbbadbeef = 0; \ - ((void(*)())0)(); /* More reliable, but doesn't say BBADBEEF */ \ -} while(false) -#endif -#endif - -/* ASSERT, ASSERT_NOT_REACHED, ASSERT_UNUSED - - These macros are compiled out of release builds. - Expressions inside them are evaluated in debug builds only. -*/ - -#if OS(WINCE) && !PLATFORM(TORCHMOBILE) -/* FIXME: We include this here only to avoid a conflict with the ASSERT macro. */ -#include <windows.h> -#undef min -#undef max -#undef ERROR -#endif - -#if OS(WINDOWS) || OS(SYMBIAN) -/* FIXME: Change to use something other than ASSERT to avoid this conflict with the underlying platform */ -#undef ASSERT -#endif - -#if PLATFORM(BREWMP) -/* FIXME: We include this here only to avoid a conflict with the COMPILE_ASSERT macro. */ -#include <AEEClassIDs.h> - -/* FIXME: Change to use something other than COMPILE_ASSERT to avoid this conflict with the underlying platform */ -#undef COMPILE_ASSERT -#endif - -#if ASSERT_DISABLED - -#define ASSERT(assertion) ((void)0) -#define ASSERT_NOT_REACHED() ((void)0) - -#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT) -template<typename T> -inline void assertUnused(T& x) { (void)x; } -#define ASSERT_UNUSED(variable, assertion) (assertUnused(variable)) -#else -#define ASSERT_UNUSED(variable, assertion) ((void)variable) -#endif - -#else - -#define ASSERT(assertion) do \ - if (!(assertion)) { \ - WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion); \ - CRASH(); \ - } \ -while (0) - -#define ASSERT_NOT_REACHED() do { \ - WTFReportAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, 0); \ - CRASH(); \ -} while (0) - -#define ASSERT_UNUSED(variable, assertion) ASSERT(assertion) - -#endif - -/* ASSERT_WITH_MESSAGE */ - -#if COMPILER(MSVC7_OR_LOWER) -#define ASSERT_WITH_MESSAGE(assertion) ((void)0) -#elif COMPILER(WINSCW) -#define ASSERT_WITH_MESSAGE(assertion, arg...) ((void)0) -#elif ASSERT_MSG_DISABLED -#define ASSERT_WITH_MESSAGE(assertion, ...) ((void)0) -#else -#define ASSERT_WITH_MESSAGE(assertion, ...) do \ - if (!(assertion)) { \ - WTFReportAssertionFailureWithMessage(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #assertion, __VA_ARGS__); \ - CRASH(); \ - } \ -while (0) -#endif - - -/* ASSERT_ARG */ - -#if ASSERT_ARG_DISABLED - -#define ASSERT_ARG(argName, assertion) ((void)0) - -#else - -#define ASSERT_ARG(argName, assertion) do \ - if (!(assertion)) { \ - WTFReportArgumentAssertionFailure(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, #argName, #assertion); \ - CRASH(); \ - } \ -while (0) - -#endif - -/* COMPILE_ASSERT */ -#ifndef COMPILE_ASSERT -#define COMPILE_ASSERT(exp, name) typedef int dummy##name [(exp) ? 1 : -1] -#endif - -/* FATAL */ - -#if COMPILER(MSVC7_OR_LOWER) -#define FATAL() ((void)0) -#elif COMPILER(WINSCW) -#define FATAL(arg...) ((void)0) -#elif FATAL_DISABLED -#define FATAL(...) ((void)0) -#else -#define FATAL(...) do { \ - WTFReportFatalError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__); \ - CRASH(); \ -} while (0) -#endif - -/* LOG_ERROR */ - -#if COMPILER(MSVC7_OR_LOWER) -#define LOG_ERROR() ((void)0) -#elif COMPILER(WINSCW) -#define LOG_ERROR(arg...) ((void)0) -#elif ERROR_DISABLED -#define LOG_ERROR(...) ((void)0) -#else -#define LOG_ERROR(...) WTFReportError(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, __VA_ARGS__) -#endif - -/* LOG */ - -#if COMPILER(MSVC7_OR_LOWER) -#define LOG() ((void)0) -#elif COMPILER(WINSCW) -#define LOG(arg...) ((void)0) -#elif LOG_DISABLED -#define LOG(channel, ...) ((void)0) -#else -#define LOG(channel, ...) WTFLog(&JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) -#define JOIN_LOG_CHANNEL_WITH_PREFIX(prefix, channel) JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) -#define JOIN_LOG_CHANNEL_WITH_PREFIX_LEVEL_2(prefix, channel) prefix ## channel -#endif - -/* LOG_VERBOSE */ - -#if COMPILER(MSVC7_OR_LOWER) -#define LOG_VERBOSE(channel) ((void)0) -#elif COMPILER(WINSCW) -#define LOG_VERBOSE(channel, arg...) ((void)0) -#elif LOG_DISABLED -#define LOG_VERBOSE(channel, ...) ((void)0) -#else -#define LOG_VERBOSE(channel, ...) WTFLogVerbose(__FILE__, __LINE__, WTF_PRETTY_FUNCTION, &JOIN_LOG_CHANNEL_WITH_PREFIX(LOG_CHANNEL_PREFIX, channel), __VA_ARGS__) -#endif - -#endif /* WTF_Assertions_h */ diff --git a/JavaScriptCore/wtf/Atomics.h b/JavaScriptCore/wtf/Atomics.h deleted file mode 100644 index 1d190a3..0000000 --- a/JavaScriptCore/wtf/Atomics.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based - * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license - * is virtually identical to the Apple license above but is included here for completeness. - * - * Boost Software License - Version 1.0 - August 17th, 2003 - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef Atomics_h -#define Atomics_h - -#include "Platform.h" - -#if OS(WINDOWS) -#include <windows.h> -#elif OS(DARWIN) -#include <libkern/OSAtomic.h> -#elif OS(ANDROID) -#include <cutils/atomic.h> -#elif COMPILER(GCC) && !OS(SYMBIAN) -#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2)) -#include <ext/atomicity.h> -#else -#include <bits/atomicity.h> -#endif -#endif - -namespace WTF { - -#if OS(WINDOWS) -#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 - -#if COMPILER(MINGW) || COMPILER(MSVC7_OR_LOWER) || OS(WINCE) -inline int atomicIncrement(int* addend) { return InterlockedIncrement(reinterpret_cast<long*>(addend)); } -inline int atomicDecrement(int* addend) { return InterlockedDecrement(reinterpret_cast<long*>(addend)); } -#else -inline int atomicIncrement(int volatile* addend) { return InterlockedIncrement(reinterpret_cast<long volatile*>(addend)); } -inline int atomicDecrement(int volatile* addend) { return InterlockedDecrement(reinterpret_cast<long volatile*>(addend)); } -#endif - -#elif OS(DARWIN) -#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 - -inline int atomicIncrement(int volatile* addend) { return OSAtomicIncrement32Barrier(const_cast<int*>(addend)); } -inline int atomicDecrement(int volatile* addend) { return OSAtomicDecrement32Barrier(const_cast<int*>(addend)); } - -#elif OS(ANDROID) - -inline int atomicIncrement(int volatile* addend) { return android_atomic_inc(addend); } -inline int atomicDecrement(int volatile* addend) { return android_atomic_dec(addend); } - -#elif COMPILER(GCC) && !CPU(SPARC64) && !OS(SYMBIAN) // sizeof(_Atomic_word) != sizeof(int) on sparc64 gcc -#define WTF_USE_LOCKFREE_THREADSAFESHARED 1 - -inline int atomicIncrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, 1) + 1; } -inline int atomicDecrement(int volatile* addend) { return __gnu_cxx::__exchange_and_add(addend, -1) - 1; } - -#endif - -} // namespace WTF - -#if USE(LOCKFREE_THREADSAFESHARED) -using WTF::atomicDecrement; -using WTF::atomicIncrement; -#endif - -#endif // Atomics_h diff --git a/JavaScriptCore/wtf/Bitmap.h b/JavaScriptCore/wtf/Bitmap.h deleted file mode 100644 index 4dd88f6..0000000 --- a/JavaScriptCore/wtf/Bitmap.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ -#ifndef Bitmap_h -#define Bitmap_h - -#include "FixedArray.h" -#include "StdLibExtras.h" - -#include <stdint.h> - -namespace WTF { - -template<size_t size> -class Bitmap { -private: - typedef uint32_t WordType; - -public: - Bitmap(); - - bool get(size_t) const; - void set(size_t); - void clear(size_t); - void clearAll(); - void advanceToNextFreeBit(size_t&) const; - size_t count(size_t = 0) const; - size_t isEmpty() const; - size_t isFull() const; - -private: - static const WordType wordSize = sizeof(WordType) * 8; - static const WordType words = (size + wordSize - 1) / wordSize; - - // the literal '1' is of type signed int. We want to use an unsigned - // version of the correct size when doing the calculations because if - // WordType is larger than int, '1 << 31' will first be sign extended - // and then casted to unsigned, meaning that set(31) when WordType is - // a 64 bit unsigned int would give 0xffff8000 - static const WordType one = 1; - - FixedArray<WordType, words> bits; -}; - -template<size_t size> -inline Bitmap<size>::Bitmap() -{ - clearAll(); -} - -template<size_t size> -inline bool Bitmap<size>::get(size_t n) const -{ - return !!(bits[n / wordSize] & (one << (n % wordSize))); -} - -template<size_t size> -inline void Bitmap<size>::set(size_t n) -{ - bits[n / wordSize] |= (one << (n % wordSize)); -} - -template<size_t size> -inline void Bitmap<size>::clear(size_t n) -{ - bits[n / wordSize] &= ~(one << (n % wordSize)); -} - -template<size_t size> -inline void Bitmap<size>::clearAll() -{ - memset(bits.data(), 0, sizeof(bits)); -} - -template<size_t size> -inline void Bitmap<size>::advanceToNextFreeBit(size_t& start) const -{ - if (!~bits[start / wordSize]) - start = ((start / wordSize) + 1) * wordSize; - else - ++start; -} - -template<size_t size> -inline size_t Bitmap<size>::count(size_t start) const -{ - size_t result = 0; - for ( ; (start % wordSize); ++start) { - if (get(start)) - ++result; - } - for (size_t i = start / wordSize; i < words; ++i) - result += WTF::bitCount(bits[i]); - return result; -} - -template<size_t size> -inline size_t Bitmap<size>::isEmpty() const -{ - for (size_t i = 0; i < words; ++i) - if (bits[i]) - return false; - return true; -} - -template<size_t size> -inline size_t Bitmap<size>::isFull() const -{ - for (size_t i = 0; i < words; ++i) - if (~bits[i]) - return false; - return true; -} - -} -#endif diff --git a/JavaScriptCore/wtf/BumpPointerAllocator.h b/JavaScriptCore/wtf/BumpPointerAllocator.h deleted file mode 100644 index 682283c..0000000 --- a/JavaScriptCore/wtf/BumpPointerAllocator.h +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef BumpPointerAllocator_h -#define BumpPointerAllocator_h - -#include <wtf/PageAllocation.h> - -namespace WTF { - -#define MINIMUM_BUMP_POOL_SIZE 0x1000 - -class BumpPointerPool { -public: - // ensureCapacity will check whether the current pool has capacity to - // allocate 'size' bytes of memory If it does not, it will attempt to - // allocate a new pool (which will be added to this one in a chain). - // - // If allocation fails (out of memory) this method will return null. - // If the return value is non-null, then callers should update any - // references they have to this current (possibly full) BumpPointerPool - // to instead point to the newly returned BumpPointerPool. - BumpPointerPool* ensureCapacity(size_t size) - { - void* allocationEnd = static_cast<char*>(m_current) + size; - ASSERT(allocationEnd > m_current); // check for overflow - if (allocationEnd <= static_cast<void*>(this)) - return this; - return ensureCapacityCrossPool(this, size); - } - - // alloc should only be called after calling ensureCapacity; as such - // alloc will never fail. - void* alloc(size_t size) - { - void* current = m_current; - void* allocationEnd = static_cast<char*>(current) + size; - ASSERT(allocationEnd > current); // check for overflow - ASSERT(allocationEnd <= static_cast<void*>(this)); - m_current = allocationEnd; - return current; - } - - // The dealloc method releases memory allocated using alloc. Memory - // must be released in a LIFO fashion, e.g. if the client calls alloc - // four times, returning pointer A, B, C, D, then the only valid order - // in which these may be deallocaed is D, C, B, A. - // - // The client may optionally skip some deallocations. In the example - // above, it would be valid to only explicitly dealloc C, A (D being - // dealloced along with C, B along with A). - // - // If pointer was not allocated from this pool (or pools) then dealloc - // will CRASH(). Callers should update any references they have to - // this current BumpPointerPool to instead point to the returned - // BumpPointerPool. - BumpPointerPool* dealloc(void* position) - { - if ((position >= m_start) && (position <= static_cast<void*>(this))) { - ASSERT(position <= m_current); - m_current = position; - return this; - } - return deallocCrossPool(this, position); - } - -private: - // Placement operator new, returns the last 'size' bytes of allocation for use as this. - void* operator new(size_t size, const PageAllocation& allocation) - { - ASSERT(size < allocation.size()); - return reinterpret_cast<char*>(reinterpret_cast<intptr_t>(allocation.base()) + allocation.size()) - size; - } - - BumpPointerPool(const PageAllocation& allocation) - : m_current(allocation.base()) - , m_start(allocation.base()) - , m_next(0) - , m_previous(0) - , m_allocation(allocation) - { - } - - static BumpPointerPool* create(size_t minimumCapacity = 0) - { - // Add size of BumpPointerPool object, check for overflow. - minimumCapacity += sizeof(BumpPointerPool); - if (minimumCapacity < sizeof(BumpPointerPool)) - return 0; - - size_t poolSize = MINIMUM_BUMP_POOL_SIZE; - while (poolSize < minimumCapacity) { - poolSize <<= 1; - // The following if check relies on MINIMUM_BUMP_POOL_SIZE being a power of 2! - ASSERT(!(MINIMUM_BUMP_POOL_SIZE & (MINIMUM_BUMP_POOL_SIZE - 1))); - if (!poolSize) - return 0; - } - - PageAllocation allocation = PageAllocation::allocate(poolSize); - if (!!allocation) - return new(allocation) BumpPointerPool(allocation); - return 0; - } - - void shrink() - { - ASSERT(!m_previous); - m_current = m_start; - while (m_next) { - BumpPointerPool* nextNext = m_next->m_next; - m_next->destroy(); - m_next = nextNext; - } - } - - void destroy() - { - m_allocation.deallocate(); - } - - static BumpPointerPool* ensureCapacityCrossPool(BumpPointerPool* previousPool, size_t size) - { - // The pool passed should not have capacity, so we'll start with the next one. - ASSERT(previousPool); - ASSERT((static_cast<char*>(previousPool->m_current) + size) > previousPool->m_current); // check for overflow - ASSERT((static_cast<char*>(previousPool->m_current) + size) > static_cast<void*>(previousPool)); - BumpPointerPool* pool = previousPool->m_next; - - while (true) { - if (!pool) { - // We've run to the end; allocate a new pool. - pool = BumpPointerPool::create(size); - previousPool->m_next = pool; - pool->m_previous = previousPool; - return pool; - } - - // - void* current = pool->m_current; - void* allocationEnd = static_cast<char*>(current) + size; - ASSERT(allocationEnd > current); // check for overflow - if (allocationEnd <= static_cast<void*>(pool)) - return pool; - } - } - - static BumpPointerPool* deallocCrossPool(BumpPointerPool* pool, void* position) - { - // Should only be called if position is not in the current pool. - ASSERT((position < pool->m_start) || (position > static_cast<void*>(pool))); - - while (true) { - // Unwind the current pool to the start, move back in the chain to the previous pool. - pool->m_current = pool->m_start; - pool = pool->m_previous; - - // position was nowhere in the chain! - if (!pool) - CRASH(); - - if ((position >= pool->m_start) && (position <= static_cast<void*>(pool))) { - ASSERT(position <= pool->m_current); - pool->m_current = position; - return pool; - } - } - } - - void* m_current; - void* m_start; - BumpPointerPool* m_next; - BumpPointerPool* m_previous; - PageAllocation m_allocation; - - friend class BumpPointerAllocator; -}; - -// A BumpPointerAllocator manages a set of BumpPointerPool objects, which -// can be used for LIFO (stack like) allocation. -// -// To begin allocating using this class call startAllocator(). The result -// of this method will be null if the initial pool allocation fails, or a -// pointer to a BumpPointerPool object that can be used to perform -// allocations. Whilst running no memory will be released until -// stopAllocator() is called. At this point all allocations made through -// this allocator will be reaped, and underlying memory may be freed. -// -// (In practice we will still hold on to the initial pool to allow allocation -// to be quickly restared, but aditional pools will be freed). -// -// This allocator is non-renetrant, it is encumbant on the clients to ensure -// startAllocator() is not called again until stopAllocator() has been called. -class BumpPointerAllocator { -public: - BumpPointerAllocator() - : m_head(0) - { - } - - ~BumpPointerAllocator() - { - if (m_head) - m_head->destroy(); - } - - BumpPointerPool* startAllocator() - { - if (!m_head) - m_head = BumpPointerPool::create(); - return m_head; - } - - void stopAllocator() - { - if (m_head) - m_head->shrink(); - } - -private: - BumpPointerPool* m_head; -}; - -} - -using WTF::BumpPointerAllocator; - -#endif // BumpPointerAllocator_h diff --git a/JavaScriptCore/wtf/ByteArray.cpp b/JavaScriptCore/wtf/ByteArray.cpp deleted file mode 100644 index 910af59..0000000 --- a/JavaScriptCore/wtf/ByteArray.cpp +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ByteArray.h" -#include "StdLibExtras.h" - -namespace WTF { - -PassRefPtr<ByteArray> ByteArray::create(size_t size) -{ - unsigned char* buffer = new unsigned char[size + OBJECT_OFFSETOF(ByteArray, m_data)]; - ASSERT((reinterpret_cast<size_t>(buffer) & 3) == 0); - return adoptRef(new (buffer) ByteArray(size)); -} - -} diff --git a/JavaScriptCore/wtf/ByteArray.h b/JavaScriptCore/wtf/ByteArray.h deleted file mode 100644 index bdec630..0000000 --- a/JavaScriptCore/wtf/ByteArray.h +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ByteArray_h -#define ByteArray_h - -#include <limits.h> -#include <wtf/PassRefPtr.h> -#include <wtf/Platform.h> -#include <wtf/RefCounted.h> - -namespace WTF { - class ByteArray : public RefCountedBase { - public: - unsigned length() const { return m_size; } - - void set(unsigned index, double value) - { - if (index >= m_size) - return; - if (!(value > 0)) // Clamp NaN to 0 - value = 0; - else if (value > 255) - value = 255; - m_data[index] = static_cast<unsigned char>(value + 0.5); - } - - void set(unsigned index, unsigned char value) - { - if (index >= m_size) - return; - m_data[index] = value; - } - - bool get(unsigned index, unsigned char& result) const - { - if (index >= m_size) - return false; - result = m_data[index]; - return true; - } - - unsigned char get(unsigned index) const - { - ASSERT(index < m_size); - return m_data[index]; - } - - unsigned char* data() { return m_data; } - - void deref() - { - if (derefBase()) { - // We allocated with new unsigned char[] in create(), - // and then used placement new to construct the object. - this->~ByteArray(); - delete[] reinterpret_cast<unsigned char*>(this); - } - } - - static PassRefPtr<ByteArray> create(size_t size); - - private: - ByteArray(size_t size) - : m_size(size) - { - } - size_t m_size; -// MSVC can't handle correctly unsized array. -// warning C4200: nonstandard extension used : zero-sized array in struct/union -// Cannot generate copy-ctor or copy-assignment operator when UDT contains a zero-sized array -#if COMPILER(MSVC) - unsigned char m_data[INT_MAX]; -#else - unsigned char m_data[]; -#endif - }; -} // namespace WTF - -using WTF::ByteArray; - -#endif diff --git a/JavaScriptCore/wtf/CMakeLists.txt b/JavaScriptCore/wtf/CMakeLists.txt deleted file mode 100644 index 98cd7e4..0000000 --- a/JavaScriptCore/wtf/CMakeLists.txt +++ /dev/null @@ -1,52 +0,0 @@ -SET(WTF_SOURCES - Assertions.cpp - ByteArray.cpp - CurrentTime.cpp - DecimalNumber.cpp - FastMalloc.cpp - HashTable.cpp - MainThread.cpp - MD5.cpp - RandomNumber.cpp - RefCountedLeakCounter.cpp - StackBounds.cpp - StringExtras.cpp - Threading.cpp - TypeTraits.cpp - WTFThreadData.cpp - dtoa.cpp - - text/AtomicString.cpp - text/CString.cpp - text/StringBuilder.cpp - text/StringImpl.cpp - text/StringStatics.cpp - text/WTFString.cpp - - unicode/UTF8.cpp -) - -SET(WTF_LIBRARIES -) - -SET(WTF_PORT_FLAGS ) -INCLUDE_IF_EXISTS(${JAVASCRIPTCORE_DIR}/wtf/CMakeLists${PORT}.txt) - -LIST(APPEND WTF_INCLUDE_DIRECTORIES - "${CMAKE_BINARY_DIR}" -) - -WEBKIT_WRAP_SOURCELIST(${WTF_SOURCES}) -INCLUDE_DIRECTORIES(${WTF_INCLUDE_DIRECTORIES}) -ADD_DEFINITIONS(-DBUILDING_WTF) -ADD_LIBRARY(${WTF_LIBRARY_NAME} ${WTF_LIBRARY_TYPE} ${WTF_SOURCES}) -TARGET_LINK_LIBRARIES(${WTF_LIBRARY_NAME} ${WTF_LIBRARIES}) - -IF (WTF_LINK_FLAGS) - ADD_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} LINK_FLAGS "${WTF_LINK_FLAGS}") -ENDIF () - -IF (SHARED_CORE) - SET_TARGET_PROPERTIES(${WTF_LIBRARY_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) - INSTALL(TARGETS ${WTF_LIBRARY_NAME} DESTINATION lib) -ENDIF () diff --git a/JavaScriptCore/wtf/CMakeListsEfl.txt b/JavaScriptCore/wtf/CMakeListsEfl.txt deleted file mode 100644 index e5d8bd7..0000000 --- a/JavaScriptCore/wtf/CMakeListsEfl.txt +++ /dev/null @@ -1,46 +0,0 @@ -IF (ENABLE_FAST_MALLOC) - LIST(APPEND WTF_SOURCES - TCSystemAlloc.cpp - ) -ELSE () - ADD_DEFINITIONS(-DUSE_SYSTEM_MALLOC=1) -ENDIF() - -LIST(APPEND WTF_SOURCES - efl/MainThreadEfl.cpp - - ThreadIdentifierDataPthreads.cpp - ThreadingPthreads.cpp - - unicode/icu/CollatorICU.cpp -) - -IF (ENABLE_GLIB_SUPPORT) - LIST(APPEND WTF_SOURCES - gobject/GOwnPtr.cpp - gobject/GRefPtr.cpp - ) - - LIST(APPEND WTF_INCLUDE_DIRECTORIES - ${Glib_INCLUDE_DIRS} - ${JAVASCRIPTCORE_DIR}/wtf/gobject - ) - - LIST(APPEND WTF_LIBRARIES - ${Glib_LIBRARIES} - ) -ENDIF () - -LIST(APPEND WTF_LIBRARIES - pthread - ${ICU_LIBRARIES} -) - -LIST(APPEND WTF_LINK_FLAGS - ${ECORE_LDFLAGS} -) - -LIST(APPEND WTF_INCLUDE_DIRECTORIES - ${ECORE_INCLUDE_DIRS} - ${JAVASCRIPTCORE_DIR}/wtf/unicode/ -) diff --git a/JavaScriptCore/wtf/CMakeListsWinCE.txt b/JavaScriptCore/wtf/CMakeListsWinCE.txt deleted file mode 100644 index ed38c6f..0000000 --- a/JavaScriptCore/wtf/CMakeListsWinCE.txt +++ /dev/null @@ -1,20 +0,0 @@ -LIST(APPEND WTF_SOURCES - NullPtr.cpp - OSAllocatorWin.cpp - TCSystemAlloc.cpp - ThreadingWin.cpp - ThreadSpecificWin.cpp - - unicode/CollatorDefault.cpp - unicode/wince/UnicodeWinCE.cpp - - win/MainThreadWin.cpp - win/OwnPtrWin.cpp - - ${3RDPARTY_DIR}/ce-compat/ce_time.c - ${3RDPARTY_DIR}/ce-compat/ce_unicode.cpp -) - -LIST(APPEND WTF_LIBRARIES - mmtimer -) diff --git a/JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32 b/JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32 deleted file mode 100644 index 7de0f26..0000000 --- a/JavaScriptCore/wtf/CONTRIBUTORS.pthreads-win32 +++ /dev/null @@ -1,137 +0,0 @@ -This is a copy of CONTRIBUTORS file for the Pthreads-win32 library, downloaded -from http://sourceware.org/cgi-bin/cvsweb.cgi/~checkout~/pthreads/CONTRIBUTORS?rev=1.32&cvsroot=pthreads-win32 - -Included here to compliment the Pthreads-win32 license header in wtf/ThreadingWin.cpp file. -WebKit is using derived sources of ThreadCondition code from Pthreads-win32. - -------------------------------------------------------------------------------- - -Contributors (in approximate order of appearance) - -[See also the ChangeLog file where individuals are -attributed in log entries. Likewise in the FAQ file.] - -Ben Elliston bje at cygnus dot com - Initiated the project; - setup the project infrastructure (CVS, web page, etc.); - early prototype routines. -Ross Johnson rpj at callisto dot canberra dot edu dot au - early prototype routines; - ongoing project coordination/maintenance; - implementation of spin locks and barriers; - various enhancements; - bug fixes; - documentation; - testsuite. -Robert Colquhoun rjc at trump dot net dot au - Early bug fixes. -John E. Bossom John dot Bossom at cognos dot com - Contributed substantial original working implementation; - bug fixes; - ongoing guidance and standards interpretation. -Anders Norlander anorland at hem2 dot passagen dot se - Early enhancements and runtime checking for supported - Win32 routines. -Tor Lillqvist tml at iki dot fi - General enhancements; - early bug fixes to condition variables. -Scott Lightner scott at curriculum dot com - Bug fix. -Kevin Ruland Kevin dot Ruland at anheuser-busch dot com - Various bug fixes. -Mike Russo miker at eai dot com - Bug fix. -Mark E. Armstrong avail at pacbell dot net - Bug fixes. -Lorin Hochstein lmh at xiphos dot ca - general bug fixes; bug fixes to condition variables. -Peter Slacik Peter dot Slacik at tatramed dot sk - Bug fixes. -Mumit Khan khan at xraylith dot wisc dot edu - Fixes to work with Mingw32. -Milan Gardian mg at tatramed dot sk - Bug fixes and reports/analyses of obscure problems. -Aurelio Medina aureliom at crt dot com - First implementation of read-write locks. -Graham Dumpleton Graham dot Dumpleton at ra dot pad dot otc dot telstra dot com dot au - Bug fix in condition variables. -Tristan Savatier tristan at mpegtv dot com - WinCE port. -Erik Hensema erik at hensema dot xs4all dot nl - Bug fixes. -Rich Peters rpeters at micro-magic dot com -Todd Owen towen at lucidcalm dot dropbear dot id dot au - Bug fixes to dll loading. -Jason Nye jnye at nbnet dot nb dot ca - Implementation of async cancelation. -Fred Forester fforest at eticomm dot net -Kevin D. Clark kclark at cabletron dot com -David Baggett dmb at itasoftware dot com - Bug fixes. -Paul Redondo paul at matchvision dot com -Scott McCaskill scott at 3dfx dot com - Bug fixes. -Jef Gearhart jgearhart at tpssys dot com - Bug fix. -Arthur Kantor akantor at bexusa dot com - Mutex enhancements. -Steven Reddie smr at essemer dot com dot au - Bug fix. -Alexander Terekhov TEREKHOV at de dot ibm dot com - Re-implemented and improved read-write locks; - (with Louis Thomas) re-implemented and improved - condition variables; - enhancements to semaphores; - enhancements to mutexes; - new mutex implementation in 'futex' style; - suggested a robust implementation of pthread_once - similar to that implemented by V.Kliathcko; - system clock change handling re CV timeouts; - bug fixes. -Thomas Pfaff tpfaff at gmx dot net - Changes to make C version usable with C++ applications; - re-implemented mutex routines to avoid Win32 mutexes - and TryEnterCriticalSection; - procedure to fix Mingw32 thread-safety issues. -Franco Bez franco dot bez at gmx dot de - procedure to fix Mingw32 thread-safety issues. -Louis Thomas lthomas at arbitrade dot com - (with Alexander Terekhov) re-implemented and improved - condition variables. -David Korn dgk at research dot att dot com - Ported to UWIN. -Phil Frisbie, Jr. phil at hawksoft dot com - Bug fix. -Ralf Brese Ralf dot Brese at pdb4 dot siemens dot de - Bug fix. -prionx at juno dot com prionx at juno dot com - Bug fixes. -Max Woodbury mtew at cds dot duke dot edu - POSIX versioning conditionals; - reduced namespace pollution; - idea to separate routines to reduce statically - linked image sizes. -Rob Fanner rfanner at stonethree dot com - Bug fix. -Michael Johnson michaelj at maine dot rr dot com - Bug fix. -Nicolas Barry boozai at yahoo dot com - Bug fixes. -Piet van Bruggen pietvb at newbridges dot nl - Bug fix. -Makoto Kato raven at oldskool dot jp - AMD64 port. -Panagiotis E. Hadjidoukas peh at hpclab dot ceid dot upatras dot gr - Contributed the QueueUserAPCEx package which - makes preemptive async cancelation possible. -Will Bryant will dot bryant at ecosm dot com - Borland compiler patch and makefile. -Anuj Goyal anuj dot goyal at gmail dot com - Port to Digital Mars compiler. -Gottlob Frege gottlobfrege at gmail dot com - re-implemented pthread_once (version 2) - (pthread_once cancellation added by rpj). -Vladimir Kliatchko vladimir at kliatchko dot com - reimplemented pthread_once with the same form - as described by A.Terekhov (later version 2); - implementation of MCS (Mellor-Crummey/Scott) locks.
\ No newline at end of file diff --git a/JavaScriptCore/wtf/Complex.h b/JavaScriptCore/wtf/Complex.h deleted file mode 100644 index 40fe56a..0000000 --- a/JavaScriptCore/wtf/Complex.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_Complex_h -#define WTF_Complex_h - -#include <complex> -#include <wtf/MathExtras.h> - -namespace WTF { - -typedef std::complex<double> Complex; - -inline Complex complexFromMagnitudePhase(double magnitude, double phase) -{ - return Complex(magnitude * cos(phase), magnitude * sin(phase)); -} - -} // namespace WTF - -using WTF::Complex; -using WTF::complexFromMagnitudePhase; - -#endif // WTF_Complex_h diff --git a/JavaScriptCore/wtf/CrossThreadRefCounted.h b/JavaScriptCore/wtf/CrossThreadRefCounted.h deleted file mode 100644 index 0c0e997..0000000 --- a/JavaScriptCore/wtf/CrossThreadRefCounted.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CrossThreadRefCounted_h -#define CrossThreadRefCounted_h - -#include "PassRefPtr.h" -#include "RefCounted.h" -#include "Threading.h" - -namespace WTF { - - // Used to allowing sharing data across classes and threads (like ThreadedSafeShared). - // - // Why not just use ThreadSafeShared? - // ThreadSafeShared can have a significant perf impact when used in low level classes - // (like UString) that get ref/deref'ed a lot. This class has the benefit of doing fast ref - // counts like RefPtr whenever possible, but it has the downside that you need to copy it - // to use it on another thread. - // - // Is this class threadsafe? - // While each instance of the class is not threadsafe, the copied instance is threadsafe - // with respect to the original and any other copies. The underlying m_data is jointly - // owned by the original instance and all copies. - template<class T> - class CrossThreadRefCounted : public Noncopyable { - public: - static PassRefPtr<CrossThreadRefCounted<T> > create(T* data) - { - return adoptRef(new CrossThreadRefCounted<T>(data, 0)); - } - - // Used to make an instance that can be used on another thread. - PassRefPtr<CrossThreadRefCounted<T> > crossThreadCopy(); - - void ref(); - void deref(); - T* release(); - - bool isShared() const - { - return !m_refCounter.hasOneRef() || (m_threadSafeRefCounter && !m_threadSafeRefCounter->hasOneRef()); - } - - private: - CrossThreadRefCounted(T* data, ThreadSafeSharedBase* threadedCounter) - : m_threadSafeRefCounter(threadedCounter) - , m_data(data) -#ifndef NDEBUG - , m_threadId(0) -#endif - { - // We use RefCountedBase in an unusual way here, so get rid of the requirement - // that adoptRef be called on it. - m_refCounter.relaxAdoptionRequirement(); - } - - ~CrossThreadRefCounted() - { - if (!m_threadSafeRefCounter) - delete m_data; - } - - void threadSafeDeref(); - -#ifndef NDEBUG - bool isOwnedByCurrentThread() const { return !m_threadId || m_threadId == currentThread(); } -#endif - - RefCountedBase m_refCounter; - ThreadSafeSharedBase* m_threadSafeRefCounter; - T* m_data; -#ifndef NDEBUG - ThreadIdentifier m_threadId; -#endif - }; - - template<class T> - void CrossThreadRefCounted<T>::ref() - { - ASSERT(isOwnedByCurrentThread()); - m_refCounter.ref(); -#ifndef NDEBUG - // Store the threadId as soon as the ref count gets to 2. - // The class gets created with a ref count of 1 and then passed - // to another thread where to ref count get increased. This - // is a heuristic but it seems to always work and has helped - // find some bugs. - if (!m_threadId && m_refCounter.refCount() == 2) - m_threadId = currentThread(); -#endif - } - - template<class T> - void CrossThreadRefCounted<T>::deref() - { - ASSERT(isOwnedByCurrentThread()); - if (m_refCounter.derefBase()) { - threadSafeDeref(); - delete this; - } else { -#ifndef NDEBUG - // Clear the threadId when the ref goes to 1 because it - // is safe to be passed to another thread at this point. - if (m_threadId && m_refCounter.refCount() == 1) - m_threadId = 0; -#endif - } - } - - template<class T> - T* CrossThreadRefCounted<T>::release() - { - ASSERT(!isShared()); - - T* data = m_data; - m_data = 0; - return data; - } - - template<class T> - PassRefPtr<CrossThreadRefCounted<T> > CrossThreadRefCounted<T>::crossThreadCopy() - { - ASSERT(isOwnedByCurrentThread()); - if (m_threadSafeRefCounter) - m_threadSafeRefCounter->ref(); - else - m_threadSafeRefCounter = new ThreadSafeSharedBase(2); - - return adoptRef(new CrossThreadRefCounted<T>(m_data, m_threadSafeRefCounter)); - } - - - template<class T> - void CrossThreadRefCounted<T>::threadSafeDeref() - { - if (m_threadSafeRefCounter && m_threadSafeRefCounter->derefBase()) { - delete m_threadSafeRefCounter; - m_threadSafeRefCounter = 0; - } - } -} // namespace WTF - -using WTF::CrossThreadRefCounted; - -#endif // CrossThreadRefCounted_h diff --git a/JavaScriptCore/wtf/CurrentTime.cpp b/JavaScriptCore/wtf/CurrentTime.cpp deleted file mode 100644 index 56724cb..0000000 --- a/JavaScriptCore/wtf/CurrentTime.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2008 Google Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "CurrentTime.h" - -#if OS(WINDOWS) - -// Windows is first since we want to use hires timers, despite PLATFORM(CF) -// being defined. -// If defined, WIN32_LEAN_AND_MEAN disables timeBeginPeriod/timeEndPeriod. -#undef WIN32_LEAN_AND_MEAN -#include <windows.h> -#include <math.h> -#include <stdint.h> -#include <time.h> - -#if USE(QUERY_PERFORMANCE_COUNTER) -#if OS(WINCE) -extern "C" time_t mktime(struct tm *t); -#else -#include <sys/timeb.h> -#include <sys/types.h> -#endif -#endif - -#elif PLATFORM(GTK) -#include <glib.h> -#elif PLATFORM(WX) -#include <wx/datetime.h> -#elif PLATFORM(BREWMP) -#include <AEEStdLib.h> -#else -#include <sys/time.h> -#endif - -#if PLATFORM(CHROMIUM) -#error Chromium uses a different timer implementation -#endif - -namespace WTF { - -const double msPerSecond = 1000.0; - -#if OS(WINDOWS) - -#if USE(QUERY_PERFORMANCE_COUNTER) - -static LARGE_INTEGER qpcFrequency; -static bool syncedTime; - -static double highResUpTime() -{ - // We use QPC, but only after sanity checking its result, due to bugs: - // http://support.microsoft.com/kb/274323 - // http://support.microsoft.com/kb/895980 - // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)." - - static LARGE_INTEGER qpcLast; - static DWORD tickCountLast; - static bool inited; - - LARGE_INTEGER qpc; - QueryPerformanceCounter(&qpc); - DWORD tickCount = GetTickCount(); - - if (inited) { - __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart; - __int64 tickCountElapsed; - if (tickCount >= tickCountLast) - tickCountElapsed = (tickCount - tickCountLast); - else { -#if COMPILER(MINGW) - __int64 tickCountLarge = tickCount + 0x100000000ULL; -#else - __int64 tickCountLarge = tickCount + 0x100000000I64; -#endif - tickCountElapsed = tickCountLarge - tickCountLast; - } - - // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms. - // (500ms value is from http://support.microsoft.com/kb/274323) - __int64 diff = tickCountElapsed - qpcElapsed; - if (diff > 500 || diff < -500) - syncedTime = false; - } else - inited = true; - - qpcLast = qpc; - tickCountLast = tickCount; - - return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart); -} - -static double lowResUTCTime() -{ -#if OS(WINCE) - SYSTEMTIME systemTime; - GetSystemTime(&systemTime); - struct tm tmtime; - tmtime.tm_year = systemTime.wYear - 1900; - tmtime.tm_mon = systemTime.wMonth - 1; - tmtime.tm_mday = systemTime.wDay; - tmtime.tm_wday = systemTime.wDayOfWeek; - tmtime.tm_hour = systemTime.wHour; - tmtime.tm_min = systemTime.wMinute; - tmtime.tm_sec = systemTime.wSecond; - time_t timet = mktime(&tmtime); - return timet * msPerSecond + systemTime.wMilliseconds; -#else - struct _timeb timebuffer; - _ftime(&timebuffer); - return timebuffer.time * msPerSecond + timebuffer.millitm; -#endif -} - -static bool qpcAvailable() -{ - static bool available; - static bool checked; - - if (checked) - return available; - - available = QueryPerformanceFrequency(&qpcFrequency); - checked = true; - return available; -} - -double currentTime() -{ - // Use a combination of ftime and QueryPerformanceCounter. - // ftime returns the information we want, but doesn't have sufficient resolution. - // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals. - // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter - // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift. - static double syncLowResUTCTime; - static double syncHighResUpTime; - static double lastUTCTime; - - double lowResTime = lowResUTCTime(); - - if (!qpcAvailable()) - return lowResTime / 1000.0; - - double highResTime = highResUpTime(); - - if (!syncedTime) { - timeBeginPeriod(1); // increase time resolution around low-res time getter - syncLowResUTCTime = lowResTime = lowResUTCTime(); - timeEndPeriod(1); // restore time resolution - syncHighResUpTime = highResTime; - syncedTime = true; - } - - double highResElapsed = highResTime - syncHighResUpTime; - double utc = syncLowResUTCTime + highResElapsed; - - // force a clock re-sync if we've drifted - double lowResElapsed = lowResTime - syncLowResUTCTime; - const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy - if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec) - syncedTime = false; - - // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur) - const double backwardTimeLimit = 2000.0; - if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit) - return lastUTCTime / 1000.0; - lastUTCTime = utc; - return utc / 1000.0; -} - -#else - -static double currentSystemTime() -{ - FILETIME ft; - GetCurrentFT(&ft); - - // As per Windows documentation for FILETIME, copy the resulting FILETIME structure to a - // ULARGE_INTEGER structure using memcpy (using memcpy instead of direct assignment can - // prevent alignment faults on 64-bit Windows). - - ULARGE_INTEGER t; - memcpy(&t, &ft, sizeof(t)); - - // Windows file times are in 100s of nanoseconds. - // To convert to seconds, we have to divide by 10,000,000, which is more quickly - // done by multiplying by 0.0000001. - - // Between January 1, 1601 and January 1, 1970, there were 369 complete years, - // of which 89 were leap years (1700, 1800, and 1900 were not leap years). - // That is a total of 134774 days, which is 11644473600 seconds. - - return t.QuadPart * 0.0000001 - 11644473600.0; -} - -double currentTime() -{ - static bool init = false; - static double lastTime; - static DWORD lastTickCount; - if (!init) { - lastTime = currentSystemTime(); - lastTickCount = GetTickCount(); - init = true; - return lastTime; - } - - DWORD tickCountNow = GetTickCount(); - DWORD elapsed = tickCountNow - lastTickCount; - double timeNow = lastTime + (double)elapsed / 1000.; - if (elapsed >= 0x7FFFFFFF) { - lastTime = timeNow; - lastTickCount = tickCountNow; - } - return timeNow; -} - -#endif // USE(QUERY_PERFORMANCE_COUNTER) - -#elif PLATFORM(GTK) - -// Note: GTK on Windows will pick up the PLATFORM(WIN) implementation above which provides -// better accuracy compared with Windows implementation of g_get_current_time: -// (http://www.google.com/codesearch/p?hl=en#HHnNRjks1t0/glib-2.5.2/glib/gmain.c&q=g_get_current_time). -// Non-Windows GTK builds could use gettimeofday() directly but for the sake of consistency lets use GTK function. -double currentTime() -{ - GTimeVal now; - g_get_current_time(&now); - return static_cast<double>(now.tv_sec) + static_cast<double>(now.tv_usec / 1000000.0); -} - -#elif PLATFORM(WX) - -double currentTime() -{ - wxDateTime now = wxDateTime::UNow(); - return (double)now.GetTicks() + (double)(now.GetMillisecond() / 1000.0); -} - -#elif PLATFORM(BREWMP) - -// GETUTCSECONDS returns the number of seconds since 1980/01/06 00:00:00 UTC, -// and GETTIMEMS returns the number of milliseconds that have elapsed since the last -// occurrence of 00:00:00 local time. -// We can combine GETUTCSECONDS and GETTIMEMS to calculate the number of milliseconds -// since 1970/01/01 00:00:00 UTC. -double currentTime() -{ - // diffSeconds is the number of seconds from 1970/01/01 to 1980/01/06 - const unsigned diffSeconds = 315964800; - return static_cast<double>(diffSeconds + GETUTCSECONDS() + ((GETTIMEMS() % 1000) / msPerSecond)); -} - -#else - -double currentTime() -{ - struct timeval now; - gettimeofday(&now, 0); - return now.tv_sec + now.tv_usec / 1000000.0; -} - -#endif - -} // namespace WTF diff --git a/JavaScriptCore/wtf/CurrentTime.h b/JavaScriptCore/wtf/CurrentTime.h deleted file mode 100644 index 7119656..0000000 --- a/JavaScriptCore/wtf/CurrentTime.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2008 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CurrentTime_h -#define CurrentTime_h - -#include <time.h> - -namespace WTF { - - // Returns the current UTC time in seconds, counted from January 1, 1970. - // Precision varies depending on platform but is usually as good or better - // than a millisecond. - double currentTime(); - - // Same thing, in milliseconds. - inline double currentTimeMS() - { - return currentTime() * 1000.0; - } - - inline void getLocalTime(const time_t* localTime, struct tm* localTM) - { - #if COMPILER(MSVC7_OR_LOWER) || COMPILER(MINGW) || OS(WINCE) - *localTM = *localtime(localTime); - #elif COMPILER(MSVC) - localtime_s(localTM, localTime); - #else - localtime_r(localTime, localTM); - #endif - } - -} // namespace WTF - -using WTF::currentTime; -using WTF::currentTimeMS; -using WTF::getLocalTime; - -#endif // CurrentTime_h - diff --git a/JavaScriptCore/wtf/DateMath.cpp b/JavaScriptCore/wtf/DateMath.cpp deleted file mode 100644 index 8873352..0000000 --- a/JavaScriptCore/wtf/DateMath.cpp +++ /dev/null @@ -1,1154 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * Copyright (C) 2010 &yet, LLC. (nate@andyet.net) - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Alternatively, the contents of this file may be used under the terms - * of either the Mozilla Public License Version 1.1, found at - * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public - * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html - * (the "GPL"), in which case the provisions of the MPL or the GPL are - * applicable instead of those above. If you wish to allow use of your - * version of this file only under the terms of one of those two - * licenses (the MPL or the GPL) and not to allow others to use your - * version of this file under the LGPL, indicate your decision by - * deletingthe provisions above and replace them with the notice and - * other provisions required by the MPL or the GPL, as the case may be. - * If you do not delete the provisions above, a recipient may use your - * version of this file under any of the LGPL, the MPL or the GPL. - - * Copyright 2006-2008 the V8 project authors. All rights reserved. - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "DateMath.h" - -#include "Assertions.h" -#include "ASCIICType.h" -#include "CurrentTime.h" -#include "MathExtras.h" -#include "StdLibExtras.h" -#include "StringExtras.h" - -#include <algorithm> -#include <limits.h> -#include <limits> -#include <stdint.h> -#include <time.h> - - -#if HAVE(ERRNO_H) -#include <errno.h> -#endif - -#if OS(WINCE) -extern "C" size_t strftime(char * const s, const size_t maxsize, const char * const format, const struct tm * const t); -extern "C" struct tm * localtime(const time_t *timer); -#endif - -#if HAVE(SYS_TIME_H) -#include <sys/time.h> -#endif - -#if HAVE(SYS_TIMEB_H) -#include <sys/timeb.h> -#endif - -#if USE(JSC) -#include "CallFrame.h" -#endif - -#define NaN std::numeric_limits<double>::quiet_NaN() - -using namespace WTF; - -namespace WTF { - -/* Constants */ - -static const double minutesPerDay = 24.0 * 60.0; -static const double secondsPerDay = 24.0 * 60.0 * 60.0; -static const double secondsPerYear = 24.0 * 60.0 * 60.0 * 365.0; - -static const double usecPerSec = 1000000.0; - -static const double maxUnixTime = 2145859200.0; // 12/31/2037 -// ECMAScript asks not to support for a date of which total -// millisecond value is larger than the following value. -// See 15.9.1.14 of ECMA-262 5th edition. -static const double maxECMAScriptTime = 8.64E15; - -// Day of year for the first day of each month, where index 0 is January, and day 0 is January 1. -// First for non-leap years, then for leap years. -static const int firstDayOfMonth[2][12] = { - {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}, - {0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335} -}; - -static inline bool isLeapYear(int year) -{ - if (year % 4 != 0) - return false; - if (year % 400 == 0) - return true; - if (year % 100 == 0) - return false; - return true; -} - -static inline int daysInYear(int year) -{ - return 365 + isLeapYear(year); -} - -static inline double daysFrom1970ToYear(int year) -{ - // The Gregorian Calendar rules for leap years: - // Every fourth year is a leap year. 2004, 2008, and 2012 are leap years. - // However, every hundredth year is not a leap year. 1900 and 2100 are not leap years. - // Every four hundred years, there's a leap year after all. 2000 and 2400 are leap years. - - static const int leapDaysBefore1971By4Rule = 1970 / 4; - static const int excludedLeapDaysBefore1971By100Rule = 1970 / 100; - static const int leapDaysBefore1971By400Rule = 1970 / 400; - - const double yearMinusOne = year - 1; - const double yearsToAddBy4Rule = floor(yearMinusOne / 4.0) - leapDaysBefore1971By4Rule; - const double yearsToExcludeBy100Rule = floor(yearMinusOne / 100.0) - excludedLeapDaysBefore1971By100Rule; - const double yearsToAddBy400Rule = floor(yearMinusOne / 400.0) - leapDaysBefore1971By400Rule; - - return 365.0 * (year - 1970) + yearsToAddBy4Rule - yearsToExcludeBy100Rule + yearsToAddBy400Rule; -} - -static inline double msToDays(double ms) -{ - return floor(ms / msPerDay); -} - -int msToYear(double ms) -{ - int approxYear = static_cast<int>(floor(ms / (msPerDay * 365.2425)) + 1970); - double msFromApproxYearTo1970 = msPerDay * daysFrom1970ToYear(approxYear); - if (msFromApproxYearTo1970 > ms) - return approxYear - 1; - if (msFromApproxYearTo1970 + msPerDay * daysInYear(approxYear) <= ms) - return approxYear + 1; - return approxYear; -} - -int dayInYear(double ms, int year) -{ - return static_cast<int>(msToDays(ms) - daysFrom1970ToYear(year)); -} - -static inline double msToMilliseconds(double ms) -{ - double result = fmod(ms, msPerDay); - if (result < 0) - result += msPerDay; - return result; -} - -// 0: Sunday, 1: Monday, etc. -static inline int msToWeekDay(double ms) -{ - int wd = (static_cast<int>(msToDays(ms)) + 4) % 7; - if (wd < 0) - wd += 7; - return wd; -} - -static inline int msToSeconds(double ms) -{ - double result = fmod(floor(ms / msPerSecond), secondsPerMinute); - if (result < 0) - result += secondsPerMinute; - return static_cast<int>(result); -} - -static inline int msToMinutes(double ms) -{ - double result = fmod(floor(ms / msPerMinute), minutesPerHour); - if (result < 0) - result += minutesPerHour; - return static_cast<int>(result); -} - -static inline int msToHours(double ms) -{ - double result = fmod(floor(ms/msPerHour), hoursPerDay); - if (result < 0) - result += hoursPerDay; - return static_cast<int>(result); -} - -int monthFromDayInYear(int dayInYear, bool leapYear) -{ - const int d = dayInYear; - int step; - - if (d < (step = 31)) - return 0; - step += (leapYear ? 29 : 28); - if (d < step) - return 1; - if (d < (step += 31)) - return 2; - if (d < (step += 30)) - return 3; - if (d < (step += 31)) - return 4; - if (d < (step += 30)) - return 5; - if (d < (step += 31)) - return 6; - if (d < (step += 31)) - return 7; - if (d < (step += 30)) - return 8; - if (d < (step += 31)) - return 9; - if (d < (step += 30)) - return 10; - return 11; -} - -static inline bool checkMonth(int dayInYear, int& startDayOfThisMonth, int& startDayOfNextMonth, int daysInThisMonth) -{ - startDayOfThisMonth = startDayOfNextMonth; - startDayOfNextMonth += daysInThisMonth; - return (dayInYear <= startDayOfNextMonth); -} - -int dayInMonthFromDayInYear(int dayInYear, bool leapYear) -{ - const int d = dayInYear; - int step; - int next = 30; - - if (d <= next) - return d + 1; - const int daysInFeb = (leapYear ? 29 : 28); - if (checkMonth(d, step, next, daysInFeb)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - if (checkMonth(d, step, next, 31)) - return d - step; - if (checkMonth(d, step, next, 30)) - return d - step; - step = next; - return d - step; -} - -static inline int monthToDayInYear(int month, bool isLeapYear) -{ - return firstDayOfMonth[isLeapYear][month]; -} - -static inline double timeToMS(double hour, double min, double sec, double ms) -{ - return (((hour * minutesPerHour + min) * secondsPerMinute + sec) * msPerSecond + ms); -} - -double dateToDaysFrom1970(int year, int month, int day) -{ - year += month / 12; - - month %= 12; - if (month < 0) { - month += 12; - --year; - } - - double yearday = floor(daysFrom1970ToYear(year)); - ASSERT((year >= 1970 && yearday >= 0) || (year < 1970 && yearday < 0)); - int monthday = monthToDayInYear(month, isLeapYear(year)); - - return yearday + monthday + day - 1; -} - -// There is a hard limit at 2038 that we currently do not have a workaround -// for (rdar://problem/5052975). -static inline int maximumYearForDST() -{ - return 2037; -} - -static inline int minimumYearForDST() -{ - // Because of the 2038 issue (see maximumYearForDST) if the current year is - // greater than the max year minus 27 (2010), we want to use the max year - // minus 27 instead, to ensure there is a range of 28 years that all years - // can map to. - return std::min(msToYear(jsCurrentTime()), maximumYearForDST() - 27) ; -} - -/* - * Find an equivalent year for the one given, where equivalence is deterined by - * the two years having the same leapness and the first day of the year, falling - * on the same day of the week. - * - * This function returns a year between this current year and 2037, however this - * function will potentially return incorrect results if the current year is after - * 2010, (rdar://problem/5052975), if the year passed in is before 1900 or after - * 2100, (rdar://problem/5055038). - */ -int equivalentYearForDST(int year) -{ - // It is ok if the cached year is not the current year as long as the rules - // for DST did not change between the two years; if they did the app would need - // to be restarted. - static int minYear = minimumYearForDST(); - int maxYear = maximumYearForDST(); - - int difference; - if (year > maxYear) - difference = minYear - year; - else if (year < minYear) - difference = maxYear - year; - else - return year; - - int quotient = difference / 28; - int product = (quotient) * 28; - - year += product; - ASSERT((year >= minYear && year <= maxYear) || (product - year == static_cast<int>(NaN))); - return year; -} - -int32_t calculateUTCOffset() -{ -#if PLATFORM(BREWMP) - time_t localTime = static_cast<time_t>(currentTime()); -#else - time_t localTime = time(0); -#endif - tm localt; - getLocalTime(&localTime, &localt); - - // Get the difference between this time zone and UTC on the 1st of January of this year. - localt.tm_sec = 0; - localt.tm_min = 0; - localt.tm_hour = 0; - localt.tm_mday = 1; - localt.tm_mon = 0; - // Not setting localt.tm_year! - localt.tm_wday = 0; - localt.tm_yday = 0; - localt.tm_isdst = 0; -#if HAVE(TM_GMTOFF) - localt.tm_gmtoff = 0; -#endif -#if HAVE(TM_ZONE) - localt.tm_zone = 0; -#endif - -#if HAVE(TIMEGM) - time_t utcOffset = timegm(&localt) - mktime(&localt); -#else - // Using a canned date of 01/01/2009 on platforms with weaker date-handling foo. - localt.tm_year = 109; - time_t utcOffset = 1230768000 - mktime(&localt); -#endif - - return static_cast<int32_t>(utcOffset * 1000); -} - -/* - * Get the DST offset for the time passed in. - */ -static double calculateDSTOffsetSimple(double localTimeSeconds, double utcOffset) -{ - if (localTimeSeconds > maxUnixTime) - localTimeSeconds = maxUnixTime; - else if (localTimeSeconds < 0) // Go ahead a day to make localtime work (does not work with 0) - localTimeSeconds += secondsPerDay; - - //input is UTC so we have to shift back to local time to determine DST thus the + getUTCOffset() - double offsetTime = (localTimeSeconds * msPerSecond) + utcOffset; - - // Offset from UTC but doesn't include DST obviously - int offsetHour = msToHours(offsetTime); - int offsetMinute = msToMinutes(offsetTime); - - // FIXME: time_t has a potential problem in 2038 - time_t localTime = static_cast<time_t>(localTimeSeconds); - - tm localTM; - getLocalTime(&localTime, &localTM); - - double diff = ((localTM.tm_hour - offsetHour) * secondsPerHour) + ((localTM.tm_min - offsetMinute) * 60); - - if (diff < 0) - diff += secondsPerDay; - - return (diff * msPerSecond); -} - -// Get the DST offset, given a time in UTC -double calculateDSTOffset(double ms, double utcOffset) -{ - // On Mac OS X, the call to localtime (see calculateDSTOffsetSimple) will return historically accurate - // DST information (e.g. New Zealand did not have DST from 1946 to 1974) however the JavaScript - // standard explicitly dictates that historical information should not be considered when - // determining DST. For this reason we shift away from years that localtime can handle but would - // return historically accurate information. - int year = msToYear(ms); - int equivalentYear = equivalentYearForDST(year); - if (year != equivalentYear) { - bool leapYear = isLeapYear(year); - int dayInYearLocal = dayInYear(ms, year); - int dayInMonth = dayInMonthFromDayInYear(dayInYearLocal, leapYear); - int month = monthFromDayInYear(dayInYearLocal, leapYear); - double day = dateToDaysFrom1970(equivalentYear, month, dayInMonth); - ms = (day * msPerDay) + msToMilliseconds(ms); - } - - return calculateDSTOffsetSimple(ms / msPerSecond, utcOffset); -} - -void initializeDates() -{ -#ifndef NDEBUG - static bool alreadyInitialized; - ASSERT(!alreadyInitialized); - alreadyInitialized = true; -#endif - - equivalentYearForDST(2000); // Need to call once to initialize a static used in this function. -} - -static inline double ymdhmsToSeconds(long year, int mon, int day, int hour, int minute, double second) -{ - double days = (day - 32075) - + floor(1461 * (year + 4800.0 + (mon - 14) / 12) / 4) - + 367 * (mon - 2 - (mon - 14) / 12 * 12) / 12 - - floor(3 * ((year + 4900.0 + (mon - 14) / 12) / 100) / 4) - - 2440588; - return ((days * hoursPerDay + hour) * minutesPerHour + minute) * secondsPerMinute + second; -} - -// We follow the recommendation of RFC 2822 to consider all -// obsolete time zones not listed here equivalent to "-0000". -static const struct KnownZone { -#if !OS(WINDOWS) - const -#endif - char tzName[4]; - int tzOffset; -} known_zones[] = { - { "UT", 0 }, - { "GMT", 0 }, - { "EST", -300 }, - { "EDT", -240 }, - { "CST", -360 }, - { "CDT", -300 }, - { "MST", -420 }, - { "MDT", -360 }, - { "PST", -480 }, - { "PDT", -420 } -}; - -inline static void skipSpacesAndComments(const char*& s) -{ - int nesting = 0; - char ch; - while ((ch = *s)) { - if (!isASCIISpace(ch)) { - if (ch == '(') - nesting++; - else if (ch == ')' && nesting > 0) - nesting--; - else if (nesting == 0) - break; - } - s++; - } -} - -// returns 0-11 (Jan-Dec); -1 on failure -static int findMonth(const char* monthStr) -{ - ASSERT(monthStr); - char needle[4]; - for (int i = 0; i < 3; ++i) { - if (!*monthStr) - return -1; - needle[i] = static_cast<char>(toASCIILower(*monthStr++)); - } - needle[3] = '\0'; - const char *haystack = "janfebmaraprmayjunjulaugsepoctnovdec"; - const char *str = strstr(haystack, needle); - if (str) { - int position = static_cast<int>(str - haystack); - if (position % 3 == 0) - return position / 3; - } - return -1; -} - -static bool parseLong(const char* string, char** stopPosition, int base, long* result) -{ - *result = strtol(string, stopPosition, base); - // Avoid the use of errno as it is not available on Windows CE - if (string == *stopPosition || *result == LONG_MIN || *result == LONG_MAX) - return false; - return true; -} - -double parseES5DateFromNullTerminatedCharacters(const char* dateString) -{ - // This parses a date of the form defined in ECMA-262-5, section 15.9.1.15 - // (similar to RFC 3339 / ISO 8601: YYYY-MM-DDTHH:mm:ss[.sss]Z). - // In most cases it is intentionally strict (e.g. correct field widths, no stray whitespace). - - static const long daysPerMonth[12] = { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; - - const char* currentPosition = dateString; - char* postParsePosition; - - // This is a bit more lenient on the year string than ES5 specifies: - // instead of restricting to 4 digits (or 6 digits with mandatory +/-), - // it accepts any integer value. Consider this an implementation fallback. - long year; - if (!parseLong(currentPosition, &postParsePosition, 10, &year)) - return NaN; - if (*postParsePosition != '-') - return NaN; - currentPosition = postParsePosition + 1; - - long month; - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &month)) - return NaN; - if (*postParsePosition != '-' || (postParsePosition - currentPosition) != 2) - return NaN; - currentPosition = postParsePosition + 1; - - long day; - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &day)) - return NaN; - if (*postParsePosition != 'T' || (postParsePosition - currentPosition) != 2) - return NaN; - currentPosition = postParsePosition + 1; - - long hours; - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &hours)) - return NaN; - if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) - return NaN; - currentPosition = postParsePosition + 1; - - long minutes; - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &minutes)) - return NaN; - if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) - return NaN; - currentPosition = postParsePosition + 1; - - long intSeconds; - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &intSeconds)) - return NaN; - if ((postParsePosition - currentPosition) != 2) - return NaN; - - double seconds = intSeconds; - if (*postParsePosition == '.') { - currentPosition = postParsePosition + 1; - - // In ECMA-262-5 it's a bit unclear if '.' can be present without milliseconds, but - // a reasonable interpretation guided by the given examples and RFC 3339 says "no". - // We check the next character to avoid reading +/- timezone hours after an invalid decimal. - if (!isASCIIDigit(*currentPosition)) - return NaN; - - // We are more lenient than ES5 by accepting more or less than 3 fraction digits. - long fracSeconds; - if (!parseLong(currentPosition, &postParsePosition, 10, &fracSeconds)) - return NaN; - - long numFracDigits = postParsePosition - currentPosition; - seconds += fracSeconds * pow(10.0, static_cast<double>(-numFracDigits)); - } - currentPosition = postParsePosition; - - // A few of these checks could be done inline above, but since many of them are interrelated - // we would be sacrificing readability to "optimize" the (presumably less common) failure path. - if (month < 1 || month > 12) - return NaN; - if (day < 1 || day > daysPerMonth[month - 1]) - return NaN; - if (month == 2 && day > 28 && !isLeapYear(year)) - return NaN; - if (hours < 0 || hours > 24) - return NaN; - if (hours == 24 && (minutes || seconds)) - return NaN; - if (minutes < 0 || minutes > 59) - return NaN; - if (seconds < 0 || seconds >= 61) - return NaN; - if (seconds > 60) { - // Discard leap seconds by clamping to the end of a minute. - seconds = 60; - } - - long timeZoneSeconds = 0; - if (*currentPosition != 'Z') { - bool tzNegative; - if (*currentPosition == '-') - tzNegative = true; - else if (*currentPosition == '+') - tzNegative = false; - else - return NaN; - currentPosition += 1; - - long tzHours; - long tzHoursAbs; - long tzMinutes; - - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &tzHours)) - return NaN; - if (*postParsePosition != ':' || (postParsePosition - currentPosition) != 2) - return NaN; - tzHoursAbs = abs(tzHours); - currentPosition = postParsePosition + 1; - - if (!isASCIIDigit(*currentPosition)) - return NaN; - if (!parseLong(currentPosition, &postParsePosition, 10, &tzMinutes)) - return NaN; - if ((postParsePosition - currentPosition) != 2) - return NaN; - currentPosition = postParsePosition; - - if (tzHoursAbs > 24) - return NaN; - if (tzMinutes < 0 || tzMinutes > 59) - return NaN; - - timeZoneSeconds = 60 * (tzMinutes + (60 * tzHoursAbs)); - if (tzNegative) - timeZoneSeconds = -timeZoneSeconds; - } else { - currentPosition += 1; - } - if (*currentPosition) - return NaN; - - double dateSeconds = ymdhmsToSeconds(year, month, day, hours, minutes, seconds) - timeZoneSeconds; - return dateSeconds * msPerSecond; -} - -// Odd case where 'exec' is allowed to be 0, to accomodate a caller in WebCore. -static double parseDateFromNullTerminatedCharacters(const char* dateString, bool& haveTZ, int& offset) -{ - haveTZ = false; - offset = 0; - - // This parses a date in the form: - // Tuesday, 09-Nov-99 23:12:40 GMT - // or - // Sat, 01-Jan-2000 08:00:00 GMT - // or - // Sat, 01 Jan 2000 08:00:00 GMT - // or - // 01 Jan 99 22:00 +0100 (exceptions in rfc822/rfc2822) - // ### non RFC formats, added for Javascript: - // [Wednesday] January 09 1999 23:12:40 GMT - // [Wednesday] January 09 23:12:40 GMT 1999 - // - // We ignore the weekday. - - // Skip leading space - skipSpacesAndComments(dateString); - - long month = -1; - const char *wordStart = dateString; - // Check contents of first words if not number - while (*dateString && !isASCIIDigit(*dateString)) { - if (isASCIISpace(*dateString) || *dateString == '(') { - if (dateString - wordStart >= 3) - month = findMonth(wordStart); - skipSpacesAndComments(dateString); - wordStart = dateString; - } else - dateString++; - } - - // Missing delimiter between month and day (like "January29")? - if (month == -1 && wordStart != dateString) - month = findMonth(wordStart); - - skipSpacesAndComments(dateString); - - if (!*dateString) - return NaN; - - // ' 09-Nov-99 23:12:40 GMT' - char* newPosStr; - long day; - if (!parseLong(dateString, &newPosStr, 10, &day)) - return NaN; - dateString = newPosStr; - - if (!*dateString) - return NaN; - - if (day < 0) - return NaN; - - long year = 0; - if (day > 31) { - // ### where is the boundary and what happens below? - if (*dateString != '/') - return NaN; - // looks like a YYYY/MM/DD date - if (!*++dateString) - return NaN; - year = day; - if (!parseLong(dateString, &newPosStr, 10, &month)) - return NaN; - month -= 1; - dateString = newPosStr; - if (*dateString++ != '/' || !*dateString) - return NaN; - if (!parseLong(dateString, &newPosStr, 10, &day)) - return NaN; - dateString = newPosStr; - } else if (*dateString == '/' && month == -1) { - dateString++; - // This looks like a MM/DD/YYYY date, not an RFC date. - month = day - 1; // 0-based - if (!parseLong(dateString, &newPosStr, 10, &day)) - return NaN; - if (day < 1 || day > 31) - return NaN; - dateString = newPosStr; - if (*dateString == '/') - dateString++; - if (!*dateString) - return NaN; - } else { - if (*dateString == '-') - dateString++; - - skipSpacesAndComments(dateString); - - if (*dateString == ',') - dateString++; - - if (month == -1) { // not found yet - month = findMonth(dateString); - if (month == -1) - return NaN; - - while (*dateString && *dateString != '-' && *dateString != ',' && !isASCIISpace(*dateString)) - dateString++; - - if (!*dateString) - return NaN; - - // '-99 23:12:40 GMT' - if (*dateString != '-' && *dateString != '/' && *dateString != ',' && !isASCIISpace(*dateString)) - return NaN; - dateString++; - } - } - - if (month < 0 || month > 11) - return NaN; - - // '99 23:12:40 GMT' - if (year <= 0 && *dateString) { - if (!parseLong(dateString, &newPosStr, 10, &year)) - return NaN; - } - - // Don't fail if the time is missing. - long hour = 0; - long minute = 0; - long second = 0; - if (!*newPosStr) - dateString = newPosStr; - else { - // ' 23:12:40 GMT' - if (!(isASCIISpace(*newPosStr) || *newPosStr == ',')) { - if (*newPosStr != ':') - return NaN; - // There was no year; the number was the hour. - year = -1; - } else { - // in the normal case (we parsed the year), advance to the next number - dateString = ++newPosStr; - skipSpacesAndComments(dateString); - } - - parseLong(dateString, &newPosStr, 10, &hour); - // Do not check for errno here since we want to continue - // even if errno was set becasue we are still looking - // for the timezone! - - // Read a number? If not, this might be a timezone name. - if (newPosStr != dateString) { - dateString = newPosStr; - - if (hour < 0 || hour > 23) - return NaN; - - if (!*dateString) - return NaN; - - // ':12:40 GMT' - if (*dateString++ != ':') - return NaN; - - if (!parseLong(dateString, &newPosStr, 10, &minute)) - return NaN; - dateString = newPosStr; - - if (minute < 0 || minute > 59) - return NaN; - - // ':40 GMT' - if (*dateString && *dateString != ':' && !isASCIISpace(*dateString)) - return NaN; - - // seconds are optional in rfc822 + rfc2822 - if (*dateString ==':') { - dateString++; - - if (!parseLong(dateString, &newPosStr, 10, &second)) - return NaN; - dateString = newPosStr; - - if (second < 0 || second > 59) - return NaN; - } - - skipSpacesAndComments(dateString); - - if (strncasecmp(dateString, "AM", 2) == 0) { - if (hour > 12) - return NaN; - if (hour == 12) - hour = 0; - dateString += 2; - skipSpacesAndComments(dateString); - } else if (strncasecmp(dateString, "PM", 2) == 0) { - if (hour > 12) - return NaN; - if (hour != 12) - hour += 12; - dateString += 2; - skipSpacesAndComments(dateString); - } - } - } - - // Don't fail if the time zone is missing. - // Some websites omit the time zone (4275206). - if (*dateString) { - if (strncasecmp(dateString, "GMT", 3) == 0 || strncasecmp(dateString, "UTC", 3) == 0) { - dateString += 3; - haveTZ = true; - } - - if (*dateString == '+' || *dateString == '-') { - long o; - if (!parseLong(dateString, &newPosStr, 10, &o)) - return NaN; - dateString = newPosStr; - - if (o < -9959 || o > 9959) - return NaN; - - int sgn = (o < 0) ? -1 : 1; - o = labs(o); - if (*dateString != ':') { - offset = ((o / 100) * 60 + (o % 100)) * sgn; - } else { // GMT+05:00 - long o2; - if (!parseLong(dateString, &newPosStr, 10, &o2)) - return NaN; - dateString = newPosStr; - offset = (o * 60 + o2) * sgn; - } - haveTZ = true; - } else { - for (size_t i = 0; i < WTF_ARRAY_LENGTH(known_zones); ++i) { - if (0 == strncasecmp(dateString, known_zones[i].tzName, strlen(known_zones[i].tzName))) { - offset = known_zones[i].tzOffset; - dateString += strlen(known_zones[i].tzName); - haveTZ = true; - break; - } - } - } - } - - skipSpacesAndComments(dateString); - - if (*dateString && year == -1) { - if (!parseLong(dateString, &newPosStr, 10, &year)) - return NaN; - dateString = newPosStr; - } - - skipSpacesAndComments(dateString); - - // Trailing garbage - if (*dateString) - return NaN; - - // Y2K: Handle 2 digit years. - if (year >= 0 && year < 100) { - if (year < 50) - year += 2000; - else - year += 1900; - } - - return ymdhmsToSeconds(year, month + 1, day, hour, minute, second) * msPerSecond; -} - -double parseDateFromNullTerminatedCharacters(const char* dateString) -{ - bool haveTZ; - int offset; - double ms = parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset); - if (isnan(ms)) - return NaN; - - // fall back to local timezone - if (!haveTZ) { - double utcOffset = calculateUTCOffset(); - double dstOffset = calculateDSTOffset(ms, utcOffset); - offset = static_cast<int>((utcOffset + dstOffset) / msPerMinute); - } - return ms - (offset * msPerMinute); -} - -double timeClip(double t) -{ - if (!isfinite(t)) - return NaN; - if (fabs(t) > maxECMAScriptTime) - return NaN; - return trunc(t); -} -} // namespace WTF - -#if USE(JSC) -namespace JSC { - -// Get the DST offset for the time passed in. -// -// NOTE: The implementation relies on the fact that no time zones have -// more than one daylight savings offset change per month. -// If this function is called with NaN it returns NaN. -static double getDSTOffset(ExecState* exec, double ms, double utcOffset) -{ - DSTOffsetCache& cache = exec->globalData().dstOffsetCache; - double start = cache.start; - double end = cache.end; - - if (start <= ms) { - // If the time fits in the cached interval, return the cached offset. - if (ms <= end) return cache.offset; - - // Compute a possible new interval end. - double newEnd = end + cache.increment; - - if (ms <= newEnd) { - double endOffset = calculateDSTOffset(newEnd, utcOffset); - if (cache.offset == endOffset) { - // If the offset at the end of the new interval still matches - // the offset in the cache, we grow the cached time interval - // and return the offset. - cache.end = newEnd; - cache.increment = msPerMonth; - return endOffset; - } else { - double offset = calculateDSTOffset(ms, utcOffset); - if (offset == endOffset) { - // The offset at the given time is equal to the offset at the - // new end of the interval, so that means that we've just skipped - // the point in time where the DST offset change occurred. Updated - // the interval to reflect this and reset the increment. - cache.start = ms; - cache.end = newEnd; - cache.increment = msPerMonth; - } else { - // The interval contains a DST offset change and the given time is - // before it. Adjust the increment to avoid a linear search for - // the offset change point and change the end of the interval. - cache.increment /= 3; - cache.end = ms; - } - // Update the offset in the cache and return it. - cache.offset = offset; - return offset; - } - } - } - - // Compute the DST offset for the time and shrink the cache interval - // to only contain the time. This allows fast repeated DST offset - // computations for the same time. - double offset = calculateDSTOffset(ms, utcOffset); - cache.offset = offset; - cache.start = ms; - cache.end = ms; - cache.increment = msPerMonth; - return offset; -} - -/* - * Get the difference in milliseconds between this time zone and UTC (GMT) - * NOT including DST. - */ -double getUTCOffset(ExecState* exec) -{ - double utcOffset = exec->globalData().cachedUTCOffset; - if (!isnan(utcOffset)) - return utcOffset; - exec->globalData().cachedUTCOffset = calculateUTCOffset(); - return exec->globalData().cachedUTCOffset; -} - -double gregorianDateTimeToMS(ExecState* exec, const GregorianDateTime& t, double milliSeconds, bool inputIsUTC) -{ - double day = dateToDaysFrom1970(t.year + 1900, t.month, t.monthDay); - double ms = timeToMS(t.hour, t.minute, t.second, milliSeconds); - double result = (day * WTF::msPerDay) + ms; - - if (!inputIsUTC) { // convert to UTC - double utcOffset = getUTCOffset(exec); - result -= utcOffset; - result -= getDSTOffset(exec, result, utcOffset); - } - - return result; -} - -// input is UTC -void msToGregorianDateTime(ExecState* exec, double ms, bool outputIsUTC, GregorianDateTime& tm) -{ - double dstOff = 0.0; - double utcOff = 0.0; - if (!outputIsUTC) { - utcOff = getUTCOffset(exec); - dstOff = getDSTOffset(exec, ms, utcOff); - ms += dstOff + utcOff; - } - - const int year = msToYear(ms); - tm.second = msToSeconds(ms); - tm.minute = msToMinutes(ms); - tm.hour = msToHours(ms); - tm.weekDay = msToWeekDay(ms); - tm.yearDay = dayInYear(ms, year); - tm.monthDay = dayInMonthFromDayInYear(tm.yearDay, isLeapYear(year)); - tm.month = monthFromDayInYear(tm.yearDay, isLeapYear(year)); - tm.year = year - 1900; - tm.isDST = dstOff != 0.0; - tm.utcOffset = static_cast<long>((dstOff + utcOff) / WTF::msPerSecond); - tm.timeZone = nullptr; -} - -double parseDateFromNullTerminatedCharacters(ExecState* exec, const char* dateString) -{ - ASSERT(exec); - bool haveTZ; - int offset; - double ms = WTF::parseDateFromNullTerminatedCharacters(dateString, haveTZ, offset); - if (isnan(ms)) - return NaN; - - // fall back to local timezone - if (!haveTZ) { - double utcOffset = getUTCOffset(exec); - double dstOffset = getDSTOffset(exec, ms, utcOffset); - offset = static_cast<int>((utcOffset + dstOffset) / WTF::msPerMinute); - } - return ms - (offset * WTF::msPerMinute); -} - -} // namespace JSC -#endif // USE(JSC) diff --git a/JavaScriptCore/wtf/DateMath.h b/JavaScriptCore/wtf/DateMath.h deleted file mode 100644 index 8d0d932..0000000 --- a/JavaScriptCore/wtf/DateMath.h +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 1999-2000 Harri Porten (porten@kde.org) - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * Copyright (C) 2010 Research In Motion Limited. All rights reserved. - * - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is Mozilla Communicator client code, released - * March 31, 1998. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1998 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - */ - -#ifndef DateMath_h -#define DateMath_h - -#include <math.h> -#include <string.h> -#include <time.h> -#include <wtf/CurrentTime.h> -#include <wtf/Noncopyable.h> -#include <wtf/OwnArrayPtr.h> -#include <wtf/PassOwnArrayPtr.h> -#include <wtf/UnusedParam.h> - -namespace WTF { -void initializeDates(); -int equivalentYearForDST(int year); - -// Not really math related, but this is currently the only shared place to put these. -double parseES5DateFromNullTerminatedCharacters(const char* dateString); -double parseDateFromNullTerminatedCharacters(const char* dateString); -double timeClip(double); - -inline double jsCurrentTime() -{ - // JavaScript doesn't recognize fractions of a millisecond. - return floor(WTF::currentTimeMS()); -} - -const char * const weekdayName[7] = { "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun" }; -const char * const monthName[12] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - -const double hoursPerDay = 24.0; -const double minutesPerHour = 60.0; -const double secondsPerHour = 60.0 * 60.0; -const double secondsPerMinute = 60.0; -const double msPerSecond = 1000.0; -const double msPerMinute = 60.0 * 1000.0; -const double msPerHour = 60.0 * 60.0 * 1000.0; -const double msPerDay = 24.0 * 60.0 * 60.0 * 1000.0; -const double msPerMonth = 2592000000.0; - -// Returns the number of days from 1970-01-01 to the specified date. -double dateToDaysFrom1970(int year, int month, int day); -int msToYear(double ms); -int dayInYear(double ms, int year); -int monthFromDayInYear(int dayInYear, bool leapYear); -int dayInMonthFromDayInYear(int dayInYear, bool leapYear); - -// Returns offset milliseconds for UTC and DST. -int32_t calculateUTCOffset(); -double calculateDSTOffset(double ms, double utcOffset); - -} // namespace WTF - -using WTF::adoptArrayPtr; -using WTF::dateToDaysFrom1970; -using WTF::dayInMonthFromDayInYear; -using WTF::dayInYear; -using WTF::minutesPerHour; -using WTF::monthFromDayInYear; -using WTF::msPerDay; -using WTF::msPerMinute; -using WTF::msPerSecond; -using WTF::msToYear; -using WTF::secondsPerMinute; -using WTF::parseDateFromNullTerminatedCharacters; -using WTF::calculateUTCOffset; -using WTF::calculateDSTOffset; - -#if USE(JSC) -namespace JSC { -class ExecState; -struct GregorianDateTime; - -void msToGregorianDateTime(ExecState*, double, bool outputIsUTC, GregorianDateTime&); -double gregorianDateTimeToMS(ExecState*, const GregorianDateTime&, double, bool inputIsUTC); -double getUTCOffset(ExecState*); -double parseDateFromNullTerminatedCharacters(ExecState*, const char* dateString); - -// Intentionally overridding the default tm of the system. -// The members of tm differ on various operating systems. -struct GregorianDateTime : Noncopyable { - GregorianDateTime() - : second(0) - , minute(0) - , hour(0) - , weekDay(0) - , monthDay(0) - , yearDay(0) - , month(0) - , year(0) - , isDST(0) - , utcOffset(0) - , timeZone(0) - { - } - - GregorianDateTime(ExecState* exec, const tm& inTm) - : second(inTm.tm_sec) - , minute(inTm.tm_min) - , hour(inTm.tm_hour) - , weekDay(inTm.tm_wday) - , monthDay(inTm.tm_mday) - , yearDay(inTm.tm_yday) - , month(inTm.tm_mon) - , year(inTm.tm_year) - , isDST(inTm.tm_isdst) - { - UNUSED_PARAM(exec); -#if HAVE(TM_GMTOFF) - utcOffset = static_cast<int>(inTm.tm_gmtoff); -#else - utcOffset = static_cast<int>(getUTCOffset(exec) / WTF::msPerSecond + (isDST ? WTF::secondsPerHour : 0)); -#endif - -#if HAVE(TM_ZONE) - int inZoneSize = strlen(inTm.tm_zone) + 1; - timeZone = adoptArrayPtr(new char[inZoneSize]); - strncpy(timeZone.get(), inTm.tm_zone, inZoneSize); -#else - timeZone = nullptr; -#endif - } - - operator tm() const - { - tm ret; - memset(&ret, 0, sizeof(ret)); - - ret.tm_sec = second; - ret.tm_min = minute; - ret.tm_hour = hour; - ret.tm_wday = weekDay; - ret.tm_mday = monthDay; - ret.tm_yday = yearDay; - ret.tm_mon = month; - ret.tm_year = year; - ret.tm_isdst = isDST; - -#if HAVE(TM_GMTOFF) - ret.tm_gmtoff = static_cast<long>(utcOffset); -#endif -#if HAVE(TM_ZONE) - ret.tm_zone = timeZone.get(); -#endif - - return ret; - } - - void copyFrom(const GregorianDateTime& rhs) - { - second = rhs.second; - minute = rhs.minute; - hour = rhs.hour; - weekDay = rhs.weekDay; - monthDay = rhs.monthDay; - yearDay = rhs.yearDay; - month = rhs.month; - year = rhs.year; - isDST = rhs.isDST; - utcOffset = rhs.utcOffset; - if (rhs.timeZone) { - int inZoneSize = strlen(rhs.timeZone.get()) + 1; - timeZone = adoptArrayPtr(new char[inZoneSize]); - strncpy(timeZone.get(), rhs.timeZone.get(), inZoneSize); - } else - timeZone = nullptr; - } - - int second; - int minute; - int hour; - int weekDay; - int monthDay; - int yearDay; - int month; - int year; - int isDST; - int utcOffset; - OwnArrayPtr<char> timeZone; -}; - -static inline int gmtoffset(const GregorianDateTime& t) -{ - return t.utcOffset; -} -} // namespace JSC -#endif // USE(JSC) - -#endif // DateMath_h diff --git a/JavaScriptCore/wtf/DecimalNumber.cpp b/JavaScriptCore/wtf/DecimalNumber.cpp deleted file mode 100644 index 70304e2..0000000 --- a/JavaScriptCore/wtf/DecimalNumber.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "DecimalNumber.h" -#include <math.h> -#include <wtf/MathExtras.h> -#include <wtf/text/WTFString.h> - -namespace WTF { - -unsigned DecimalNumber::bufferLengthForStringDecimal() const -{ - unsigned length = 0; - // if the exponent is negative the number decimal representation is of the form: - // [<sign>]0.[<zeros>]<significand> - if (m_exponent < 0) { - if (m_sign) - ++length; - length += 2; // for "0." - length += -m_exponent - 1; - length += m_precision; - return length; - } - - unsigned digitsBeforeDecimalPoint = m_exponent + 1; - - // If the precision is <= than the number of digits to get up to the decimal - // point, then there is no fractional part, number is of the form: - // [<sign>]<significand>[<zeros>] - if (m_precision <= digitsBeforeDecimalPoint) { - if (m_sign) - ++length; - length += m_precision; - length += digitsBeforeDecimalPoint - m_precision; - return length; - } - - // If we get here, number starts before the decimal point, and ends after it, - // as such is of the form: - // [<sign>]<significand-begin>.<significand-end> - if (m_sign) - ++length; - length += digitsBeforeDecimalPoint; - ++length; // for decimal point - length += m_precision - digitsBeforeDecimalPoint; - - return length; -} - -unsigned DecimalNumber::bufferLengthForStringExponential() const -{ - unsigned length = 0; - if (m_sign) - ++length; - - // Add the significand - ++length; - - if (m_precision > 1) { - ++length; // for decimal point - length += m_precision - 1; - } - - // Add "e+" or "e-" - length += 2; - - int exponent = (m_exponent >= 0) ? m_exponent : -m_exponent; - - // Add the exponent - if (exponent >= 100) - ++length; - if (exponent >= 10) - ++length; - ++length; - - return length; -} - -unsigned DecimalNumber::toStringDecimal(UChar* buffer, unsigned bufferLength) const -{ - ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringDecimal()); - - // Should always be at least one digit to add to the string! - ASSERT(m_precision); - UChar* next = buffer; - - // if the exponent is negative the number decimal representation is of the form: - // [<sign>]0.[<zeros>]<significand> - if (m_exponent < 0) { - unsigned zeros = -m_exponent - 1; - - if (m_sign) - *next++ = '-'; - *next++ = '0'; - *next++ = '.'; - for (unsigned i = 0; i < zeros; ++i) - *next++ = '0'; - for (unsigned i = 0; i < m_precision; ++i) - *next++ = m_significand[i]; - - return next - buffer; - } - - unsigned digitsBeforeDecimalPoint = m_exponent + 1; - - // If the precision is <= than the number of digits to get up to the decimal - // point, then there is no fractional part, number is of the form: - // [<sign>]<significand>[<zeros>] - if (m_precision <= digitsBeforeDecimalPoint) { - if (m_sign) - *next++ = '-'; - for (unsigned i = 0; i < m_precision; ++i) - *next++ = m_significand[i]; - for (unsigned i = 0; i < (digitsBeforeDecimalPoint - m_precision); ++i) - *next++ = '0'; - - return next - buffer; - } - - // If we get here, number starts before the decimal point, and ends after it, - // as such is of the form: - // [<sign>]<significand-begin>.<significand-end> - - if (m_sign) - *next++ = '-'; - for (unsigned i = 0; i < digitsBeforeDecimalPoint; ++i) - *next++ = m_significand[i]; - *next++ = '.'; - for (unsigned i = digitsBeforeDecimalPoint; i < m_precision; ++i) - *next++ = m_significand[i]; - - return next - buffer; -} - -unsigned DecimalNumber::toStringExponential(UChar* buffer, unsigned bufferLength) const -{ - ASSERT_UNUSED(bufferLength, bufferLength >= bufferLengthForStringExponential()); - - // Should always be at least one digit to add to the string! - ASSERT(m_precision); - UChar* next = buffer; - - // Add the sign - if (m_sign) - *next++ = '-'; - - // Add the significand - *next++ = m_significand[0]; - if (m_precision > 1) { - *next++ = '.'; - for (unsigned i = 1; i < m_precision; ++i) - *next++ = m_significand[i]; - } - - // Add "e+" or "e-" - *next++ = 'e'; - int exponent; - if (m_exponent >= 0) { - *next++ = '+'; - exponent = m_exponent; - } else { - *next++ = '-'; - exponent = -m_exponent; - } - - // Add the exponent - if (exponent >= 100) - *next++ = '0' + exponent / 100; - if (exponent >= 10) - *next++ = '0' + (exponent % 100) / 10; - *next++ = '0' + exponent % 10; - - return next - buffer; -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/DecimalNumber.h b/JavaScriptCore/wtf/DecimalNumber.h deleted file mode 100644 index c42f00b..0000000 --- a/JavaScriptCore/wtf/DecimalNumber.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef DecimalNumber_h -#define DecimalNumber_h - -#include <math.h> -#include <wtf/dtoa.h> -#include <wtf/MathExtras.h> -#include <wtf/text/WTFString.h> - -namespace WTF { - -enum RoundingSignificantFiguresType { RoundingSignificantFigures }; -enum RoundingDecimalPlacesType { RoundingDecimalPlaces }; - -class DecimalNumber { -public: - DecimalNumber(double d) - { - ASSERT(!isnan(d) && !isinf(d)); - dtoa(m_significand, d, m_sign, m_exponent, m_precision); - - ASSERT(m_precision); - // Zero should always have exponent 0. - ASSERT(m_significand[0] != '0' || !m_exponent); - // No values other than zero should have a leading zero. - ASSERT(m_significand[0] != '0' || m_precision == 1); - // No values other than zero should have trailing zeros. - ASSERT(m_significand[0] == '0' || m_significand[m_precision - 1] != '0'); - } - - DecimalNumber(double d, RoundingSignificantFiguresType, unsigned significantFigures) - { - ASSERT(!isnan(d) && !isinf(d)); - dtoaRoundSF(m_significand, d, significantFigures, m_sign, m_exponent, m_precision); - - ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer)); - while (m_precision < significantFigures) - m_significand[m_precision++] = '0'; - - ASSERT(m_precision); - // Zero should always have exponent 0. - ASSERT(m_significand[0] != '0' || !m_exponent); - } - - DecimalNumber(double d, RoundingDecimalPlacesType, unsigned decimalPlaces) - { - ASSERT(!isnan(d) && !isinf(d)); - dtoaRoundDP(m_significand, d, decimalPlaces, m_sign, m_exponent, m_precision); - - unsigned significantFigures = 1 + m_exponent + decimalPlaces; - ASSERT(significantFigures && significantFigures <= sizeof(DtoaBuffer)); - while (m_precision < significantFigures) - m_significand[m_precision++] = '0'; - - ASSERT(m_precision); - // Zero should always have exponent 0. - ASSERT(m_significand[0] != '0' || !m_exponent); - } - - unsigned bufferLengthForStringDecimal() const; - unsigned bufferLengthForStringExponential() const; - - unsigned toStringDecimal(UChar* buffer, unsigned bufferLength) const; - unsigned toStringExponential(UChar* buffer, unsigned bufferLength) const; - - bool sign() const { return m_sign; } - int exponent() const { return m_exponent; } - const char* significand() const { return m_significand; } // significand contains precision characters, is not null-terminated. - unsigned precision() const { return m_precision; } - -private: - bool m_sign; - int m_exponent; - DtoaBuffer m_significand; - unsigned m_precision; -}; - -} // namespace WTF - -using WTF::DecimalNumber; -using WTF::RoundingSignificantFigures; -using WTF::RoundingDecimalPlaces; - -#endif // DecimalNumber_h diff --git a/JavaScriptCore/wtf/Deque.h b/JavaScriptCore/wtf/Deque.h deleted file mode 100644 index 745e0b6..0000000 --- a/JavaScriptCore/wtf/Deque.h +++ /dev/null @@ -1,678 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_Deque_h -#define WTF_Deque_h - -// FIXME: Could move what Vector and Deque share into a separate file. -// Deque doesn't actually use Vector. - -#include "Vector.h" - -namespace WTF { - - template<typename T> class DequeIteratorBase; - template<typename T> class DequeIterator; - template<typename T> class DequeConstIterator; - template<typename T> class DequeReverseIterator; - template<typename T> class DequeConstReverseIterator; - - template<typename T> - class Deque : public FastAllocBase { - public: - typedef DequeIterator<T> iterator; - typedef DequeConstIterator<T> const_iterator; - typedef DequeReverseIterator<T> reverse_iterator; - typedef DequeConstReverseIterator<T> const_reverse_iterator; - - Deque(); - Deque(const Deque<T>&); - Deque& operator=(const Deque<T>&); - ~Deque(); - - void swap(Deque<T>&); - - size_t size() const { return m_start <= m_end ? m_end - m_start : m_end + m_buffer.capacity() - m_start; } - bool isEmpty() const { return m_start == m_end; } - - iterator begin() { return iterator(this, m_start); } - iterator end() { return iterator(this, m_end); } - const_iterator begin() const { return const_iterator(this, m_start); } - const_iterator end() const { return const_iterator(this, m_end); } - reverse_iterator rbegin() { return reverse_iterator(this, m_end); } - reverse_iterator rend() { return reverse_iterator(this, m_start); } - const_reverse_iterator rbegin() const { return const_reverse_iterator(this, m_end); } - const_reverse_iterator rend() const { return const_reverse_iterator(this, m_start); } - - T& first() { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; } - const T& first() const { ASSERT(m_start != m_end); return m_buffer.buffer()[m_start]; } - T takeFirst(); - - template<typename U> void append(const U&); - template<typename U> void prepend(const U&); - void removeFirst(); - void remove(iterator&); - void remove(const_iterator&); - - void clear(); - - template<typename Predicate> - iterator findIf(Predicate&); - - private: - friend class DequeIteratorBase<T>; - - typedef VectorBuffer<T, 0> Buffer; - typedef VectorTypeOperations<T> TypeOperations; - typedef DequeIteratorBase<T> IteratorBase; - - void remove(size_t position); - void invalidateIterators(); - void destroyAll(); - void checkValidity() const; - void checkIndexValidity(size_t) const; - void expandCapacityIfNeeded(); - void expandCapacity(); - - size_t m_start; - size_t m_end; - Buffer m_buffer; -#ifndef NDEBUG - mutable IteratorBase* m_iterators; -#endif - }; - - template<typename T> - class DequeIteratorBase { - private: - typedef DequeIteratorBase<T> Base; - - protected: - DequeIteratorBase(); - DequeIteratorBase(const Deque<T>*, size_t); - DequeIteratorBase(const Base&); - Base& operator=(const Base&); - ~DequeIteratorBase(); - - void assign(const Base& other) { *this = other; } - - void increment(); - void decrement(); - - T* before() const; - T* after() const; - - bool isEqual(const Base&) const; - - private: - void addToIteratorsList(); - void removeFromIteratorsList(); - void checkValidity() const; - void checkValidity(const Base&) const; - - Deque<T>* m_deque; - size_t m_index; - - friend class Deque<T>; - -#ifndef NDEBUG - mutable DequeIteratorBase* m_next; - mutable DequeIteratorBase* m_previous; -#endif - }; - - template<typename T> - class DequeIterator : public DequeIteratorBase<T> { - private: - typedef DequeIteratorBase<T> Base; - typedef DequeIterator<T> Iterator; - - public: - DequeIterator(Deque<T>* deque, size_t index) : Base(deque, index) { } - - DequeIterator(const Iterator& other) : Base(other) { } - DequeIterator& operator=(const Iterator& other) { Base::assign(other); return *this; } - - T& operator*() const { return *Base::after(); } - T* operator->() const { return Base::after(); } - - bool operator==(const Iterator& other) const { return Base::isEqual(other); } - bool operator!=(const Iterator& other) const { return !Base::isEqual(other); } - - Iterator& operator++() { Base::increment(); return *this; } - // postfix ++ intentionally omitted - Iterator& operator--() { Base::decrement(); return *this; } - // postfix -- intentionally omitted - }; - - template<typename T> - class DequeConstIterator : public DequeIteratorBase<T> { - private: - typedef DequeIteratorBase<T> Base; - typedef DequeConstIterator<T> Iterator; - typedef DequeIterator<T> NonConstIterator; - - public: - DequeConstIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { } - - DequeConstIterator(const Iterator& other) : Base(other) { } - DequeConstIterator(const NonConstIterator& other) : Base(other) { } - DequeConstIterator& operator=(const Iterator& other) { Base::assign(other); return *this; } - DequeConstIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; } - - const T& operator*() const { return *Base::after(); } - const T* operator->() const { return Base::after(); } - - bool operator==(const Iterator& other) const { return Base::isEqual(other); } - bool operator!=(const Iterator& other) const { return !Base::isEqual(other); } - - Iterator& operator++() { Base::increment(); return *this; } - // postfix ++ intentionally omitted - Iterator& operator--() { Base::decrement(); return *this; } - // postfix -- intentionally omitted - }; - - template<typename T> - class DequeReverseIterator : public DequeIteratorBase<T> { - private: - typedef DequeIteratorBase<T> Base; - typedef DequeReverseIterator<T> Iterator; - - public: - DequeReverseIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { } - - DequeReverseIterator(const Iterator& other) : Base(other) { } - DequeReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; } - - T& operator*() const { return *Base::before(); } - T* operator->() const { return Base::before(); } - - bool operator==(const Iterator& other) const { return Base::isEqual(other); } - bool operator!=(const Iterator& other) const { return !Base::isEqual(other); } - - Iterator& operator++() { Base::decrement(); return *this; } - // postfix ++ intentionally omitted - Iterator& operator--() { Base::increment(); return *this; } - // postfix -- intentionally omitted - }; - - template<typename T> - class DequeConstReverseIterator : public DequeIteratorBase<T> { - private: - typedef DequeIteratorBase<T> Base; - typedef DequeConstReverseIterator<T> Iterator; - typedef DequeReverseIterator<T> NonConstIterator; - - public: - DequeConstReverseIterator(const Deque<T>* deque, size_t index) : Base(deque, index) { } - - DequeConstReverseIterator(const Iterator& other) : Base(other) { } - DequeConstReverseIterator(const NonConstIterator& other) : Base(other) { } - DequeConstReverseIterator& operator=(const Iterator& other) { Base::assign(other); return *this; } - DequeConstReverseIterator& operator=(const NonConstIterator& other) { Base::assign(other); return *this; } - - const T& operator*() const { return *Base::before(); } - const T* operator->() const { return Base::before(); } - - bool operator==(const Iterator& other) const { return Base::isEqual(other); } - bool operator!=(const Iterator& other) const { return !Base::isEqual(other); } - - Iterator& operator++() { Base::decrement(); return *this; } - // postfix ++ intentionally omitted - Iterator& operator--() { Base::increment(); return *this; } - // postfix -- intentionally omitted - }; - -#ifdef NDEBUG - template<typename T> inline void Deque<T>::checkValidity() const { } - template<typename T> inline void Deque<T>::checkIndexValidity(size_t) const { } - template<typename T> inline void Deque<T>::invalidateIterators() { } -#else - template<typename T> - void Deque<T>::checkValidity() const - { - if (!m_buffer.capacity()) { - ASSERT(!m_start); - ASSERT(!m_end); - } else { - ASSERT(m_start < m_buffer.capacity()); - ASSERT(m_end < m_buffer.capacity()); - } - } - - template<typename T> - void Deque<T>::checkIndexValidity(size_t index) const - { - ASSERT(index <= m_buffer.capacity()); - if (m_start <= m_end) { - ASSERT(index >= m_start); - ASSERT(index <= m_end); - } else { - ASSERT(index >= m_start || index <= m_end); - } - } - - template<typename T> - void Deque<T>::invalidateIterators() - { - IteratorBase* next; - for (IteratorBase* p = m_iterators; p; p = next) { - next = p->m_next; - p->m_deque = 0; - p->m_next = 0; - p->m_previous = 0; - } - m_iterators = 0; - } -#endif - - template<typename T> - inline Deque<T>::Deque() - : m_start(0) - , m_end(0) -#ifndef NDEBUG - , m_iterators(0) -#endif - { - checkValidity(); - } - - template<typename T> - inline Deque<T>::Deque(const Deque<T>& other) - : m_start(other.m_start) - , m_end(other.m_end) - , m_buffer(other.m_buffer.capacity()) -#ifndef NDEBUG - , m_iterators(0) -#endif - { - const T* otherBuffer = other.m_buffer.buffer(); - if (m_start <= m_end) - TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_end, m_buffer.buffer() + m_start); - else { - TypeOperations::uninitializedCopy(otherBuffer, otherBuffer + m_end, m_buffer.buffer()); - TypeOperations::uninitializedCopy(otherBuffer + m_start, otherBuffer + m_buffer.capacity(), m_buffer.buffer() + m_start); - } - } - - template<typename T> - void deleteAllValues(const Deque<T>& collection) - { - typedef typename Deque<T>::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete *it; - } - - template<typename T> - inline Deque<T>& Deque<T>::operator=(const Deque<T>& other) - { - Deque<T> copy(other); - swap(copy); - return *this; - } - - template<typename T> - inline void Deque<T>::destroyAll() - { - if (m_start <= m_end) - TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_end); - else { - TypeOperations::destruct(m_buffer.buffer(), m_buffer.buffer() + m_end); - TypeOperations::destruct(m_buffer.buffer() + m_start, m_buffer.buffer() + m_buffer.capacity()); - } - } - - template<typename T> - inline Deque<T>::~Deque() - { - checkValidity(); - invalidateIterators(); - destroyAll(); - } - - template<typename T> - inline void Deque<T>::swap(Deque<T>& other) - { - checkValidity(); - other.checkValidity(); - invalidateIterators(); - std::swap(m_start, other.m_start); - std::swap(m_end, other.m_end); - m_buffer.swap(other.m_buffer); - checkValidity(); - other.checkValidity(); - } - - template<typename T> - inline void Deque<T>::clear() - { - checkValidity(); - invalidateIterators(); - destroyAll(); - m_start = 0; - m_end = 0; - checkValidity(); - } - - template<typename T> - template<typename Predicate> - inline DequeIterator<T> Deque<T>::findIf(Predicate& predicate) - { - iterator end_iterator = end(); - for (iterator it = begin(); it != end_iterator; ++it) { - if (predicate(*it)) - return it; - } - return end_iterator; - } - - template<typename T> - inline void Deque<T>::expandCapacityIfNeeded() - { - if (m_start) { - if (m_end + 1 != m_start) - return; - } else if (m_end) { - if (m_end != m_buffer.capacity() - 1) - return; - } else if (m_buffer.capacity()) - return; - - expandCapacity(); - } - - template<typename T> - void Deque<T>::expandCapacity() - { - checkValidity(); - size_t oldCapacity = m_buffer.capacity(); - size_t newCapacity = max(static_cast<size_t>(16), oldCapacity + oldCapacity / 4 + 1); - T* oldBuffer = m_buffer.buffer(); - m_buffer.allocateBuffer(newCapacity); - if (m_start <= m_end) - TypeOperations::move(oldBuffer + m_start, oldBuffer + m_end, m_buffer.buffer() + m_start); - else { - TypeOperations::move(oldBuffer, oldBuffer + m_end, m_buffer.buffer()); - size_t newStart = newCapacity - (oldCapacity - m_start); - TypeOperations::move(oldBuffer + m_start, oldBuffer + oldCapacity, m_buffer.buffer() + newStart); - m_start = newStart; - } - m_buffer.deallocateBuffer(oldBuffer); - checkValidity(); - } - - template<typename T> - inline T Deque<T>::takeFirst() - { - T oldFirst = first(); - removeFirst(); - return oldFirst; - } - - template<typename T> template<typename U> - inline void Deque<T>::append(const U& value) - { - checkValidity(); - expandCapacityIfNeeded(); - new (&m_buffer.buffer()[m_end]) T(value); - if (m_end == m_buffer.capacity() - 1) - m_end = 0; - else - ++m_end; - checkValidity(); - } - - template<typename T> template<typename U> - inline void Deque<T>::prepend(const U& value) - { - checkValidity(); - expandCapacityIfNeeded(); - if (!m_start) - m_start = m_buffer.capacity() - 1; - else - --m_start; - new (&m_buffer.buffer()[m_start]) T(value); - checkValidity(); - } - - template<typename T> - inline void Deque<T>::removeFirst() - { - checkValidity(); - invalidateIterators(); - ASSERT(!isEmpty()); - TypeOperations::destruct(&m_buffer.buffer()[m_start], &m_buffer.buffer()[m_start + 1]); - if (m_start == m_buffer.capacity() - 1) - m_start = 0; - else - ++m_start; - checkValidity(); - } - - template<typename T> - inline void Deque<T>::remove(iterator& it) - { - it.checkValidity(); - remove(it.m_index); - } - - template<typename T> - inline void Deque<T>::remove(const_iterator& it) - { - it.checkValidity(); - remove(it.m_index); - } - - template<typename T> - inline void Deque<T>::remove(size_t position) - { - if (position == m_end) - return; - - checkValidity(); - invalidateIterators(); - - T* buffer = m_buffer.buffer(); - TypeOperations::destruct(&buffer[position], &buffer[position + 1]); - - // Find which segment of the circular buffer contained the remove element, and only move elements in that part. - if (position >= m_start) { - TypeOperations::moveOverlapping(buffer + m_start, buffer + position, buffer + m_start + 1); - m_start = (m_start + 1) % m_buffer.capacity(); - } else { - TypeOperations::moveOverlapping(buffer + position + 1, buffer + m_end, buffer + position); - m_end = (m_end - 1 + m_buffer.capacity()) % m_buffer.capacity(); - } - checkValidity(); - } - -#ifdef NDEBUG - template<typename T> inline void DequeIteratorBase<T>::checkValidity() const { } - template<typename T> inline void DequeIteratorBase<T>::checkValidity(const DequeIteratorBase<T>&) const { } - template<typename T> inline void DequeIteratorBase<T>::addToIteratorsList() { } - template<typename T> inline void DequeIteratorBase<T>::removeFromIteratorsList() { } -#else - template<typename T> - void DequeIteratorBase<T>::checkValidity() const - { - ASSERT(m_deque); - m_deque->checkIndexValidity(m_index); - } - - template<typename T> - void DequeIteratorBase<T>::checkValidity(const Base& other) const - { - checkValidity(); - other.checkValidity(); - ASSERT(m_deque == other.m_deque); - } - - template<typename T> - void DequeIteratorBase<T>::addToIteratorsList() - { - if (!m_deque) - m_next = 0; - else { - m_next = m_deque->m_iterators; - m_deque->m_iterators = this; - if (m_next) - m_next->m_previous = this; - } - m_previous = 0; - } - - template<typename T> - void DequeIteratorBase<T>::removeFromIteratorsList() - { - if (!m_deque) { - ASSERT(!m_next); - ASSERT(!m_previous); - } else { - if (m_next) { - ASSERT(m_next->m_previous == this); - m_next->m_previous = m_previous; - } - if (m_previous) { - ASSERT(m_deque->m_iterators != this); - ASSERT(m_previous->m_next == this); - m_previous->m_next = m_next; - } else { - ASSERT(m_deque->m_iterators == this); - m_deque->m_iterators = m_next; - } - } - m_next = 0; - m_previous = 0; - } -#endif - - template<typename T> - inline DequeIteratorBase<T>::DequeIteratorBase() - : m_deque(0) - { - } - - template<typename T> - inline DequeIteratorBase<T>::DequeIteratorBase(const Deque<T>* deque, size_t index) - : m_deque(const_cast<Deque<T>*>(deque)) - , m_index(index) - { - addToIteratorsList(); - checkValidity(); - } - - template<typename T> - inline DequeIteratorBase<T>::DequeIteratorBase(const Base& other) - : m_deque(other.m_deque) - , m_index(other.m_index) - { - addToIteratorsList(); - checkValidity(); - } - - template<typename T> - inline DequeIteratorBase<T>& DequeIteratorBase<T>::operator=(const Base& other) - { - checkValidity(); - other.checkValidity(); - removeFromIteratorsList(); - - m_deque = other.m_deque; - m_index = other.m_index; - addToIteratorsList(); - checkValidity(); - return *this; - } - - template<typename T> - inline DequeIteratorBase<T>::~DequeIteratorBase() - { -#ifndef NDEBUG - removeFromIteratorsList(); - m_deque = 0; -#endif - } - - template<typename T> - inline bool DequeIteratorBase<T>::isEqual(const Base& other) const - { - checkValidity(other); - return m_index == other.m_index; - } - - template<typename T> - inline void DequeIteratorBase<T>::increment() - { - checkValidity(); - ASSERT(m_index != m_deque->m_end); - ASSERT(m_deque->m_buffer.capacity()); - if (m_index == m_deque->m_buffer.capacity() - 1) - m_index = 0; - else - ++m_index; - checkValidity(); - } - - template<typename T> - inline void DequeIteratorBase<T>::decrement() - { - checkValidity(); - ASSERT(m_index != m_deque->m_start); - ASSERT(m_deque->m_buffer.capacity()); - if (!m_index) - m_index = m_deque->m_buffer.capacity() - 1; - else - --m_index; - checkValidity(); - } - - template<typename T> - inline T* DequeIteratorBase<T>::after() const - { - checkValidity(); - ASSERT(m_index != m_deque->m_end); - return &m_deque->m_buffer.buffer()[m_index]; - } - - template<typename T> - inline T* DequeIteratorBase<T>::before() const - { - checkValidity(); - ASSERT(m_index != m_deque->m_start); - if (!m_index) - return &m_deque->m_buffer.buffer()[m_deque->m_buffer.capacity() - 1]; - return &m_deque->m_buffer.buffer()[m_index - 1]; - } - -} // namespace WTF - -using WTF::Deque; - -#endif // WTF_Deque_h diff --git a/JavaScriptCore/wtf/DisallowCType.h b/JavaScriptCore/wtf/DisallowCType.h deleted file mode 100644 index 436f7f2..0000000 --- a/JavaScriptCore/wtf/DisallowCType.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_DisallowCType_h -#define WTF_DisallowCType_h - -// The behavior of many of the functions in the <ctype.h> header is dependent -// on the current locale. But almost all uses of these functions are for -// locale-independent, ASCII-specific purposes. In WebKit code we use our own -// ASCII-specific functions instead. This header makes sure we get a compile-time -// error if we use one of the <ctype.h> functions by accident. - -#include <ctype.h> - -#undef isalnum -#undef isalpha -#undef isascii -#undef isblank -#undef iscntrl -#undef isdigit -#undef isgraph -#undef islower -#undef isprint -#undef ispunct -#undef isspace -#undef isupper -#undef isxdigit -#undef toascii -#undef tolower -#undef toupper - -#define isalnum isalnum_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isalpha isalpha_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isascii isascii_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isblank isblank_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define iscntrl iscntrl_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isdigit isdigit_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isgraph isgraph_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define islower islower_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isprint isprint_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define ispunct ispunct_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isspace isspace_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isupper isupper_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define isxdigit isxdigit_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define toascii toascii_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define tolower tolower_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h -#define toupper toupper_WTF_Please_use_ASCIICType_instead_of_ctype_see_comment_in_ASCIICType_h - -#endif diff --git a/JavaScriptCore/wtf/FastAllocBase.h b/JavaScriptCore/wtf/FastAllocBase.h deleted file mode 100644 index bb1825e..0000000 --- a/JavaScriptCore/wtf/FastAllocBase.h +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Paul Pedriana <ppedriana@ea.com>. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FastAllocBase_h -#define FastAllocBase_h - -// Provides customizable overrides of fastMalloc/fastFree and operator new/delete -// -// Provided functionality: -// namespace WTF { -// class FastAllocBase; -// -// T* fastNew<T>(); -// T* fastNew<T>(arg); -// T* fastNew<T>(arg, arg); -// T* fastNewArray<T>(count); -// void fastDelete(T* p); -// void fastDeleteArray(T* p); -// void fastNonNullDelete(T* p); -// void fastNonNullDeleteArray(T* p); -// } -// -// FastDelete assumes that the underlying -// -// Example usage: -// class Widget : public FastAllocBase { ... }; -// -// char* charPtr = fastNew<char>(); -// fastDelete(charPtr); -// -// char* charArrayPtr = fastNewArray<char>(37); -// fastDeleteArray(charArrayPtr); -// -// void** voidPtrPtr = fastNew<void*>(); -// fastDelete(voidPtrPtr); -// -// void** voidPtrArrayPtr = fastNewArray<void*>(37); -// fastDeleteArray(voidPtrArrayPtr); -// -// POD* podPtr = fastNew<POD>(); -// fastDelete(podPtr); -// -// POD* podArrayPtr = fastNewArray<POD>(37); -// fastDeleteArray(podArrayPtr); -// -// Object* objectPtr = fastNew<Object>(); -// fastDelete(objectPtr); -// -// Object* objectArrayPtr = fastNewArray<Object>(37); -// fastDeleteArray(objectArrayPtr); -// - -#include <new> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include "Assertions.h" -#include "FastMalloc.h" -#include "TypeTraits.h" - -namespace WTF { - -#define WTF_MAKE_FAST_ALLOCATED \ -public: \ - void* operator new(size_t, void* p) { return p; } \ - void* operator new[](size_t, void* p) { return p; } \ - \ - void* operator new(size_t size) \ - { \ - void* p = ::WTF::fastMalloc(size); \ - ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNew); \ - return p; \ - } \ - \ - void operator delete(void* p) \ - { \ - ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNew); \ - ::WTF::fastFree(p); \ - } \ - \ - void* operator new[](size_t size) \ - { \ - void* p = ::WTF::fastMalloc(size); \ - ::WTF::fastMallocMatchValidateMalloc(p, ::WTF::Internal::AllocTypeClassNewArray); \ - return p; \ - } \ - \ - void operator delete[](void* p) \ - { \ - ::WTF::fastMallocMatchValidateFree(p, ::WTF::Internal::AllocTypeClassNewArray); \ - ::WTF::fastFree(p); \ - } \ -private: - -class FastAllocBase { - WTF_MAKE_FAST_ALLOCATED -}; - - // fastNew / fastDelete - - template <typename T> - inline T* fastNew() - { - void* p = fastMalloc(sizeof(T)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); - return ::new(p) T; - } - - template <typename T, typename Arg1> - inline T* fastNew(Arg1 arg1) - { - void* p = fastMalloc(sizeof(T)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); - return ::new(p) T(arg1); - } - - template <typename T, typename Arg1, typename Arg2> - inline T* fastNew(Arg1 arg1, Arg2 arg2) - { - void* p = fastMalloc(sizeof(T)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); - return ::new(p) T(arg1, arg2); - } - - template <typename T, typename Arg1, typename Arg2, typename Arg3> - inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3) - { - void* p = fastMalloc(sizeof(T)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); - return ::new(p) T(arg1, arg2, arg3); - } - - template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4> - inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4) - { - void* p = fastMalloc(sizeof(T)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); - return ::new(p) T(arg1, arg2, arg3, arg4); - } - - template <typename T, typename Arg1, typename Arg2, typename Arg3, typename Arg4, typename Arg5> - inline T* fastNew(Arg1 arg1, Arg2 arg2, Arg3 arg3, Arg4 arg4, Arg5 arg5) - { - void* p = fastMalloc(sizeof(T)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNew); - return ::new(p) T(arg1, arg2, arg3, arg4, arg5); - } - - namespace Internal { - - // We define a union of pointer to an integer and pointer to T. - // When non-POD arrays are allocated we add a few leading bytes to tell what - // the size of the array is. We return to the user the pointer to T. - // The way to think of it is as if we allocate a struct like so: - // struct Array { - // AllocAlignmentInteger m_size; - // T m_T[array count]; - // }; - - template <typename T> - union ArraySize { - AllocAlignmentInteger* size; - T* t; - }; - - // This is a support template for fastNewArray. - // This handles the case wherein T has a trivial ctor and a trivial dtor. - template <typename T, bool trivialCtor, bool trivialDtor> - struct NewArrayImpl { - static T* fastNewArray(size_t count) - { - T* p = static_cast<T*>(fastMalloc(sizeof(T) * count)); - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); - return p; - } - }; - - // This is a support template for fastNewArray. - // This handles the case wherein T has a non-trivial ctor and a trivial dtor. - template <typename T> - struct NewArrayImpl<T, false, true> { - static T* fastNewArray(size_t count) - { - T* p = static_cast<T*>(fastMalloc(sizeof(T) * count)); - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); - - for (T* pObject = p, *pObjectEnd = pObject + count; pObject != pObjectEnd; ++pObject) - ::new(pObject) T; - - return p; - } - }; - - // This is a support template for fastNewArray. - // This handles the case wherein T has a trivial ctor and a non-trivial dtor. - template <typename T> - struct NewArrayImpl<T, true, false> { - static T* fastNewArray(size_t count) - { - void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count)); - ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) }; - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); - *a.size++ = count; - // No need to construct the objects in this case. - - return a.t; - } - }; - - // This is a support template for fastNewArray. - // This handles the case wherein T has a non-trivial ctor and a non-trivial dtor. - template <typename T> - struct NewArrayImpl<T, false, false> { - static T* fastNewArray(size_t count) - { - void* p = fastMalloc(sizeof(AllocAlignmentInteger) + (sizeof(T) * count)); - ArraySize<T> a = { static_cast<AllocAlignmentInteger*>(p) }; - - if (!p) - return 0; - - fastMallocMatchValidateMalloc(p, Internal::AllocTypeFastNewArray); - *a.size++ = count; - - for (T* pT = a.t, *pTEnd = pT + count; pT != pTEnd; ++pT) - ::new(pT) T; - - return a.t; - } - }; - } // namespace Internal - - template <typename T> - inline T* fastNewArray(size_t count) - { - return Internal::NewArrayImpl<T, WTF::HasTrivialConstructor<T>::value, WTF::HasTrivialDestructor<T>::value>::fastNewArray(count); - } - - template <typename T> - inline void fastDelete(T* p) - { - if (!p) - return; - - fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); - p->~T(); - fastFree(p); - } - - template <typename T> - inline void fastDeleteSkippingDestructor(T* p) - { - if (!p) - return; - - fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); - fastFree(p); - } - - namespace Internal { - // This is a support template for fastDeleteArray. - // This handles the case wherein T has a trivial dtor. - template <typename T, bool trivialDtor> - struct DeleteArrayImpl { - static void fastDeleteArray(void* p) - { - // No need to destruct the objects in this case. - // We expect that fastFree checks for null. - fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray); - fastFree(p); - } - }; - - // This is a support template for fastDeleteArray. - // This handles the case wherein T has a non-trivial dtor. - template <typename T> - struct DeleteArrayImpl<T, false> { - static void fastDeleteArray(T* p) - { - if (!p) - return; - - ArraySize<T> a; - a.t = p; - a.size--; // Decrement size pointer - - T* pEnd = p + *a.size; - while (pEnd-- != p) - pEnd->~T(); - - fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray); - fastFree(a.size); - } - }; - - } // namespace Internal - - template <typename T> - void fastDeleteArray(T* p) - { - Internal::DeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastDeleteArray(p); - } - - - template <typename T> - inline void fastNonNullDelete(T* p) - { - fastMallocMatchValidateFree(p, Internal::AllocTypeFastNew); - p->~T(); - fastFree(p); - } - - namespace Internal { - // This is a support template for fastDeleteArray. - // This handles the case wherein T has a trivial dtor. - template <typename T, bool trivialDtor> - struct NonNullDeleteArrayImpl { - static void fastNonNullDeleteArray(void* p) - { - fastMallocMatchValidateFree(p, Internal::AllocTypeFastNewArray); - // No need to destruct the objects in this case. - fastFree(p); - } - }; - - // This is a support template for fastDeleteArray. - // This handles the case wherein T has a non-trivial dtor. - template <typename T> - struct NonNullDeleteArrayImpl<T, false> { - static void fastNonNullDeleteArray(T* p) - { - ArraySize<T> a; - a.t = p; - a.size--; - - T* pEnd = p + *a.size; - while (pEnd-- != p) - pEnd->~T(); - - fastMallocMatchValidateFree(a.size, Internal::AllocTypeFastNewArray); - fastFree(a.size); - } - }; - - } // namespace Internal - - template <typename T> - void fastNonNullDeleteArray(T* p) - { - Internal::NonNullDeleteArrayImpl<T, WTF::HasTrivialDestructor<T>::value>::fastNonNullDeleteArray(p); - } - - -} // namespace WTF - -using WTF::FastAllocBase; -using WTF::fastDeleteSkippingDestructor; - -#endif // FastAllocBase_h diff --git a/JavaScriptCore/wtf/FastMalloc.cpp b/JavaScriptCore/wtf/FastMalloc.cpp deleted file mode 100644 index bbbdaf2..0000000 --- a/JavaScriptCore/wtf/FastMalloc.cpp +++ /dev/null @@ -1,4523 +0,0 @@ -// Copyright (c) 2005, 2007, Google Inc. -// All rights reserved. -// Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Sanjay Ghemawat <opensource@google.com> -// -// A malloc that uses a per-thread cache to satisfy small malloc requests. -// (The time for malloc/free of a small object drops from 300 ns to 50 ns.) -// -// See doc/tcmalloc.html for a high-level -// description of how this malloc works. -// -// SYNCHRONIZATION -// 1. The thread-specific lists are accessed without acquiring any locks. -// This is safe because each such list is only accessed by one thread. -// 2. We have a lock per central free-list, and hold it while manipulating -// the central free list for a particular size. -// 3. The central page allocator is protected by "pageheap_lock". -// 4. The pagemap (which maps from page-number to descriptor), -// can be read without holding any locks, and written while holding -// the "pageheap_lock". -// 5. To improve performance, a subset of the information one can get -// from the pagemap is cached in a data structure, pagemap_cache_, -// that atomically reads and writes its entries. This cache can be -// read and written without locking. -// -// This multi-threaded access to the pagemap is safe for fairly -// subtle reasons. We basically assume that when an object X is -// allocated by thread A and deallocated by thread B, there must -// have been appropriate synchronization in the handoff of object -// X from thread A to thread B. The same logic applies to pagemap_cache_. -// -// THE PAGEID-TO-SIZECLASS CACHE -// Hot PageID-to-sizeclass mappings are held by pagemap_cache_. If this cache -// returns 0 for a particular PageID then that means "no information," not that -// the sizeclass is 0. The cache may have stale information for pages that do -// not hold the beginning of any free()'able object. Staleness is eliminated -// in Populate() for pages with sizeclass > 0 objects, and in do_malloc() and -// do_memalign() for all other relevant pages. -// -// TODO: Bias reclamation to larger addresses -// TODO: implement mallinfo/mallopt -// TODO: Better testing -// -// 9/28/2003 (new page-level allocator replaces ptmalloc2): -// * malloc/free of small objects goes from ~300 ns to ~50 ns. -// * allocation of a reasonably complicated struct -// goes from about 1100 ns to about 300 ns. - -#include "config.h" -#include "FastMalloc.h" - -#include "Assertions.h" -#include <limits> -#if ENABLE(JSC_MULTIPLE_THREADS) -#include <pthread.h> -#endif -#include <wtf/StdLibExtras.h> - -#ifndef NO_TCMALLOC_SAMPLES -#ifdef WTF_CHANGES -#define NO_TCMALLOC_SAMPLES -#endif -#endif - -#if !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) && defined(NDEBUG) -#define FORCE_SYSTEM_MALLOC 0 -#else -#define FORCE_SYSTEM_MALLOC 1 -#endif - -// Use a background thread to periodically scavenge memory to release back to the system -// https://bugs.webkit.org/show_bug.cgi?id=27900: don't turn this on for Tiger until we have figured out why it caused a crash. -#if defined(BUILDING_ON_TIGER) -#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 0 -#else -#define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1 -#endif - -#ifndef NDEBUG -namespace WTF { - -#if ENABLE(JSC_MULTIPLE_THREADS) -static pthread_key_t isForbiddenKey; -static pthread_once_t isForbiddenKeyOnce = PTHREAD_ONCE_INIT; -static void initializeIsForbiddenKey() -{ - pthread_key_create(&isForbiddenKey, 0); -} - -#if !ASSERT_DISABLED -static bool isForbidden() -{ - pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey); - return !!pthread_getspecific(isForbiddenKey); -} -#endif - -void fastMallocForbid() -{ - pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey); - pthread_setspecific(isForbiddenKey, &isForbiddenKey); -} - -void fastMallocAllow() -{ - pthread_once(&isForbiddenKeyOnce, initializeIsForbiddenKey); - pthread_setspecific(isForbiddenKey, 0); -} - -#else - -static bool staticIsForbidden; -static bool isForbidden() -{ - return staticIsForbidden; -} - -void fastMallocForbid() -{ - staticIsForbidden = true; -} - -void fastMallocAllow() -{ - staticIsForbidden = false; -} -#endif // ENABLE(JSC_MULTIPLE_THREADS) - -} // namespace WTF -#endif // NDEBUG - -#include <string.h> - -namespace WTF { - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - -namespace Internal { - -void fastMallocMatchFailed(void*) -{ - CRASH(); -} - -} // namespace Internal - -#endif - -void* fastZeroedMalloc(size_t n) -{ - void* result = fastMalloc(n); - memset(result, 0, n); - return result; -} - -char* fastStrDup(const char* src) -{ - int len = strlen(src) + 1; - char* dup = static_cast<char*>(fastMalloc(len)); - - if (dup) - memcpy(dup, src, len); - - return dup; -} - -TryMallocReturnValue tryFastZeroedMalloc(size_t n) -{ - void* result; - if (!tryFastMalloc(n).getValue(result)) - return 0; - memset(result, 0, n); - return result; -} - -} // namespace WTF - -#if FORCE_SYSTEM_MALLOC - -#if PLATFORM(BREWMP) -#include "brew/SystemMallocBrew.h" -#endif - -#if OS(DARWIN) -#include <malloc/malloc.h> -#elif COMPILER(MSVC) -#include <malloc.h> -#endif - -namespace WTF { - -TryMallocReturnValue tryFastMalloc(size_t n) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= n) // If overflow would occur... - return 0; - - void* result = malloc(n + sizeof(AllocAlignmentInteger)); - if (!result) - return 0; - - *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc; - result = static_cast<AllocAlignmentInteger*>(result) + 1; - - return result; -#else - return malloc(n); -#endif -} - -void* fastMalloc(size_t n) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - TryMallocReturnValue returnValue = tryFastMalloc(n); - void* result; - returnValue.getValue(result); -#else - void* result = malloc(n); -#endif - - if (!result) { -#if PLATFORM(BREWMP) - // The behavior of malloc(0) is implementation defined. - // To make sure that fastMalloc never returns 0, retry with fastMalloc(1). - if (!n) - return fastMalloc(1); -#endif - CRASH(); - } - - return result; -} - -TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - size_t totalBytes = n_elements * element_size; - if (n_elements > 1 && element_size && (totalBytes / element_size) != n_elements || (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= totalBytes)) - return 0; - - totalBytes += sizeof(AllocAlignmentInteger); - void* result = malloc(totalBytes); - if (!result) - return 0; - - memset(result, 0, totalBytes); - *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc; - result = static_cast<AllocAlignmentInteger*>(result) + 1; - return result; -#else - return calloc(n_elements, element_size); -#endif -} - -void* fastCalloc(size_t n_elements, size_t element_size) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - TryMallocReturnValue returnValue = tryFastCalloc(n_elements, element_size); - void* result; - returnValue.getValue(result); -#else - void* result = calloc(n_elements, element_size); -#endif - - if (!result) { -#if PLATFORM(BREWMP) - // If either n_elements or element_size is 0, the behavior of calloc is implementation defined. - // To make sure that fastCalloc never returns 0, retry with fastCalloc(1, 1). - if (!n_elements || !element_size) - return fastCalloc(1, 1); -#endif - CRASH(); - } - - return result; -} - -void fastFree(void* p) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (!p) - return; - - AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(p); - if (*header != Internal::AllocTypeMalloc) - Internal::fastMallocMatchFailed(p); - free(header); -#else - free(p); -#endif -} - -TryMallocReturnValue tryFastRealloc(void* p, size_t n) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (p) { - if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= n) // If overflow would occur... - return 0; - AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(p); - if (*header != Internal::AllocTypeMalloc) - Internal::fastMallocMatchFailed(p); - void* result = realloc(header, n + sizeof(AllocAlignmentInteger)); - if (!result) - return 0; - - // This should not be needed because the value is already there: - // *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc; - result = static_cast<AllocAlignmentInteger*>(result) + 1; - return result; - } else { - return fastMalloc(n); - } -#else - return realloc(p, n); -#endif -} - -void* fastRealloc(void* p, size_t n) -{ - ASSERT(!isForbidden()); - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - TryMallocReturnValue returnValue = tryFastRealloc(p, n); - void* result; - returnValue.getValue(result); -#else - void* result = realloc(p, n); -#endif - - if (!result) - CRASH(); - return result; -} - -void releaseFastMallocFreeMemory() { } - -FastMallocStatistics fastMallocStatistics() -{ - FastMallocStatistics statistics = { 0, 0, 0 }; - return statistics; -} - -size_t fastMallocSize(const void* p) -{ -#if OS(DARWIN) - return malloc_size(p); -#elif COMPILER(MSVC) && !PLATFORM(BREWMP) - // Brew MP uses its own memory allocator, so _msize does not work on the Brew MP simulator. - return _msize(const_cast<void*>(p)); -#else - return 1; -#endif -} - -} // namespace WTF - -#if OS(DARWIN) -// This symbol is present in the JavaScriptCore exports file even when FastMalloc is disabled. -// It will never be used in this case, so it's type and value are less interesting than its presence. -extern "C" const int jscore_fastmalloc_introspection = 0; -#endif - -#else // FORCE_SYSTEM_MALLOC - -#if HAVE(STDINT_H) -#include <stdint.h> -#elif HAVE(INTTYPES_H) -#include <inttypes.h> -#else -#include <sys/types.h> -#endif - -#include "AlwaysInline.h" -#include "Assertions.h" -#include "TCPackedCache.h" -#include "TCPageMap.h" -#include "TCSpinLock.h" -#include "TCSystemAlloc.h" -#include <algorithm> -#include <limits> -#include <pthread.h> -#include <stdarg.h> -#include <stddef.h> -#include <stdio.h> -#if HAVE(ERRNO_H) -#include <errno.h> -#endif -#if OS(UNIX) -#include <unistd.h> -#endif -#if OS(WINDOWS) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> -#endif - -#ifdef WTF_CHANGES - -#if OS(DARWIN) -#include "MallocZoneSupport.h" -#include <wtf/HashSet.h> -#include <wtf/Vector.h> -#endif -#if HAVE(DISPATCH_H) -#include <dispatch/dispatch.h> -#endif - - -#ifndef PRIuS -#define PRIuS "zu" -#endif - -// Calling pthread_getspecific through a global function pointer is faster than a normal -// call to the function on Mac OS X, and it's used in performance-critical code. So we -// use a function pointer. But that's not necessarily faster on other platforms, and we had -// problems with this technique on Windows, so we'll do this only on Mac OS X. -#if OS(DARWIN) -static void* (*pthread_getspecific_function_pointer)(pthread_key_t) = pthread_getspecific; -#define pthread_getspecific(key) pthread_getspecific_function_pointer(key) -#endif - -#define DEFINE_VARIABLE(type, name, value, meaning) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead { \ - type FLAGS_##name(value); \ - char FLAGS_no##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_##type##_instead::FLAGS_##name - -#define DEFINE_int64(name, value, meaning) \ - DEFINE_VARIABLE(int64_t, name, value, meaning) - -#define DEFINE_double(name, value, meaning) \ - DEFINE_VARIABLE(double, name, value, meaning) - -namespace WTF { - -#define malloc fastMalloc -#define calloc fastCalloc -#define free fastFree -#define realloc fastRealloc - -#define MESSAGE LOG_ERROR -#define CHECK_CONDITION ASSERT - -#if OS(DARWIN) -struct Span; -class TCMalloc_Central_FreeListPadded; -class TCMalloc_PageHeap; -class TCMalloc_ThreadCache; -template <typename T> class PageHeapAllocator; - -class FastMallocZone { -public: - static void init(); - - static kern_return_t enumerate(task_t, void*, unsigned typeMmask, vm_address_t zoneAddress, memory_reader_t, vm_range_recorder_t); - static size_t goodSize(malloc_zone_t*, size_t size) { return size; } - static boolean_t check(malloc_zone_t*) { return true; } - static void print(malloc_zone_t*, boolean_t) { } - static void log(malloc_zone_t*, void*) { } - static void forceLock(malloc_zone_t*) { } - static void forceUnlock(malloc_zone_t*) { } - static void statistics(malloc_zone_t*, malloc_statistics_t* stats) { memset(stats, 0, sizeof(malloc_statistics_t)); } - -private: - FastMallocZone(TCMalloc_PageHeap*, TCMalloc_ThreadCache**, TCMalloc_Central_FreeListPadded*, PageHeapAllocator<Span>*, PageHeapAllocator<TCMalloc_ThreadCache>*); - static size_t size(malloc_zone_t*, const void*); - static void* zoneMalloc(malloc_zone_t*, size_t); - static void* zoneCalloc(malloc_zone_t*, size_t numItems, size_t size); - static void zoneFree(malloc_zone_t*, void*); - static void* zoneRealloc(malloc_zone_t*, void*, size_t); - static void* zoneValloc(malloc_zone_t*, size_t) { LOG_ERROR("valloc is not supported"); return 0; } - static void zoneDestroy(malloc_zone_t*) { } - - malloc_zone_t m_zone; - TCMalloc_PageHeap* m_pageHeap; - TCMalloc_ThreadCache** m_threadHeaps; - TCMalloc_Central_FreeListPadded* m_centralCaches; - PageHeapAllocator<Span>* m_spanAllocator; - PageHeapAllocator<TCMalloc_ThreadCache>* m_pageHeapAllocator; -}; - -#endif - -#endif - -#ifndef WTF_CHANGES -// This #ifdef should almost never be set. Set NO_TCMALLOC_SAMPLES if -// you're porting to a system where you really can't get a stacktrace. -#ifdef NO_TCMALLOC_SAMPLES -// We use #define so code compiles even if you #include stacktrace.h somehow. -# define GetStackTrace(stack, depth, skip) (0) -#else -# include <google/stacktrace.h> -#endif -#endif - -// Even if we have support for thread-local storage in the compiler -// and linker, the OS may not support it. We need to check that at -// runtime. Right now, we have to keep a manual set of "bad" OSes. -#if defined(HAVE_TLS) - static bool kernel_supports_tls = false; // be conservative - static inline bool KernelSupportsTLS() { - return kernel_supports_tls; - } -# if !HAVE_DECL_UNAME // if too old for uname, probably too old for TLS - static void CheckIfKernelSupportsTLS() { - kernel_supports_tls = false; - } -# else -# include <sys/utsname.h> // DECL_UNAME checked for <sys/utsname.h> too - static void CheckIfKernelSupportsTLS() { - struct utsname buf; - if (uname(&buf) != 0) { // should be impossible - MESSAGE("uname failed assuming no TLS support (errno=%d)\n", errno); - kernel_supports_tls = false; - } else if (strcasecmp(buf.sysname, "linux") == 0) { - // The linux case: the first kernel to support TLS was 2.6.0 - if (buf.release[0] < '2' && buf.release[1] == '.') // 0.x or 1.x - kernel_supports_tls = false; - else if (buf.release[0] == '2' && buf.release[1] == '.' && - buf.release[2] >= '0' && buf.release[2] < '6' && - buf.release[3] == '.') // 2.0 - 2.5 - kernel_supports_tls = false; - else - kernel_supports_tls = true; - } else { // some other kernel, we'll be optimisitic - kernel_supports_tls = true; - } - // TODO(csilvers): VLOG(1) the tls status once we support RAW_VLOG - } -# endif // HAVE_DECL_UNAME -#endif // HAVE_TLS - -// __THROW is defined in glibc systems. It means, counter-intuitively, -// "This function will never throw an exception." It's an optional -// optimization tool, but we may need to use it to match glibc prototypes. -#ifndef __THROW // I guess we're not on a glibc system -# define __THROW // __THROW is just an optimization, so ok to make it "" -#endif - -//------------------------------------------------------------------- -// Configuration -//------------------------------------------------------------------- - -// Not all possible combinations of the following parameters make -// sense. In particular, if kMaxSize increases, you may have to -// increase kNumClasses as well. -static const size_t kPageShift = 12; -static const size_t kPageSize = 1 << kPageShift; -static const size_t kMaxSize = 8u * kPageSize; -static const size_t kAlignShift = 3; -static const size_t kAlignment = 1 << kAlignShift; -static const size_t kNumClasses = 68; - -// Allocates a big block of memory for the pagemap once we reach more than -// 128MB -static const size_t kPageMapBigAllocationThreshold = 128 << 20; - -// Minimum number of pages to fetch from system at a time. Must be -// significantly bigger than kPageSize to amortize system-call -// overhead, and also to reduce external fragementation. Also, we -// should keep this value big because various incarnations of Linux -// have small limits on the number of mmap() regions per -// address-space. -static const size_t kMinSystemAlloc = 1 << (20 - kPageShift); - -// Number of objects to move between a per-thread list and a central -// list in one shot. We want this to be not too small so we can -// amortize the lock overhead for accessing the central list. Making -// it too big may temporarily cause unnecessary memory wastage in the -// per-thread free list until the scavenger cleans up the list. -static int num_objects_to_move[kNumClasses]; - -// Maximum length we allow a per-thread free-list to have before we -// move objects from it into the corresponding central free-list. We -// want this big to avoid locking the central free-list too often. It -// should not hurt to make this list somewhat big because the -// scavenging code will shrink it down when its contents are not in use. -static const int kMaxFreeListLength = 256; - -// Lower and upper bounds on the per-thread cache sizes -static const size_t kMinThreadCacheSize = kMaxSize * 2; -static const size_t kMaxThreadCacheSize = 2 << 20; - -// Default bound on the total amount of thread caches -static const size_t kDefaultOverallThreadCacheSize = 16 << 20; - -// For all span-lengths < kMaxPages we keep an exact-size list. -// REQUIRED: kMaxPages >= kMinSystemAlloc; -static const size_t kMaxPages = kMinSystemAlloc; - -/* The smallest prime > 2^n */ -static int primes_list[] = { - // Small values might cause high rates of sampling - // and hence commented out. - // 2, 5, 11, 17, 37, 67, 131, 257, - // 521, 1031, 2053, 4099, 8209, 16411, - 32771, 65537, 131101, 262147, 524309, 1048583, - 2097169, 4194319, 8388617, 16777259, 33554467 }; - -// Twice the approximate gap between sampling actions. -// I.e., we take one sample approximately once every -// tcmalloc_sample_parameter/2 -// bytes of allocation, i.e., ~ once every 128KB. -// Must be a prime number. -#ifdef NO_TCMALLOC_SAMPLES -DEFINE_int64(tcmalloc_sample_parameter, 0, - "Unused: code is compiled with NO_TCMALLOC_SAMPLES"); -static size_t sample_period = 0; -#else -DEFINE_int64(tcmalloc_sample_parameter, 262147, - "Twice the approximate gap between sampling actions." - " Must be a prime number. Otherwise will be rounded up to a " - " larger prime number"); -static size_t sample_period = 262147; -#endif - -// Protects sample_period above -static SpinLock sample_period_lock = SPINLOCK_INITIALIZER; - -// Parameters for controlling how fast memory is returned to the OS. - -DEFINE_double(tcmalloc_release_rate, 1, - "Rate at which we release unused memory to the system. " - "Zero means we never release memory back to the system. " - "Increase this flag to return memory faster; decrease it " - "to return memory slower. Reasonable rates are in the " - "range [0,10]"); - -//------------------------------------------------------------------- -// Mapping from size to size_class and vice versa -//------------------------------------------------------------------- - -// Sizes <= 1024 have an alignment >= 8. So for such sizes we have an -// array indexed by ceil(size/8). Sizes > 1024 have an alignment >= 128. -// So for these larger sizes we have an array indexed by ceil(size/128). -// -// We flatten both logical arrays into one physical array and use -// arithmetic to compute an appropriate index. The constants used by -// ClassIndex() were selected to make the flattening work. -// -// Examples: -// Size Expression Index -// ------------------------------------------------------- -// 0 (0 + 7) / 8 0 -// 1 (1 + 7) / 8 1 -// ... -// 1024 (1024 + 7) / 8 128 -// 1025 (1025 + 127 + (120<<7)) / 128 129 -// ... -// 32768 (32768 + 127 + (120<<7)) / 128 376 -static const size_t kMaxSmallSize = 1024; -static const int shift_amount[2] = { 3, 7 }; // For divides by 8 or 128 -static const int add_amount[2] = { 7, 127 + (120 << 7) }; -static unsigned char class_array[377]; - -// Compute index of the class_array[] entry for a given size -static inline int ClassIndex(size_t s) { - const int i = (s > kMaxSmallSize); - return static_cast<int>((s + add_amount[i]) >> shift_amount[i]); -} - -// Mapping from size class to max size storable in that class -static size_t class_to_size[kNumClasses]; - -// Mapping from size class to number of pages to allocate at a time -static size_t class_to_pages[kNumClasses]; - -// TransferCache is used to cache transfers of num_objects_to_move[size_class] -// back and forth between thread caches and the central cache for a given size -// class. -struct TCEntry { - void *head; // Head of chain of objects. - void *tail; // Tail of chain of objects. -}; -// A central cache freelist can have anywhere from 0 to kNumTransferEntries -// slots to put link list chains into. To keep memory usage bounded the total -// number of TCEntries across size classes is fixed. Currently each size -// class is initially given one TCEntry which also means that the maximum any -// one class can have is kNumClasses. -static const int kNumTransferEntries = kNumClasses; - -// Note: the following only works for "n"s that fit in 32-bits, but -// that is fine since we only use it for small sizes. -static inline int LgFloor(size_t n) { - int log = 0; - for (int i = 4; i >= 0; --i) { - int shift = (1 << i); - size_t x = n >> shift; - if (x != 0) { - n = x; - log += shift; - } - } - ASSERT(n == 1); - return log; -} - -// Some very basic linked list functions for dealing with using void * as -// storage. - -static inline void *SLL_Next(void *t) { - return *(reinterpret_cast<void**>(t)); -} - -static inline void SLL_SetNext(void *t, void *n) { - *(reinterpret_cast<void**>(t)) = n; -} - -static inline void SLL_Push(void **list, void *element) { - SLL_SetNext(element, *list); - *list = element; -} - -static inline void *SLL_Pop(void **list) { - void *result = *list; - *list = SLL_Next(*list); - return result; -} - - -// Remove N elements from a linked list to which head points. head will be -// modified to point to the new head. start and end will point to the first -// and last nodes of the range. Note that end will point to NULL after this -// function is called. -static inline void SLL_PopRange(void **head, int N, void **start, void **end) { - if (N == 0) { - *start = NULL; - *end = NULL; - return; - } - - void *tmp = *head; - for (int i = 1; i < N; ++i) { - tmp = SLL_Next(tmp); - } - - *start = *head; - *end = tmp; - *head = SLL_Next(tmp); - // Unlink range from list. - SLL_SetNext(tmp, NULL); -} - -static inline void SLL_PushRange(void **head, void *start, void *end) { - if (!start) return; - SLL_SetNext(end, *head); - *head = start; -} - -static inline size_t SLL_Size(void *head) { - int count = 0; - while (head) { - count++; - head = SLL_Next(head); - } - return count; -} - -// Setup helper functions. - -static ALWAYS_INLINE size_t SizeClass(size_t size) { - return class_array[ClassIndex(size)]; -} - -// Get the byte-size for a specified class -static ALWAYS_INLINE size_t ByteSizeForClass(size_t cl) { - return class_to_size[cl]; -} -static int NumMoveSize(size_t size) { - if (size == 0) return 0; - // Use approx 64k transfers between thread and central caches. - int num = static_cast<int>(64.0 * 1024.0 / size); - if (num < 2) num = 2; - // Clamp well below kMaxFreeListLength to avoid ping pong between central - // and thread caches. - if (num > static_cast<int>(0.8 * kMaxFreeListLength)) - num = static_cast<int>(0.8 * kMaxFreeListLength); - - // Also, avoid bringing in too many objects into small object free - // lists. There are lots of such lists, and if we allow each one to - // fetch too many at a time, we end up having to scavenge too often - // (especially when there are lots of threads and each thread gets a - // small allowance for its thread cache). - // - // TODO: Make thread cache free list sizes dynamic so that we do not - // have to equally divide a fixed resource amongst lots of threads. - if (num > 32) num = 32; - - return num; -} - -// Initialize the mapping arrays -static void InitSizeClasses() { - // Do some sanity checking on add_amount[]/shift_amount[]/class_array[] - if (ClassIndex(0) < 0) { - MESSAGE("Invalid class index %d for size 0\n", ClassIndex(0)); - CRASH(); - } - if (static_cast<size_t>(ClassIndex(kMaxSize)) >= sizeof(class_array)) { - MESSAGE("Invalid class index %d for kMaxSize\n", ClassIndex(kMaxSize)); - CRASH(); - } - - // Compute the size classes we want to use - size_t sc = 1; // Next size class to assign - unsigned char alignshift = kAlignShift; - int last_lg = -1; - for (size_t size = kAlignment; size <= kMaxSize; size += (1 << alignshift)) { - int lg = LgFloor(size); - if (lg > last_lg) { - // Increase alignment every so often. - // - // Since we double the alignment every time size doubles and - // size >= 128, this means that space wasted due to alignment is - // at most 16/128 i.e., 12.5%. Plus we cap the alignment at 256 - // bytes, so the space wasted as a percentage starts falling for - // sizes > 2K. - if ((lg >= 7) && (alignshift < 8)) { - alignshift++; - } - last_lg = lg; - } - - // Allocate enough pages so leftover is less than 1/8 of total. - // This bounds wasted space to at most 12.5%. - size_t psize = kPageSize; - while ((psize % size) > (psize >> 3)) { - psize += kPageSize; - } - const size_t my_pages = psize >> kPageShift; - - if (sc > 1 && my_pages == class_to_pages[sc-1]) { - // See if we can merge this into the previous class without - // increasing the fragmentation of the previous class. - const size_t my_objects = (my_pages << kPageShift) / size; - const size_t prev_objects = (class_to_pages[sc-1] << kPageShift) - / class_to_size[sc-1]; - if (my_objects == prev_objects) { - // Adjust last class to include this size - class_to_size[sc-1] = size; - continue; - } - } - - // Add new class - class_to_pages[sc] = my_pages; - class_to_size[sc] = size; - sc++; - } - if (sc != kNumClasses) { - MESSAGE("wrong number of size classes: found %" PRIuS " instead of %d\n", - sc, int(kNumClasses)); - CRASH(); - } - - // Initialize the mapping arrays - int next_size = 0; - for (unsigned char c = 1; c < kNumClasses; c++) { - const size_t max_size_in_class = class_to_size[c]; - for (size_t s = next_size; s <= max_size_in_class; s += kAlignment) { - class_array[ClassIndex(s)] = c; - } - next_size = static_cast<int>(max_size_in_class + kAlignment); - } - - // Double-check sizes just to be safe - for (size_t size = 0; size <= kMaxSize; size++) { - const size_t sc = SizeClass(size); - if (sc == 0) { - MESSAGE("Bad size class %" PRIuS " for %" PRIuS "\n", sc, size); - CRASH(); - } - if (sc > 1 && size <= class_to_size[sc-1]) { - MESSAGE("Allocating unnecessarily large class %" PRIuS " for %" PRIuS - "\n", sc, size); - CRASH(); - } - if (sc >= kNumClasses) { - MESSAGE("Bad size class %" PRIuS " for %" PRIuS "\n", sc, size); - CRASH(); - } - const size_t s = class_to_size[sc]; - if (size > s) { - MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %" PRIuS ")\n", s, size, sc); - CRASH(); - } - if (s == 0) { - MESSAGE("Bad size %" PRIuS " for %" PRIuS " (sc = %" PRIuS ")\n", s, size, sc); - CRASH(); - } - } - - // Initialize the num_objects_to_move array. - for (size_t cl = 1; cl < kNumClasses; ++cl) { - num_objects_to_move[cl] = NumMoveSize(ByteSizeForClass(cl)); - } - -#ifndef WTF_CHANGES - if (false) { - // Dump class sizes and maximum external wastage per size class - for (size_t cl = 1; cl < kNumClasses; ++cl) { - const int alloc_size = class_to_pages[cl] << kPageShift; - const int alloc_objs = alloc_size / class_to_size[cl]; - const int min_used = (class_to_size[cl-1] + 1) * alloc_objs; - const int max_waste = alloc_size - min_used; - MESSAGE("SC %3d [ %8d .. %8d ] from %8d ; %2.0f%% maxwaste\n", - int(cl), - int(class_to_size[cl-1] + 1), - int(class_to_size[cl]), - int(class_to_pages[cl] << kPageShift), - max_waste * 100.0 / alloc_size - ); - } - } -#endif -} - -// ------------------------------------------------------------------------- -// Simple allocator for objects of a specified type. External locking -// is required before accessing one of these objects. -// ------------------------------------------------------------------------- - -// Metadata allocator -- keeps stats about how many bytes allocated -static uint64_t metadata_system_bytes = 0; -static void* MetaDataAlloc(size_t bytes) { - void* result = TCMalloc_SystemAlloc(bytes, 0); - if (result != NULL) { - metadata_system_bytes += bytes; - } - return result; -} - -template <class T> -class PageHeapAllocator { - private: - // How much to allocate from system at a time - static const size_t kAllocIncrement = 32 << 10; - - // Aligned size of T - static const size_t kAlignedSize - = (((sizeof(T) + kAlignment - 1) / kAlignment) * kAlignment); - - // Free area from which to carve new objects - char* free_area_; - size_t free_avail_; - - // Linked list of all regions allocated by this allocator - void* allocated_regions_; - - // Free list of already carved objects - void* free_list_; - - // Number of allocated but unfreed objects - int inuse_; - - public: - void Init() { - ASSERT(kAlignedSize <= kAllocIncrement); - inuse_ = 0; - allocated_regions_ = 0; - free_area_ = NULL; - free_avail_ = 0; - free_list_ = NULL; - } - - T* New() { - // Consult free list - void* result; - if (free_list_ != NULL) { - result = free_list_; - free_list_ = *(reinterpret_cast<void**>(result)); - } else { - if (free_avail_ < kAlignedSize) { - // Need more room - char* new_allocation = reinterpret_cast<char*>(MetaDataAlloc(kAllocIncrement)); - if (!new_allocation) - CRASH(); - - *reinterpret_cast_ptr<void**>(new_allocation) = allocated_regions_; - allocated_regions_ = new_allocation; - free_area_ = new_allocation + kAlignedSize; - free_avail_ = kAllocIncrement - kAlignedSize; - } - result = free_area_; - free_area_ += kAlignedSize; - free_avail_ -= kAlignedSize; - } - inuse_++; - return reinterpret_cast<T*>(result); - } - - void Delete(T* p) { - *(reinterpret_cast<void**>(p)) = free_list_; - free_list_ = p; - inuse_--; - } - - int inuse() const { return inuse_; } - -#if defined(WTF_CHANGES) && OS(DARWIN) - template <class Recorder> - void recordAdministrativeRegions(Recorder& recorder, const RemoteMemoryReader& reader) - { - vm_address_t adminAllocation = reinterpret_cast<vm_address_t>(allocated_regions_); - while (adminAllocation) { - recorder.recordRegion(adminAllocation, kAllocIncrement); - adminAllocation = *reader(reinterpret_cast<vm_address_t*>(adminAllocation)); - } - } -#endif -}; - -// ------------------------------------------------------------------------- -// Span - a contiguous run of pages -// ------------------------------------------------------------------------- - -// Type that can hold a page number -typedef uintptr_t PageID; - -// Type that can hold the length of a run of pages -typedef uintptr_t Length; - -static const Length kMaxValidPages = (~static_cast<Length>(0)) >> kPageShift; - -// Convert byte size into pages. This won't overflow, but may return -// an unreasonably large value if bytes is huge enough. -static inline Length pages(size_t bytes) { - return (bytes >> kPageShift) + - ((bytes & (kPageSize - 1)) > 0 ? 1 : 0); -} - -// Convert a user size into the number of bytes that will actually be -// allocated -static size_t AllocationSize(size_t bytes) { - if (bytes > kMaxSize) { - // Large object: we allocate an integral number of pages - ASSERT(bytes <= (kMaxValidPages << kPageShift)); - return pages(bytes) << kPageShift; - } else { - // Small object: find the size class to which it belongs - return ByteSizeForClass(SizeClass(bytes)); - } -} - -// Information kept for a span (a contiguous run of pages). -struct Span { - PageID start; // Starting page number - Length length; // Number of pages in span - Span* next; // Used when in link list - Span* prev; // Used when in link list - void* objects; // Linked list of free objects - unsigned int free : 1; // Is the span free -#ifndef NO_TCMALLOC_SAMPLES - unsigned int sample : 1; // Sampled object? -#endif - unsigned int sizeclass : 8; // Size-class for small objects (or 0) - unsigned int refcount : 11; // Number of non-free objects - bool decommitted : 1; - -#undef SPAN_HISTORY -#ifdef SPAN_HISTORY - // For debugging, we can keep a log events per span - int nexthistory; - char history[64]; - int value[64]; -#endif -}; - -#define ASSERT_SPAN_COMMITTED(span) ASSERT(!span->decommitted) - -#ifdef SPAN_HISTORY -void Event(Span* span, char op, int v = 0) { - span->history[span->nexthistory] = op; - span->value[span->nexthistory] = v; - span->nexthistory++; - if (span->nexthistory == sizeof(span->history)) span->nexthistory = 0; -} -#else -#define Event(s,o,v) ((void) 0) -#endif - -// Allocator/deallocator for spans -static PageHeapAllocator<Span> span_allocator; -static Span* NewSpan(PageID p, Length len) { - Span* result = span_allocator.New(); - memset(result, 0, sizeof(*result)); - result->start = p; - result->length = len; -#ifdef SPAN_HISTORY - result->nexthistory = 0; -#endif - return result; -} - -static inline void DeleteSpan(Span* span) { -#ifndef NDEBUG - // In debug mode, trash the contents of deleted Spans - memset(span, 0x3f, sizeof(*span)); -#endif - span_allocator.Delete(span); -} - -// ------------------------------------------------------------------------- -// Doubly linked list of spans. -// ------------------------------------------------------------------------- - -static inline void DLL_Init(Span* list) { - list->next = list; - list->prev = list; -} - -static inline void DLL_Remove(Span* span) { - span->prev->next = span->next; - span->next->prev = span->prev; - span->prev = NULL; - span->next = NULL; -} - -static ALWAYS_INLINE bool DLL_IsEmpty(const Span* list) { - return list->next == list; -} - -static int DLL_Length(const Span* list) { - int result = 0; - for (Span* s = list->next; s != list; s = s->next) { - result++; - } - return result; -} - -#if 0 /* Not needed at the moment -- causes compiler warnings if not used */ -static void DLL_Print(const char* label, const Span* list) { - MESSAGE("%-10s %p:", label, list); - for (const Span* s = list->next; s != list; s = s->next) { - MESSAGE(" <%p,%u,%u>", s, s->start, s->length); - } - MESSAGE("\n"); -} -#endif - -static inline void DLL_Prepend(Span* list, Span* span) { - ASSERT(span->next == NULL); - ASSERT(span->prev == NULL); - span->next = list->next; - span->prev = list; - list->next->prev = span; - list->next = span; -} - -// ------------------------------------------------------------------------- -// Stack traces kept for sampled allocations -// The following state is protected by pageheap_lock_. -// ------------------------------------------------------------------------- - -// size/depth are made the same size as a pointer so that some generic -// code below can conveniently cast them back and forth to void*. -static const int kMaxStackDepth = 31; -struct StackTrace { - uintptr_t size; // Size of object - uintptr_t depth; // Number of PC values stored in array below - void* stack[kMaxStackDepth]; -}; -static PageHeapAllocator<StackTrace> stacktrace_allocator; -static Span sampled_objects; - -// ------------------------------------------------------------------------- -// Map from page-id to per-page data -// ------------------------------------------------------------------------- - -// We use PageMap2<> for 32-bit and PageMap3<> for 64-bit machines. -// We also use a simple one-level cache for hot PageID-to-sizeclass mappings, -// because sometimes the sizeclass is all the information we need. - -// Selector class -- general selector uses 3-level map -template <int BITS> class MapSelector { - public: - typedef TCMalloc_PageMap3<BITS-kPageShift> Type; - typedef PackedCache<BITS, uint64_t> CacheType; -}; - -#if defined(WTF_CHANGES) -#if CPU(X86_64) -// On all known X86-64 platforms, the upper 16 bits are always unused and therefore -// can be excluded from the PageMap key. -// See http://en.wikipedia.org/wiki/X86-64#Virtual_address_space_details - -static const size_t kBitsUnusedOn64Bit = 16; -#else -static const size_t kBitsUnusedOn64Bit = 0; -#endif - -// A three-level map for 64-bit machines -template <> class MapSelector<64> { - public: - typedef TCMalloc_PageMap3<64 - kPageShift - kBitsUnusedOn64Bit> Type; - typedef PackedCache<64, uint64_t> CacheType; -}; -#endif - -// A two-level map for 32-bit machines -template <> class MapSelector<32> { - public: - typedef TCMalloc_PageMap2<32 - kPageShift> Type; - typedef PackedCache<32 - kPageShift, uint16_t> CacheType; -}; - -// ------------------------------------------------------------------------- -// Page-level allocator -// * Eager coalescing -// -// Heap for page-level allocation. We allow allocating and freeing a -// contiguous runs of pages (called a "span"). -// ------------------------------------------------------------------------- - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -// The page heap maintains a free list for spans that are no longer in use by -// the central cache or any thread caches. We use a background thread to -// periodically scan the free list and release a percentage of it back to the OS. - -// If free_committed_pages_ exceeds kMinimumFreeCommittedPageCount, the -// background thread: -// - wakes up -// - pauses for kScavengeDelayInSeconds -// - returns to the OS a percentage of the memory that remained unused during -// that pause (kScavengePercentage * min_free_committed_pages_since_last_scavenge_) -// The goal of this strategy is to reduce memory pressure in a timely fashion -// while avoiding thrashing the OS allocator. - -// Time delay before the page heap scavenger will consider returning pages to -// the OS. -static const int kScavengeDelayInSeconds = 2; - -// Approximate percentage of free committed pages to return to the OS in one -// scavenge. -static const float kScavengePercentage = .5f; - -// number of span lists to keep spans in when memory is returned. -static const int kMinSpanListsWithSpans = 32; - -// Number of free committed pages that we want to keep around. The minimum number of pages used when there -// is 1 span in each of the first kMinSpanListsWithSpans spanlists. Currently 528 pages. -static const size_t kMinimumFreeCommittedPageCount = kMinSpanListsWithSpans * ((1.0f+kMinSpanListsWithSpans) / 2.0f); - -#endif - -class TCMalloc_PageHeap { - public: - void init(); - - // Allocate a run of "n" pages. Returns zero if out of memory. - Span* New(Length n); - - // Delete the span "[p, p+n-1]". - // REQUIRES: span was returned by earlier call to New() and - // has not yet been deleted. - void Delete(Span* span); - - // Mark an allocated span as being used for small objects of the - // specified size-class. - // REQUIRES: span was returned by an earlier call to New() - // and has not yet been deleted. - void RegisterSizeClass(Span* span, size_t sc); - - // Split an allocated span into two spans: one of length "n" pages - // followed by another span of length "span->length - n" pages. - // Modifies "*span" to point to the first span of length "n" pages. - // Returns a pointer to the second span. - // - // REQUIRES: "0 < n < span->length" - // REQUIRES: !span->free - // REQUIRES: span->sizeclass == 0 - Span* Split(Span* span, Length n); - - // Return the descriptor for the specified page. - inline Span* GetDescriptor(PageID p) const { - return reinterpret_cast<Span*>(pagemap_.get(p)); - } - -#ifdef WTF_CHANGES - inline Span* GetDescriptorEnsureSafe(PageID p) - { - pagemap_.Ensure(p, 1); - return GetDescriptor(p); - } - - size_t ReturnedBytes() const; -#endif - - // Dump state to stderr -#ifndef WTF_CHANGES - void Dump(TCMalloc_Printer* out); -#endif - - // Return number of bytes allocated from system - inline uint64_t SystemBytes() const { return system_bytes_; } - - // Return number of free bytes in heap - uint64_t FreeBytes() const { - return (static_cast<uint64_t>(free_pages_) << kPageShift); - } - - bool Check(); - bool CheckList(Span* list, Length min_pages, Length max_pages); - - // Release all pages on the free list for reuse by the OS: - void ReleaseFreePages(); - - // Return 0 if we have no information, or else the correct sizeclass for p. - // Reads and writes to pagemap_cache_ do not require locking. - // The entries are 64 bits on 64-bit hardware and 16 bits on - // 32-bit hardware, and we don't mind raciness as long as each read of - // an entry yields a valid entry, not a partially updated entry. - size_t GetSizeClassIfCached(PageID p) const { - return pagemap_cache_.GetOrDefault(p, 0); - } - void CacheSizeClass(PageID p, size_t cl) const { pagemap_cache_.Put(p, cl); } - - private: - // Pick the appropriate map and cache types based on pointer size - typedef MapSelector<8*sizeof(uintptr_t)>::Type PageMap; - typedef MapSelector<8*sizeof(uintptr_t)>::CacheType PageMapCache; - PageMap pagemap_; - mutable PageMapCache pagemap_cache_; - - // We segregate spans of a given size into two circular linked - // lists: one for normal spans, and one for spans whose memory - // has been returned to the system. - struct SpanList { - Span normal; - Span returned; - }; - - // List of free spans of length >= kMaxPages - SpanList large_; - - // Array mapping from span length to a doubly linked list of free spans - SpanList free_[kMaxPages]; - - // Number of pages kept in free lists - uintptr_t free_pages_; - - // Bytes allocated from system - uint64_t system_bytes_; - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - // Number of pages kept in free lists that are still committed. - Length free_committed_pages_; - - // Minimum number of free committed pages since last scavenge. (Can be 0 if - // we've committed new pages since the last scavenge.) - Length min_free_committed_pages_since_last_scavenge_; -#endif - - bool GrowHeap(Length n); - - // REQUIRES span->length >= n - // Remove span from its free list, and move any leftover part of - // span into appropriate free lists. Also update "span" to have - // length exactly "n" and mark it as non-free so it can be returned - // to the client. - // - // "released" is true iff "span" was found on a "returned" list. - void Carve(Span* span, Length n, bool released); - - void RecordSpan(Span* span) { - pagemap_.set(span->start, span); - if (span->length > 1) { - pagemap_.set(span->start + span->length - 1, span); - } - } - - // Allocate a large span of length == n. If successful, returns a - // span of exactly the specified length. Else, returns NULL. - Span* AllocLarge(Length n); - -#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - // Incrementally release some memory to the system. - // IncrementalScavenge(n) is called whenever n pages are freed. - void IncrementalScavenge(Length n); -#endif - - // Number of pages to deallocate before doing more scavenging - int64_t scavenge_counter_; - - // Index of last free list we scavenged - size_t scavenge_index_; - -#if defined(WTF_CHANGES) && OS(DARWIN) - friend class FastMallocZone; -#endif - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - void initializeScavenger(); - ALWAYS_INLINE void signalScavenger(); - void scavenge(); - ALWAYS_INLINE bool shouldScavenge() const; - -#if !HAVE(DISPATCH_H) - static NO_RETURN_WITH_VALUE void* runScavengerThread(void*); - NO_RETURN void scavengerThread(); - - // Keeps track of whether the background thread is actively scavenging memory every kScavengeDelayInSeconds, or - // it's blocked waiting for more pages to be deleted. - bool m_scavengeThreadActive; - - pthread_mutex_t m_scavengeMutex; - pthread_cond_t m_scavengeCondition; -#else // !HAVE(DISPATCH_H) - void periodicScavenge(); - - dispatch_queue_t m_scavengeQueue; - dispatch_source_t m_scavengeTimer; - bool m_scavengingScheduled; -#endif - -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -}; - -void TCMalloc_PageHeap::init() -{ - pagemap_.init(MetaDataAlloc); - pagemap_cache_ = PageMapCache(0); - free_pages_ = 0; - system_bytes_ = 0; - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - free_committed_pages_ = 0; - min_free_committed_pages_since_last_scavenge_ = 0; -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - - scavenge_counter_ = 0; - // Start scavenging at kMaxPages list - scavenge_index_ = kMaxPages-1; - COMPILE_ASSERT(kNumClasses <= (1 << PageMapCache::kValuebits), valuebits); - DLL_Init(&large_.normal); - DLL_Init(&large_.returned); - for (size_t i = 0; i < kMaxPages; i++) { - DLL_Init(&free_[i].normal); - DLL_Init(&free_[i].returned); - } - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - initializeScavenger(); -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -} - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - -#if !HAVE(DISPATCH_H) - -void TCMalloc_PageHeap::initializeScavenger() -{ - // Create a non-recursive mutex. -#if !defined(PTHREAD_MUTEX_NORMAL) || PTHREAD_MUTEX_NORMAL == PTHREAD_MUTEX_DEFAULT - pthread_mutex_init(&m_scavengeMutex, 0); -#else - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - - pthread_mutex_init(&m_scavengeMutex, &attr); - - pthread_mutexattr_destroy(&attr); -#endif - - pthread_cond_init(&m_scavengeCondition, 0); - m_scavengeThreadActive = true; - pthread_t thread; - pthread_create(&thread, 0, runScavengerThread, this); -} - -void* TCMalloc_PageHeap::runScavengerThread(void* context) -{ - static_cast<TCMalloc_PageHeap*>(context)->scavengerThread(); -#if COMPILER(MSVC) - // Without this, Visual Studio will complain that this method does not return a value. - return 0; -#endif -} - -ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger() -{ - // m_scavengeMutex should be held before accessing m_scavengeThreadActive. - ASSERT(pthread_mutex_trylock(m_scavengeMutex)); - if (!m_scavengeThreadActive && shouldScavenge()) - pthread_cond_signal(&m_scavengeCondition); -} - -#else // !HAVE(DISPATCH_H) - -void TCMalloc_PageHeap::initializeScavenger() -{ - m_scavengeQueue = dispatch_queue_create("com.apple.JavaScriptCore.FastMallocSavenger", NULL); - m_scavengeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, m_scavengeQueue); - dispatch_time_t startTime = dispatch_time(DISPATCH_TIME_NOW, kScavengeDelayInSeconds * NSEC_PER_SEC); - dispatch_source_set_timer(m_scavengeTimer, startTime, kScavengeDelayInSeconds * NSEC_PER_SEC, 1000 * NSEC_PER_USEC); - dispatch_source_set_event_handler(m_scavengeTimer, ^{ periodicScavenge(); }); - m_scavengingScheduled = false; -} - -ALWAYS_INLINE void TCMalloc_PageHeap::signalScavenger() -{ - ASSERT(IsHeld(pageheap_lock)); - if (!m_scavengingScheduled && shouldScavenge()) { - m_scavengingScheduled = true; - dispatch_resume(m_scavengeTimer); - } -} - -#endif - -void TCMalloc_PageHeap::scavenge() -{ - size_t pagesToRelease = min_free_committed_pages_since_last_scavenge_ * kScavengePercentage; - size_t targetPageCount = std::max<size_t>(kMinimumFreeCommittedPageCount, free_committed_pages_ - pagesToRelease); - - while (free_committed_pages_ > targetPageCount) { - for (int i = kMaxPages; i > 0 && free_committed_pages_ >= targetPageCount; i--) { - SpanList* slist = (static_cast<size_t>(i) == kMaxPages) ? &large_ : &free_[i]; - // If the span size is bigger than kMinSpanListsWithSpans pages return all the spans in the list, else return all but 1 span. - // Return only 50% of a spanlist at a time so spans of size 1 are not the only ones left. - size_t length = DLL_Length(&slist->normal); - size_t numSpansToReturn = (i > kMinSpanListsWithSpans) ? length : length / 2; - for (int j = 0; static_cast<size_t>(j) < numSpansToReturn && !DLL_IsEmpty(&slist->normal) && free_committed_pages_ > targetPageCount; j++) { - Span* s = slist->normal.prev; - DLL_Remove(s); - ASSERT(!s->decommitted); - if (!s->decommitted) { - TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), - static_cast<size_t>(s->length << kPageShift)); - ASSERT(free_committed_pages_ >= s->length); - free_committed_pages_ -= s->length; - s->decommitted = true; - } - DLL_Prepend(&slist->returned, s); - } - } - } - - min_free_committed_pages_since_last_scavenge_ = free_committed_pages_; -} - -ALWAYS_INLINE bool TCMalloc_PageHeap::shouldScavenge() const -{ - return free_committed_pages_ > kMinimumFreeCommittedPageCount; -} - -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - -inline Span* TCMalloc_PageHeap::New(Length n) { - ASSERT(Check()); - ASSERT(n > 0); - - // Find first size >= n that has a non-empty list - for (Length s = n; s < kMaxPages; s++) { - Span* ll = NULL; - bool released = false; - if (!DLL_IsEmpty(&free_[s].normal)) { - // Found normal span - ll = &free_[s].normal; - } else if (!DLL_IsEmpty(&free_[s].returned)) { - // Found returned span; reallocate it - ll = &free_[s].returned; - released = true; - } else { - // Keep looking in larger classes - continue; - } - - Span* result = ll->next; - Carve(result, n, released); -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - // The newly allocated memory is from a span that's in the normal span list (already committed). Update the - // free committed pages count. - ASSERT(free_committed_pages_ >= n); - free_committed_pages_ -= n; - if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_) - min_free_committed_pages_since_last_scavenge_ = free_committed_pages_; -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - ASSERT(Check()); - free_pages_ -= n; - return result; - } - - Span* result = AllocLarge(n); - if (result != NULL) { - ASSERT_SPAN_COMMITTED(result); - return result; - } - - // Grow the heap and try again - if (!GrowHeap(n)) { - ASSERT(Check()); - return NULL; - } - - return AllocLarge(n); -} - -Span* TCMalloc_PageHeap::AllocLarge(Length n) { - // find the best span (closest to n in size). - // The following loops implements address-ordered best-fit. - bool from_released = false; - Span *best = NULL; - - // Search through normal list - for (Span* span = large_.normal.next; - span != &large_.normal; - span = span->next) { - if (span->length >= n) { - if ((best == NULL) - || (span->length < best->length) - || ((span->length == best->length) && (span->start < best->start))) { - best = span; - from_released = false; - } - } - } - - // Search through released list in case it has a better fit - for (Span* span = large_.returned.next; - span != &large_.returned; - span = span->next) { - if (span->length >= n) { - if ((best == NULL) - || (span->length < best->length) - || ((span->length == best->length) && (span->start < best->start))) { - best = span; - from_released = true; - } - } - } - - if (best != NULL) { - Carve(best, n, from_released); -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - // The newly allocated memory is from a span that's in the normal span list (already committed). Update the - // free committed pages count. - ASSERT(free_committed_pages_ >= n); - free_committed_pages_ -= n; - if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_) - min_free_committed_pages_since_last_scavenge_ = free_committed_pages_; -#endif // USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - ASSERT(Check()); - free_pages_ -= n; - return best; - } - return NULL; -} - -Span* TCMalloc_PageHeap::Split(Span* span, Length n) { - ASSERT(0 < n); - ASSERT(n < span->length); - ASSERT(!span->free); - ASSERT(span->sizeclass == 0); - Event(span, 'T', n); - - const Length extra = span->length - n; - Span* leftover = NewSpan(span->start + n, extra); - Event(leftover, 'U', extra); - RecordSpan(leftover); - pagemap_.set(span->start + n - 1, span); // Update map from pageid to span - span->length = n; - - return leftover; -} - -inline void TCMalloc_PageHeap::Carve(Span* span, Length n, bool released) { - ASSERT(n > 0); - DLL_Remove(span); - span->free = 0; - Event(span, 'A', n); - - if (released) { - // If the span chosen to carve from is decommited, commit the entire span at once to avoid committing spans 1 page at a time. - ASSERT(span->decommitted); - TCMalloc_SystemCommit(reinterpret_cast<void*>(span->start << kPageShift), static_cast<size_t>(span->length << kPageShift)); - span->decommitted = false; -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - free_committed_pages_ += span->length; -#endif - } - - const int extra = static_cast<int>(span->length - n); - ASSERT(extra >= 0); - if (extra > 0) { - Span* leftover = NewSpan(span->start + n, extra); - leftover->free = 1; - leftover->decommitted = false; - Event(leftover, 'S', extra); - RecordSpan(leftover); - - // Place leftover span on appropriate free list - SpanList* listpair = (static_cast<size_t>(extra) < kMaxPages) ? &free_[extra] : &large_; - Span* dst = &listpair->normal; - DLL_Prepend(dst, leftover); - - span->length = n; - pagemap_.set(span->start + n - 1, span); - } -} - -static ALWAYS_INLINE void mergeDecommittedStates(Span* destination, Span* other) -{ - if (destination->decommitted && !other->decommitted) { - TCMalloc_SystemRelease(reinterpret_cast<void*>(other->start << kPageShift), - static_cast<size_t>(other->length << kPageShift)); - } else if (other->decommitted && !destination->decommitted) { - TCMalloc_SystemRelease(reinterpret_cast<void*>(destination->start << kPageShift), - static_cast<size_t>(destination->length << kPageShift)); - destination->decommitted = true; - } -} - -inline void TCMalloc_PageHeap::Delete(Span* span) { - ASSERT(Check()); - ASSERT(!span->free); - ASSERT(span->length > 0); - ASSERT(GetDescriptor(span->start) == span); - ASSERT(GetDescriptor(span->start + span->length - 1) == span); - span->sizeclass = 0; -#ifndef NO_TCMALLOC_SAMPLES - span->sample = 0; -#endif - - // Coalesce -- we guarantee that "p" != 0, so no bounds checking - // necessary. We do not bother resetting the stale pagemap - // entries for the pieces we are merging together because we only - // care about the pagemap entries for the boundaries. -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - // Track the total size of the neighboring free spans that are committed. - Length neighboringCommittedSpansLength = 0; -#endif - const PageID p = span->start; - const Length n = span->length; - Span* prev = GetDescriptor(p-1); - if (prev != NULL && prev->free) { - // Merge preceding span into this span - ASSERT(prev->start + prev->length == p); - const Length len = prev->length; -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - if (!prev->decommitted) - neighboringCommittedSpansLength += len; -#endif - mergeDecommittedStates(span, prev); - DLL_Remove(prev); - DeleteSpan(prev); - span->start -= len; - span->length += len; - pagemap_.set(span->start, span); - Event(span, 'L', len); - } - Span* next = GetDescriptor(p+n); - if (next != NULL && next->free) { - // Merge next span into this span - ASSERT(next->start == p+n); - const Length len = next->length; -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - if (!next->decommitted) - neighboringCommittedSpansLength += len; -#endif - mergeDecommittedStates(span, next); - DLL_Remove(next); - DeleteSpan(next); - span->length += len; - pagemap_.set(span->start + span->length - 1, span); - Event(span, 'R', len); - } - - Event(span, 'D', span->length); - span->free = 1; - if (span->decommitted) { - if (span->length < kMaxPages) - DLL_Prepend(&free_[span->length].returned, span); - else - DLL_Prepend(&large_.returned, span); - } else { - if (span->length < kMaxPages) - DLL_Prepend(&free_[span->length].normal, span); - else - DLL_Prepend(&large_.normal, span); - } - free_pages_ += n; - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - if (span->decommitted) { - // If the merged span is decommitted, that means we decommitted any neighboring spans that were - // committed. Update the free committed pages count. - free_committed_pages_ -= neighboringCommittedSpansLength; - if (free_committed_pages_ < min_free_committed_pages_since_last_scavenge_) - min_free_committed_pages_since_last_scavenge_ = free_committed_pages_; - } else { - // If the merged span remains committed, add the deleted span's size to the free committed pages count. - free_committed_pages_ += n; - } - - // Make sure the scavenge thread becomes active if we have enough freed pages to release some back to the system. - signalScavenger(); -#else - IncrementalScavenge(n); -#endif - - ASSERT(Check()); -} - -#if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY -void TCMalloc_PageHeap::IncrementalScavenge(Length n) { - // Fast path; not yet time to release memory - scavenge_counter_ -= n; - if (scavenge_counter_ >= 0) return; // Not yet time to scavenge - - // If there is nothing to release, wait for so many pages before - // scavenging again. With 4K pages, this comes to 16MB of memory. - static const size_t kDefaultReleaseDelay = 1 << 8; - - // Find index of free list to scavenge - size_t index = scavenge_index_ + 1; - for (size_t i = 0; i < kMaxPages+1; i++) { - if (index > kMaxPages) index = 0; - SpanList* slist = (index == kMaxPages) ? &large_ : &free_[index]; - if (!DLL_IsEmpty(&slist->normal)) { - // Release the last span on the normal portion of this list - Span* s = slist->normal.prev; - DLL_Remove(s); - TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), - static_cast<size_t>(s->length << kPageShift)); - s->decommitted = true; - DLL_Prepend(&slist->returned, s); - - scavenge_counter_ = std::max<size_t>(64UL, std::min<size_t>(kDefaultReleaseDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay))); - - if (index == kMaxPages && !DLL_IsEmpty(&slist->normal)) - scavenge_index_ = index - 1; - else - scavenge_index_ = index; - return; - } - index++; - } - - // Nothing to scavenge, delay for a while - scavenge_counter_ = kDefaultReleaseDelay; -} -#endif - -void TCMalloc_PageHeap::RegisterSizeClass(Span* span, size_t sc) { - // Associate span object with all interior pages as well - ASSERT(!span->free); - ASSERT(GetDescriptor(span->start) == span); - ASSERT(GetDescriptor(span->start+span->length-1) == span); - Event(span, 'C', sc); - span->sizeclass = static_cast<unsigned int>(sc); - for (Length i = 1; i < span->length-1; i++) { - pagemap_.set(span->start+i, span); - } -} - -#ifdef WTF_CHANGES -size_t TCMalloc_PageHeap::ReturnedBytes() const { - size_t result = 0; - for (unsigned s = 0; s < kMaxPages; s++) { - const int r_length = DLL_Length(&free_[s].returned); - unsigned r_pages = s * r_length; - result += r_pages << kPageShift; - } - - for (Span* s = large_.returned.next; s != &large_.returned; s = s->next) - result += s->length << kPageShift; - return result; -} -#endif - -#ifndef WTF_CHANGES -static double PagesToMB(uint64_t pages) { - return (pages << kPageShift) / 1048576.0; -} - -void TCMalloc_PageHeap::Dump(TCMalloc_Printer* out) { - int nonempty_sizes = 0; - for (int s = 0; s < kMaxPages; s++) { - if (!DLL_IsEmpty(&free_[s].normal) || !DLL_IsEmpty(&free_[s].returned)) { - nonempty_sizes++; - } - } - out->printf("------------------------------------------------\n"); - out->printf("PageHeap: %d sizes; %6.1f MB free\n", - nonempty_sizes, PagesToMB(free_pages_)); - out->printf("------------------------------------------------\n"); - uint64_t total_normal = 0; - uint64_t total_returned = 0; - for (int s = 0; s < kMaxPages; s++) { - const int n_length = DLL_Length(&free_[s].normal); - const int r_length = DLL_Length(&free_[s].returned); - if (n_length + r_length > 0) { - uint64_t n_pages = s * n_length; - uint64_t r_pages = s * r_length; - total_normal += n_pages; - total_returned += r_pages; - out->printf("%6u pages * %6u spans ~ %6.1f MB; %6.1f MB cum" - "; unmapped: %6.1f MB; %6.1f MB cum\n", - s, - (n_length + r_length), - PagesToMB(n_pages + r_pages), - PagesToMB(total_normal + total_returned), - PagesToMB(r_pages), - PagesToMB(total_returned)); - } - } - - uint64_t n_pages = 0; - uint64_t r_pages = 0; - int n_spans = 0; - int r_spans = 0; - out->printf("Normal large spans:\n"); - for (Span* s = large_.normal.next; s != &large_.normal; s = s->next) { - out->printf(" [ %6" PRIuS " pages ] %6.1f MB\n", - s->length, PagesToMB(s->length)); - n_pages += s->length; - n_spans++; - } - out->printf("Unmapped large spans:\n"); - for (Span* s = large_.returned.next; s != &large_.returned; s = s->next) { - out->printf(" [ %6" PRIuS " pages ] %6.1f MB\n", - s->length, PagesToMB(s->length)); - r_pages += s->length; - r_spans++; - } - total_normal += n_pages; - total_returned += r_pages; - out->printf(">255 large * %6u spans ~ %6.1f MB; %6.1f MB cum" - "; unmapped: %6.1f MB; %6.1f MB cum\n", - (n_spans + r_spans), - PagesToMB(n_pages + r_pages), - PagesToMB(total_normal + total_returned), - PagesToMB(r_pages), - PagesToMB(total_returned)); -} -#endif - -bool TCMalloc_PageHeap::GrowHeap(Length n) { - ASSERT(kMaxPages >= kMinSystemAlloc); - if (n > kMaxValidPages) return false; - Length ask = (n>kMinSystemAlloc) ? n : static_cast<Length>(kMinSystemAlloc); - size_t actual_size; - void* ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize); - if (ptr == NULL) { - if (n < ask) { - // Try growing just "n" pages - ask = n; - ptr = TCMalloc_SystemAlloc(ask << kPageShift, &actual_size, kPageSize); - } - if (ptr == NULL) return false; - } - ask = actual_size >> kPageShift; - - uint64_t old_system_bytes = system_bytes_; - system_bytes_ += (ask << kPageShift); - const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; - ASSERT(p > 0); - - // If we have already a lot of pages allocated, just pre allocate a bunch of - // memory for the page map. This prevents fragmentation by pagemap metadata - // when a program keeps allocating and freeing large blocks. - - if (old_system_bytes < kPageMapBigAllocationThreshold - && system_bytes_ >= kPageMapBigAllocationThreshold) { - pagemap_.PreallocateMoreMemory(); - } - - // Make sure pagemap_ has entries for all of the new pages. - // Plus ensure one before and one after so coalescing code - // does not need bounds-checking. - if (pagemap_.Ensure(p-1, ask+2)) { - // Pretend the new area is allocated and then Delete() it to - // cause any necessary coalescing to occur. - // - // We do not adjust free_pages_ here since Delete() will do it for us. - Span* span = NewSpan(p, ask); - RecordSpan(span); - Delete(span); - ASSERT(Check()); - return true; - } else { - // We could not allocate memory within "pagemap_" - // TODO: Once we can return memory to the system, return the new span - return false; - } -} - -bool TCMalloc_PageHeap::Check() { - ASSERT(free_[0].normal.next == &free_[0].normal); - ASSERT(free_[0].returned.next == &free_[0].returned); - CheckList(&large_.normal, kMaxPages, 1000000000); - CheckList(&large_.returned, kMaxPages, 1000000000); - for (Length s = 1; s < kMaxPages; s++) { - CheckList(&free_[s].normal, s, s); - CheckList(&free_[s].returned, s, s); - } - return true; -} - -#if ASSERT_DISABLED -bool TCMalloc_PageHeap::CheckList(Span*, Length, Length) { - return true; -} -#else -bool TCMalloc_PageHeap::CheckList(Span* list, Length min_pages, Length max_pages) { - for (Span* s = list->next; s != list; s = s->next) { - CHECK_CONDITION(s->free); - CHECK_CONDITION(s->length >= min_pages); - CHECK_CONDITION(s->length <= max_pages); - CHECK_CONDITION(GetDescriptor(s->start) == s); - CHECK_CONDITION(GetDescriptor(s->start+s->length-1) == s); - } - return true; -} -#endif - -static void ReleaseFreeList(Span* list, Span* returned) { - // Walk backwards through list so that when we push these - // spans on the "returned" list, we preserve the order. - while (!DLL_IsEmpty(list)) { - Span* s = list->prev; - DLL_Remove(s); - DLL_Prepend(returned, s); - TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), - static_cast<size_t>(s->length << kPageShift)); - } -} - -void TCMalloc_PageHeap::ReleaseFreePages() { - for (Length s = 0; s < kMaxPages; s++) { - ReleaseFreeList(&free_[s].normal, &free_[s].returned); - } - ReleaseFreeList(&large_.normal, &large_.returned); - ASSERT(Check()); -} - -//------------------------------------------------------------------- -// Free list -//------------------------------------------------------------------- - -class TCMalloc_ThreadCache_FreeList { - private: - void* list_; // Linked list of nodes - uint16_t length_; // Current length - uint16_t lowater_; // Low water mark for list length - - public: - void Init() { - list_ = NULL; - length_ = 0; - lowater_ = 0; - } - - // Return current length of list - int length() const { - return length_; - } - - // Is list empty? - bool empty() const { - return list_ == NULL; - } - - // Low-water mark management - int lowwatermark() const { return lowater_; } - void clear_lowwatermark() { lowater_ = length_; } - - ALWAYS_INLINE void Push(void* ptr) { - SLL_Push(&list_, ptr); - length_++; - } - - void PushRange(int N, void *start, void *end) { - SLL_PushRange(&list_, start, end); - length_ = length_ + static_cast<uint16_t>(N); - } - - void PopRange(int N, void **start, void **end) { - SLL_PopRange(&list_, N, start, end); - ASSERT(length_ >= N); - length_ = length_ - static_cast<uint16_t>(N); - if (length_ < lowater_) lowater_ = length_; - } - - ALWAYS_INLINE void* Pop() { - ASSERT(list_ != NULL); - length_--; - if (length_ < lowater_) lowater_ = length_; - return SLL_Pop(&list_); - } - -#ifdef WTF_CHANGES - template <class Finder, class Reader> - void enumerateFreeObjects(Finder& finder, const Reader& reader) - { - for (void* nextObject = list_; nextObject; nextObject = *reader(reinterpret_cast<void**>(nextObject))) - finder.visit(nextObject); - } -#endif -}; - -//------------------------------------------------------------------- -// Data kept per thread -//------------------------------------------------------------------- - -class TCMalloc_ThreadCache { - private: - typedef TCMalloc_ThreadCache_FreeList FreeList; -#if COMPILER(MSVC) - typedef DWORD ThreadIdentifier; -#else - typedef pthread_t ThreadIdentifier; -#endif - - size_t size_; // Combined size of data - ThreadIdentifier tid_; // Which thread owns it - bool in_setspecific_; // Called pthread_setspecific? - FreeList list_[kNumClasses]; // Array indexed by size-class - - // We sample allocations, biased by the size of the allocation - uint32_t rnd_; // Cheap random number generator - size_t bytes_until_sample_; // Bytes until we sample next - - // Allocate a new heap. REQUIRES: pageheap_lock is held. - static inline TCMalloc_ThreadCache* NewHeap(ThreadIdentifier tid); - - // Use only as pthread thread-specific destructor function. - static void DestroyThreadCache(void* ptr); - public: - // All ThreadCache objects are kept in a linked list (for stats collection) - TCMalloc_ThreadCache* next_; - TCMalloc_ThreadCache* prev_; - - void Init(ThreadIdentifier tid); - void Cleanup(); - - // Accessors (mostly just for printing stats) - int freelist_length(size_t cl) const { return list_[cl].length(); } - - // Total byte size in cache - size_t Size() const { return size_; } - - ALWAYS_INLINE void* Allocate(size_t size); - void Deallocate(void* ptr, size_t size_class); - - ALWAYS_INLINE void FetchFromCentralCache(size_t cl, size_t allocationSize); - void ReleaseToCentralCache(size_t cl, int N); - void Scavenge(); - void Print() const; - - // Record allocation of "k" bytes. Return true iff allocation - // should be sampled - bool SampleAllocation(size_t k); - - // Pick next sampling point - void PickNextSample(size_t k); - - static void InitModule(); - static void InitTSD(); - static TCMalloc_ThreadCache* GetThreadHeap(); - static TCMalloc_ThreadCache* GetCache(); - static TCMalloc_ThreadCache* GetCacheIfPresent(); - static TCMalloc_ThreadCache* CreateCacheIfNecessary(); - static void DeleteCache(TCMalloc_ThreadCache* heap); - static void BecomeIdle(); - static void RecomputeThreadCacheSize(); - -#ifdef WTF_CHANGES - template <class Finder, class Reader> - void enumerateFreeObjects(Finder& finder, const Reader& reader) - { - for (unsigned sizeClass = 0; sizeClass < kNumClasses; sizeClass++) - list_[sizeClass].enumerateFreeObjects(finder, reader); - } -#endif -}; - -//------------------------------------------------------------------- -// Data kept per size-class in central cache -//------------------------------------------------------------------- - -class TCMalloc_Central_FreeList { - public: - void Init(size_t cl); - - // These methods all do internal locking. - - // Insert the specified range into the central freelist. N is the number of - // elements in the range. - void InsertRange(void *start, void *end, int N); - - // Returns the actual number of fetched elements into N. - void RemoveRange(void **start, void **end, int *N); - - // Returns the number of free objects in cache. - size_t length() { - SpinLockHolder h(&lock_); - return counter_; - } - - // Returns the number of free objects in the transfer cache. - int tc_length() { - SpinLockHolder h(&lock_); - return used_slots_ * num_objects_to_move[size_class_]; - } - -#ifdef WTF_CHANGES - template <class Finder, class Reader> - void enumerateFreeObjects(Finder& finder, const Reader& reader, TCMalloc_Central_FreeList* remoteCentralFreeList) - { - for (Span* span = &empty_; span && span != &empty_; span = (span->next ? reader(span->next) : 0)) - ASSERT(!span->objects); - - ASSERT(!nonempty_.objects); - static const ptrdiff_t nonemptyOffset = reinterpret_cast<const char*>(&nonempty_) - reinterpret_cast<const char*>(this); - - Span* remoteNonempty = reinterpret_cast<Span*>(reinterpret_cast<char*>(remoteCentralFreeList) + nonemptyOffset); - Span* remoteSpan = nonempty_.next; - - for (Span* span = reader(remoteSpan); span && remoteSpan != remoteNonempty; remoteSpan = span->next, span = (span->next ? reader(span->next) : 0)) { - for (void* nextObject = span->objects; nextObject; nextObject = *reader(reinterpret_cast<void**>(nextObject))) - finder.visit(nextObject); - } - } -#endif - - private: - // REQUIRES: lock_ is held - // Remove object from cache and return. - // Return NULL if no free entries in cache. - void* FetchFromSpans(); - - // REQUIRES: lock_ is held - // Remove object from cache and return. Fetches - // from pageheap if cache is empty. Only returns - // NULL on allocation failure. - void* FetchFromSpansSafe(); - - // REQUIRES: lock_ is held - // Release a linked list of objects to spans. - // May temporarily release lock_. - void ReleaseListToSpans(void *start); - - // REQUIRES: lock_ is held - // Release an object to spans. - // May temporarily release lock_. - ALWAYS_INLINE void ReleaseToSpans(void* object); - - // REQUIRES: lock_ is held - // Populate cache by fetching from the page heap. - // May temporarily release lock_. - ALWAYS_INLINE void Populate(); - - // REQUIRES: lock is held. - // Tries to make room for a TCEntry. If the cache is full it will try to - // expand it at the cost of some other cache size. Return false if there is - // no space. - bool MakeCacheSpace(); - - // REQUIRES: lock_ for locked_size_class is held. - // Picks a "random" size class to steal TCEntry slot from. In reality it - // just iterates over the sizeclasses but does so without taking a lock. - // Returns true on success. - // May temporarily lock a "random" size class. - static ALWAYS_INLINE bool EvictRandomSizeClass(size_t locked_size_class, bool force); - - // REQUIRES: lock_ is *not* held. - // Tries to shrink the Cache. If force is true it will relase objects to - // spans if it allows it to shrink the cache. Return false if it failed to - // shrink the cache. Decrements cache_size_ on succeess. - // May temporarily take lock_. If it takes lock_, the locked_size_class - // lock is released to the thread from holding two size class locks - // concurrently which could lead to a deadlock. - bool ShrinkCache(int locked_size_class, bool force); - - // This lock protects all the data members. cached_entries and cache_size_ - // may be looked at without holding the lock. - SpinLock lock_; - - // We keep linked lists of empty and non-empty spans. - size_t size_class_; // My size class - Span empty_; // Dummy header for list of empty spans - Span nonempty_; // Dummy header for list of non-empty spans - size_t counter_; // Number of free objects in cache entry - - // Here we reserve space for TCEntry cache slots. Since one size class can - // end up getting all the TCEntries quota in the system we just preallocate - // sufficient number of entries here. - TCEntry tc_slots_[kNumTransferEntries]; - - // Number of currently used cached entries in tc_slots_. This variable is - // updated under a lock but can be read without one. - int32_t used_slots_; - // The current number of slots for this size class. This is an - // adaptive value that is increased if there is lots of traffic - // on a given size class. - int32_t cache_size_; -}; - -// Pad each CentralCache object to multiple of 64 bytes -class TCMalloc_Central_FreeListPadded : public TCMalloc_Central_FreeList { - private: - char pad_[(64 - (sizeof(TCMalloc_Central_FreeList) % 64)) % 64]; -}; - -//------------------------------------------------------------------- -// Global variables -//------------------------------------------------------------------- - -// Central cache -- a collection of free-lists, one per size-class. -// We have a separate lock per free-list to reduce contention. -static TCMalloc_Central_FreeListPadded central_cache[kNumClasses]; - -// Page-level allocator -static SpinLock pageheap_lock = SPINLOCK_INITIALIZER; -static AllocAlignmentInteger pageheap_memory[(sizeof(TCMalloc_PageHeap) + sizeof(AllocAlignmentInteger) - 1) / sizeof(AllocAlignmentInteger)]; -static bool phinited = false; - -// Avoid extra level of indirection by making "pageheap" be just an alias -// of pageheap_memory. -typedef union { - void* m_memory; - TCMalloc_PageHeap* m_pageHeap; -} PageHeapUnion; - -static inline TCMalloc_PageHeap* getPageHeap() -{ - PageHeapUnion u = { &pageheap_memory[0] }; - return u.m_pageHeap; -} - -#define pageheap getPageHeap() - -#if USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY - -#if !HAVE(DISPATCH_H) -#if OS(WINDOWS) -static void sleep(unsigned seconds) -{ - ::Sleep(seconds * 1000); -} -#endif - -void TCMalloc_PageHeap::scavengerThread() -{ -#if HAVE(PTHREAD_SETNAME_NP) - pthread_setname_np("JavaScriptCore: FastMalloc scavenger"); -#endif - - while (1) { - if (!shouldScavenge()) { - pthread_mutex_lock(&m_scavengeMutex); - m_scavengeThreadActive = false; - // Block until there are enough free committed pages to release back to the system. - pthread_cond_wait(&m_scavengeCondition, &m_scavengeMutex); - m_scavengeThreadActive = true; - pthread_mutex_unlock(&m_scavengeMutex); - } - sleep(kScavengeDelayInSeconds); - { - SpinLockHolder h(&pageheap_lock); - pageheap->scavenge(); - } - } -} - -#else - -void TCMalloc_PageHeap::periodicScavenge() -{ - SpinLockHolder h(&pageheap_lock); - pageheap->scavenge(); - - if (!shouldScavenge()) { - m_scavengingScheduled = false; - dispatch_suspend(m_scavengeTimer); - } -} -#endif // HAVE(DISPATCH_H) - -#endif - -// If TLS is available, we also store a copy -// of the per-thread object in a __thread variable -// since __thread variables are faster to read -// than pthread_getspecific(). We still need -// pthread_setspecific() because __thread -// variables provide no way to run cleanup -// code when a thread is destroyed. -#ifdef HAVE_TLS -static __thread TCMalloc_ThreadCache *threadlocal_heap; -#endif -// Thread-specific key. Initialization here is somewhat tricky -// because some Linux startup code invokes malloc() before it -// is in a good enough state to handle pthread_keycreate(). -// Therefore, we use TSD keys only after tsd_inited is set to true. -// Until then, we use a slow path to get the heap object. -static bool tsd_inited = false; -static pthread_key_t heap_key; -#if COMPILER(MSVC) -DWORD tlsIndex = TLS_OUT_OF_INDEXES; -#endif - -static ALWAYS_INLINE void setThreadHeap(TCMalloc_ThreadCache* heap) -{ - // still do pthread_setspecific when using MSVC fast TLS to - // benefit from the delete callback. - pthread_setspecific(heap_key, heap); -#if COMPILER(MSVC) - TlsSetValue(tlsIndex, heap); -#endif -} - -// Allocator for thread heaps -static PageHeapAllocator<TCMalloc_ThreadCache> threadheap_allocator; - -// Linked list of heap objects. Protected by pageheap_lock. -static TCMalloc_ThreadCache* thread_heaps = NULL; -static int thread_heap_count = 0; - -// Overall thread cache size. Protected by pageheap_lock. -static size_t overall_thread_cache_size = kDefaultOverallThreadCacheSize; - -// Global per-thread cache size. Writes are protected by -// pageheap_lock. Reads are done without any locking, which should be -// fine as long as size_t can be written atomically and we don't place -// invariants between this variable and other pieces of state. -static volatile size_t per_thread_cache_size = kMaxThreadCacheSize; - -//------------------------------------------------------------------- -// Central cache implementation -//------------------------------------------------------------------- - -void TCMalloc_Central_FreeList::Init(size_t cl) { - lock_.Init(); - size_class_ = cl; - DLL_Init(&empty_); - DLL_Init(&nonempty_); - counter_ = 0; - - cache_size_ = 1; - used_slots_ = 0; - ASSERT(cache_size_ <= kNumTransferEntries); -} - -void TCMalloc_Central_FreeList::ReleaseListToSpans(void* start) { - while (start) { - void *next = SLL_Next(start); - ReleaseToSpans(start); - start = next; - } -} - -ALWAYS_INLINE void TCMalloc_Central_FreeList::ReleaseToSpans(void* object) { - const PageID p = reinterpret_cast<uintptr_t>(object) >> kPageShift; - Span* span = pageheap->GetDescriptor(p); - ASSERT(span != NULL); - ASSERT(span->refcount > 0); - - // If span is empty, move it to non-empty list - if (span->objects == NULL) { - DLL_Remove(span); - DLL_Prepend(&nonempty_, span); - Event(span, 'N', 0); - } - - // The following check is expensive, so it is disabled by default - if (false) { - // Check that object does not occur in list - unsigned got = 0; - for (void* p = span->objects; p != NULL; p = *((void**) p)) { - ASSERT(p != object); - got++; - } - ASSERT(got + span->refcount == - (span->length<<kPageShift)/ByteSizeForClass(span->sizeclass)); - } - - counter_++; - span->refcount--; - if (span->refcount == 0) { - Event(span, '#', 0); - counter_ -= (span->length<<kPageShift) / ByteSizeForClass(span->sizeclass); - DLL_Remove(span); - - // Release central list lock while operating on pageheap - lock_.Unlock(); - { - SpinLockHolder h(&pageheap_lock); - pageheap->Delete(span); - } - lock_.Lock(); - } else { - *(reinterpret_cast<void**>(object)) = span->objects; - span->objects = object; - } -} - -ALWAYS_INLINE bool TCMalloc_Central_FreeList::EvictRandomSizeClass( - size_t locked_size_class, bool force) { - static int race_counter = 0; - int t = race_counter++; // Updated without a lock, but who cares. - if (t >= static_cast<int>(kNumClasses)) { - while (t >= static_cast<int>(kNumClasses)) { - t -= kNumClasses; - } - race_counter = t; - } - ASSERT(t >= 0); - ASSERT(t < static_cast<int>(kNumClasses)); - if (t == static_cast<int>(locked_size_class)) return false; - return central_cache[t].ShrinkCache(static_cast<int>(locked_size_class), force); -} - -bool TCMalloc_Central_FreeList::MakeCacheSpace() { - // Is there room in the cache? - if (used_slots_ < cache_size_) return true; - // Check if we can expand this cache? - if (cache_size_ == kNumTransferEntries) return false; - // Ok, we'll try to grab an entry from some other size class. - if (EvictRandomSizeClass(size_class_, false) || - EvictRandomSizeClass(size_class_, true)) { - // Succeeded in evicting, we're going to make our cache larger. - cache_size_++; - return true; - } - return false; -} - - -namespace { -class LockInverter { - private: - SpinLock *held_, *temp_; - public: - inline explicit LockInverter(SpinLock* held, SpinLock *temp) - : held_(held), temp_(temp) { held_->Unlock(); temp_->Lock(); } - inline ~LockInverter() { temp_->Unlock(); held_->Lock(); } -}; -} - -bool TCMalloc_Central_FreeList::ShrinkCache(int locked_size_class, bool force) { - // Start with a quick check without taking a lock. - if (cache_size_ == 0) return false; - // We don't evict from a full cache unless we are 'forcing'. - if (force == false && used_slots_ == cache_size_) return false; - - // Grab lock, but first release the other lock held by this thread. We use - // the lock inverter to ensure that we never hold two size class locks - // concurrently. That can create a deadlock because there is no well - // defined nesting order. - LockInverter li(¢ral_cache[locked_size_class].lock_, &lock_); - ASSERT(used_slots_ <= cache_size_); - ASSERT(0 <= cache_size_); - if (cache_size_ == 0) return false; - if (used_slots_ == cache_size_) { - if (force == false) return false; - // ReleaseListToSpans releases the lock, so we have to make all the - // updates to the central list before calling it. - cache_size_--; - used_slots_--; - ReleaseListToSpans(tc_slots_[used_slots_].head); - return true; - } - cache_size_--; - return true; -} - -void TCMalloc_Central_FreeList::InsertRange(void *start, void *end, int N) { - SpinLockHolder h(&lock_); - if (N == num_objects_to_move[size_class_] && - MakeCacheSpace()) { - int slot = used_slots_++; - ASSERT(slot >=0); - ASSERT(slot < kNumTransferEntries); - TCEntry *entry = &tc_slots_[slot]; - entry->head = start; - entry->tail = end; - return; - } - ReleaseListToSpans(start); -} - -void TCMalloc_Central_FreeList::RemoveRange(void **start, void **end, int *N) { - int num = *N; - ASSERT(num > 0); - - SpinLockHolder h(&lock_); - if (num == num_objects_to_move[size_class_] && used_slots_ > 0) { - int slot = --used_slots_; - ASSERT(slot >= 0); - TCEntry *entry = &tc_slots_[slot]; - *start = entry->head; - *end = entry->tail; - return; - } - - // TODO: Prefetch multiple TCEntries? - void *tail = FetchFromSpansSafe(); - if (!tail) { - // We are completely out of memory. - *start = *end = NULL; - *N = 0; - return; - } - - SLL_SetNext(tail, NULL); - void *head = tail; - int count = 1; - while (count < num) { - void *t = FetchFromSpans(); - if (!t) break; - SLL_Push(&head, t); - count++; - } - *start = head; - *end = tail; - *N = count; -} - - -void* TCMalloc_Central_FreeList::FetchFromSpansSafe() { - void *t = FetchFromSpans(); - if (!t) { - Populate(); - t = FetchFromSpans(); - } - return t; -} - -void* TCMalloc_Central_FreeList::FetchFromSpans() { - if (DLL_IsEmpty(&nonempty_)) return NULL; - Span* span = nonempty_.next; - - ASSERT(span->objects != NULL); - ASSERT_SPAN_COMMITTED(span); - span->refcount++; - void* result = span->objects; - span->objects = *(reinterpret_cast<void**>(result)); - if (span->objects == NULL) { - // Move to empty list - DLL_Remove(span); - DLL_Prepend(&empty_, span); - Event(span, 'E', 0); - } - counter_--; - return result; -} - -// Fetch memory from the system and add to the central cache freelist. -ALWAYS_INLINE void TCMalloc_Central_FreeList::Populate() { - // Release central list lock while operating on pageheap - lock_.Unlock(); - const size_t npages = class_to_pages[size_class_]; - - Span* span; - { - SpinLockHolder h(&pageheap_lock); - span = pageheap->New(npages); - if (span) pageheap->RegisterSizeClass(span, size_class_); - } - if (span == NULL) { -#if HAVE(ERRNO_H) - MESSAGE("allocation failed: %d\n", errno); -#elif OS(WINDOWS) - MESSAGE("allocation failed: %d\n", ::GetLastError()); -#else - MESSAGE("allocation failed\n"); -#endif - lock_.Lock(); - return; - } - ASSERT_SPAN_COMMITTED(span); - ASSERT(span->length == npages); - // Cache sizeclass info eagerly. Locking is not necessary. - // (Instead of being eager, we could just replace any stale info - // about this span, but that seems to be no better in practice.) - for (size_t i = 0; i < npages; i++) { - pageheap->CacheSizeClass(span->start + i, size_class_); - } - - // Split the block into pieces and add to the free-list - // TODO: coloring of objects to avoid cache conflicts? - void** tail = &span->objects; - char* ptr = reinterpret_cast<char*>(span->start << kPageShift); - char* limit = ptr + (npages << kPageShift); - const size_t size = ByteSizeForClass(size_class_); - int num = 0; - char* nptr; - while ((nptr = ptr + size) <= limit) { - *tail = ptr; - tail = reinterpret_cast_ptr<void**>(ptr); - ptr = nptr; - num++; - } - ASSERT(ptr <= limit); - *tail = NULL; - span->refcount = 0; // No sub-object in use yet - - // Add span to list of non-empty spans - lock_.Lock(); - DLL_Prepend(&nonempty_, span); - counter_ += num; -} - -//------------------------------------------------------------------- -// TCMalloc_ThreadCache implementation -//------------------------------------------------------------------- - -inline bool TCMalloc_ThreadCache::SampleAllocation(size_t k) { - if (bytes_until_sample_ < k) { - PickNextSample(k); - return true; - } else { - bytes_until_sample_ -= k; - return false; - } -} - -void TCMalloc_ThreadCache::Init(ThreadIdentifier tid) { - size_ = 0; - next_ = NULL; - prev_ = NULL; - tid_ = tid; - in_setspecific_ = false; - for (size_t cl = 0; cl < kNumClasses; ++cl) { - list_[cl].Init(); - } - - // Initialize RNG -- run it for a bit to get to good values - bytes_until_sample_ = 0; - rnd_ = static_cast<uint32_t>(reinterpret_cast<uintptr_t>(this)); - for (int i = 0; i < 100; i++) { - PickNextSample(static_cast<size_t>(FLAGS_tcmalloc_sample_parameter * 2)); - } -} - -void TCMalloc_ThreadCache::Cleanup() { - // Put unused memory back into central cache - for (size_t cl = 0; cl < kNumClasses; ++cl) { - if (list_[cl].length() > 0) { - ReleaseToCentralCache(cl, list_[cl].length()); - } - } -} - -ALWAYS_INLINE void* TCMalloc_ThreadCache::Allocate(size_t size) { - ASSERT(size <= kMaxSize); - const size_t cl = SizeClass(size); - FreeList* list = &list_[cl]; - size_t allocationSize = ByteSizeForClass(cl); - if (list->empty()) { - FetchFromCentralCache(cl, allocationSize); - if (list->empty()) return NULL; - } - size_ -= allocationSize; - return list->Pop(); -} - -inline void TCMalloc_ThreadCache::Deallocate(void* ptr, size_t cl) { - size_ += ByteSizeForClass(cl); - FreeList* list = &list_[cl]; - list->Push(ptr); - // If enough data is free, put back into central cache - if (list->length() > kMaxFreeListLength) { - ReleaseToCentralCache(cl, num_objects_to_move[cl]); - } - if (size_ >= per_thread_cache_size) Scavenge(); -} - -// Remove some objects of class "cl" from central cache and add to thread heap -ALWAYS_INLINE void TCMalloc_ThreadCache::FetchFromCentralCache(size_t cl, size_t allocationSize) { - int fetch_count = num_objects_to_move[cl]; - void *start, *end; - central_cache[cl].RemoveRange(&start, &end, &fetch_count); - list_[cl].PushRange(fetch_count, start, end); - size_ += allocationSize * fetch_count; -} - -// Remove some objects of class "cl" from thread heap and add to central cache -inline void TCMalloc_ThreadCache::ReleaseToCentralCache(size_t cl, int N) { - ASSERT(N > 0); - FreeList* src = &list_[cl]; - if (N > src->length()) N = src->length(); - size_ -= N*ByteSizeForClass(cl); - - // We return prepackaged chains of the correct size to the central cache. - // TODO: Use the same format internally in the thread caches? - int batch_size = num_objects_to_move[cl]; - while (N > batch_size) { - void *tail, *head; - src->PopRange(batch_size, &head, &tail); - central_cache[cl].InsertRange(head, tail, batch_size); - N -= batch_size; - } - void *tail, *head; - src->PopRange(N, &head, &tail); - central_cache[cl].InsertRange(head, tail, N); -} - -// Release idle memory to the central cache -inline void TCMalloc_ThreadCache::Scavenge() { - // If the low-water mark for the free list is L, it means we would - // not have had to allocate anything from the central cache even if - // we had reduced the free list size by L. We aim to get closer to - // that situation by dropping L/2 nodes from the free list. This - // may not release much memory, but if so we will call scavenge again - // pretty soon and the low-water marks will be high on that call. - //int64 start = CycleClock::Now(); - - for (size_t cl = 0; cl < kNumClasses; cl++) { - FreeList* list = &list_[cl]; - const int lowmark = list->lowwatermark(); - if (lowmark > 0) { - const int drop = (lowmark > 1) ? lowmark/2 : 1; - ReleaseToCentralCache(cl, drop); - } - list->clear_lowwatermark(); - } - - //int64 finish = CycleClock::Now(); - //CycleTimer ct; - //MESSAGE("GC: %.0f ns\n", ct.CyclesToUsec(finish-start)*1000.0); -} - -void TCMalloc_ThreadCache::PickNextSample(size_t k) { - // Make next "random" number - // x^32+x^22+x^2+x^1+1 is a primitive polynomial for random numbers - static const uint32_t kPoly = (1 << 22) | (1 << 2) | (1 << 1) | (1 << 0); - uint32_t r = rnd_; - rnd_ = (r << 1) ^ ((static_cast<int32_t>(r) >> 31) & kPoly); - - // Next point is "rnd_ % (sample_period)". I.e., average - // increment is "sample_period/2". - const int flag_value = static_cast<int>(FLAGS_tcmalloc_sample_parameter); - static int last_flag_value = -1; - - if (flag_value != last_flag_value) { - SpinLockHolder h(&sample_period_lock); - int i; - for (i = 0; i < (static_cast<int>(sizeof(primes_list)/sizeof(primes_list[0])) - 1); i++) { - if (primes_list[i] >= flag_value) { - break; - } - } - sample_period = primes_list[i]; - last_flag_value = flag_value; - } - - bytes_until_sample_ += rnd_ % sample_period; - - if (k > (static_cast<size_t>(-1) >> 2)) { - // If the user has asked for a huge allocation then it is possible - // for the code below to loop infinitely. Just return (note that - // this throws off the sampling accuracy somewhat, but a user who - // is allocating more than 1G of memory at a time can live with a - // minor inaccuracy in profiling of small allocations, and also - // would rather not wait for the loop below to terminate). - return; - } - - while (bytes_until_sample_ < k) { - // Increase bytes_until_sample_ by enough average sampling periods - // (sample_period >> 1) to allow us to sample past the current - // allocation. - bytes_until_sample_ += (sample_period >> 1); - } - - bytes_until_sample_ -= k; -} - -void TCMalloc_ThreadCache::InitModule() { - // There is a slight potential race here because of double-checked - // locking idiom. However, as long as the program does a small - // allocation before switching to multi-threaded mode, we will be - // fine. We increase the chances of doing such a small allocation - // by doing one in the constructor of the module_enter_exit_hook - // object declared below. - SpinLockHolder h(&pageheap_lock); - if (!phinited) { -#ifdef WTF_CHANGES - InitTSD(); -#endif - InitSizeClasses(); - threadheap_allocator.Init(); - span_allocator.Init(); - span_allocator.New(); // Reduce cache conflicts - span_allocator.New(); // Reduce cache conflicts - stacktrace_allocator.Init(); - DLL_Init(&sampled_objects); - for (size_t i = 0; i < kNumClasses; ++i) { - central_cache[i].Init(i); - } - pageheap->init(); - phinited = 1; -#if defined(WTF_CHANGES) && OS(DARWIN) - FastMallocZone::init(); -#endif - } -} - -inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::NewHeap(ThreadIdentifier tid) { - // Create the heap and add it to the linked list - TCMalloc_ThreadCache *heap = threadheap_allocator.New(); - heap->Init(tid); - heap->next_ = thread_heaps; - heap->prev_ = NULL; - if (thread_heaps != NULL) thread_heaps->prev_ = heap; - thread_heaps = heap; - thread_heap_count++; - RecomputeThreadCacheSize(); - return heap; -} - -inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetThreadHeap() { -#ifdef HAVE_TLS - // __thread is faster, but only when the kernel supports it - if (KernelSupportsTLS()) - return threadlocal_heap; -#elif COMPILER(MSVC) - return static_cast<TCMalloc_ThreadCache*>(TlsGetValue(tlsIndex)); -#else - return static_cast<TCMalloc_ThreadCache*>(pthread_getspecific(heap_key)); -#endif -} - -inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() { - TCMalloc_ThreadCache* ptr = NULL; - if (!tsd_inited) { - InitModule(); - } else { - ptr = GetThreadHeap(); - } - if (ptr == NULL) ptr = CreateCacheIfNecessary(); - return ptr; -} - -// In deletion paths, we do not try to create a thread-cache. This is -// because we may be in the thread destruction code and may have -// already cleaned up the cache for this thread. -inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() { - if (!tsd_inited) return NULL; - void* const p = GetThreadHeap(); - return reinterpret_cast<TCMalloc_ThreadCache*>(p); -} - -void TCMalloc_ThreadCache::InitTSD() { - ASSERT(!tsd_inited); - pthread_key_create(&heap_key, DestroyThreadCache); -#if COMPILER(MSVC) - tlsIndex = TlsAlloc(); -#endif - tsd_inited = true; - -#if !COMPILER(MSVC) - // We may have used a fake pthread_t for the main thread. Fix it. - pthread_t zero; - memset(&zero, 0, sizeof(zero)); -#endif -#ifndef WTF_CHANGES - SpinLockHolder h(&pageheap_lock); -#else - ASSERT(pageheap_lock.IsHeld()); -#endif - for (TCMalloc_ThreadCache* h = thread_heaps; h != NULL; h = h->next_) { -#if COMPILER(MSVC) - if (h->tid_ == 0) { - h->tid_ = GetCurrentThreadId(); - } -#else - if (pthread_equal(h->tid_, zero)) { - h->tid_ = pthread_self(); - } -#endif - } -} - -TCMalloc_ThreadCache* TCMalloc_ThreadCache::CreateCacheIfNecessary() { - // Initialize per-thread data if necessary - TCMalloc_ThreadCache* heap = NULL; - { - SpinLockHolder h(&pageheap_lock); - -#if COMPILER(MSVC) - DWORD me; - if (!tsd_inited) { - me = 0; - } else { - me = GetCurrentThreadId(); - } -#else - // Early on in glibc's life, we cannot even call pthread_self() - pthread_t me; - if (!tsd_inited) { - memset(&me, 0, sizeof(me)); - } else { - me = pthread_self(); - } -#endif - - // This may be a recursive malloc call from pthread_setspecific() - // In that case, the heap for this thread has already been created - // and added to the linked list. So we search for that first. - for (TCMalloc_ThreadCache* h = thread_heaps; h != NULL; h = h->next_) { -#if COMPILER(MSVC) - if (h->tid_ == me) { -#else - if (pthread_equal(h->tid_, me)) { -#endif - heap = h; - break; - } - } - - if (heap == NULL) heap = NewHeap(me); - } - - // We call pthread_setspecific() outside the lock because it may - // call malloc() recursively. The recursive call will never get - // here again because it will find the already allocated heap in the - // linked list of heaps. - if (!heap->in_setspecific_ && tsd_inited) { - heap->in_setspecific_ = true; - setThreadHeap(heap); - } - return heap; -} - -void TCMalloc_ThreadCache::BecomeIdle() { - if (!tsd_inited) return; // No caches yet - TCMalloc_ThreadCache* heap = GetThreadHeap(); - if (heap == NULL) return; // No thread cache to remove - if (heap->in_setspecific_) return; // Do not disturb the active caller - - heap->in_setspecific_ = true; - setThreadHeap(NULL); -#ifdef HAVE_TLS - // Also update the copy in __thread - threadlocal_heap = NULL; -#endif - heap->in_setspecific_ = false; - if (GetThreadHeap() == heap) { - // Somehow heap got reinstated by a recursive call to malloc - // from pthread_setspecific. We give up in this case. - return; - } - - // We can now get rid of the heap - DeleteCache(heap); -} - -void TCMalloc_ThreadCache::DestroyThreadCache(void* ptr) { - // Note that "ptr" cannot be NULL since pthread promises not - // to invoke the destructor on NULL values, but for safety, - // we check anyway. - if (ptr == NULL) return; -#ifdef HAVE_TLS - // Prevent fast path of GetThreadHeap() from returning heap. - threadlocal_heap = NULL; -#endif - DeleteCache(reinterpret_cast<TCMalloc_ThreadCache*>(ptr)); -} - -void TCMalloc_ThreadCache::DeleteCache(TCMalloc_ThreadCache* heap) { - // Remove all memory from heap - heap->Cleanup(); - - // Remove from linked list - SpinLockHolder h(&pageheap_lock); - if (heap->next_ != NULL) heap->next_->prev_ = heap->prev_; - if (heap->prev_ != NULL) heap->prev_->next_ = heap->next_; - if (thread_heaps == heap) thread_heaps = heap->next_; - thread_heap_count--; - RecomputeThreadCacheSize(); - - threadheap_allocator.Delete(heap); -} - -void TCMalloc_ThreadCache::RecomputeThreadCacheSize() { - // Divide available space across threads - int n = thread_heap_count > 0 ? thread_heap_count : 1; - size_t space = overall_thread_cache_size / n; - - // Limit to allowed range - if (space < kMinThreadCacheSize) space = kMinThreadCacheSize; - if (space > kMaxThreadCacheSize) space = kMaxThreadCacheSize; - - per_thread_cache_size = space; -} - -void TCMalloc_ThreadCache::Print() const { - for (size_t cl = 0; cl < kNumClasses; ++cl) { - MESSAGE(" %5" PRIuS " : %4d len; %4d lo\n", - ByteSizeForClass(cl), - list_[cl].length(), - list_[cl].lowwatermark()); - } -} - -// Extract interesting stats -struct TCMallocStats { - uint64_t system_bytes; // Bytes alloced from system - uint64_t thread_bytes; // Bytes in thread caches - uint64_t central_bytes; // Bytes in central cache - uint64_t transfer_bytes; // Bytes in central transfer cache - uint64_t pageheap_bytes; // Bytes in page heap - uint64_t metadata_bytes; // Bytes alloced for metadata -}; - -#ifndef WTF_CHANGES -// Get stats into "r". Also get per-size-class counts if class_count != NULL -static void ExtractStats(TCMallocStats* r, uint64_t* class_count) { - r->central_bytes = 0; - r->transfer_bytes = 0; - for (int cl = 0; cl < kNumClasses; ++cl) { - const int length = central_cache[cl].length(); - const int tc_length = central_cache[cl].tc_length(); - r->central_bytes += static_cast<uint64_t>(ByteSizeForClass(cl)) * length; - r->transfer_bytes += - static_cast<uint64_t>(ByteSizeForClass(cl)) * tc_length; - if (class_count) class_count[cl] = length + tc_length; - } - - // Add stats from per-thread heaps - r->thread_bytes = 0; - { // scope - SpinLockHolder h(&pageheap_lock); - for (TCMalloc_ThreadCache* h = thread_heaps; h != NULL; h = h->next_) { - r->thread_bytes += h->Size(); - if (class_count) { - for (size_t cl = 0; cl < kNumClasses; ++cl) { - class_count[cl] += h->freelist_length(cl); - } - } - } - } - - { //scope - SpinLockHolder h(&pageheap_lock); - r->system_bytes = pageheap->SystemBytes(); - r->metadata_bytes = metadata_system_bytes; - r->pageheap_bytes = pageheap->FreeBytes(); - } -} -#endif - -#ifndef WTF_CHANGES -// WRITE stats to "out" -static void DumpStats(TCMalloc_Printer* out, int level) { - TCMallocStats stats; - uint64_t class_count[kNumClasses]; - ExtractStats(&stats, (level >= 2 ? class_count : NULL)); - - if (level >= 2) { - out->printf("------------------------------------------------\n"); - uint64_t cumulative = 0; - for (int cl = 0; cl < kNumClasses; ++cl) { - if (class_count[cl] > 0) { - uint64_t class_bytes = class_count[cl] * ByteSizeForClass(cl); - cumulative += class_bytes; - out->printf("class %3d [ %8" PRIuS " bytes ] : " - "%8" PRIu64 " objs; %5.1f MB; %5.1f cum MB\n", - cl, ByteSizeForClass(cl), - class_count[cl], - class_bytes / 1048576.0, - cumulative / 1048576.0); - } - } - - SpinLockHolder h(&pageheap_lock); - pageheap->Dump(out); - } - - const uint64_t bytes_in_use = stats.system_bytes - - stats.pageheap_bytes - - stats.central_bytes - - stats.transfer_bytes - - stats.thread_bytes; - - out->printf("------------------------------------------------\n" - "MALLOC: %12" PRIu64 " Heap size\n" - "MALLOC: %12" PRIu64 " Bytes in use by application\n" - "MALLOC: %12" PRIu64 " Bytes free in page heap\n" - "MALLOC: %12" PRIu64 " Bytes free in central cache\n" - "MALLOC: %12" PRIu64 " Bytes free in transfer cache\n" - "MALLOC: %12" PRIu64 " Bytes free in thread caches\n" - "MALLOC: %12" PRIu64 " Spans in use\n" - "MALLOC: %12" PRIu64 " Thread heaps in use\n" - "MALLOC: %12" PRIu64 " Metadata allocated\n" - "------------------------------------------------\n", - stats.system_bytes, - bytes_in_use, - stats.pageheap_bytes, - stats.central_bytes, - stats.transfer_bytes, - stats.thread_bytes, - uint64_t(span_allocator.inuse()), - uint64_t(threadheap_allocator.inuse()), - stats.metadata_bytes); -} - -static void PrintStats(int level) { - const int kBufferSize = 16 << 10; - char* buffer = new char[kBufferSize]; - TCMalloc_Printer printer(buffer, kBufferSize); - DumpStats(&printer, level); - write(STDERR_FILENO, buffer, strlen(buffer)); - delete[] buffer; -} - -static void** DumpStackTraces() { - // Count how much space we need - int needed_slots = 0; - { - SpinLockHolder h(&pageheap_lock); - for (Span* s = sampled_objects.next; s != &sampled_objects; s = s->next) { - StackTrace* stack = reinterpret_cast<StackTrace*>(s->objects); - needed_slots += 3 + stack->depth; - } - needed_slots += 100; // Slop in case sample grows - needed_slots += needed_slots/8; // An extra 12.5% slop - } - - void** result = new void*[needed_slots]; - if (result == NULL) { - MESSAGE("tcmalloc: could not allocate %d slots for stack traces\n", - needed_slots); - return NULL; - } - - SpinLockHolder h(&pageheap_lock); - int used_slots = 0; - for (Span* s = sampled_objects.next; s != &sampled_objects; s = s->next) { - ASSERT(used_slots < needed_slots); // Need to leave room for terminator - StackTrace* stack = reinterpret_cast<StackTrace*>(s->objects); - if (used_slots + 3 + stack->depth >= needed_slots) { - // No more room - break; - } - - result[used_slots+0] = reinterpret_cast<void*>(static_cast<uintptr_t>(1)); - result[used_slots+1] = reinterpret_cast<void*>(stack->size); - result[used_slots+2] = reinterpret_cast<void*>(stack->depth); - for (int d = 0; d < stack->depth; d++) { - result[used_slots+3+d] = stack->stack[d]; - } - used_slots += 3 + stack->depth; - } - result[used_slots] = reinterpret_cast<void*>(static_cast<uintptr_t>(0)); - return result; -} -#endif - -#ifndef WTF_CHANGES - -// TCMalloc's support for extra malloc interfaces -class TCMallocImplementation : public MallocExtension { - public: - virtual void GetStats(char* buffer, int buffer_length) { - ASSERT(buffer_length > 0); - TCMalloc_Printer printer(buffer, buffer_length); - - // Print level one stats unless lots of space is available - if (buffer_length < 10000) { - DumpStats(&printer, 1); - } else { - DumpStats(&printer, 2); - } - } - - virtual void** ReadStackTraces() { - return DumpStackTraces(); - } - - virtual bool GetNumericProperty(const char* name, size_t* value) { - ASSERT(name != NULL); - - if (strcmp(name, "generic.current_allocated_bytes") == 0) { - TCMallocStats stats; - ExtractStats(&stats, NULL); - *value = stats.system_bytes - - stats.thread_bytes - - stats.central_bytes - - stats.pageheap_bytes; - return true; - } - - if (strcmp(name, "generic.heap_size") == 0) { - TCMallocStats stats; - ExtractStats(&stats, NULL); - *value = stats.system_bytes; - return true; - } - - if (strcmp(name, "tcmalloc.slack_bytes") == 0) { - // We assume that bytes in the page heap are not fragmented too - // badly, and are therefore available for allocation. - SpinLockHolder l(&pageheap_lock); - *value = pageheap->FreeBytes(); - return true; - } - - if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) { - SpinLockHolder l(&pageheap_lock); - *value = overall_thread_cache_size; - return true; - } - - if (strcmp(name, "tcmalloc.current_total_thread_cache_bytes") == 0) { - TCMallocStats stats; - ExtractStats(&stats, NULL); - *value = stats.thread_bytes; - return true; - } - - return false; - } - - virtual bool SetNumericProperty(const char* name, size_t value) { - ASSERT(name != NULL); - - if (strcmp(name, "tcmalloc.max_total_thread_cache_bytes") == 0) { - // Clip the value to a reasonable range - if (value < kMinThreadCacheSize) value = kMinThreadCacheSize; - if (value > (1<<30)) value = (1<<30); // Limit to 1GB - - SpinLockHolder l(&pageheap_lock); - overall_thread_cache_size = static_cast<size_t>(value); - TCMalloc_ThreadCache::RecomputeThreadCacheSize(); - return true; - } - - return false; - } - - virtual void MarkThreadIdle() { - TCMalloc_ThreadCache::BecomeIdle(); - } - - virtual void ReleaseFreeMemory() { - SpinLockHolder h(&pageheap_lock); - pageheap->ReleaseFreePages(); - } -}; -#endif - -// The constructor allocates an object to ensure that initialization -// runs before main(), and therefore we do not have a chance to become -// multi-threaded before initialization. We also create the TSD key -// here. Presumably by the time this constructor runs, glibc is in -// good enough shape to handle pthread_key_create(). -// -// The constructor also takes the opportunity to tell STL to use -// tcmalloc. We want to do this early, before construct time, so -// all user STL allocations go through tcmalloc (which works really -// well for STL). -// -// The destructor prints stats when the program exits. -class TCMallocGuard { - public: - - TCMallocGuard() { -#ifdef HAVE_TLS // this is true if the cc/ld/libc combo support TLS - // Check whether the kernel also supports TLS (needs to happen at runtime) - CheckIfKernelSupportsTLS(); -#endif -#ifndef WTF_CHANGES -#ifdef WIN32 // patch the windows VirtualAlloc, etc. - PatchWindowsFunctions(); // defined in windows/patch_functions.cc -#endif -#endif - free(malloc(1)); - TCMalloc_ThreadCache::InitTSD(); - free(malloc(1)); -#ifndef WTF_CHANGES - MallocExtension::Register(new TCMallocImplementation); -#endif - } - -#ifndef WTF_CHANGES - ~TCMallocGuard() { - const char* env = getenv("MALLOCSTATS"); - if (env != NULL) { - int level = atoi(env); - if (level < 1) level = 1; - PrintStats(level); - } -#ifdef WIN32 - UnpatchWindowsFunctions(); -#endif - } -#endif -}; - -#ifndef WTF_CHANGES -static TCMallocGuard module_enter_exit_hook; -#endif - - -//------------------------------------------------------------------- -// Helpers for the exported routines below -//------------------------------------------------------------------- - -#ifndef WTF_CHANGES - -static Span* DoSampledAllocation(size_t size) { - - // Grab the stack trace outside the heap lock - StackTrace tmp; - tmp.depth = GetStackTrace(tmp.stack, kMaxStackDepth, 1); - tmp.size = size; - - SpinLockHolder h(&pageheap_lock); - // Allocate span - Span *span = pageheap->New(pages(size == 0 ? 1 : size)); - if (span == NULL) { - return NULL; - } - - // Allocate stack trace - StackTrace *stack = stacktrace_allocator.New(); - if (stack == NULL) { - // Sampling failed because of lack of memory - return span; - } - - *stack = tmp; - span->sample = 1; - span->objects = stack; - DLL_Prepend(&sampled_objects, span); - - return span; -} -#endif - -static inline bool CheckCachedSizeClass(void *ptr) { - PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; - size_t cached_value = pageheap->GetSizeClassIfCached(p); - return cached_value == 0 || - cached_value == pageheap->GetDescriptor(p)->sizeclass; -} - -static inline void* CheckedMallocResult(void *result) -{ - ASSERT(result == 0 || CheckCachedSizeClass(result)); - return result; -} - -static inline void* SpanToMallocResult(Span *span) { - ASSERT_SPAN_COMMITTED(span); - pageheap->CacheSizeClass(span->start, 0); - return - CheckedMallocResult(reinterpret_cast<void*>(span->start << kPageShift)); -} - -#ifdef WTF_CHANGES -template <bool crashOnFailure> -#endif -static ALWAYS_INLINE void* do_malloc(size_t size) { - void* ret = NULL; - -#ifdef WTF_CHANGES - ASSERT(!isForbidden()); -#endif - - // The following call forces module initialization - TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCache(); -#ifndef WTF_CHANGES - if ((FLAGS_tcmalloc_sample_parameter > 0) && heap->SampleAllocation(size)) { - Span* span = DoSampledAllocation(size); - if (span != NULL) { - ret = SpanToMallocResult(span); - } - } else -#endif - if (size > kMaxSize) { - // Use page-level allocator - SpinLockHolder h(&pageheap_lock); - Span* span = pageheap->New(pages(size)); - if (span != NULL) { - ret = SpanToMallocResult(span); - } - } else { - // The common case, and also the simplest. This just pops the - // size-appropriate freelist, afer replenishing it if it's empty. - ret = CheckedMallocResult(heap->Allocate(size)); - } - if (!ret) { -#ifdef WTF_CHANGES - if (crashOnFailure) // This branch should be optimized out by the compiler. - CRASH(); -#else - errno = ENOMEM; -#endif - } - return ret; -} - -static ALWAYS_INLINE void do_free(void* ptr) { - if (ptr == NULL) return; - ASSERT(pageheap != NULL); // Should not call free() before malloc() - const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; - Span* span = NULL; - size_t cl = pageheap->GetSizeClassIfCached(p); - - if (cl == 0) { - span = pageheap->GetDescriptor(p); - cl = span->sizeclass; - pageheap->CacheSizeClass(p, cl); - } - if (cl != 0) { -#ifndef NO_TCMALLOC_SAMPLES - ASSERT(!pageheap->GetDescriptor(p)->sample); -#endif - TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCacheIfPresent(); - if (heap != NULL) { - heap->Deallocate(ptr, cl); - } else { - // Delete directly into central cache - SLL_SetNext(ptr, NULL); - central_cache[cl].InsertRange(ptr, ptr, 1); - } - } else { - SpinLockHolder h(&pageheap_lock); - ASSERT(reinterpret_cast<uintptr_t>(ptr) % kPageSize == 0); - ASSERT(span != NULL && span->start == p); -#ifndef NO_TCMALLOC_SAMPLES - if (span->sample) { - DLL_Remove(span); - stacktrace_allocator.Delete(reinterpret_cast<StackTrace*>(span->objects)); - span->objects = NULL; - } -#endif - pageheap->Delete(span); - } -} - -#ifndef WTF_CHANGES -// For use by exported routines below that want specific alignments -// -// Note: this code can be slow, and can significantly fragment memory. -// The expectation is that memalign/posix_memalign/valloc/pvalloc will -// not be invoked very often. This requirement simplifies our -// implementation and allows us to tune for expected allocation -// patterns. -static void* do_memalign(size_t align, size_t size) { - ASSERT((align & (align - 1)) == 0); - ASSERT(align > 0); - if (pageheap == NULL) TCMalloc_ThreadCache::InitModule(); - - // Allocate at least one byte to avoid boundary conditions below - if (size == 0) size = 1; - - if (size <= kMaxSize && align < kPageSize) { - // Search through acceptable size classes looking for one with - // enough alignment. This depends on the fact that - // InitSizeClasses() currently produces several size classes that - // are aligned at powers of two. We will waste time and space if - // we miss in the size class array, but that is deemed acceptable - // since memalign() should be used rarely. - size_t cl = SizeClass(size); - while (cl < kNumClasses && ((class_to_size[cl] & (align - 1)) != 0)) { - cl++; - } - if (cl < kNumClasses) { - TCMalloc_ThreadCache* heap = TCMalloc_ThreadCache::GetCache(); - return CheckedMallocResult(heap->Allocate(class_to_size[cl])); - } - } - - // We will allocate directly from the page heap - SpinLockHolder h(&pageheap_lock); - - if (align <= kPageSize) { - // Any page-level allocation will be fine - // TODO: We could put the rest of this page in the appropriate - // TODO: cache but it does not seem worth it. - Span* span = pageheap->New(pages(size)); - return span == NULL ? NULL : SpanToMallocResult(span); - } - - // Allocate extra pages and carve off an aligned portion - const Length alloc = pages(size + align); - Span* span = pageheap->New(alloc); - if (span == NULL) return NULL; - - // Skip starting portion so that we end up aligned - Length skip = 0; - while ((((span->start+skip) << kPageShift) & (align - 1)) != 0) { - skip++; - } - ASSERT(skip < alloc); - if (skip > 0) { - Span* rest = pageheap->Split(span, skip); - pageheap->Delete(span); - span = rest; - } - - // Skip trailing portion that we do not need to return - const Length needed = pages(size); - ASSERT(span->length >= needed); - if (span->length > needed) { - Span* trailer = pageheap->Split(span, needed); - pageheap->Delete(trailer); - } - return SpanToMallocResult(span); -} -#endif - -// Helpers for use by exported routines below: - -#ifndef WTF_CHANGES -static inline void do_malloc_stats() { - PrintStats(1); -} -#endif - -static inline int do_mallopt(int, int) { - return 1; // Indicates error -} - -#ifdef HAVE_STRUCT_MALLINFO // mallinfo isn't defined on freebsd, for instance -static inline struct mallinfo do_mallinfo() { - TCMallocStats stats; - ExtractStats(&stats, NULL); - - // Just some of the fields are filled in. - struct mallinfo info; - memset(&info, 0, sizeof(info)); - - // Unfortunately, the struct contains "int" field, so some of the - // size values will be truncated. - info.arena = static_cast<int>(stats.system_bytes); - info.fsmblks = static_cast<int>(stats.thread_bytes - + stats.central_bytes - + stats.transfer_bytes); - info.fordblks = static_cast<int>(stats.pageheap_bytes); - info.uordblks = static_cast<int>(stats.system_bytes - - stats.thread_bytes - - stats.central_bytes - - stats.transfer_bytes - - stats.pageheap_bytes); - - return info; -} -#endif - -//------------------------------------------------------------------- -// Exported routines -//------------------------------------------------------------------- - -// CAVEAT: The code structure below ensures that MallocHook methods are always -// called from the stack frame of the invoked allocation function. -// heap-checker.cc depends on this to start a stack trace from -// the call to the (de)allocation function. - -#ifndef WTF_CHANGES -extern "C" -#else -#define do_malloc do_malloc<crashOnFailure> - -template <bool crashOnFailure> -ALWAYS_INLINE void* malloc(size_t); - -void* fastMalloc(size_t size) -{ - return malloc<true>(size); -} - -TryMallocReturnValue tryFastMalloc(size_t size) -{ - return malloc<false>(size); -} - -template <bool crashOnFailure> -ALWAYS_INLINE -#endif -void* malloc(size_t size) { -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= size) // If overflow would occur... - return 0; - size += sizeof(AllocAlignmentInteger); - void* result = do_malloc(size); - if (!result) - return 0; - - *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc; - result = static_cast<AllocAlignmentInteger*>(result) + 1; -#else - void* result = do_malloc(size); -#endif - -#ifndef WTF_CHANGES - MallocHook::InvokeNewHook(result, size); -#endif - return result; -} - -#ifndef WTF_CHANGES -extern "C" -#endif -void free(void* ptr) { -#ifndef WTF_CHANGES - MallocHook::InvokeDeleteHook(ptr); -#endif - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (!ptr) - return; - - AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(ptr); - if (*header != Internal::AllocTypeMalloc) - Internal::fastMallocMatchFailed(ptr); - do_free(header); -#else - do_free(ptr); -#endif -} - -#ifndef WTF_CHANGES -extern "C" -#else -template <bool crashOnFailure> -ALWAYS_INLINE void* calloc(size_t, size_t); - -void* fastCalloc(size_t n, size_t elem_size) -{ - return calloc<true>(n, elem_size); -} - -TryMallocReturnValue tryFastCalloc(size_t n, size_t elem_size) -{ - return calloc<false>(n, elem_size); -} - -template <bool crashOnFailure> -ALWAYS_INLINE -#endif -void* calloc(size_t n, size_t elem_size) { - size_t totalBytes = n * elem_size; - - // Protect against overflow - if (n > 1 && elem_size && (totalBytes / elem_size) != n) - return 0; - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= totalBytes) // If overflow would occur... - return 0; - - totalBytes += sizeof(AllocAlignmentInteger); - void* result = do_malloc(totalBytes); - if (!result) - return 0; - - memset(result, 0, totalBytes); - *static_cast<AllocAlignmentInteger*>(result) = Internal::AllocTypeMalloc; - result = static_cast<AllocAlignmentInteger*>(result) + 1; -#else - void* result = do_malloc(totalBytes); - if (result != NULL) { - memset(result, 0, totalBytes); - } -#endif - -#ifndef WTF_CHANGES - MallocHook::InvokeNewHook(result, totalBytes); -#endif - return result; -} - -// Since cfree isn't used anywhere, we don't compile it in. -#ifndef WTF_CHANGES -#ifndef WTF_CHANGES -extern "C" -#endif -void cfree(void* ptr) { -#ifndef WTF_CHANGES - MallocHook::InvokeDeleteHook(ptr); -#endif - do_free(ptr); -} -#endif - -#ifndef WTF_CHANGES -extern "C" -#else -template <bool crashOnFailure> -ALWAYS_INLINE void* realloc(void*, size_t); - -void* fastRealloc(void* old_ptr, size_t new_size) -{ - return realloc<true>(old_ptr, new_size); -} - -TryMallocReturnValue tryFastRealloc(void* old_ptr, size_t new_size) -{ - return realloc<false>(old_ptr, new_size); -} - -template <bool crashOnFailure> -ALWAYS_INLINE -#endif -void* realloc(void* old_ptr, size_t new_size) { - if (old_ptr == NULL) { -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - void* result = malloc(new_size); -#else - void* result = do_malloc(new_size); -#ifndef WTF_CHANGES - MallocHook::InvokeNewHook(result, new_size); -#endif -#endif - return result; - } - if (new_size == 0) { -#ifndef WTF_CHANGES - MallocHook::InvokeDeleteHook(old_ptr); -#endif - free(old_ptr); - return NULL; - } - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - if (std::numeric_limits<size_t>::max() - sizeof(AllocAlignmentInteger) <= new_size) // If overflow would occur... - return 0; - new_size += sizeof(AllocAlignmentInteger); - AllocAlignmentInteger* header = Internal::fastMallocMatchValidationValue(old_ptr); - if (*header != Internal::AllocTypeMalloc) - Internal::fastMallocMatchFailed(old_ptr); - old_ptr = header; -#endif - - // Get the size of the old entry - const PageID p = reinterpret_cast<uintptr_t>(old_ptr) >> kPageShift; - size_t cl = pageheap->GetSizeClassIfCached(p); - Span *span = NULL; - size_t old_size; - if (cl == 0) { - span = pageheap->GetDescriptor(p); - cl = span->sizeclass; - pageheap->CacheSizeClass(p, cl); - } - if (cl != 0) { - old_size = ByteSizeForClass(cl); - } else { - ASSERT(span != NULL); - old_size = span->length << kPageShift; - } - - // Reallocate if the new size is larger than the old size, - // or if the new size is significantly smaller than the old size. - if ((new_size > old_size) || (AllocationSize(new_size) < old_size)) { - // Need to reallocate - void* new_ptr = do_malloc(new_size); - if (new_ptr == NULL) { - return NULL; - } -#ifndef WTF_CHANGES - MallocHook::InvokeNewHook(new_ptr, new_size); -#endif - memcpy(new_ptr, old_ptr, ((old_size < new_size) ? old_size : new_size)); -#ifndef WTF_CHANGES - MallocHook::InvokeDeleteHook(old_ptr); -#endif - // We could use a variant of do_free() that leverages the fact - // that we already know the sizeclass of old_ptr. The benefit - // would be small, so don't bother. - do_free(old_ptr); -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - new_ptr = static_cast<AllocAlignmentInteger*>(new_ptr) + 1; -#endif - return new_ptr; - } else { -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - old_ptr = static_cast<AllocAlignmentInteger*>(old_ptr) + 1; // Set old_ptr back to the user pointer. -#endif - return old_ptr; - } -} - -#ifdef WTF_CHANGES -#undef do_malloc -#else - -static SpinLock set_new_handler_lock = SPINLOCK_INITIALIZER; - -static inline void* cpp_alloc(size_t size, bool nothrow) { - for (;;) { - void* p = do_malloc(size); -#ifdef PREANSINEW - return p; -#else - if (p == NULL) { // allocation failed - // Get the current new handler. NB: this function is not - // thread-safe. We make a feeble stab at making it so here, but - // this lock only protects against tcmalloc interfering with - // itself, not with other libraries calling set_new_handler. - std::new_handler nh; - { - SpinLockHolder h(&set_new_handler_lock); - nh = std::set_new_handler(0); - (void) std::set_new_handler(nh); - } - // If no new_handler is established, the allocation failed. - if (!nh) { - if (nothrow) return 0; - throw std::bad_alloc(); - } - // Otherwise, try the new_handler. If it returns, retry the - // allocation. If it throws std::bad_alloc, fail the allocation. - // if it throws something else, don't interfere. - try { - (*nh)(); - } catch (const std::bad_alloc&) { - if (!nothrow) throw; - return p; - } - } else { // allocation success - return p; - } -#endif - } -} - -#if ENABLE(GLOBAL_FASTMALLOC_NEW) - -void* operator new(size_t size) { - void* p = cpp_alloc(size, false); - // We keep this next instruction out of cpp_alloc for a reason: when - // it's in, and new just calls cpp_alloc, the optimizer may fold the - // new call into cpp_alloc, which messes up our whole section-based - // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc - // isn't the last thing this fn calls, and prevents the folding. - MallocHook::InvokeNewHook(p, size); - return p; -} - -void* operator new(size_t size, const std::nothrow_t&) __THROW { - void* p = cpp_alloc(size, true); - MallocHook::InvokeNewHook(p, size); - return p; -} - -void operator delete(void* p) __THROW { - MallocHook::InvokeDeleteHook(p); - do_free(p); -} - -void operator delete(void* p, const std::nothrow_t&) __THROW { - MallocHook::InvokeDeleteHook(p); - do_free(p); -} - -void* operator new[](size_t size) { - void* p = cpp_alloc(size, false); - // We keep this next instruction out of cpp_alloc for a reason: when - // it's in, and new just calls cpp_alloc, the optimizer may fold the - // new call into cpp_alloc, which messes up our whole section-based - // stacktracing (see ATTRIBUTE_SECTION, above). This ensures cpp_alloc - // isn't the last thing this fn calls, and prevents the folding. - MallocHook::InvokeNewHook(p, size); - return p; -} - -void* operator new[](size_t size, const std::nothrow_t&) __THROW { - void* p = cpp_alloc(size, true); - MallocHook::InvokeNewHook(p, size); - return p; -} - -void operator delete[](void* p) __THROW { - MallocHook::InvokeDeleteHook(p); - do_free(p); -} - -void operator delete[](void* p, const std::nothrow_t&) __THROW { - MallocHook::InvokeDeleteHook(p); - do_free(p); -} - -#endif - -extern "C" void* memalign(size_t align, size_t size) __THROW { - void* result = do_memalign(align, size); - MallocHook::InvokeNewHook(result, size); - return result; -} - -extern "C" int posix_memalign(void** result_ptr, size_t align, size_t size) - __THROW { - if (((align % sizeof(void*)) != 0) || - ((align & (align - 1)) != 0) || - (align == 0)) { - return EINVAL; - } - - void* result = do_memalign(align, size); - MallocHook::InvokeNewHook(result, size); - if (result == NULL) { - return ENOMEM; - } else { - *result_ptr = result; - return 0; - } -} - -static size_t pagesize = 0; - -extern "C" void* valloc(size_t size) __THROW { - // Allocate page-aligned object of length >= size bytes - if (pagesize == 0) pagesize = getpagesize(); - void* result = do_memalign(pagesize, size); - MallocHook::InvokeNewHook(result, size); - return result; -} - -extern "C" void* pvalloc(size_t size) __THROW { - // Round up size to a multiple of pagesize - if (pagesize == 0) pagesize = getpagesize(); - size = (size + pagesize - 1) & ~(pagesize - 1); - void* result = do_memalign(pagesize, size); - MallocHook::InvokeNewHook(result, size); - return result; -} - -extern "C" void malloc_stats(void) { - do_malloc_stats(); -} - -extern "C" int mallopt(int cmd, int value) { - return do_mallopt(cmd, value); -} - -#ifdef HAVE_STRUCT_MALLINFO -extern "C" struct mallinfo mallinfo(void) { - return do_mallinfo(); -} -#endif - -//------------------------------------------------------------------- -// Some library routines on RedHat 9 allocate memory using malloc() -// and free it using __libc_free() (or vice-versa). Since we provide -// our own implementations of malloc/free, we need to make sure that -// the __libc_XXX variants (defined as part of glibc) also point to -// the same implementations. -//------------------------------------------------------------------- - -#if defined(__GLIBC__) -extern "C" { -#if COMPILER(GCC) && !defined(__MACH__) && defined(HAVE___ATTRIBUTE__) - // Potentially faster variants that use the gcc alias extension. - // Mach-O (Darwin) does not support weak aliases, hence the __MACH__ check. -# define ALIAS(x) __attribute__ ((weak, alias (x))) - void* __libc_malloc(size_t size) ALIAS("malloc"); - void __libc_free(void* ptr) ALIAS("free"); - void* __libc_realloc(void* ptr, size_t size) ALIAS("realloc"); - void* __libc_calloc(size_t n, size_t size) ALIAS("calloc"); - void __libc_cfree(void* ptr) ALIAS("cfree"); - void* __libc_memalign(size_t align, size_t s) ALIAS("memalign"); - void* __libc_valloc(size_t size) ALIAS("valloc"); - void* __libc_pvalloc(size_t size) ALIAS("pvalloc"); - int __posix_memalign(void** r, size_t a, size_t s) ALIAS("posix_memalign"); -# undef ALIAS -# else /* not __GNUC__ */ - // Portable wrappers - void* __libc_malloc(size_t size) { return malloc(size); } - void __libc_free(void* ptr) { free(ptr); } - void* __libc_realloc(void* ptr, size_t size) { return realloc(ptr, size); } - void* __libc_calloc(size_t n, size_t size) { return calloc(n, size); } - void __libc_cfree(void* ptr) { cfree(ptr); } - void* __libc_memalign(size_t align, size_t s) { return memalign(align, s); } - void* __libc_valloc(size_t size) { return valloc(size); } - void* __libc_pvalloc(size_t size) { return pvalloc(size); } - int __posix_memalign(void** r, size_t a, size_t s) { - return posix_memalign(r, a, s); - } -# endif /* __GNUC__ */ -} -#endif /* __GLIBC__ */ - -// Override __libc_memalign in libc on linux boxes specially. -// They have a bug in libc that causes them to (very rarely) allocate -// with __libc_memalign() yet deallocate with free() and the -// definitions above don't catch it. -// This function is an exception to the rule of calling MallocHook method -// from the stack frame of the allocation function; -// heap-checker handles this special case explicitly. -static void *MemalignOverride(size_t align, size_t size, const void *caller) - __THROW { - void* result = do_memalign(align, size); - MallocHook::InvokeNewHook(result, size); - return result; -} -void *(*__memalign_hook)(size_t, size_t, const void *) = MemalignOverride; - -#endif - -#ifdef WTF_CHANGES -void releaseFastMallocFreeMemory() -{ - // Flush free pages in the current thread cache back to the page heap. - // Low watermark mechanism in Scavenge() prevents full return on the first pass. - // The second pass flushes everything. - if (TCMalloc_ThreadCache* threadCache = TCMalloc_ThreadCache::GetCacheIfPresent()) { - threadCache->Scavenge(); - threadCache->Scavenge(); - } - - SpinLockHolder h(&pageheap_lock); - pageheap->ReleaseFreePages(); -} - -FastMallocStatistics fastMallocStatistics() -{ - FastMallocStatistics statistics; - - SpinLockHolder lockHolder(&pageheap_lock); - statistics.reservedVMBytes = static_cast<size_t>(pageheap->SystemBytes()); - statistics.committedVMBytes = statistics.reservedVMBytes - pageheap->ReturnedBytes(); - - statistics.freeListBytes = 0; - for (unsigned cl = 0; cl < kNumClasses; ++cl) { - const int length = central_cache[cl].length(); - const int tc_length = central_cache[cl].tc_length(); - - statistics.freeListBytes += ByteSizeForClass(cl) * (length + tc_length); - } - for (TCMalloc_ThreadCache* threadCache = thread_heaps; threadCache ; threadCache = threadCache->next_) - statistics.freeListBytes += threadCache->Size(); - - return statistics; -} - -size_t fastMallocSize(const void* ptr) -{ - const PageID p = reinterpret_cast<uintptr_t>(ptr) >> kPageShift; - Span* span = pageheap->GetDescriptorEnsureSafe(p); - - if (!span || span->free) - return 0; - - for (void* free = span->objects; free != NULL; free = *((void**) free)) { - if (ptr == free) - return 0; - } - - if (size_t cl = span->sizeclass) - return ByteSizeForClass(cl); - - return span->length << kPageShift; -} - -#if OS(DARWIN) - -class FreeObjectFinder { - const RemoteMemoryReader& m_reader; - HashSet<void*> m_freeObjects; - -public: - FreeObjectFinder(const RemoteMemoryReader& reader) : m_reader(reader) { } - - void visit(void* ptr) { m_freeObjects.add(ptr); } - bool isFreeObject(void* ptr) const { return m_freeObjects.contains(ptr); } - bool isFreeObject(vm_address_t ptr) const { return isFreeObject(reinterpret_cast<void*>(ptr)); } - size_t freeObjectCount() const { return m_freeObjects.size(); } - - void findFreeObjects(TCMalloc_ThreadCache* threadCache) - { - for (; threadCache; threadCache = (threadCache->next_ ? m_reader(threadCache->next_) : 0)) - threadCache->enumerateFreeObjects(*this, m_reader); - } - - void findFreeObjects(TCMalloc_Central_FreeListPadded* centralFreeList, size_t numSizes, TCMalloc_Central_FreeListPadded* remoteCentralFreeList) - { - for (unsigned i = 0; i < numSizes; i++) - centralFreeList[i].enumerateFreeObjects(*this, m_reader, remoteCentralFreeList + i); - } -}; - -class PageMapFreeObjectFinder { - const RemoteMemoryReader& m_reader; - FreeObjectFinder& m_freeObjectFinder; - -public: - PageMapFreeObjectFinder(const RemoteMemoryReader& reader, FreeObjectFinder& freeObjectFinder) - : m_reader(reader) - , m_freeObjectFinder(freeObjectFinder) - { } - - int visit(void* ptr) const - { - if (!ptr) - return 1; - - Span* span = m_reader(reinterpret_cast<Span*>(ptr)); - if (span->free) { - void* ptr = reinterpret_cast<void*>(span->start << kPageShift); - m_freeObjectFinder.visit(ptr); - } else if (span->sizeclass) { - // Walk the free list of the small-object span, keeping track of each object seen - for (void* nextObject = span->objects; nextObject; nextObject = *m_reader(reinterpret_cast<void**>(nextObject))) - m_freeObjectFinder.visit(nextObject); - } - return span->length; - } -}; - -class PageMapMemoryUsageRecorder { - task_t m_task; - void* m_context; - unsigned m_typeMask; - vm_range_recorder_t* m_recorder; - const RemoteMemoryReader& m_reader; - const FreeObjectFinder& m_freeObjectFinder; - - HashSet<void*> m_seenPointers; - Vector<Span*> m_coalescedSpans; - -public: - PageMapMemoryUsageRecorder(task_t task, void* context, unsigned typeMask, vm_range_recorder_t* recorder, const RemoteMemoryReader& reader, const FreeObjectFinder& freeObjectFinder) - : m_task(task) - , m_context(context) - , m_typeMask(typeMask) - , m_recorder(recorder) - , m_reader(reader) - , m_freeObjectFinder(freeObjectFinder) - { } - - ~PageMapMemoryUsageRecorder() - { - ASSERT(!m_coalescedSpans.size()); - } - - void recordPendingRegions() - { - Span* lastSpan = m_coalescedSpans[m_coalescedSpans.size() - 1]; - vm_range_t ptrRange = { m_coalescedSpans[0]->start << kPageShift, 0 }; - ptrRange.size = (lastSpan->start << kPageShift) - ptrRange.address + (lastSpan->length * kPageSize); - - // Mark the memory region the spans represent as a candidate for containing pointers - if (m_typeMask & MALLOC_PTR_REGION_RANGE_TYPE) - (*m_recorder)(m_task, m_context, MALLOC_PTR_REGION_RANGE_TYPE, &ptrRange, 1); - - if (!(m_typeMask & MALLOC_PTR_IN_USE_RANGE_TYPE)) { - m_coalescedSpans.clear(); - return; - } - - Vector<vm_range_t, 1024> allocatedPointers; - for (size_t i = 0; i < m_coalescedSpans.size(); ++i) { - Span *theSpan = m_coalescedSpans[i]; - if (theSpan->free) - continue; - - vm_address_t spanStartAddress = theSpan->start << kPageShift; - vm_size_t spanSizeInBytes = theSpan->length * kPageSize; - - if (!theSpan->sizeclass) { - // If it's an allocated large object span, mark it as in use - if (!m_freeObjectFinder.isFreeObject(spanStartAddress)) - allocatedPointers.append((vm_range_t){spanStartAddress, spanSizeInBytes}); - } else { - const size_t objectSize = ByteSizeForClass(theSpan->sizeclass); - - // Mark each allocated small object within the span as in use - const vm_address_t endOfSpan = spanStartAddress + spanSizeInBytes; - for (vm_address_t object = spanStartAddress; object + objectSize <= endOfSpan; object += objectSize) { - if (!m_freeObjectFinder.isFreeObject(object)) - allocatedPointers.append((vm_range_t){object, objectSize}); - } - } - } - - (*m_recorder)(m_task, m_context, MALLOC_PTR_IN_USE_RANGE_TYPE, allocatedPointers.data(), allocatedPointers.size()); - - m_coalescedSpans.clear(); - } - - int visit(void* ptr) - { - if (!ptr) - return 1; - - Span* span = m_reader(reinterpret_cast<Span*>(ptr)); - if (!span->start) - return 1; - - if (m_seenPointers.contains(ptr)) - return span->length; - m_seenPointers.add(ptr); - - if (!m_coalescedSpans.size()) { - m_coalescedSpans.append(span); - return span->length; - } - - Span* previousSpan = m_coalescedSpans[m_coalescedSpans.size() - 1]; - vm_address_t previousSpanStartAddress = previousSpan->start << kPageShift; - vm_size_t previousSpanSizeInBytes = previousSpan->length * kPageSize; - - // If the new span is adjacent to the previous span, do nothing for now. - vm_address_t spanStartAddress = span->start << kPageShift; - if (spanStartAddress == previousSpanStartAddress + previousSpanSizeInBytes) { - m_coalescedSpans.append(span); - return span->length; - } - - // New span is not adjacent to previous span, so record the spans coalesced so far. - recordPendingRegions(); - m_coalescedSpans.append(span); - - return span->length; - } -}; - -class AdminRegionRecorder { - task_t m_task; - void* m_context; - unsigned m_typeMask; - vm_range_recorder_t* m_recorder; - const RemoteMemoryReader& m_reader; - - Vector<vm_range_t, 1024> m_pendingRegions; - -public: - AdminRegionRecorder(task_t task, void* context, unsigned typeMask, vm_range_recorder_t* recorder, const RemoteMemoryReader& reader) - : m_task(task) - , m_context(context) - , m_typeMask(typeMask) - , m_recorder(recorder) - , m_reader(reader) - { } - - void recordRegion(vm_address_t ptr, size_t size) - { - if (m_typeMask & MALLOC_ADMIN_REGION_RANGE_TYPE) - m_pendingRegions.append((vm_range_t){ ptr, size }); - } - - void visit(void *ptr, size_t size) - { - recordRegion(reinterpret_cast<vm_address_t>(ptr), size); - } - - void recordPendingRegions() - { - if (m_pendingRegions.size()) { - (*m_recorder)(m_task, m_context, MALLOC_ADMIN_REGION_RANGE_TYPE, m_pendingRegions.data(), m_pendingRegions.size()); - m_pendingRegions.clear(); - } - } - - ~AdminRegionRecorder() - { - ASSERT(!m_pendingRegions.size()); - } -}; - -kern_return_t FastMallocZone::enumerate(task_t task, void* context, unsigned typeMask, vm_address_t zoneAddress, memory_reader_t reader, vm_range_recorder_t recorder) -{ - RemoteMemoryReader memoryReader(task, reader); - - InitSizeClasses(); - - FastMallocZone* mzone = memoryReader(reinterpret_cast<FastMallocZone*>(zoneAddress)); - TCMalloc_PageHeap* pageHeap = memoryReader(mzone->m_pageHeap); - TCMalloc_ThreadCache** threadHeapsPointer = memoryReader(mzone->m_threadHeaps); - TCMalloc_ThreadCache* threadHeaps = memoryReader(*threadHeapsPointer); - - TCMalloc_Central_FreeListPadded* centralCaches = memoryReader(mzone->m_centralCaches, sizeof(TCMalloc_Central_FreeListPadded) * kNumClasses); - - FreeObjectFinder finder(memoryReader); - finder.findFreeObjects(threadHeaps); - finder.findFreeObjects(centralCaches, kNumClasses, mzone->m_centralCaches); - - TCMalloc_PageHeap::PageMap* pageMap = &pageHeap->pagemap_; - PageMapFreeObjectFinder pageMapFinder(memoryReader, finder); - pageMap->visitValues(pageMapFinder, memoryReader); - - PageMapMemoryUsageRecorder usageRecorder(task, context, typeMask, recorder, memoryReader, finder); - pageMap->visitValues(usageRecorder, memoryReader); - usageRecorder.recordPendingRegions(); - - AdminRegionRecorder adminRegionRecorder(task, context, typeMask, recorder, memoryReader); - pageMap->visitAllocations(adminRegionRecorder, memoryReader); - - PageHeapAllocator<Span>* spanAllocator = memoryReader(mzone->m_spanAllocator); - PageHeapAllocator<TCMalloc_ThreadCache>* pageHeapAllocator = memoryReader(mzone->m_pageHeapAllocator); - - spanAllocator->recordAdministrativeRegions(adminRegionRecorder, memoryReader); - pageHeapAllocator->recordAdministrativeRegions(adminRegionRecorder, memoryReader); - - adminRegionRecorder.recordPendingRegions(); - - return 0; -} - -size_t FastMallocZone::size(malloc_zone_t*, const void*) -{ - return 0; -} - -void* FastMallocZone::zoneMalloc(malloc_zone_t*, size_t) -{ - return 0; -} - -void* FastMallocZone::zoneCalloc(malloc_zone_t*, size_t, size_t) -{ - return 0; -} - -void FastMallocZone::zoneFree(malloc_zone_t*, void* ptr) -{ - // Due to <rdar://problem/5671357> zoneFree may be called by the system free even if the pointer - // is not in this zone. When this happens, the pointer being freed was not allocated by any - // zone so we need to print a useful error for the application developer. - malloc_printf("*** error for object %p: pointer being freed was not allocated\n", ptr); -} - -void* FastMallocZone::zoneRealloc(malloc_zone_t*, void*, size_t) -{ - return 0; -} - - -#undef malloc -#undef free -#undef realloc -#undef calloc - -extern "C" { -malloc_introspection_t jscore_fastmalloc_introspection = { &FastMallocZone::enumerate, &FastMallocZone::goodSize, &FastMallocZone::check, &FastMallocZone::print, - &FastMallocZone::log, &FastMallocZone::forceLock, &FastMallocZone::forceUnlock, &FastMallocZone::statistics - -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) - , 0 // zone_locked will not be called on the zone unless it advertises itself as version five or higher. -#endif -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_SNOW_LEOPARD) - , 0, 0, 0, 0 // These members will not be used unless the zone advertises itself as version seven or higher. -#endif - - }; -} - -FastMallocZone::FastMallocZone(TCMalloc_PageHeap* pageHeap, TCMalloc_ThreadCache** threadHeaps, TCMalloc_Central_FreeListPadded* centralCaches, PageHeapAllocator<Span>* spanAllocator, PageHeapAllocator<TCMalloc_ThreadCache>* pageHeapAllocator) - : m_pageHeap(pageHeap) - , m_threadHeaps(threadHeaps) - , m_centralCaches(centralCaches) - , m_spanAllocator(spanAllocator) - , m_pageHeapAllocator(pageHeapAllocator) -{ - memset(&m_zone, 0, sizeof(m_zone)); - m_zone.version = 4; - m_zone.zone_name = "JavaScriptCore FastMalloc"; - m_zone.size = &FastMallocZone::size; - m_zone.malloc = &FastMallocZone::zoneMalloc; - m_zone.calloc = &FastMallocZone::zoneCalloc; - m_zone.realloc = &FastMallocZone::zoneRealloc; - m_zone.free = &FastMallocZone::zoneFree; - m_zone.valloc = &FastMallocZone::zoneValloc; - m_zone.destroy = &FastMallocZone::zoneDestroy; - m_zone.introspect = &jscore_fastmalloc_introspection; - malloc_zone_register(&m_zone); -} - - -void FastMallocZone::init() -{ - static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Central_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator); -} - -#endif // OS(DARWIN) - -} // namespace WTF -#endif // WTF_CHANGES - -#endif // FORCE_SYSTEM_MALLOC diff --git a/JavaScriptCore/wtf/FastMalloc.h b/JavaScriptCore/wtf/FastMalloc.h deleted file mode 100644 index 9729bc3..0000000 --- a/JavaScriptCore/wtf/FastMalloc.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_FastMalloc_h -#define WTF_FastMalloc_h - -#include "Platform.h" -#include "PossiblyNull.h" -#include <stdlib.h> -#include <new> - -namespace WTF { - - // These functions call CRASH() if an allocation fails. - void* fastMalloc(size_t); - void* fastZeroedMalloc(size_t); - void* fastCalloc(size_t numElements, size_t elementSize); - void* fastRealloc(void*, size_t); - char* fastStrDup(const char*); - size_t fastMallocSize(const void*); - - struct TryMallocReturnValue { - TryMallocReturnValue(void* data) - : m_data(data) - { - } - TryMallocReturnValue(const TryMallocReturnValue& source) - : m_data(source.m_data) - { - source.m_data = 0; - } - ~TryMallocReturnValue() { ASSERT(!m_data); } - template <typename T> bool getValue(T& data) WARN_UNUSED_RETURN; - template <typename T> operator PossiblyNull<T>() - { - T value; - getValue(value); - return PossiblyNull<T>(value); - } - private: - mutable void* m_data; - }; - - template <typename T> bool TryMallocReturnValue::getValue(T& data) - { - union u { void* data; T target; } res; - res.data = m_data; - data = res.target; - bool returnValue = !!m_data; - m_data = 0; - return returnValue; - } - - TryMallocReturnValue tryFastMalloc(size_t n); - TryMallocReturnValue tryFastZeroedMalloc(size_t n); - TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size); - TryMallocReturnValue tryFastRealloc(void* p, size_t n); - - void fastFree(void*); - -#ifndef NDEBUG - void fastMallocForbid(); - void fastMallocAllow(); -#endif - - void releaseFastMallocFreeMemory(); - - struct FastMallocStatistics { - size_t reservedVMBytes; - size_t committedVMBytes; - size_t freeListBytes; - }; - FastMallocStatistics fastMallocStatistics(); - - // This defines a type which holds an unsigned integer and is the same - // size as the minimally aligned memory allocation. - typedef unsigned long long AllocAlignmentInteger; - - namespace Internal { - enum AllocType { // Start with an unusual number instead of zero, because zero is common. - AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc. - AllocTypeClassNew, // Encompasses class operator new from FastAllocBase. - AllocTypeClassNewArray, // Encompasses class operator new[] from FastAllocBase. - AllocTypeFastNew, // Encompasses fastNew. - AllocTypeFastNewArray, // Encompasses fastNewArray. - AllocTypeNew, // Encompasses global operator new. - AllocTypeNewArray // Encompasses global operator new[]. - }; - } - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - - // Malloc validation is a scheme whereby a tag is attached to an - // allocation which identifies how it was originally allocated. - // This allows us to verify that the freeing operation matches the - // allocation operation. If memory is allocated with operator new[] - // but freed with free or delete, this system would detect that. - // In the implementation here, the tag is an integer prepended to - // the allocation memory which is assigned one of the AllocType - // enumeration values. An alternative implementation of this - // scheme could store the tag somewhere else or ignore it. - // Users of FastMalloc don't need to know or care how this tagging - // is implemented. - - namespace Internal { - - // Return the AllocType tag associated with the allocated block p. - inline AllocType fastMallocMatchValidationType(const void* p) - { - const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1; - return static_cast<AllocType>(*type); - } - - // Return the address of the AllocType tag associated with the allocated block p. - inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p) - { - return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger)); - } - - // Set the AllocType tag to be associaged with the allocated block p. - inline void setFastMallocMatchValidationType(void* p, AllocType allocType) - { - AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1; - *type = static_cast<AllocAlignmentInteger>(allocType); - } - - // Handle a detected alloc/free mismatch. By default this calls CRASH(). - void fastMallocMatchFailed(void* p); - - } // namespace Internal - - // This is a higher level function which is used by FastMalloc-using code. - inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType) - { - if (!p) - return; - - Internal::setFastMallocMatchValidationType(p, allocType); - } - - // This is a higher level function which is used by FastMalloc-using code. - inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType) - { - if (!p) - return; - - if (Internal::fastMallocMatchValidationType(p) != allocType) - Internal::fastMallocMatchFailed(p); - Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc); // Set it to this so that fastFree thinks it's OK. - } - -#else - - inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType) - { - } - - inline void fastMallocMatchValidateFree(void*, Internal::AllocType) - { - } - -#endif - -} // namespace WTF - -using WTF::fastCalloc; -using WTF::fastFree; -using WTF::fastMalloc; -using WTF::fastMallocSize; -using WTF::fastRealloc; -using WTF::fastStrDup; -using WTF::fastZeroedMalloc; -using WTF::tryFastCalloc; -using WTF::tryFastMalloc; -using WTF::tryFastRealloc; -using WTF::tryFastZeroedMalloc; - -#ifndef NDEBUG -using WTF::fastMallocForbid; -using WTF::fastMallocAllow; -#endif - -#if COMPILER(GCC) && OS(DARWIN) -#define WTF_PRIVATE_INLINE __private_extern__ inline __attribute__((always_inline)) -#elif COMPILER(GCC) -#define WTF_PRIVATE_INLINE inline __attribute__((always_inline)) -#elif COMPILER(MSVC) || COMPILER(RVCT) -#define WTF_PRIVATE_INLINE __forceinline -#else -#define WTF_PRIVATE_INLINE inline -#endif - -#if !defined(_CRTDBG_MAP_ALLOC) && !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC && !PLATFORM(BREWMP)) - -// The nothrow functions here are actually not all that helpful, because fastMalloc will -// call CRASH() rather than returning 0, and returning 0 is what nothrow is all about. -// But since WebKit code never uses exceptions or nothrow at all, this is probably OK. -// Long term we will adopt FastAllocBase.h everywhere, and and replace this with -// debug-only code to make sure we don't use the system malloc via the default operator -// new by accident. - -#if ENABLE(GLOBAL_FASTMALLOC_NEW) - -#if COMPILER(MSVC) -#pragma warning(push) -#pragma warning(disable: 4290) // Disable the C++ exception specification ignored warning. -#endif -WTF_PRIVATE_INLINE void* operator new(size_t size) throw (std::bad_alloc) { return fastMalloc(size); } -WTF_PRIVATE_INLINE void* operator new(size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } -WTF_PRIVATE_INLINE void operator delete(void* p) throw() { fastFree(p); } -WTF_PRIVATE_INLINE void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); } -WTF_PRIVATE_INLINE void* operator new[](size_t size) throw (std::bad_alloc) { return fastMalloc(size); } -WTF_PRIVATE_INLINE void* operator new[](size_t size, const std::nothrow_t&) throw() { return fastMalloc(size); } -WTF_PRIVATE_INLINE void operator delete[](void* p) throw() { fastFree(p); } -WTF_PRIVATE_INLINE void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); } -#if COMPILER(MSVC) -#pragma warning(pop) -#endif - -#endif - -#endif - -#endif /* WTF_FastMalloc_h */ diff --git a/JavaScriptCore/wtf/FixedArray.h b/JavaScriptCore/wtf/FixedArray.h deleted file mode 100644 index c67d18c..0000000 --- a/JavaScriptCore/wtf/FixedArray.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef FixedArray_h -#define FixedArray_h - -#include <wtf/Assertions.h> - -namespace WTF { - -template <typename T, size_t Size> class FixedArray { -public: - T& operator[](size_t i) - { - ASSERT(i < Size); - return m_data[i]; - } - - const T& operator[](size_t i) const - { - ASSERT(i < Size); - return m_data[i]; - } - - T* data() { return m_data; } - size_t size() const { return Size; } - -private: - T m_data[Size]; -}; - -} // namespace WTF - -using WTF::FixedArray; - -#endif // FixedArray_h diff --git a/JavaScriptCore/wtf/Forward.h b/JavaScriptCore/wtf/Forward.h deleted file mode 100644 index 3a9cfa7..0000000 --- a/JavaScriptCore/wtf/Forward.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2006, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_Forward_h -#define WTF_Forward_h - -#include <stddef.h> - -namespace WTF { - template<typename T> class ListRefPtr; - template<typename T> class OwnArrayPtr; - template<typename T> class OwnPtr; - template<typename T> class PassOwnArrayPtr; - template<typename T> class PassOwnPtr; - template<typename T> class PassRefPtr; - template<typename T> class RefPtr; - template<typename T, size_t inlineCapacity> class Vector; - - class AtomicString; - class AtomicStringImpl; - class CString; - class String; - class StringBuffer; - class StringImpl; -} - -using WTF::ListRefPtr; -using WTF::OwnArrayPtr; -using WTF::OwnPtr; -using WTF::PassOwnArrayPtr; -using WTF::PassOwnPtr; -using WTF::PassRefPtr; -using WTF::RefPtr; -using WTF::Vector; - -using WTF::AtomicString; -using WTF::AtomicStringImpl; -using WTF::CString; -using WTF::String; -using WTF::StringBuffer; -using WTF::StringImpl; - -#endif // WTF_Forward_h diff --git a/JavaScriptCore/wtf/GetPtr.h b/JavaScriptCore/wtf/GetPtr.h deleted file mode 100644 index 25a0e6d..0000000 --- a/JavaScriptCore/wtf/GetPtr.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_GetPtr_h -#define WTF_GetPtr_h - -namespace WTF { - - template <typename T> inline T* getPtr(T* p) - { - return p; - } - -} // namespace WTF - -#endif // WTF_GetPtr_h diff --git a/JavaScriptCore/wtf/HashCountedSet.h b/JavaScriptCore/wtf/HashCountedSet.h deleted file mode 100644 index 4ed75c5..0000000 --- a/JavaScriptCore/wtf/HashCountedSet.h +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_HashCountedSet_h -#define WTF_HashCountedSet_h - -#include "Assertions.h" -#include "FastAllocBase.h" -#include "HashMap.h" -#include "Vector.h" - -namespace WTF { - - template<typename Value, typename HashFunctions = typename DefaultHash<Value>::Hash, - typename Traits = HashTraits<Value> > class HashCountedSet : public FastAllocBase { - private: - typedef HashMap<Value, unsigned, HashFunctions, Traits> ImplType; - public: - typedef Value ValueType; - typedef typename ImplType::iterator iterator; - typedef typename ImplType::const_iterator const_iterator; - - HashCountedSet() {} - - int size() const; - int capacity() const; - bool isEmpty() const; - - // Iterators iterate over pairs of values and counts. - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - - iterator find(const ValueType&); - const_iterator find(const ValueType&) const; - bool contains(const ValueType&) const; - unsigned count(const ValueType&) const; - - // Increases the count if an equal value is already present - // the return value is a pair of an interator to the new value's - // location, and a bool that is true if an new entry was added. - std::pair<iterator, bool> add(const ValueType&); - - // Reduces the count of the value, and removes it if count - // goes down to zero, returns true if the value is removed. - bool remove(const ValueType&); - bool remove(iterator); - - // Removes the value, regardless of its count. - void removeAll(iterator); - void removeAll(const ValueType&); - - // Clears the whole set. - void clear(); - - private: - ImplType m_impl; - }; - - template<typename Value, typename HashFunctions, typename Traits> - inline int HashCountedSet<Value, HashFunctions, Traits>::size() const - { - return m_impl.size(); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline int HashCountedSet<Value, HashFunctions, Traits>::capacity() const - { - return m_impl.capacity(); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline bool HashCountedSet<Value, HashFunctions, Traits>::isEmpty() const - { - return size() == 0; - } - - template<typename Value, typename HashFunctions, typename Traits> - inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::begin() - { - return m_impl.begin(); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::end() - { - return m_impl.end(); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::begin() const - { - return m_impl.begin(); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::end() const - { - return m_impl.end(); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline typename HashCountedSet<Value, HashFunctions, Traits>::iterator HashCountedSet<Value, HashFunctions, Traits>::find(const ValueType& value) - { - return m_impl.find(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator HashCountedSet<Value, HashFunctions, Traits>::find(const ValueType& value) const - { - return m_impl.find(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline bool HashCountedSet<Value, HashFunctions, Traits>::contains(const ValueType& value) const - { - return m_impl.contains(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline unsigned HashCountedSet<Value, HashFunctions, Traits>::count(const ValueType& value) const - { - return m_impl.get(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline std::pair<typename HashCountedSet<Value, HashFunctions, Traits>::iterator, bool> HashCountedSet<Value, HashFunctions, Traits>::add(const ValueType &value) - { - pair<iterator, bool> result = m_impl.add(value, 0); - ++result.first->second; - return result; - } - - template<typename Value, typename HashFunctions, typename Traits> - inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(const ValueType& value) - { - return remove(find(value)); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline bool HashCountedSet<Value, HashFunctions, Traits>::remove(iterator it) - { - if (it == end()) - return false; - - unsigned oldVal = it->second; - ASSERT(oldVal); - unsigned newVal = oldVal - 1; - if (newVal) { - it->second = newVal; - return false; - } - - m_impl.remove(it); - return true; - } - - template<typename Value, typename HashFunctions, typename Traits> - inline void HashCountedSet<Value, HashFunctions, Traits>::removeAll(const ValueType& value) - { - removeAll(find(value)); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline void HashCountedSet<Value, HashFunctions, Traits>::removeAll(iterator it) - { - if (it == end()) - return; - - m_impl.remove(it); - } - - template<typename Value, typename HashFunctions, typename Traits> - inline void HashCountedSet<Value, HashFunctions, Traits>::clear() - { - m_impl.clear(); - } - - template<typename Value, typename HashFunctions, typename Traits, typename VectorType> - inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits>& collection, VectorType& vector) - { - typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator; - - vector.resize(collection.size()); - - iterator it = collection.begin(); - iterator end = collection.end(); - for (unsigned i = 0; it != end; ++it, ++i) - vector[i] = *it; - } - - template<typename Value, typename HashFunctions, typename Traits> - inline void copyToVector(const HashCountedSet<Value, HashFunctions, Traits>& collection, Vector<Value>& vector) - { - typedef typename HashCountedSet<Value, HashFunctions, Traits>::const_iterator iterator; - - vector.resize(collection.size()); - - iterator it = collection.begin(); - iterator end = collection.end(); - for (unsigned i = 0; it != end; ++it, ++i) - vector[i] = (*it).first; - } - - -} // namespace khtml - -using WTF::HashCountedSet; - -#endif /* WTF_HashCountedSet_h */ diff --git a/JavaScriptCore/wtf/HashFunctions.h b/JavaScriptCore/wtf/HashFunctions.h deleted file mode 100644 index 2c66a2d..0000000 --- a/JavaScriptCore/wtf/HashFunctions.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_HashFunctions_h -#define WTF_HashFunctions_h - -#include "RefPtr.h" -#include <stdint.h> - -namespace WTF { - - template<size_t size> struct IntTypes; - template<> struct IntTypes<1> { typedef int8_t SignedType; typedef uint8_t UnsignedType; }; - template<> struct IntTypes<2> { typedef int16_t SignedType; typedef uint16_t UnsignedType; }; - template<> struct IntTypes<4> { typedef int32_t SignedType; typedef uint32_t UnsignedType; }; - template<> struct IntTypes<8> { typedef int64_t SignedType; typedef uint64_t UnsignedType; }; - - // integer hash function - - // Thomas Wang's 32 Bit Mix Function: http://www.cris.com/~Ttwang/tech/inthash.htm - inline unsigned intHash(uint8_t key8) - { - unsigned key = key8; - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; - } - - // Thomas Wang's 32 Bit Mix Function: http://www.cris.com/~Ttwang/tech/inthash.htm - inline unsigned intHash(uint16_t key16) - { - unsigned key = key16; - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; - } - - // Thomas Wang's 32 Bit Mix Function: http://www.cris.com/~Ttwang/tech/inthash.htm - inline unsigned intHash(uint32_t key) - { - key += ~(key << 15); - key ^= (key >> 10); - key += (key << 3); - key ^= (key >> 6); - key += ~(key << 11); - key ^= (key >> 16); - return key; - } - - // Thomas Wang's 64 bit Mix Function: http://www.cris.com/~Ttwang/tech/inthash.htm - inline unsigned intHash(uint64_t key) - { - key += ~(key << 32); - key ^= (key >> 22); - key += ~(key << 13); - key ^= (key >> 8); - key += (key << 3); - key ^= (key >> 15); - key += ~(key << 27); - key ^= (key >> 31); - return static_cast<unsigned>(key); - } - - template<typename T> struct IntHash { - static unsigned hash(T key) { return intHash(static_cast<typename IntTypes<sizeof(T)>::UnsignedType>(key)); } - static bool equal(T a, T b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = true; - }; - - template<typename T> struct FloatHash { - static unsigned hash(T key) - { - union { - T key; - typename IntTypes<sizeof(T)>::UnsignedType bits; - } u; - u.key = key; - return intHash(u.bits); - } - static bool equal(T a, T b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = true; - }; - - // pointer identity hash function - - template<typename T> struct PtrHash { - static unsigned hash(T key) - { -#if COMPILER(MSVC) -#pragma warning(push) -#pragma warning(disable: 4244) // work around what seems to be a bug in MSVC's conversion warnings -#endif - return IntHash<uintptr_t>::hash(reinterpret_cast<uintptr_t>(key)); -#if COMPILER(MSVC) -#pragma warning(pop) -#endif - } - static bool equal(T a, T b) { return a == b; } - static const bool safeToCompareToEmptyOrDeleted = true; - }; - template<typename P> struct PtrHash<RefPtr<P> > : PtrHash<P*> { - using PtrHash<P*>::hash; - static unsigned hash(const RefPtr<P>& key) { return hash(key.get()); } - using PtrHash<P*>::equal; - static bool equal(const RefPtr<P>& a, const RefPtr<P>& b) { return a == b; } - static bool equal(P* a, const RefPtr<P>& b) { return a == b; } - static bool equal(const RefPtr<P>& a, P* b) { return a == b; } - }; - - // default hash function for each type - - template<typename T> struct DefaultHash; - - template<typename T, typename U> struct PairHash { - static unsigned hash(const std::pair<T, U>& p) - { - return intHash((static_cast<uint64_t>(DefaultHash<T>::Hash::hash(p.first)) << 32 | DefaultHash<U>::Hash::hash(p.second))); - } - static bool equal(const std::pair<T, U>& a, const std::pair<T, U>& b) - { - return DefaultHash<T>::Hash::equal(a.first, b.first) && DefaultHash<U>::Hash::equal(a.second, b.second); - } - static const bool safeToCompareToEmptyOrDeleted = DefaultHash<T>::Hash::safeToCompareToEmptyOrDeleted - && DefaultHash<U>::Hash::safeToCompareToEmptyOrDeleted; - }; - - // make IntHash the default hash function for many integer types - - template<> struct DefaultHash<short> { typedef IntHash<unsigned> Hash; }; - template<> struct DefaultHash<unsigned short> { typedef IntHash<unsigned> Hash; }; - template<> struct DefaultHash<int> { typedef IntHash<unsigned> Hash; }; - template<> struct DefaultHash<unsigned> { typedef IntHash<unsigned> Hash; }; - template<> struct DefaultHash<long> { typedef IntHash<unsigned long> Hash; }; - template<> struct DefaultHash<unsigned long> { typedef IntHash<unsigned long> Hash; }; - template<> struct DefaultHash<long long> { typedef IntHash<unsigned long long> Hash; }; - template<> struct DefaultHash<unsigned long long> { typedef IntHash<unsigned long long> Hash; }; - -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - template<> struct DefaultHash<wchar_t> { typedef IntHash<wchar_t> Hash; }; -#endif - - template<> struct DefaultHash<float> { typedef FloatHash<float> Hash; }; - template<> struct DefaultHash<double> { typedef FloatHash<double> Hash; }; - - // make PtrHash the default hash function for pointer types that don't specialize - - template<typename P> struct DefaultHash<P*> { typedef PtrHash<P*> Hash; }; - template<typename P> struct DefaultHash<RefPtr<P> > { typedef PtrHash<RefPtr<P> > Hash; }; - - template<typename T, typename U> struct DefaultHash<std::pair<T, U> > { typedef PairHash<T, U> Hash; }; - -} // namespace WTF - -using WTF::DefaultHash; -using WTF::IntHash; -using WTF::PtrHash; - -#endif // WTF_HashFunctions_h diff --git a/JavaScriptCore/wtf/HashIterators.h b/JavaScriptCore/wtf/HashIterators.h deleted file mode 100644 index 682c83b..0000000 --- a/JavaScriptCore/wtf/HashIterators.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_HashIterators_h -#define WTF_HashIterators_h - -namespace WTF { - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstKeysIterator; - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstValuesIterator; - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableKeysIterator; - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableValuesIterator; - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > { - private: - typedef std::pair<KeyType, MappedType> ValueType; - public: - typedef HashTableConstKeysIterator<HashTableType, KeyType, MappedType> Keys; - typedef HashTableConstValuesIterator<HashTableType, KeyType, MappedType> Values; - - HashTableConstIteratorAdapter(const typename HashTableType::const_iterator& impl) : m_impl(impl) {} - - const ValueType* get() const { return (const ValueType*)m_impl.get(); } - const ValueType& operator*() const { return *get(); } - const ValueType* operator->() const { return get(); } - - HashTableConstIteratorAdapter& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - Keys keys() { return Keys(*this); } - Values values() { return Values(*this); } - - typename HashTableType::const_iterator m_impl; - }; - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > { - private: - typedef std::pair<KeyType, MappedType> ValueType; - public: - typedef HashTableKeysIterator<HashTableType, KeyType, MappedType> Keys; - typedef HashTableValuesIterator<HashTableType, KeyType, MappedType> Values; - - HashTableIteratorAdapter(const typename HashTableType::iterator& impl) : m_impl(impl) {} - - ValueType* get() const { return (ValueType*)m_impl.get(); } - ValueType& operator*() const { return *get(); } - ValueType* operator->() const { return get(); } - - HashTableIteratorAdapter& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - operator HashTableConstIteratorAdapter<HashTableType, ValueType>() { - typename HashTableType::const_iterator i = m_impl; - return i; - } - - Keys keys() { return Keys(*this); } - Values values() { return Values(*this); } - - typename HashTableType::iterator m_impl; - }; - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstKeysIterator { - private: - typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator; - - public: - HashTableConstKeysIterator(const ConstIterator& impl) : m_impl(impl) {} - - const KeyType* get() const { return &(m_impl.get()->first); } - const KeyType& operator*() const { return *get(); } - const KeyType* operator->() const { return get(); } - - HashTableConstKeysIterator& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - ConstIterator m_impl; - }; - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstValuesIterator { - private: - typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator; - - public: - HashTableConstValuesIterator(const ConstIterator& impl) : m_impl(impl) {} - - const MappedType* get() const { return &(m_impl.get()->second); } - const MappedType& operator*() const { return *get(); } - const MappedType* operator->() const { return get(); } - - HashTableConstValuesIterator& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - ConstIterator m_impl; - }; - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableKeysIterator { - private: - typedef HashTableIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > Iterator; - typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator; - - public: - HashTableKeysIterator(const Iterator& impl) : m_impl(impl) {} - - KeyType* get() const { return &(m_impl.get()->first); } - KeyType& operator*() const { return *get(); } - KeyType* operator->() const { return get(); } - - HashTableKeysIterator& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - operator HashTableConstKeysIterator<HashTableType, KeyType, MappedType>() { - ConstIterator i = m_impl; - return i; - } - - Iterator m_impl; - }; - - template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableValuesIterator { - private: - typedef HashTableIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > Iterator; - typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator; - - public: - HashTableValuesIterator(const Iterator& impl) : m_impl(impl) {} - - MappedType* get() const { return &(m_impl.get()->second); } - MappedType& operator*() const { return *get(); } - MappedType* operator->() const { return get(); } - - HashTableValuesIterator& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - operator HashTableConstValuesIterator<HashTableType, KeyType, MappedType>() { - ConstIterator i = m_impl; - return i; - } - - Iterator m_impl; - }; - - template<typename T, typename U, typename V> - inline bool operator==(const HashTableConstKeysIterator<T, U, V>& a, const HashTableConstKeysIterator<T, U, V>& b) - { - return a.m_impl == b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator!=(const HashTableConstKeysIterator<T, U, V>& a, const HashTableConstKeysIterator<T, U, V>& b) - { - return a.m_impl != b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator==(const HashTableConstValuesIterator<T, U, V>& a, const HashTableConstValuesIterator<T, U, V>& b) - { - return a.m_impl == b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator!=(const HashTableConstValuesIterator<T, U, V>& a, const HashTableConstValuesIterator<T, U, V>& b) - { - return a.m_impl != b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator==(const HashTableKeysIterator<T, U, V>& a, const HashTableKeysIterator<T, U, V>& b) - { - return a.m_impl == b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator!=(const HashTableKeysIterator<T, U, V>& a, const HashTableKeysIterator<T, U, V>& b) - { - return a.m_impl != b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator==(const HashTableValuesIterator<T, U, V>& a, const HashTableValuesIterator<T, U, V>& b) - { - return a.m_impl == b.m_impl; - } - - template<typename T, typename U, typename V> - inline bool operator!=(const HashTableValuesIterator<T, U, V>& a, const HashTableValuesIterator<T, U, V>& b) - { - return a.m_impl != b.m_impl; - } - - -} // namespace WTF - -#endif // WTF_HashIterators_h diff --git a/JavaScriptCore/wtf/HashMap.h b/JavaScriptCore/wtf/HashMap.h deleted file mode 100644 index 09094d1..0000000 --- a/JavaScriptCore/wtf/HashMap.h +++ /dev/null @@ -1,410 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_HashMap_h -#define WTF_HashMap_h - -#include "HashTable.h" - -namespace WTF { - - template<typename PairType> struct PairFirstExtractor; - - template<typename KeyArg, typename MappedArg, typename HashArg = typename DefaultHash<KeyArg>::Hash, - typename KeyTraitsArg = HashTraits<KeyArg>, typename MappedTraitsArg = HashTraits<MappedArg> > - class HashMap : public FastAllocBase { - private: - typedef KeyTraitsArg KeyTraits; - typedef MappedTraitsArg MappedTraits; - typedef PairHashTraits<KeyTraits, MappedTraits> ValueTraits; - - public: - typedef typename KeyTraits::TraitType KeyType; - typedef typename MappedTraits::TraitType MappedType; - typedef typename ValueTraits::TraitType ValueType; - - private: - typedef HashArg HashFunctions; - - typedef HashTable<KeyType, ValueType, PairFirstExtractor<ValueType>, - HashFunctions, ValueTraits, KeyTraits> HashTableType; - - public: - typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; - typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator; - - void swap(HashMap&); - - int size() const; - int capacity() const; - bool isEmpty() const; - - // iterators iterate over pairs of keys and values - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - - iterator find(const KeyType&); - const_iterator find(const KeyType&) const; - bool contains(const KeyType&) const; - MappedType get(const KeyType&) const; - - // replaces value but not key if key is already present - // return value is a pair of the iterator to the key location, - // and a boolean that's true if a new value was actually added - pair<iterator, bool> set(const KeyType&, const MappedType&); - - // does nothing if key is already present - // return value is a pair of the iterator to the key location, - // and a boolean that's true if a new value was actually added - pair<iterator, bool> add(const KeyType&, const MappedType&); - - void remove(const KeyType&); - void remove(iterator); - void clear(); - - MappedType take(const KeyType&); // efficient combination of get with remove - - // An alternate version of find() that finds the object by hashing and comparing - // with some other type, to avoid the cost of type conversion. HashTranslator - // must have the following function members: - // static unsigned hash(const T&); - // static bool equal(const ValueType&, const T&); - template<typename T, typename HashTranslator> iterator find(const T&); - template<typename T, typename HashTranslator> const_iterator find(const T&) const; - template<typename T, typename HashTranslator> bool contains(const T&) const; - - // An alternate version of add() that finds the object by hashing and comparing - // with some other type, to avoid the cost of type conversion if the object is already - // in the table. HashTranslator must have the following function members: - // static unsigned hash(const T&); - // static bool equal(const ValueType&, const T&); - // static translate(ValueType&, const T&, unsigned hashCode); - template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&, const MappedType&); - - void checkConsistency() const; - - private: - pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&); - - HashTableType m_impl; - }; - - template<typename PairType> struct PairFirstExtractor { - static const typename PairType::first_type& extract(const PairType& p) { return p.first; } - }; - - template<typename ValueType, typename ValueTraits, typename HashFunctions> - struct HashMapTranslator { - typedef typename ValueType::first_type KeyType; - typedef typename ValueType::second_type MappedType; - - static unsigned hash(const KeyType& key) { return HashFunctions::hash(key); } - static bool equal(const KeyType& a, const KeyType& b) { return HashFunctions::equal(a, b); } - static void translate(ValueType& location, const KeyType& key, const MappedType& mapped) - { - location.first = key; - location.second = mapped; - } - }; - - template<typename ValueType, typename ValueTraits, typename T, typename Translator> - struct HashMapTranslatorAdapter { - typedef typename ValueType::first_type KeyType; - typedef typename ValueType::second_type MappedType; - - static unsigned hash(const T& key) { return Translator::hash(key); } - static bool equal(const KeyType& a, const T& b) { return Translator::equal(a, b); } - static void translate(ValueType& location, const T& key, const MappedType& mapped, unsigned hashCode) - { - Translator::translate(location.first, key, hashCode); - location.second = mapped; - } - }; - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<T, U, V, W, X>::swap(HashMap& other) - { - m_impl.swap(other.m_impl); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline int HashMap<T, U, V, W, X>::size() const - { - return m_impl.size(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline int HashMap<T, U, V, W, X>::capacity() const - { - return m_impl.capacity(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline bool HashMap<T, U, V, W, X>::isEmpty() const - { - return m_impl.isEmpty(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::begin() - { - return m_impl.begin(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::end() - { - return m_impl.end(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::begin() const - { - return m_impl.begin(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::end() const - { - return m_impl.end(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<T, U, V, W, X>::iterator HashMap<T, U, V, W, X>::find(const KeyType& key) - { - return m_impl.find(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<T, U, V, W, X>::const_iterator HashMap<T, U, V, W, X>::find(const KeyType& key) const - { - return m_impl.find(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline bool HashMap<T, U, V, W, X>::contains(const KeyType& key) const - { - return m_impl.contains(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - template<typename TYPE, typename HashTranslator> - inline typename HashMap<T, U, V, W, X>::iterator - HashMap<T, U, V, W, X>::find(const TYPE& value) - { - typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter; - return m_impl.template find<TYPE, Adapter>(value); - } - - template<typename T, typename U, typename V, typename W, typename X> - template<typename TYPE, typename HashTranslator> - inline typename HashMap<T, U, V, W, X>::const_iterator - HashMap<T, U, V, W, X>::find(const TYPE& value) const - { - typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter; - return m_impl.template find<TYPE, Adapter>(value); - } - - template<typename T, typename U, typename V, typename W, typename X> - template<typename TYPE, typename HashTranslator> - inline bool - HashMap<T, U, V, W, X>::contains(const TYPE& value) const - { - typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter; - return m_impl.template contains<TYPE, Adapter>(value); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline pair<typename HashMap<T, U, V, W, X>::iterator, bool> - HashMap<T, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped) - { - typedef HashMapTranslator<ValueType, ValueTraits, HashFunctions> TranslatorType; - return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped); - } - - template<typename T, typename U, typename V, typename W, typename X> - pair<typename HashMap<T, U, V, W, X>::iterator, bool> - HashMap<T, U, V, W, X>::set(const KeyType& key, const MappedType& mapped) - { - pair<iterator, bool> result = inlineAdd(key, mapped); - if (!result.second) { - // add call above didn't change anything, so set the mapped value - result.first->second = mapped; - } - return result; - } - - template<typename T, typename U, typename V, typename W, typename X> - template<typename TYPE, typename HashTranslator> - pair<typename HashMap<T, U, V, W, X>::iterator, bool> - HashMap<T, U, V, W, X>::add(const TYPE& key, const MappedType& value) - { - typedef HashMapTranslatorAdapter<ValueType, ValueTraits, TYPE, HashTranslator> Adapter; - return m_impl.template addPassingHashCode<TYPE, MappedType, Adapter>(key, value); - } - - template<typename T, typename U, typename V, typename W, typename X> - pair<typename HashMap<T, U, V, W, X>::iterator, bool> - HashMap<T, U, V, W, X>::add(const KeyType& key, const MappedType& mapped) - { - return inlineAdd(key, mapped); - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<T, U, V, W, MappedTraits>::MappedType - HashMap<T, U, V, W, MappedTraits>::get(const KeyType& key) const - { - ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); - if (!entry) - return MappedTraits::emptyValue(); - return entry->second; - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<T, U, V, W, X>::remove(iterator it) - { - if (it.m_impl == m_impl.end()) - return; - m_impl.internalCheckTableConsistency(); - m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<T, U, V, W, X>::remove(const KeyType& key) - { - remove(find(key)); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<T, U, V, W, X>::clear() - { - m_impl.clear(); - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<T, U, V, W, MappedTraits>::MappedType - HashMap<T, U, V, W, MappedTraits>::take(const KeyType& key) - { - // This can probably be made more efficient to avoid ref/deref churn. - iterator it = find(key); - if (it == end()) - return MappedTraits::emptyValue(); - typename HashMap<T, U, V, W, MappedTraits>::MappedType result = it->second; - remove(it); - return result; - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<T, U, V, W, X>::checkConsistency() const - { - m_impl.checkTableConsistency(); - } - - - template<typename T, typename U, typename V, typename W, typename X> - bool operator==(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b) - { - if (a.size() != b.size()) - return false; - - typedef typename HashMap<T, U, V, W, X>::const_iterator const_iterator; - - const_iterator end = a.end(); - const_iterator notFound = b.end(); - for (const_iterator it = a.begin(); it != end; ++it) { - const_iterator bPos = b.find(it->first); - if (bPos == notFound || it->second != bPos->second) - return false; - } - - return true; - } - - template<typename T, typename U, typename V, typename W, typename X> - inline bool operator!=(const HashMap<T, U, V, W, X>& a, const HashMap<T, U, V, W, X>& b) - { - return !(a == b); - } - - template<typename MappedType, typename HashTableType> - void deleteAllPairSeconds(HashTableType& collection) - { - typedef typename HashTableType::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete it->second; - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void deleteAllValues(const HashMap<T, U, V, W, X>& collection) - { - deleteAllPairSeconds<typename HashMap<T, U, V, W, X>::MappedType>(collection); - } - - template<typename KeyType, typename HashTableType> - void deleteAllPairFirsts(HashTableType& collection) - { - typedef typename HashTableType::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete it->first; - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void deleteAllKeys(const HashMap<T, U, V, W, X>& collection) - { - deleteAllPairFirsts<typename HashMap<T, U, V, W, X>::KeyType>(collection); - } - - template<typename T, typename U, typename V, typename W, typename X, typename Y> - inline void copyKeysToVector(const HashMap<T, U, V, W, X>& collection, Y& vector) - { - typedef typename HashMap<T, U, V, W, X>::const_iterator::Keys iterator; - - vector.resize(collection.size()); - - iterator it = collection.begin().keys(); - iterator end = collection.end().keys(); - for (unsigned i = 0; it != end; ++it, ++i) - vector[i] = *it; - } - - template<typename T, typename U, typename V, typename W, typename X, typename Y> - inline void copyValuesToVector(const HashMap<T, U, V, W, X>& collection, Y& vector) - { - typedef typename HashMap<T, U, V, W, X>::const_iterator::Values iterator; - - vector.resize(collection.size()); - - iterator it = collection.begin().values(); - iterator end = collection.end().values(); - for (unsigned i = 0; it != end; ++it, ++i) - vector[i] = *it; - } - -} // namespace WTF - -using WTF::HashMap; - -#include "RefPtrHashMap.h" - -#endif /* WTF_HashMap_h */ diff --git a/JavaScriptCore/wtf/HashSet.h b/JavaScriptCore/wtf/HashSet.h deleted file mode 100644 index 66639e4..0000000 --- a/JavaScriptCore/wtf/HashSet.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_HashSet_h -#define WTF_HashSet_h - -#include "FastAllocBase.h" -#include "HashTable.h" - -namespace WTF { - - template<typename Value, typename HashFunctions, typename Traits> class HashSet; - template<typename Value, typename HashFunctions, typename Traits> - void deleteAllValues(const HashSet<Value, HashFunctions, Traits>&); - template<typename Value, typename HashFunctions, typename Traits> - void fastDeleteAllValues(const HashSet<Value, HashFunctions, Traits>&); - - template<typename T> struct IdentityExtractor; - - template<typename ValueArg, typename HashArg = typename DefaultHash<ValueArg>::Hash, - typename TraitsArg = HashTraits<ValueArg> > class HashSet : public FastAllocBase { - private: - typedef HashArg HashFunctions; - typedef TraitsArg ValueTraits; - - public: - typedef typename ValueTraits::TraitType ValueType; - - private: - typedef HashTable<ValueType, ValueType, IdentityExtractor<ValueType>, - HashFunctions, ValueTraits, ValueTraits> HashTableType; - - public: - typedef HashTableConstIteratorAdapter<HashTableType, ValueType> iterator; - typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator; - - void swap(HashSet&); - - int size() const; - int capacity() const; - bool isEmpty() const; - - iterator begin() const; - iterator end() const; - - iterator find(const ValueType&) const; - bool contains(const ValueType&) const; - - // An alternate version of find() that finds the object by hashing and comparing - // with some other type, to avoid the cost of type conversion. HashTranslator - // must have the following function members: - // static unsigned hash(const T&); - // static bool equal(const ValueType&, const T&); - template<typename T, typename HashTranslator> iterator find(const T&) const; - template<typename T, typename HashTranslator> bool contains(const T&) const; - - // The return value is a pair of an interator to the new value's location, - // and a bool that is true if an new entry was added. - pair<iterator, bool> add(const ValueType&); - - // An alternate version of add() that finds the object by hashing and comparing - // with some other type, to avoid the cost of type conversion if the object is already - // in the table. HashTranslator must have the following function members: - // static unsigned hash(const T&); - // static bool equal(const ValueType&, const T&); - // static translate(ValueType&, const T&, unsigned hashCode); - template<typename T, typename HashTranslator> pair<iterator, bool> add(const T&); - - void remove(const ValueType&); - void remove(iterator); - void clear(); - - private: - friend void deleteAllValues<>(const HashSet&); - friend void fastDeleteAllValues<>(const HashSet&); - - HashTableType m_impl; - }; - - template<typename T> struct IdentityExtractor { - static const T& extract(const T& t) { return t; } - }; - - template<typename ValueType, typename ValueTraits, typename T, typename Translator> - struct HashSetTranslatorAdapter { - static unsigned hash(const T& key) { return Translator::hash(key); } - static bool equal(const ValueType& a, const T& b) { return Translator::equal(a, b); } - static void translate(ValueType& location, const T& key, const T&, unsigned hashCode) - { - Translator::translate(location, key, hashCode); - } - }; - - template<typename T, typename U, typename V> - inline void HashSet<T, U, V>::swap(HashSet& other) - { - m_impl.swap(other.m_impl); - } - - template<typename T, typename U, typename V> - inline int HashSet<T, U, V>::size() const - { - return m_impl.size(); - } - - template<typename T, typename U, typename V> - inline int HashSet<T, U, V>::capacity() const - { - return m_impl.capacity(); - } - - template<typename T, typename U, typename V> - inline bool HashSet<T, U, V>::isEmpty() const - { - return m_impl.isEmpty(); - } - - template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::begin() const - { - return m_impl.begin(); - } - - template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::end() const - { - return m_impl.end(); - } - - template<typename T, typename U, typename V> - inline typename HashSet<T, U, V>::iterator HashSet<T, U, V>::find(const ValueType& value) const - { - return m_impl.find(value); - } - - template<typename T, typename U, typename V> - inline bool HashSet<T, U, V>::contains(const ValueType& value) const - { - return m_impl.contains(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename HashTranslator> - typename HashSet<Value, HashFunctions, Traits>::iterator - inline HashSet<Value, HashFunctions, Traits>::find(const T& value) const - { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; - return m_impl.template find<T, Adapter>(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename HashTranslator> - inline bool HashSet<Value, HashFunctions, Traits>::contains(const T& value) const - { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; - return m_impl.template contains<T, Adapter>(value); - } - - template<typename T, typename U, typename V> - pair<typename HashSet<T, U, V>::iterator, bool> HashSet<T, U, V>::add(const ValueType& value) - { - return m_impl.add(value); - } - - template<typename Value, typename HashFunctions, typename Traits> - template<typename T, typename HashTranslator> - pair<typename HashSet<Value, HashFunctions, Traits>::iterator, bool> - HashSet<Value, HashFunctions, Traits>::add(const T& value) - { - typedef HashSetTranslatorAdapter<ValueType, ValueTraits, T, HashTranslator> Adapter; - return m_impl.template addPassingHashCode<T, T, Adapter>(value, value); - } - - template<typename T, typename U, typename V> - inline void HashSet<T, U, V>::remove(iterator it) - { - if (it.m_impl == m_impl.end()) - return; - m_impl.internalCheckTableConsistency(); - m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); - } - - template<typename T, typename U, typename V> - inline void HashSet<T, U, V>::remove(const ValueType& value) - { - remove(find(value)); - } - - template<typename T, typename U, typename V> - inline void HashSet<T, U, V>::clear() - { - m_impl.clear(); - } - - template<typename ValueType, typename HashTableType> - void deleteAllValues(HashTableType& collection) - { - typedef typename HashTableType::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete *it; - } - - template<typename T, typename U, typename V> - inline void deleteAllValues(const HashSet<T, U, V>& collection) - { - deleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl); - } - - template<typename ValueType, typename HashTableType> - void fastDeleteAllValues(HashTableType& collection) - { - typedef typename HashTableType::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - fastDelete(*it); - } - - template<typename T, typename U, typename V> - inline void fastDeleteAllValues(const HashSet<T, U, V>& collection) - { - fastDeleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl); - } - - template<typename T, typename U, typename V, typename W> - inline void copyToVector(const HashSet<T, U, V>& collection, W& vector) - { - typedef typename HashSet<T, U, V>::const_iterator iterator; - - vector.resize(collection.size()); - - iterator it = collection.begin(); - iterator end = collection.end(); - for (unsigned i = 0; it != end; ++it, ++i) - vector[i] = *it; - } - -} // namespace WTF - -using WTF::HashSet; - -#endif /* WTF_HashSet_h */ diff --git a/JavaScriptCore/wtf/HashTable.cpp b/JavaScriptCore/wtf/HashTable.cpp deleted file mode 100644 index 71d3f86..0000000 --- a/JavaScriptCore/wtf/HashTable.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/* - Copyright (C) 2005 Apple Inc. All rights reserved. - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public License - along with this library; see the file COPYING.LIB. If not, write to - the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. -*/ - -#include "config.h" -#include "HashTable.h" - -namespace WTF { - -#if DUMP_HASHTABLE_STATS - -int HashTableStats::numAccesses; -int HashTableStats::numCollisions; -int HashTableStats::collisionGraph[4096]; -int HashTableStats::maxCollisions; -int HashTableStats::numRehashes; -int HashTableStats::numRemoves; -int HashTableStats::numReinserts; - -static HashTableStats logger; - -static Mutex& hashTableStatsMutex() -{ - AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); - return mutex; -} - -HashTableStats::~HashTableStats() -{ - // Don't lock hashTableStatsMutex here because it can cause deadlocks at shutdown - // if any thread was killed while holding the mutex. - printf("\nWTF::HashTable statistics\n\n"); - printf("%d accesses\n", numAccesses); - printf("%d total collisions, average %.2f probes per access\n", numCollisions, 1.0 * (numAccesses + numCollisions) / numAccesses); - printf("longest collision chain: %d\n", maxCollisions); - for (int i = 1; i <= maxCollisions; i++) { - printf(" %d lookups with exactly %d collisions (%.2f%% , %.2f%% with this many or more)\n", collisionGraph[i], i, 100.0 * (collisionGraph[i] - collisionGraph[i+1]) / numAccesses, 100.0 * collisionGraph[i] / numAccesses); - } - printf("%d rehashes\n", numRehashes); - printf("%d reinserts\n", numReinserts); -} - -void HashTableStats::recordCollisionAtCount(int count) -{ - MutexLocker lock(hashTableStatsMutex()); - if (count > maxCollisions) - maxCollisions = count; - numCollisions++; - collisionGraph[count]++; -} - -#endif - -} // namespace WTF diff --git a/JavaScriptCore/wtf/HashTable.h b/JavaScriptCore/wtf/HashTable.h deleted file mode 100644 index 1c4ae6d..0000000 --- a/JavaScriptCore/wtf/HashTable.h +++ /dev/null @@ -1,1179 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 David Levin <levin@chromium.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_HashTable_h -#define WTF_HashTable_h - -#include "FastMalloc.h" -#include "HashTraits.h" -#include "ValueCheck.h" -#include <wtf/Assertions.h> -#include <wtf/Threading.h> - -namespace WTF { - -#define DUMP_HASHTABLE_STATS 0 -// Enables internal WTF consistency checks that are invoked automatically. Non-WTF callers can call checkTableConsistency() even if internal checks are disabled. -#define CHECK_HASHTABLE_CONSISTENCY 0 - -#ifdef NDEBUG -#define CHECK_HASHTABLE_ITERATORS 0 -#define CHECK_HASHTABLE_USE_AFTER_DESTRUCTION 0 -#else -#define CHECK_HASHTABLE_ITERATORS 1 -#define CHECK_HASHTABLE_USE_AFTER_DESTRUCTION 1 -#endif - -#if DUMP_HASHTABLE_STATS - - struct HashTableStats { - ~HashTableStats(); - // All of the variables are accessed in ~HashTableStats when the static struct is destroyed. - - // The following variables are all atomically incremented when modified. - static int numAccesses; - static int numRehashes; - static int numRemoves; - static int numReinserts; - - // The following variables are only modified in the recordCollisionAtCount method within a mutex. - static int maxCollisions; - static int numCollisions; - static int collisionGraph[4096]; - - static void recordCollisionAtCount(int count); - }; - -#endif - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - class HashTable; - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - class HashTableIterator; - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - class HashTableConstIterator; - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void addIterator(const HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*, - HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*); - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void removeIterator(HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*); - -#if !CHECK_HASHTABLE_ITERATORS - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void addIterator(const HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*, - HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*) { } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void removeIterator(HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>*) { } - -#endif - - typedef enum { HashItemKnownGood } HashItemKnownGoodTag; - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - class HashTableConstIterator { - private: - typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> HashTableType; - typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> iterator; - typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator; - typedef Value ValueType; - typedef const ValueType& ReferenceType; - typedef const ValueType* PointerType; - - friend class HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>; - friend class HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>; - - void skipEmptyBuckets() - { - while (m_position != m_endPosition && HashTableType::isEmptyOrDeletedBucket(*m_position)) - ++m_position; - } - - HashTableConstIterator(const HashTableType* table, PointerType position, PointerType endPosition) - : m_position(position), m_endPosition(endPosition) - { - addIterator(table, this); - skipEmptyBuckets(); - } - - HashTableConstIterator(const HashTableType* table, PointerType position, PointerType endPosition, HashItemKnownGoodTag) - : m_position(position), m_endPosition(endPosition) - { - addIterator(table, this); - } - - public: - HashTableConstIterator() - { - addIterator(0, this); - } - - // default copy, assignment and destructor are OK if CHECK_HASHTABLE_ITERATORS is 0 - -#if CHECK_HASHTABLE_ITERATORS - ~HashTableConstIterator() - { - removeIterator(this); - } - - HashTableConstIterator(const const_iterator& other) - : m_position(other.m_position), m_endPosition(other.m_endPosition) - { - addIterator(other.m_table, this); - } - - const_iterator& operator=(const const_iterator& other) - { - m_position = other.m_position; - m_endPosition = other.m_endPosition; - - removeIterator(this); - addIterator(other.m_table, this); - - return *this; - } -#endif - - PointerType get() const - { - checkValidity(); - return m_position; - } - ReferenceType operator*() const { return *get(); } - PointerType operator->() const { return get(); } - - const_iterator& operator++() - { - checkValidity(); - ASSERT(m_position != m_endPosition); - ++m_position; - skipEmptyBuckets(); - return *this; - } - - // postfix ++ intentionally omitted - - // Comparison. - bool operator==(const const_iterator& other) const - { - checkValidity(other); - return m_position == other.m_position; - } - bool operator!=(const const_iterator& other) const - { - checkValidity(other); - return m_position != other.m_position; - } - - private: - void checkValidity() const - { -#if CHECK_HASHTABLE_ITERATORS - ASSERT(m_table); -#endif - } - - -#if CHECK_HASHTABLE_ITERATORS - void checkValidity(const const_iterator& other) const - { - ASSERT(m_table); - ASSERT_UNUSED(other, other.m_table); - ASSERT(m_table == other.m_table); - } -#else - void checkValidity(const const_iterator&) const { } -#endif - - PointerType m_position; - PointerType m_endPosition; - -#if CHECK_HASHTABLE_ITERATORS - public: - // Any modifications of the m_next or m_previous of an iterator that is in a linked list of a HashTable::m_iterator, - // should be guarded with m_table->m_mutex. - mutable const HashTableType* m_table; - mutable const_iterator* m_next; - mutable const_iterator* m_previous; -#endif - }; - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - class HashTableIterator { - private: - typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> HashTableType; - typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> iterator; - typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator; - typedef Value ValueType; - typedef ValueType& ReferenceType; - typedef ValueType* PointerType; - - friend class HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>; - - HashTableIterator(HashTableType* table, PointerType pos, PointerType end) : m_iterator(table, pos, end) { } - HashTableIterator(HashTableType* table, PointerType pos, PointerType end, HashItemKnownGoodTag tag) : m_iterator(table, pos, end, tag) { } - - public: - HashTableIterator() { } - - // default copy, assignment and destructor are OK - - PointerType get() const { return const_cast<PointerType>(m_iterator.get()); } - ReferenceType operator*() const { return *get(); } - PointerType operator->() const { return get(); } - - iterator& operator++() { ++m_iterator; return *this; } - - // postfix ++ intentionally omitted - - // Comparison. - bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; } - bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; } - - operator const_iterator() const { return m_iterator; } - - private: - const_iterator m_iterator; - }; - - using std::swap; - -#if !COMPILER(MSVC) - // Visual C++ has a swap for pairs defined. - - // swap pairs by component, in case of pair members that specialize swap - template<typename T, typename U> inline void swap(pair<T, U>& a, pair<T, U>& b) - { - swap(a.first, b.first); - swap(a.second, b.second); - } -#endif - - template<typename T, bool useSwap> struct Mover; - template<typename T> struct Mover<T, true> { static void move(T& from, T& to) { swap(from, to); } }; - template<typename T> struct Mover<T, false> { static void move(T& from, T& to) { to = from; } }; - - template<typename Key, typename Value, typename HashFunctions> class IdentityHashTranslator { - public: - static unsigned hash(const Key& key) { return HashFunctions::hash(key); } - static bool equal(const Key& a, const Key& b) { return HashFunctions::equal(a, b); } - static void translate(Value& location, const Key&, const Value& value) { location = value; } - }; - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - class HashTable { - public: - typedef HashTableIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> iterator; - typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator; - typedef Traits ValueTraits; - typedef Key KeyType; - typedef Value ValueType; - typedef IdentityHashTranslator<Key, Value, HashFunctions> IdentityTranslatorType; - - HashTable(); - ~HashTable() - { - invalidateIterators(); - deallocateTable(m_table, m_tableSize); -#if CHECK_HASHTABLE_USE_AFTER_DESTRUCTION - m_table = (ValueType*)(uintptr_t)0xbbadbeef; -#endif - } - - HashTable(const HashTable&); - void swap(HashTable&); - HashTable& operator=(const HashTable&); - - iterator begin() { return makeIterator(m_table); } - iterator end() { return makeKnownGoodIterator(m_table + m_tableSize); } - const_iterator begin() const { return makeConstIterator(m_table); } - const_iterator end() const { return makeKnownGoodConstIterator(m_table + m_tableSize); } - - int size() const { return m_keyCount; } - int capacity() const { return m_tableSize; } - bool isEmpty() const { return !m_keyCount; } - - pair<iterator, bool> add(const ValueType& value) { return add<KeyType, ValueType, IdentityTranslatorType>(Extractor::extract(value), value); } - - // A special version of add() that finds the object by hashing and comparing - // with some other type, to avoid the cost of type conversion if the object is already - // in the table. - template<typename T, typename Extra, typename HashTranslator> pair<iterator, bool> add(const T& key, const Extra&); - template<typename T, typename Extra, typename HashTranslator> pair<iterator, bool> addPassingHashCode(const T& key, const Extra&); - - iterator find(const KeyType& key) { return find<KeyType, IdentityTranslatorType>(key); } - const_iterator find(const KeyType& key) const { return find<KeyType, IdentityTranslatorType>(key); } - bool contains(const KeyType& key) const { return contains<KeyType, IdentityTranslatorType>(key); } - - template <typename T, typename HashTranslator> iterator find(const T&); - template <typename T, typename HashTranslator> const_iterator find(const T&) const; - template <typename T, typename HashTranslator> bool contains(const T&) const; - - void remove(const KeyType&); - void remove(iterator); - void removeWithoutEntryConsistencyCheck(iterator); - void removeWithoutEntryConsistencyCheck(const_iterator); - void clear(); - - static bool isEmptyBucket(const ValueType& value) { return Extractor::extract(value) == KeyTraits::emptyValue(); } - static bool isDeletedBucket(const ValueType& value) { return KeyTraits::isDeletedValue(Extractor::extract(value)); } - static bool isEmptyOrDeletedBucket(const ValueType& value) { return isEmptyBucket(value) || isDeletedBucket(value); } - - ValueType* lookup(const Key& key) { return lookup<Key, IdentityTranslatorType>(key); } - template<typename T, typename HashTranslator> ValueType* lookup(const T&); - -#if !ASSERT_DISABLED - void checkTableConsistency() const; -#else - static void checkTableConsistency() { } -#endif -#if CHECK_HASHTABLE_CONSISTENCY - void internalCheckTableConsistency() const { checkTableConsistency(); } - void internalCheckTableConsistencyExceptSize() const { checkTableConsistencyExceptSize(); } -#else - static void internalCheckTableConsistencyExceptSize() { } - static void internalCheckTableConsistency() { } -#endif - - private: - static ValueType* allocateTable(int size); - static void deallocateTable(ValueType* table, int size); - - typedef pair<ValueType*, bool> LookupType; - typedef pair<LookupType, unsigned> FullLookupType; - - LookupType lookupForWriting(const Key& key) { return lookupForWriting<Key, IdentityTranslatorType>(key); }; - template<typename T, typename HashTranslator> FullLookupType fullLookupForWriting(const T&); - template<typename T, typename HashTranslator> LookupType lookupForWriting(const T&); - - template<typename T, typename HashTranslator> void checkKey(const T&); - - void removeAndInvalidateWithoutEntryConsistencyCheck(ValueType*); - void removeAndInvalidate(ValueType*); - void remove(ValueType*); - - bool shouldExpand() const { return (m_keyCount + m_deletedCount) * m_maxLoad >= m_tableSize; } - bool mustRehashInPlace() const { return m_keyCount * m_minLoad < m_tableSize * 2; } - bool shouldShrink() const { return m_keyCount * m_minLoad < m_tableSize && m_tableSize > m_minTableSize; } - void expand(); - void shrink() { rehash(m_tableSize / 2); } - - void rehash(int newTableSize); - void reinsert(ValueType&); - - static void initializeBucket(ValueType& bucket) { new (&bucket) ValueType(Traits::emptyValue()); } - static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Traits::constructDeletedValue(bucket); } - - FullLookupType makeLookupResult(ValueType* position, bool found, unsigned hash) - { return FullLookupType(LookupType(position, found), hash); } - - iterator makeIterator(ValueType* pos) { return iterator(this, pos, m_table + m_tableSize); } - const_iterator makeConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize); } - iterator makeKnownGoodIterator(ValueType* pos) { return iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); } - const_iterator makeKnownGoodConstIterator(ValueType* pos) const { return const_iterator(this, pos, m_table + m_tableSize, HashItemKnownGood); } - -#if !ASSERT_DISABLED - void checkTableConsistencyExceptSize() const; -#else - static void checkTableConsistencyExceptSize() { } -#endif - -#if CHECK_HASHTABLE_ITERATORS - void invalidateIterators(); -#else - static void invalidateIterators() { } -#endif - - static const int m_minTableSize = 64; - static const int m_maxLoad = 2; - static const int m_minLoad = 6; - - ValueType* m_table; - int m_tableSize; - int m_tableSizeMask; - int m_keyCount; - int m_deletedCount; - -#if CHECK_HASHTABLE_ITERATORS - public: - // All access to m_iterators should be guarded with m_mutex. - mutable const_iterator* m_iterators; - mutable Mutex m_mutex; -#endif - }; - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::HashTable() - : m_table(0) - , m_tableSize(0) - , m_tableSizeMask(0) - , m_keyCount(0) - , m_deletedCount(0) -#if CHECK_HASHTABLE_ITERATORS - , m_iterators(0) -#endif - { - } - - static inline unsigned doubleHash(unsigned key) - { - key = ~key + (key >> 23); - key ^= (key << 12); - key ^= (key >> 7); - key ^= (key << 2); - key ^= (key >> 20); - return key; - } - -#if ASSERT_DISABLED - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename HashTranslator> - inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkKey(const T&) - { - } - -#else - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename HashTranslator> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkKey(const T& key) - { - if (!HashFunctions::safeToCompareToEmptyOrDeleted) - return; - ASSERT(!HashTranslator::equal(KeyTraits::emptyValue(), key)); - ValueType deletedValue = Traits::emptyValue(); - deletedValue.~ValueType(); - Traits::constructDeletedValue(deletedValue); - ASSERT(!HashTranslator::equal(Extractor::extract(deletedValue), key)); - new (&deletedValue) ValueType(Traits::emptyValue()); - } - -#endif - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename HashTranslator> - inline Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::lookup(const T& key) - { - checkKey<T, HashTranslator>(key); - - int k = 0; - int sizeMask = m_tableSizeMask; - ValueType* table = m_table; - unsigned h = HashTranslator::hash(key); - int i = h & sizeMask; - - if (!table) - return 0; - -#if DUMP_HASHTABLE_STATS - atomicIncrement(&HashTableStats::numAccesses); - int probeCount = 0; -#endif - - while (1) { - ValueType* entry = table + i; - - // we count on the compiler to optimize out this branch - if (HashFunctions::safeToCompareToEmptyOrDeleted) { - if (HashTranslator::equal(Extractor::extract(*entry), key)) - return entry; - - if (isEmptyBucket(*entry)) - return 0; - } else { - if (isEmptyBucket(*entry)) - return 0; - - if (!isDeletedBucket(*entry) && HashTranslator::equal(Extractor::extract(*entry), key)) - return entry; - } -#if DUMP_HASHTABLE_STATS - ++probeCount; - HashTableStats::recordCollisionAtCount(probeCount); -#endif - if (k == 0) - k = 1 | doubleHash(h); - i = (i + k) & sizeMask; - } - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename HashTranslator> - inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::LookupType HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::lookupForWriting(const T& key) - { - ASSERT(m_table); - checkKey<T, HashTranslator>(key); - - int k = 0; - ValueType* table = m_table; - int sizeMask = m_tableSizeMask; - unsigned h = HashTranslator::hash(key); - int i = h & sizeMask; - -#if DUMP_HASHTABLE_STATS - atomicIncrement(&HashTableStats::numAccesses); - int probeCount = 0; -#endif - - ValueType* deletedEntry = 0; - - while (1) { - ValueType* entry = table + i; - - // we count on the compiler to optimize out this branch - if (HashFunctions::safeToCompareToEmptyOrDeleted) { - if (isEmptyBucket(*entry)) - return LookupType(deletedEntry ? deletedEntry : entry, false); - - if (HashTranslator::equal(Extractor::extract(*entry), key)) - return LookupType(entry, true); - - if (isDeletedBucket(*entry)) - deletedEntry = entry; - } else { - if (isEmptyBucket(*entry)) - return LookupType(deletedEntry ? deletedEntry : entry, false); - - if (isDeletedBucket(*entry)) - deletedEntry = entry; - else if (HashTranslator::equal(Extractor::extract(*entry), key)) - return LookupType(entry, true); - } -#if DUMP_HASHTABLE_STATS - ++probeCount; - HashTableStats::recordCollisionAtCount(probeCount); -#endif - if (k == 0) - k = 1 | doubleHash(h); - i = (i + k) & sizeMask; - } - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename HashTranslator> - inline typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::FullLookupType HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::fullLookupForWriting(const T& key) - { - ASSERT(m_table); - checkKey<T, HashTranslator>(key); - - int k = 0; - ValueType* table = m_table; - int sizeMask = m_tableSizeMask; - unsigned h = HashTranslator::hash(key); - int i = h & sizeMask; - -#if DUMP_HASHTABLE_STATS - atomicIncrement(&HashTableStats::numAccesses); - int probeCount = 0; -#endif - - ValueType* deletedEntry = 0; - - while (1) { - ValueType* entry = table + i; - - // we count on the compiler to optimize out this branch - if (HashFunctions::safeToCompareToEmptyOrDeleted) { - if (isEmptyBucket(*entry)) - return makeLookupResult(deletedEntry ? deletedEntry : entry, false, h); - - if (HashTranslator::equal(Extractor::extract(*entry), key)) - return makeLookupResult(entry, true, h); - - if (isDeletedBucket(*entry)) - deletedEntry = entry; - } else { - if (isEmptyBucket(*entry)) - return makeLookupResult(deletedEntry ? deletedEntry : entry, false, h); - - if (isDeletedBucket(*entry)) - deletedEntry = entry; - else if (HashTranslator::equal(Extractor::extract(*entry), key)) - return makeLookupResult(entry, true, h); - } -#if DUMP_HASHTABLE_STATS - ++probeCount; - HashTableStats::recordCollisionAtCount(probeCount); -#endif - if (k == 0) - k = 1 | doubleHash(h); - i = (i + k) & sizeMask; - } - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename Extra, typename HashTranslator> - inline pair<typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::iterator, bool> HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::add(const T& key, const Extra& extra) - { - checkKey<T, HashTranslator>(key); - - invalidateIterators(); - - if (!m_table) - expand(); - - internalCheckTableConsistency(); - - ASSERT(m_table); - - int k = 0; - ValueType* table = m_table; - int sizeMask = m_tableSizeMask; - unsigned h = HashTranslator::hash(key); - int i = h & sizeMask; - -#if DUMP_HASHTABLE_STATS - atomicIncrement(&HashTableStats::numAccesses); - int probeCount = 0; -#endif - - ValueType* deletedEntry = 0; - ValueType* entry; - while (1) { - entry = table + i; - - // we count on the compiler to optimize out this branch - if (HashFunctions::safeToCompareToEmptyOrDeleted) { - if (isEmptyBucket(*entry)) - break; - - if (HashTranslator::equal(Extractor::extract(*entry), key)) - return std::make_pair(makeKnownGoodIterator(entry), false); - - if (isDeletedBucket(*entry)) - deletedEntry = entry; - } else { - if (isEmptyBucket(*entry)) - break; - - if (isDeletedBucket(*entry)) - deletedEntry = entry; - else if (HashTranslator::equal(Extractor::extract(*entry), key)) - return std::make_pair(makeKnownGoodIterator(entry), false); - } -#if DUMP_HASHTABLE_STATS - ++probeCount; - HashTableStats::recordCollisionAtCount(probeCount); -#endif - if (k == 0) - k = 1 | doubleHash(h); - i = (i + k) & sizeMask; - } - - if (deletedEntry) { - initializeBucket(*deletedEntry); - entry = deletedEntry; - --m_deletedCount; - } - - HashTranslator::translate(*entry, key, extra); - - ++m_keyCount; - - if (shouldExpand()) { - // FIXME: This makes an extra copy on expand. Probably not that bad since - // expand is rare, but would be better to have a version of expand that can - // follow a pivot entry and return the new position. - KeyType enteredKey = Extractor::extract(*entry); - expand(); - pair<iterator, bool> p = std::make_pair(find(enteredKey), true); - ASSERT(p.first != end()); - return p; - } - - internalCheckTableConsistency(); - - return std::make_pair(makeKnownGoodIterator(entry), true); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template<typename T, typename Extra, typename HashTranslator> - inline pair<typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::iterator, bool> HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::addPassingHashCode(const T& key, const Extra& extra) - { - checkKey<T, HashTranslator>(key); - - invalidateIterators(); - - if (!m_table) - expand(); - - internalCheckTableConsistency(); - - FullLookupType lookupResult = fullLookupForWriting<T, HashTranslator>(key); - - ValueType* entry = lookupResult.first.first; - bool found = lookupResult.first.second; - unsigned h = lookupResult.second; - - if (found) - return std::make_pair(makeKnownGoodIterator(entry), false); - - if (isDeletedBucket(*entry)) { - initializeBucket(*entry); - --m_deletedCount; - } - - HashTranslator::translate(*entry, key, extra, h); - ++m_keyCount; - if (shouldExpand()) { - // FIXME: This makes an extra copy on expand. Probably not that bad since - // expand is rare, but would be better to have a version of expand that can - // follow a pivot entry and return the new position. - KeyType enteredKey = Extractor::extract(*entry); - expand(); - pair<iterator, bool> p = std::make_pair(find(enteredKey), true); - ASSERT(p.first != end()); - return p; - } - - internalCheckTableConsistency(); - - return std::make_pair(makeKnownGoodIterator(entry), true); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::reinsert(ValueType& entry) - { - ASSERT(m_table); - ASSERT(!lookupForWriting(Extractor::extract(entry)).second); - ASSERT(!isDeletedBucket(*(lookupForWriting(Extractor::extract(entry)).first))); -#if DUMP_HASHTABLE_STATS - atomicIncrement(&HashTableStats::numReinserts); -#endif - - Mover<ValueType, Traits::needsDestruction>::move(entry, *lookupForWriting(Extractor::extract(entry)).first); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template <typename T, typename HashTranslator> - typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::iterator HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::find(const T& key) - { - if (!m_table) - return end(); - - ValueType* entry = lookup<T, HashTranslator>(key); - if (!entry) - return end(); - - return makeKnownGoodIterator(entry); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template <typename T, typename HashTranslator> - typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::const_iterator HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::find(const T& key) const - { - if (!m_table) - return end(); - - ValueType* entry = const_cast<HashTable*>(this)->lookup<T, HashTranslator>(key); - if (!entry) - return end(); - - return makeKnownGoodConstIterator(entry); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - template <typename T, typename HashTranslator> - bool HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::contains(const T& key) const - { - if (!m_table) - return false; - - return const_cast<HashTable*>(this)->lookup<T, HashTranslator>(key); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeAndInvalidateWithoutEntryConsistencyCheck(ValueType* pos) - { - invalidateIterators(); - remove(pos); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeAndInvalidate(ValueType* pos) - { - invalidateIterators(); - internalCheckTableConsistency(); - remove(pos); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(ValueType* pos) - { -#if DUMP_HASHTABLE_STATS - atomicIncrement(&HashTableStats::numRemoves); -#endif - - deleteBucket(*pos); - ++m_deletedCount; - --m_keyCount; - - if (shouldShrink()) - shrink(); - - internalCheckTableConsistency(); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(iterator it) - { - if (it == end()) - return; - - removeAndInvalidate(const_cast<ValueType*>(it.m_iterator.m_position)); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeWithoutEntryConsistencyCheck(iterator it) - { - if (it == end()) - return; - - removeAndInvalidateWithoutEntryConsistencyCheck(const_cast<ValueType*>(it.m_iterator.m_position)); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::removeWithoutEntryConsistencyCheck(const_iterator it) - { - if (it == end()) - return; - - removeAndInvalidateWithoutEntryConsistencyCheck(const_cast<ValueType*>(it.m_position)); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::remove(const KeyType& key) - { - remove(find(key)); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - Value* HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::allocateTable(int size) - { - // would use a template member function with explicit specializations here, but - // gcc doesn't appear to support that - if (Traits::emptyValueIsZero) - return static_cast<ValueType*>(fastZeroedMalloc(size * sizeof(ValueType))); - ValueType* result = static_cast<ValueType*>(fastMalloc(size * sizeof(ValueType))); - for (int i = 0; i < size; i++) - initializeBucket(result[i]); - return result; - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::deallocateTable(ValueType* table, int size) - { - if (Traits::needsDestruction) { - for (int i = 0; i < size; ++i) { - if (!isDeletedBucket(table[i])) - table[i].~ValueType(); - } - } - fastFree(table); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::expand() - { - int newSize; - if (m_tableSize == 0) - newSize = m_minTableSize; - else if (mustRehashInPlace()) - newSize = m_tableSize; - else - newSize = m_tableSize * 2; - - rehash(newSize); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::rehash(int newTableSize) - { - internalCheckTableConsistencyExceptSize(); - - int oldTableSize = m_tableSize; - ValueType* oldTable = m_table; - -#if DUMP_HASHTABLE_STATS - if (oldTableSize != 0) - atomicIncrement(&HashTableStats::numRehashes); -#endif - - m_tableSize = newTableSize; - m_tableSizeMask = newTableSize - 1; - m_table = allocateTable(newTableSize); - - for (int i = 0; i != oldTableSize; ++i) - if (!isEmptyOrDeletedBucket(oldTable[i])) - reinsert(oldTable[i]); - - m_deletedCount = 0; - - deallocateTable(oldTable, oldTableSize); - - internalCheckTableConsistency(); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::clear() - { - invalidateIterators(); - deallocateTable(m_table, m_tableSize); - m_table = 0; - m_tableSize = 0; - m_tableSizeMask = 0; - m_keyCount = 0; - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::HashTable(const HashTable& other) - : m_table(0) - , m_tableSize(0) - , m_tableSizeMask(0) - , m_keyCount(0) - , m_deletedCount(0) -#if CHECK_HASHTABLE_ITERATORS - , m_iterators(0) -#endif - { - // Copy the hash table the dumb way, by adding each element to the new table. - // It might be more efficient to copy the table slots, but it's not clear that efficiency is needed. - const_iterator end = other.end(); - for (const_iterator it = other.begin(); it != end; ++it) - add(*it); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::swap(HashTable& other) - { - invalidateIterators(); - other.invalidateIterators(); - - ValueType* tmp_table = m_table; - m_table = other.m_table; - other.m_table = tmp_table; - - int tmp_tableSize = m_tableSize; - m_tableSize = other.m_tableSize; - other.m_tableSize = tmp_tableSize; - - int tmp_tableSizeMask = m_tableSizeMask; - m_tableSizeMask = other.m_tableSizeMask; - other.m_tableSizeMask = tmp_tableSizeMask; - - int tmp_keyCount = m_keyCount; - m_keyCount = other.m_keyCount; - other.m_keyCount = tmp_keyCount; - - int tmp_deletedCount = m_deletedCount; - m_deletedCount = other.m_deletedCount; - other.m_deletedCount = tmp_deletedCount; - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>& HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::operator=(const HashTable& other) - { - HashTable tmp(other); - swap(tmp); - return *this; - } - -#if !ASSERT_DISABLED - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkTableConsistency() const - { - checkTableConsistencyExceptSize(); - ASSERT(!m_table || !shouldExpand()); - ASSERT(!shouldShrink()); - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::checkTableConsistencyExceptSize() const - { - if (!m_table) - return; - - int count = 0; - int deletedCount = 0; - for (int j = 0; j < m_tableSize; ++j) { - ValueType* entry = m_table + j; - if (isEmptyBucket(*entry)) - continue; - - if (isDeletedBucket(*entry)) { - ++deletedCount; - continue; - } - - const_iterator it = find(Extractor::extract(*entry)); - ASSERT(entry == it.m_position); - ++count; - - ValueCheck<Key>::checkConsistency(it->first); - } - - ASSERT(count == m_keyCount); - ASSERT(deletedCount == m_deletedCount); - ASSERT(m_tableSize >= m_minTableSize); - ASSERT(m_tableSizeMask); - ASSERT(m_tableSize == m_tableSizeMask + 1); - } - -#endif // ASSERT_DISABLED - -#if CHECK_HASHTABLE_ITERATORS - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::invalidateIterators() - { - MutexLocker lock(m_mutex); - const_iterator* next; - for (const_iterator* p = m_iterators; p; p = next) { - next = p->m_next; - p->m_table = 0; - p->m_next = 0; - p->m_previous = 0; - } - m_iterators = 0; - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void addIterator(const HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>* table, - HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>* it) - { - it->m_table = table; - it->m_previous = 0; - - // Insert iterator at head of doubly-linked list of iterators. - if (!table) { - it->m_next = 0; - } else { - MutexLocker lock(table->m_mutex); - ASSERT(table->m_iterators != it); - it->m_next = table->m_iterators; - table->m_iterators = it; - if (it->m_next) { - ASSERT(!it->m_next->m_previous); - it->m_next->m_previous = it; - } - } - } - - template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits> - void removeIterator(HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>* it) - { - typedef HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> HashTableType; - typedef HashTableConstIterator<Key, Value, Extractor, HashFunctions, Traits, KeyTraits> const_iterator; - - // Delete iterator from doubly-linked list of iterators. - if (!it->m_table) { - ASSERT(!it->m_next); - ASSERT(!it->m_previous); - } else { - MutexLocker lock(it->m_table->m_mutex); - if (it->m_next) { - ASSERT(it->m_next->m_previous == it); - it->m_next->m_previous = it->m_previous; - } - if (it->m_previous) { - ASSERT(it->m_table->m_iterators != it); - ASSERT(it->m_previous->m_next == it); - it->m_previous->m_next = it->m_next; - } else { - ASSERT(it->m_table->m_iterators == it); - it->m_table->m_iterators = it->m_next; - } - } - - it->m_table = 0; - it->m_next = 0; - it->m_previous = 0; - } - -#endif // CHECK_HASHTABLE_ITERATORS - - // iterator adapters - - template<typename HashTableType, typename ValueType> struct HashTableConstIteratorAdapter { - HashTableConstIteratorAdapter(const typename HashTableType::const_iterator& impl) : m_impl(impl) {} - - const ValueType* get() const { return (const ValueType*)m_impl.get(); } - const ValueType& operator*() const { return *get(); } - const ValueType* operator->() const { return get(); } - - HashTableConstIteratorAdapter& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - typename HashTableType::const_iterator m_impl; - }; - - template<typename HashTableType, typename ValueType> struct HashTableIteratorAdapter { - HashTableIteratorAdapter(const typename HashTableType::iterator& impl) : m_impl(impl) {} - - ValueType* get() const { return (ValueType*)m_impl.get(); } - ValueType& operator*() const { return *get(); } - ValueType* operator->() const { return get(); } - - HashTableIteratorAdapter& operator++() { ++m_impl; return *this; } - // postfix ++ intentionally omitted - - operator HashTableConstIteratorAdapter<HashTableType, ValueType>() { - typename HashTableType::const_iterator i = m_impl; - return i; - } - - typename HashTableType::iterator m_impl; - }; - - template<typename T, typename U> - inline bool operator==(const HashTableConstIteratorAdapter<T, U>& a, const HashTableConstIteratorAdapter<T, U>& b) - { - return a.m_impl == b.m_impl; - } - - template<typename T, typename U> - inline bool operator!=(const HashTableConstIteratorAdapter<T, U>& a, const HashTableConstIteratorAdapter<T, U>& b) - { - return a.m_impl != b.m_impl; - } - - template<typename T, typename U> - inline bool operator==(const HashTableIteratorAdapter<T, U>& a, const HashTableIteratorAdapter<T, U>& b) - { - return a.m_impl == b.m_impl; - } - - template<typename T, typename U> - inline bool operator!=(const HashTableIteratorAdapter<T, U>& a, const HashTableIteratorAdapter<T, U>& b) - { - return a.m_impl != b.m_impl; - } - -} // namespace WTF - -#include "HashIterators.h" - -#endif // WTF_HashTable_h diff --git a/JavaScriptCore/wtf/HashTraits.h b/JavaScriptCore/wtf/HashTraits.h deleted file mode 100644 index c8d40f7..0000000 --- a/JavaScriptCore/wtf/HashTraits.h +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_HashTraits_h -#define WTF_HashTraits_h - -#include "HashFunctions.h" -#include "TypeTraits.h" -#include <utility> -#include <limits> - -namespace WTF { - - using std::pair; - using std::make_pair; - - template<typename T> struct HashTraits; - - template<bool isInteger, typename T> struct GenericHashTraitsBase; - - template<typename T> struct GenericHashTraitsBase<false, T> { - static const bool emptyValueIsZero = false; - static const bool needsDestruction = true; - }; - - // Default integer traits disallow both 0 and -1 as keys (max value instead of -1 for unsigned). - template<typename T> struct GenericHashTraitsBase<true, T> { - static const bool emptyValueIsZero = true; - static const bool needsDestruction = false; - static void constructDeletedValue(T& slot) { slot = static_cast<T>(-1); } - static bool isDeletedValue(T value) { return value == static_cast<T>(-1); } - }; - - template<typename T> struct GenericHashTraits : GenericHashTraitsBase<IsInteger<T>::value, T> { - typedef T TraitType; - static T emptyValue() { return T(); } - }; - - template<typename T> struct HashTraits : GenericHashTraits<T> { }; - - template<typename T> struct FloatHashTraits : GenericHashTraits<T> { - static const bool needsDestruction = false; - static T emptyValue() { return std::numeric_limits<T>::infinity(); } - static void constructDeletedValue(T& slot) { slot = -std::numeric_limits<T>::infinity(); } - static bool isDeletedValue(T value) { return value == -std::numeric_limits<T>::infinity(); } - }; - - template<> struct HashTraits<float> : FloatHashTraits<float> { }; - template<> struct HashTraits<double> : FloatHashTraits<double> { }; - - // Default unsigned traits disallow both 0 and max as keys -- use these traits to allow zero and disallow max - 1. - template<typename T> struct UnsignedWithZeroKeyHashTraits : GenericHashTraits<T> { - static const bool emptyValueIsZero = false; - static const bool needsDestruction = false; - static T emptyValue() { return std::numeric_limits<T>::max(); } - static void constructDeletedValue(T& slot) { slot = std::numeric_limits<T>::max() - 1; } - static bool isDeletedValue(T value) { return value == std::numeric_limits<T>::max() - 1; } - }; - - template<typename P> struct HashTraits<P*> : GenericHashTraits<P*> { - static const bool emptyValueIsZero = true; - static const bool needsDestruction = false; - static void constructDeletedValue(P*& slot) { slot = reinterpret_cast<P*>(-1); } - static bool isDeletedValue(P* value) { return value == reinterpret_cast<P*>(-1); } - }; - - template<typename P> struct HashTraits<RefPtr<P> > : GenericHashTraits<RefPtr<P> > { - static const bool emptyValueIsZero = true; - static void constructDeletedValue(RefPtr<P>& slot) { new (&slot) RefPtr<P>(HashTableDeletedValue); } - static bool isDeletedValue(const RefPtr<P>& value) { return value.isHashTableDeletedValue(); } - }; - - // special traits for pairs, helpful for their use in HashMap implementation - - template<typename FirstTraitsArg, typename SecondTraitsArg> - struct PairHashTraits : GenericHashTraits<pair<typename FirstTraitsArg::TraitType, typename SecondTraitsArg::TraitType> > { - typedef FirstTraitsArg FirstTraits; - typedef SecondTraitsArg SecondTraits; - typedef pair<typename FirstTraits::TraitType, typename SecondTraits::TraitType> TraitType; - - static const bool emptyValueIsZero = FirstTraits::emptyValueIsZero && SecondTraits::emptyValueIsZero; - static TraitType emptyValue() { return make_pair(FirstTraits::emptyValue(), SecondTraits::emptyValue()); } - - static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction; - - static void constructDeletedValue(TraitType& slot) { FirstTraits::constructDeletedValue(slot.first); } - static bool isDeletedValue(const TraitType& value) { return FirstTraits::isDeletedValue(value.first); } - }; - - template<typename First, typename Second> - struct HashTraits<pair<First, Second> > : public PairHashTraits<HashTraits<First>, HashTraits<Second> > { }; - -} // namespace WTF - -using WTF::HashTraits; -using WTF::PairHashTraits; - -#endif // WTF_HashTraits_h diff --git a/JavaScriptCore/wtf/ListHashSet.h b/JavaScriptCore/wtf/ListHashSet.h deleted file mode 100644 index e14ac45..0000000 --- a/JavaScriptCore/wtf/ListHashSet.h +++ /dev/null @@ -1,617 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_ListHashSet_h -#define WTF_ListHashSet_h - -#include "Assertions.h" -#include "HashSet.h" -#include "OwnPtr.h" -#include "StdLibExtras.h" - -namespace WTF { - - // ListHashSet: Just like HashSet, this class provides a Set - // interface - a collection of unique objects with O(1) insertion, - // removal and test for containership. However, it also has an - // order - iterating it will always give back values in the order - // in which they are added. - - // In theory it would be possible to add prepend, insertAfter - // and an append that moves the element to the end even if already present, - // but unclear yet if these are needed. - - template<typename Value, size_t inlineCapacity, typename HashFunctions> class ListHashSet; - - template<typename T> struct IdentityExtractor; - - template<typename Value, size_t inlineCapacity, typename HashFunctions> - void deleteAllValues(const ListHashSet<Value, inlineCapacity, HashFunctions>&); - - template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator; - template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator; - - template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode; - template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator; - template<typename ValueArg, size_t inlineCapacity, typename HashArg> struct ListHashSetNodeHashFunctions; - - template<typename ValueArg, size_t inlineCapacity = 256, typename HashArg = typename DefaultHash<ValueArg>::Hash> class ListHashSet : public FastAllocBase { - private: - typedef ListHashSetNode<ValueArg, inlineCapacity> Node; - typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; - - typedef HashTraits<Node*> NodeTraits; - typedef ListHashSetNodeHashFunctions<ValueArg, inlineCapacity, HashArg> NodeHash; - - typedef HashTable<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplType; - typedef HashTableIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeIterator; - typedef HashTableConstIterator<Node*, Node*, IdentityExtractor<Node*>, NodeHash, NodeTraits, NodeTraits> ImplTypeConstIterator; - - typedef HashArg HashFunctions; - - public: - typedef ValueArg ValueType; - typedef ListHashSetIterator<ValueType, inlineCapacity, HashArg> iterator; - typedef ListHashSetConstIterator<ValueType, inlineCapacity, HashArg> const_iterator; - - friend class ListHashSetConstIterator<ValueType, inlineCapacity, HashArg>; - - ListHashSet(); - ListHashSet(const ListHashSet&); - ListHashSet& operator=(const ListHashSet&); - ~ListHashSet(); - - void swap(ListHashSet&); - - int size() const; - int capacity() const; - bool isEmpty() const; - - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - - iterator find(const ValueType&); - const_iterator find(const ValueType&) const; - bool contains(const ValueType&) const; - - // the return value is a pair of an iterator to the new value's location, - // and a bool that is true if an new entry was added - pair<iterator, bool> add(const ValueType&); - - pair<iterator, bool> insertBefore(const ValueType& beforeValue, const ValueType& newValue); - pair<iterator, bool> insertBefore(iterator it, const ValueType&); - - void remove(const ValueType&); - void remove(iterator); - void clear(); - - private: - void unlinkAndDelete(Node*); - void appendNode(Node*); - void insertNodeBefore(Node* beforeNode, Node* newNode); - void deleteAllNodes(); - iterator makeIterator(Node*); - const_iterator makeConstIterator(Node*) const; - - friend void deleteAllValues<>(const ListHashSet&); - - ImplType m_impl; - Node* m_head; - Node* m_tail; - OwnPtr<NodeAllocator> m_allocator; - }; - - template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNodeAllocator { - typedef ListHashSetNode<ValueArg, inlineCapacity> Node; - typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; - - ListHashSetNodeAllocator() - : m_freeList(pool()) - , m_isDoneWithInitialFreeList(false) - { - memset(m_pool.pool, 0, sizeof(m_pool.pool)); - } - - Node* allocate() - { - Node* result = m_freeList; - - if (!result) - return static_cast<Node*>(fastMalloc(sizeof(Node))); - - ASSERT(!result->m_isAllocated); - - Node* next = result->m_next; - ASSERT(!next || !next->m_isAllocated); - if (!next && !m_isDoneWithInitialFreeList) { - next = result + 1; - if (next == pastPool()) { - m_isDoneWithInitialFreeList = true; - next = 0; - } else { - ASSERT(inPool(next)); - ASSERT(!next->m_isAllocated); - } - } - m_freeList = next; - - return result; - } - - void deallocate(Node* node) - { - if (inPool(node)) { -#ifndef NDEBUG - node->m_isAllocated = false; -#endif - node->m_next = m_freeList; - m_freeList = node; - return; - } - - fastFree(node); - } - - private: - Node* pool() { return reinterpret_cast_ptr<Node*>(m_pool.pool); } - Node* pastPool() { return pool() + m_poolSize; } - - bool inPool(Node* node) - { - return node >= pool() && node < pastPool(); - } - - Node* m_freeList; - bool m_isDoneWithInitialFreeList; - static const size_t m_poolSize = inlineCapacity; - union { - char pool[sizeof(Node) * m_poolSize]; - double forAlignment; - } m_pool; - }; - - template<typename ValueArg, size_t inlineCapacity> struct ListHashSetNode { - typedef ListHashSetNodeAllocator<ValueArg, inlineCapacity> NodeAllocator; - - ListHashSetNode(ValueArg value) - : m_value(value) - , m_prev(0) - , m_next(0) -#ifndef NDEBUG - , m_isAllocated(true) -#endif - { - } - - void* operator new(size_t, NodeAllocator* allocator) - { - return allocator->allocate(); - } - void destroy(NodeAllocator* allocator) - { - this->~ListHashSetNode(); - allocator->deallocate(this); - } - - ValueArg m_value; - ListHashSetNode* m_prev; - ListHashSetNode* m_next; - -#ifndef NDEBUG - bool m_isAllocated; -#endif - }; - - template<typename ValueArg, size_t inlineCapacity, typename HashArg> struct ListHashSetNodeHashFunctions { - typedef ListHashSetNode<ValueArg, inlineCapacity> Node; - - static unsigned hash(Node* const& key) { return HashArg::hash(key->m_value); } - static bool equal(Node* const& a, Node* const& b) { return HashArg::equal(a->m_value, b->m_value); } - static const bool safeToCompareToEmptyOrDeleted = false; - }; - - template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetIterator { - private: - typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; - typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator; - typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator; - typedef ListHashSetNode<ValueArg, inlineCapacity> Node; - typedef ValueArg ValueType; - typedef ValueType& ReferenceType; - typedef ValueType* PointerType; - - friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; - - ListHashSetIterator(const ListHashSetType* set, Node* position) : m_iterator(set, position) { } - - public: - ListHashSetIterator() { } - - // default copy, assignment and destructor are OK - - PointerType get() const { return const_cast<PointerType>(m_iterator.get()); } - ReferenceType operator*() const { return *get(); } - PointerType operator->() const { return get(); } - - iterator& operator++() { ++m_iterator; return *this; } - - // postfix ++ intentionally omitted - - iterator& operator--() { --m_iterator; return *this; } - - // postfix -- intentionally omitted - - // Comparison. - bool operator==(const iterator& other) const { return m_iterator == other.m_iterator; } - bool operator!=(const iterator& other) const { return m_iterator != other.m_iterator; } - - operator const_iterator() const { return m_iterator; } - - private: - Node* node() { return m_iterator.node(); } - - const_iterator m_iterator; - }; - - template<typename ValueArg, size_t inlineCapacity, typename HashArg> class ListHashSetConstIterator { - private: - typedef ListHashSet<ValueArg, inlineCapacity, HashArg> ListHashSetType; - typedef ListHashSetIterator<ValueArg, inlineCapacity, HashArg> iterator; - typedef ListHashSetConstIterator<ValueArg, inlineCapacity, HashArg> const_iterator; - typedef ListHashSetNode<ValueArg, inlineCapacity> Node; - typedef ValueArg ValueType; - typedef const ValueType& ReferenceType; - typedef const ValueType* PointerType; - - friend class ListHashSet<ValueArg, inlineCapacity, HashArg>; - friend class ListHashSetIterator<ValueArg, inlineCapacity, HashArg>; - - ListHashSetConstIterator(const ListHashSetType* set, Node* position) - : m_set(set) - , m_position(position) - { - } - - public: - ListHashSetConstIterator() - { - } - - PointerType get() const - { - return &m_position->m_value; - } - ReferenceType operator*() const { return *get(); } - PointerType operator->() const { return get(); } - - const_iterator& operator++() - { - ASSERT(m_position != 0); - m_position = m_position->m_next; - return *this; - } - - // postfix ++ intentionally omitted - - const_iterator& operator--() - { - ASSERT(m_position != m_set->m_head); - if (!m_position) - m_position = m_set->m_tail; - else - m_position = m_position->m_prev; - return *this; - } - - // postfix -- intentionally omitted - - // Comparison. - bool operator==(const const_iterator& other) const - { - return m_position == other.m_position; - } - bool operator!=(const const_iterator& other) const - { - return m_position != other.m_position; - } - - private: - Node* node() { return m_position; } - - const ListHashSetType* m_set; - Node* m_position; - }; - - - template<typename ValueType, size_t inlineCapacity, typename HashFunctions> - struct ListHashSetTranslator { - private: - typedef ListHashSetNode<ValueType, inlineCapacity> Node; - typedef ListHashSetNodeAllocator<ValueType, inlineCapacity> NodeAllocator; - public: - static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); } - static bool equal(Node* const& a, const ValueType& b) { return HashFunctions::equal(a->m_value, b); } - static void translate(Node*& location, const ValueType& key, NodeAllocator* allocator) - { - location = new (allocator) Node(key); - } - }; - - template<typename T, size_t inlineCapacity, typename U> - inline ListHashSet<T, inlineCapacity, U>::ListHashSet() - : m_head(0) - , m_tail(0) - , m_allocator(new NodeAllocator) - { - } - - template<typename T, size_t inlineCapacity, typename U> - inline ListHashSet<T, inlineCapacity, U>::ListHashSet(const ListHashSet& other) - : m_head(0) - , m_tail(0) - , m_allocator(new NodeAllocator) - { - const_iterator end = other.end(); - for (const_iterator it = other.begin(); it != end; ++it) - add(*it); - } - - template<typename T, size_t inlineCapacity, typename U> - inline ListHashSet<T, inlineCapacity, U>& ListHashSet<T, inlineCapacity, U>::operator=(const ListHashSet& other) - { - ListHashSet tmp(other); - swap(tmp); - return *this; - } - - template<typename T, size_t inlineCapacity, typename U> - inline void ListHashSet<T, inlineCapacity, U>::swap(ListHashSet& other) - { - m_impl.swap(other.m_impl); - std::swap(m_head, other.m_head); - std::swap(m_tail, other.m_tail); - m_allocator.swap(other.m_allocator); - } - - template<typename T, size_t inlineCapacity, typename U> - inline ListHashSet<T, inlineCapacity, U>::~ListHashSet() - { - deleteAllNodes(); - } - - template<typename T, size_t inlineCapacity, typename U> - inline int ListHashSet<T, inlineCapacity, U>::size() const - { - return m_impl.size(); - } - - template<typename T, size_t inlineCapacity, typename U> - inline int ListHashSet<T, inlineCapacity, U>::capacity() const - { - return m_impl.capacity(); - } - - template<typename T, size_t inlineCapacity, typename U> - inline bool ListHashSet<T, inlineCapacity, U>::isEmpty() const - { - return m_impl.isEmpty(); - } - - template<typename T, size_t inlineCapacity, typename U> - inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::begin() - { - return makeIterator(m_head); - } - - template<typename T, size_t inlineCapacity, typename U> - inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::end() - { - return makeIterator(0); - } - - template<typename T, size_t inlineCapacity, typename U> - inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::begin() const - { - return makeConstIterator(m_head); - } - - template<typename T, size_t inlineCapacity, typename U> - inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::end() const - { - return makeConstIterator(0); - } - - template<typename T, size_t inlineCapacity, typename U> - inline typename ListHashSet<T, inlineCapacity, U>::iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) - { - typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; - ImplTypeIterator it = m_impl.template find<ValueType, Translator>(value); - if (it == m_impl.end()) - return end(); - return makeIterator(*it); - } - - template<typename T, size_t inlineCapacity, typename U> - inline typename ListHashSet<T, inlineCapacity, U>::const_iterator ListHashSet<T, inlineCapacity, U>::find(const ValueType& value) const - { - typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; - ImplTypeConstIterator it = m_impl.template find<ValueType, Translator>(value); - if (it == m_impl.end()) - return end(); - return makeConstIterator(*it); - } - - template<typename T, size_t inlineCapacity, typename U> - inline bool ListHashSet<T, inlineCapacity, U>::contains(const ValueType& value) const - { - typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; - return m_impl.template contains<ValueType, Translator>(value); - } - - template<typename T, size_t inlineCapacity, typename U> - pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::add(const ValueType &value) - { - typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; - pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(value, m_allocator.get()); - if (result.second) - appendNode(*result.first); - return std::make_pair(makeIterator(*result.first), result.second); - } - - template<typename T, size_t inlineCapacity, typename U> - pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::insertBefore(iterator it, const ValueType& newValue) - { - typedef ListHashSetTranslator<ValueType, inlineCapacity, HashFunctions> Translator; - pair<typename ImplType::iterator, bool> result = m_impl.template add<ValueType, NodeAllocator*, Translator>(newValue, m_allocator.get()); - if (result.second) - insertNodeBefore(it.node(), *result.first); - return std::make_pair(makeIterator(*result.first), result.second); - - } - - template<typename T, size_t inlineCapacity, typename U> - pair<typename ListHashSet<T, inlineCapacity, U>::iterator, bool> ListHashSet<T, inlineCapacity, U>::insertBefore(const ValueType& beforeValue, const ValueType& newValue) - { - return insertBefore(find(beforeValue), newValue); - } - - template<typename T, size_t inlineCapacity, typename U> - inline void ListHashSet<T, inlineCapacity, U>::remove(iterator it) - { - if (it == end()) - return; - m_impl.remove(it.node()); - unlinkAndDelete(it.node()); - } - - template<typename T, size_t inlineCapacity, typename U> - inline void ListHashSet<T, inlineCapacity, U>::remove(const ValueType& value) - { - remove(find(value)); - } - - template<typename T, size_t inlineCapacity, typename U> - inline void ListHashSet<T, inlineCapacity, U>::clear() - { - deleteAllNodes(); - m_impl.clear(); - m_head = 0; - m_tail = 0; - } - - template<typename T, size_t inlineCapacity, typename U> - void ListHashSet<T, inlineCapacity, U>::unlinkAndDelete(Node* node) - { - if (!node->m_prev) { - ASSERT(node == m_head); - m_head = node->m_next; - } else { - ASSERT(node != m_head); - node->m_prev->m_next = node->m_next; - } - - if (!node->m_next) { - ASSERT(node == m_tail); - m_tail = node->m_prev; - } else { - ASSERT(node != m_tail); - node->m_next->m_prev = node->m_prev; - } - - node->destroy(m_allocator.get()); - } - - template<typename T, size_t inlineCapacity, typename U> - void ListHashSet<T, inlineCapacity, U>::appendNode(Node* node) - { - node->m_prev = m_tail; - node->m_next = 0; - - if (m_tail) { - ASSERT(m_head); - m_tail->m_next = node; - } else { - ASSERT(!m_head); - m_head = node; - } - - m_tail = node; - } - - template<typename T, size_t inlineCapacity, typename U> - void ListHashSet<T, inlineCapacity, U>::insertNodeBefore(Node* beforeNode, Node* newNode) - { - if (!beforeNode) - return appendNode(newNode); - - newNode->m_next = beforeNode; - newNode->m_prev = beforeNode->m_prev; - if (beforeNode->m_prev) - beforeNode->m_prev->m_next = newNode; - beforeNode->m_prev = newNode; - - if (!newNode->m_prev) - m_head = newNode; - } - - template<typename T, size_t inlineCapacity, typename U> - void ListHashSet<T, inlineCapacity, U>::deleteAllNodes() - { - if (!m_head) - return; - - for (Node* node = m_head, *next = m_head->m_next; node; node = next, next = node ? node->m_next : 0) - node->destroy(m_allocator.get()); - } - - template<typename T, size_t inlineCapacity, typename U> - inline ListHashSetIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeIterator(Node* position) - { - return ListHashSetIterator<T, inlineCapacity, U>(this, position); - } - - template<typename T, size_t inlineCapacity, typename U> - inline ListHashSetConstIterator<T, inlineCapacity, U> ListHashSet<T, inlineCapacity, U>::makeConstIterator(Node* position) const - { - return ListHashSetConstIterator<T, inlineCapacity, U>(this, position); - } - - template<bool, typename ValueType, typename HashTableType> - void deleteAllValues(HashTableType& collection) - { - typedef typename HashTableType::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete (*it)->m_value; - } - - template<typename T, size_t inlineCapacity, typename U> - inline void deleteAllValues(const ListHashSet<T, inlineCapacity, U>& collection) - { - deleteAllValues<true, typename ListHashSet<T, inlineCapacity, U>::ValueType>(collection.m_impl); - } - -} // namespace WTF - -using WTF::ListHashSet; - -#endif /* WTF_ListHashSet_h */ diff --git a/JavaScriptCore/wtf/ListRefPtr.h b/JavaScriptCore/wtf/ListRefPtr.h deleted file mode 100644 index 8bf6447..0000000 --- a/JavaScriptCore/wtf/ListRefPtr.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_ListRefPtr_h -#define WTF_ListRefPtr_h - -#include <wtf/RefPtr.h> - -namespace WTF { - - // Specialized version of RefPtr desgined for use in singly-linked lists. - // Derefs the list iteratively to avoid recursive derefing that can overflow the stack. - template <typename T> class ListRefPtr : public RefPtr<T> { - public: - ListRefPtr() : RefPtr<T>() {} - ListRefPtr(T* ptr) : RefPtr<T>(ptr) {} - ListRefPtr(const RefPtr<T>& o) : RefPtr<T>(o) {} - // see comment in PassRefPtr.h for why this takes const reference - template <typename U> ListRefPtr(const PassRefPtr<U>& o) : RefPtr<T>(o) {} - - ~ListRefPtr(); - - ListRefPtr& operator=(T* optr) { RefPtr<T>::operator=(optr); return *this; } - ListRefPtr& operator=(const RefPtr<T>& o) { RefPtr<T>::operator=(o); return *this; } - ListRefPtr& operator=(const PassRefPtr<T>& o) { RefPtr<T>::operator=(o); return *this; } - template <typename U> ListRefPtr& operator=(const RefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; } - template <typename U> ListRefPtr& operator=(const PassRefPtr<U>& o) { RefPtr<T>::operator=(o); return *this; } - }; - - // Remove inline for winscw compiler to prevent the compiler agressively resolving - // T::ref() in RefPtr<T>'s copy constructor. The bug is reported at: - // https://xdabug001.ext.nokia.com/bugzilla/show_bug.cgi?id=9812. - template <typename T> -#if !COMPILER(WINSCW) - inline -#endif - ListRefPtr<T>::~ListRefPtr() - { - RefPtr<T> reaper = this->release(); - while (reaper && reaper->hasOneRef()) - reaper = reaper->releaseNext(); // implicitly protects reaper->next, then derefs reaper - } - - template <typename T> inline T* getPtr(const ListRefPtr<T>& p) - { - return p.get(); - } - -} // namespace WTF - -using WTF::ListRefPtr; - -#endif // WTF_ListRefPtr_h diff --git a/JavaScriptCore/wtf/Locker.h b/JavaScriptCore/wtf/Locker.h deleted file mode 100644 index 41813d3..0000000 --- a/JavaScriptCore/wtf/Locker.h +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef Locker_h -#define Locker_h - -#include <wtf/Noncopyable.h> - -namespace WTF { - -template <typename T> class Locker : public Noncopyable { -public: - Locker(T& lockable) : m_lockable(lockable) { m_lockable.lock(); } - ~Locker() { m_lockable.unlock(); } -private: - T& m_lockable; -}; - -} - -using WTF::Locker; - -#endif diff --git a/JavaScriptCore/wtf/MD5.cpp b/JavaScriptCore/wtf/MD5.cpp deleted file mode 100644 index c926a7b..0000000 --- a/JavaScriptCore/wtf/MD5.cpp +++ /dev/null @@ -1,308 +0,0 @@ -// The original file was copied from sqlite, and was in the public domain. -// Modifications Copyright 2006 Google Inc. All Rights Reserved -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * This code implements the MD5 message-digest algorithm. - * The algorithm is due to Ron Rivest. This code was - * written by Colin Plumb in 1993, no copyright is claimed. - * This code is in the public domain; do with it what you wish. - * - * Equivalent code is available from RSA Data Security, Inc. - * This code has been tested against that, and is equivalent, - * except that you don't need to include two pages of legalese - * with every copy. - * - * To compute the message digest of a chunk of bytes, construct an - * MD5 instance, call addBytes as needed on buffers full of bytes, - * and then call checksum, which will fill a supplied 16-byte array - * with the digest. - */ - -#include "config.h" -#include "MD5.h" - -#include "Assertions.h" -#ifndef NDEBUG -#include "StringExtras.h" -#include "text/CString.h" -#endif -#include <wtf/StdLibExtras.h> - -namespace WTF { - -#ifdef NDEBUG -static inline void testMD5() { } -#else -// MD5 test case. -static bool isTestMD5Done; - -static void expectMD5(CString input, CString expected) -{ - MD5 md5; - md5.addBytes(reinterpret_cast<const uint8_t*>(input.data()), input.length()); - Vector<uint8_t, 16> digest; - md5.checksum(digest); - char* buf = 0; - CString actual = CString::newUninitialized(32, buf); - for (size_t i = 0; i < 16; i++) { - snprintf(buf, 3, "%02x", digest.at(i)); - buf += 2; - } - ASSERT_WITH_MESSAGE(actual == expected, "input:%s[%lu] actual:%s expected:%s", input.data(), static_cast<unsigned long>(input.length()), actual.data(), expected.data()); -} - -static void testMD5() -{ - if (isTestMD5Done) - return; - isTestMD5Done = true; - - // MD5 Test suite from http://www.ietf.org/rfc/rfc1321.txt - expectMD5("", "d41d8cd98f00b204e9800998ecf8427e"); - expectMD5("a", "0cc175b9c0f1b6a831c399e269772661"); - expectMD5("abc", "900150983cd24fb0d6963f7d28e17f72"); - expectMD5("message digest", "f96b697d7cb7938d525a2f31aaf161d0"); - expectMD5("abcdefghijklmnopqrstuvwxyz", "c3fcd3d76192e4007dfb496cca67e13b"); - expectMD5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", "d174ab98d277d9f5a5611c2c9f419d9f"); - expectMD5("12345678901234567890123456789012345678901234567890123456789012345678901234567890", "57edf4a22be3c955ac49da2e2107b67a"); -} -#endif - -// Note: this code is harmless on little-endian machines. - -static void reverseBytes(uint8_t* buf, unsigned longs) -{ - ASSERT(longs > 0); - do { - uint32_t t = static_cast<uint32_t>(buf[3] << 8 | buf[2]) << 16 | buf[1] << 8 | buf[0]; - ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(buf) % sizeof(t)), "alignment error of buf"); - *reinterpret_cast_ptr<uint32_t *>(buf) = t; - buf += 4; - } while (--longs); -} - -// The four core functions. -// F1 is originally defined as (x & y | ~x & z), but optimized somewhat: 4 bit ops -> 3 bit ops. -#define F1(x, y, z) (z ^ (x & (y ^ z))) -#define F2(x, y, z) F1(z, x, y) -#define F3(x, y, z) (x ^ y ^ z) -#define F4(x, y, z) (y ^ (x | ~z)) - -// This is the central step in the MD5 algorithm. -#define MD5STEP(f, w, x, y, z, data, s) \ - (w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x) - -static void MD5Transform(uint32_t buf[4], const uint32_t in[16]) -{ - uint32_t a = buf[0]; - uint32_t b = buf[1]; - uint32_t c = buf[2]; - uint32_t d = buf[3]; - - MD5STEP(F1, a, b, c, d, in[ 0]+0xd76aa478, 7); - MD5STEP(F1, d, a, b, c, in[ 1]+0xe8c7b756, 12); - MD5STEP(F1, c, d, a, b, in[ 2]+0x242070db, 17); - MD5STEP(F1, b, c, d, a, in[ 3]+0xc1bdceee, 22); - MD5STEP(F1, a, b, c, d, in[ 4]+0xf57c0faf, 7); - MD5STEP(F1, d, a, b, c, in[ 5]+0x4787c62a, 12); - MD5STEP(F1, c, d, a, b, in[ 6]+0xa8304613, 17); - MD5STEP(F1, b, c, d, a, in[ 7]+0xfd469501, 22); - MD5STEP(F1, a, b, c, d, in[ 8]+0x698098d8, 7); - MD5STEP(F1, d, a, b, c, in[ 9]+0x8b44f7af, 12); - MD5STEP(F1, c, d, a, b, in[10]+0xffff5bb1, 17); - MD5STEP(F1, b, c, d, a, in[11]+0x895cd7be, 22); - MD5STEP(F1, a, b, c, d, in[12]+0x6b901122, 7); - MD5STEP(F1, d, a, b, c, in[13]+0xfd987193, 12); - MD5STEP(F1, c, d, a, b, in[14]+0xa679438e, 17); - MD5STEP(F1, b, c, d, a, in[15]+0x49b40821, 22); - - MD5STEP(F2, a, b, c, d, in[ 1]+0xf61e2562, 5); - MD5STEP(F2, d, a, b, c, in[ 6]+0xc040b340, 9); - MD5STEP(F2, c, d, a, b, in[11]+0x265e5a51, 14); - MD5STEP(F2, b, c, d, a, in[ 0]+0xe9b6c7aa, 20); - MD5STEP(F2, a, b, c, d, in[ 5]+0xd62f105d, 5); - MD5STEP(F2, d, a, b, c, in[10]+0x02441453, 9); - MD5STEP(F2, c, d, a, b, in[15]+0xd8a1e681, 14); - MD5STEP(F2, b, c, d, a, in[ 4]+0xe7d3fbc8, 20); - MD5STEP(F2, a, b, c, d, in[ 9]+0x21e1cde6, 5); - MD5STEP(F2, d, a, b, c, in[14]+0xc33707d6, 9); - MD5STEP(F2, c, d, a, b, in[ 3]+0xf4d50d87, 14); - MD5STEP(F2, b, c, d, a, in[ 8]+0x455a14ed, 20); - MD5STEP(F2, a, b, c, d, in[13]+0xa9e3e905, 5); - MD5STEP(F2, d, a, b, c, in[ 2]+0xfcefa3f8, 9); - MD5STEP(F2, c, d, a, b, in[ 7]+0x676f02d9, 14); - MD5STEP(F2, b, c, d, a, in[12]+0x8d2a4c8a, 20); - - MD5STEP(F3, a, b, c, d, in[ 5]+0xfffa3942, 4); - MD5STEP(F3, d, a, b, c, in[ 8]+0x8771f681, 11); - MD5STEP(F3, c, d, a, b, in[11]+0x6d9d6122, 16); - MD5STEP(F3, b, c, d, a, in[14]+0xfde5380c, 23); - MD5STEP(F3, a, b, c, d, in[ 1]+0xa4beea44, 4); - MD5STEP(F3, d, a, b, c, in[ 4]+0x4bdecfa9, 11); - MD5STEP(F3, c, d, a, b, in[ 7]+0xf6bb4b60, 16); - MD5STEP(F3, b, c, d, a, in[10]+0xbebfbc70, 23); - MD5STEP(F3, a, b, c, d, in[13]+0x289b7ec6, 4); - MD5STEP(F3, d, a, b, c, in[ 0]+0xeaa127fa, 11); - MD5STEP(F3, c, d, a, b, in[ 3]+0xd4ef3085, 16); - MD5STEP(F3, b, c, d, a, in[ 6]+0x04881d05, 23); - MD5STEP(F3, a, b, c, d, in[ 9]+0xd9d4d039, 4); - MD5STEP(F3, d, a, b, c, in[12]+0xe6db99e5, 11); - MD5STEP(F3, c, d, a, b, in[15]+0x1fa27cf8, 16); - MD5STEP(F3, b, c, d, a, in[ 2]+0xc4ac5665, 23); - - MD5STEP(F4, a, b, c, d, in[ 0]+0xf4292244, 6); - MD5STEP(F4, d, a, b, c, in[ 7]+0x432aff97, 10); - MD5STEP(F4, c, d, a, b, in[14]+0xab9423a7, 15); - MD5STEP(F4, b, c, d, a, in[ 5]+0xfc93a039, 21); - MD5STEP(F4, a, b, c, d, in[12]+0x655b59c3, 6); - MD5STEP(F4, d, a, b, c, in[ 3]+0x8f0ccc92, 10); - MD5STEP(F4, c, d, a, b, in[10]+0xffeff47d, 15); - MD5STEP(F4, b, c, d, a, in[ 1]+0x85845dd1, 21); - MD5STEP(F4, a, b, c, d, in[ 8]+0x6fa87e4f, 6); - MD5STEP(F4, d, a, b, c, in[15]+0xfe2ce6e0, 10); - MD5STEP(F4, c, d, a, b, in[ 6]+0xa3014314, 15); - MD5STEP(F4, b, c, d, a, in[13]+0x4e0811a1, 21); - MD5STEP(F4, a, b, c, d, in[ 4]+0xf7537e82, 6); - MD5STEP(F4, d, a, b, c, in[11]+0xbd3af235, 10); - MD5STEP(F4, c, d, a, b, in[ 2]+0x2ad7d2bb, 15); - MD5STEP(F4, b, c, d, a, in[ 9]+0xeb86d391, 21); - - buf[0] += a; - buf[1] += b; - buf[2] += c; - buf[3] += d; -} - -MD5::MD5() -{ - testMD5(); - m_buf[0] = 0x67452301; - m_buf[1] = 0xefcdab89; - m_buf[2] = 0x98badcfe; - m_buf[3] = 0x10325476; - m_bits[0] = 0; - m_bits[1] = 0; - memset(m_in, 0, sizeof(m_in)); - ASSERT_WITH_MESSAGE(!(reinterpret_cast<uintptr_t>(m_in) % sizeof(uint32_t)), "alignment error of m_in"); -} - -void MD5::addBytes(const uint8_t* input, size_t length) -{ - const uint8_t* buf = input; - - // Update bitcount - uint32_t t = m_bits[0]; - m_bits[0] = t + (length << 3); - if (m_bits[0] < t) - m_bits[1]++; // Carry from low to high - m_bits[1] += length >> 29; - - t = (t >> 3) & 0x3f; // Bytes already in shsInfo->data - - // Handle any leading odd-sized chunks - - if (t) { - uint8_t* p = m_in + t; - - t = 64 - t; - if (length < t) { - memcpy(p, buf, length); - return; - } - memcpy(p, buf, t); - reverseBytes(m_in, 16); - MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t*>(m_in)); // m_in is 4-byte aligned. - buf += t; - length -= t; - } - - // Process data in 64-byte chunks - - while (length >= 64) { - memcpy(m_in, buf, 64); - reverseBytes(m_in, 16); - MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t*>(m_in)); // m_in is 4-byte aligned. - buf += 64; - length -= 64; - } - - // Handle any remaining bytes of data. - memcpy(m_in, buf, length); -} - -void MD5::checksum(Vector<uint8_t, 16>& digest) -{ - // Compute number of bytes mod 64 - unsigned count = (m_bits[0] >> 3) & 0x3F; - - // Set the first char of padding to 0x80. This is safe since there is - // always at least one byte free - uint8_t* p = m_in + count; - *p++ = 0x80; - - // Bytes of padding needed to make 64 bytes - count = 64 - 1 - count; - - // Pad out to 56 mod 64 - if (count < 8) { - // Two lots of padding: Pad the first block to 64 bytes - memset(p, 0, count); - reverseBytes(m_in, 16); - MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t *>(m_in)); // m_in is 4-byte aligned. - - // Now fill the next block with 56 bytes - memset(m_in, 0, 56); - } else { - // Pad block to 56 bytes - memset(p, 0, count - 8); - } - reverseBytes(m_in, 14); - - // Append length in bits and transform - // m_in is 4-byte aligned. - (reinterpret_cast_ptr<uint32_t*>(m_in))[14] = m_bits[0]; - (reinterpret_cast_ptr<uint32_t*>(m_in))[15] = m_bits[1]; - - MD5Transform(m_buf, reinterpret_cast_ptr<uint32_t*>(m_in)); - reverseBytes(reinterpret_cast<uint8_t*>(m_buf), 4); - - // Now, m_buf contains checksum result. - if (!digest.isEmpty()) - digest.clear(); - digest.append(reinterpret_cast<uint8_t*>(m_buf), 16); - - // In case it's sensitive - memset(m_buf, 0, sizeof(m_buf)); - memset(m_bits, 0, sizeof(m_bits)); - memset(m_in, 0, sizeof(m_in)); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/MD5.h b/JavaScriptCore/wtf/MD5.h deleted file mode 100644 index 3caa810..0000000 --- a/JavaScriptCore/wtf/MD5.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_MD5_h -#define WTF_MD5_h - -#include <wtf/Vector.h> - -namespace WTF { - -class MD5 { -public: - MD5(); - - void addBytes(const Vector<uint8_t>& input) - { - addBytes(input.data(), input.size()); - } - void addBytes(const uint8_t* input, size_t length); - - // checksum has a side effect of resetting the state of the object. - void checksum(Vector<uint8_t, 16>&); - -private: - uint32_t m_buf[4]; - uint32_t m_bits[2]; - uint8_t m_in[64]; -}; - -} // namespace WTF - -using WTF::MD5; - -#endif // WTF_MD5_h diff --git a/JavaScriptCore/wtf/MainThread.cpp b/JavaScriptCore/wtf/MainThread.cpp deleted file mode 100644 index a5f2346..0000000 --- a/JavaScriptCore/wtf/MainThread.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include "CurrentTime.h" -#include "Deque.h" -#include "StdLibExtras.h" -#include "Threading.h" - -#if PLATFORM(CHROMIUM) -#error Chromium uses a different main thread implementation -#endif - -namespace WTF { - -struct FunctionWithContext { - MainThreadFunction* function; - void* context; - ThreadCondition* syncFlag; - - FunctionWithContext(MainThreadFunction* function = 0, void* context = 0, ThreadCondition* syncFlag = 0) - : function(function) - , context(context) - , syncFlag(syncFlag) - { - } - bool operator == (const FunctionWithContext& o) - { - return function == o.function - && context == o.context - && syncFlag == o.syncFlag; - } -}; - -class FunctionWithContextFinder { -public: - FunctionWithContextFinder(const FunctionWithContext& m) : m(m) {} - bool operator() (FunctionWithContext& o) { return o == m; } - FunctionWithContext m; -}; - - -typedef Deque<FunctionWithContext> FunctionQueue; - -static bool callbacksPaused; // This global variable is only accessed from main thread. -#if !PLATFORM(MAC) && !PLATFORM(QT) -static ThreadIdentifier mainThreadIdentifier; -#endif - -static Mutex& mainThreadFunctionQueueMutex() -{ - DEFINE_STATIC_LOCAL(Mutex, staticMutex, ()); - return staticMutex; -} - -static FunctionQueue& functionQueue() -{ - DEFINE_STATIC_LOCAL(FunctionQueue, staticFunctionQueue, ()); - return staticFunctionQueue; -} - - -#if !PLATFORM(MAC) - -void initializeMainThread() -{ - static bool initializedMainThread; - if (initializedMainThread) - return; - initializedMainThread = true; - -#if !PLATFORM(QT) - mainThreadIdentifier = currentThread(); -#endif - - mainThreadFunctionQueueMutex(); - initializeMainThreadPlatform(); -} - -#else - -static pthread_once_t initializeMainThreadKeyOnce = PTHREAD_ONCE_INIT; - -static void initializeMainThreadOnce() -{ - mainThreadFunctionQueueMutex(); - initializeMainThreadPlatform(); -} - -void initializeMainThread() -{ - pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadOnce); -} - -static void initializeMainThreadToProcessMainThreadOnce() -{ - mainThreadFunctionQueueMutex(); - initializeMainThreadToProcessMainThreadPlatform(); -} - -void initializeMainThreadToProcessMainThread() -{ - pthread_once(&initializeMainThreadKeyOnce, initializeMainThreadToProcessMainThreadOnce); -} -#endif - -// 0.1 sec delays in UI is approximate threshold when they become noticeable. Have a limit that's half of that. -static const double maxRunLoopSuspensionTime = 0.05; - -void dispatchFunctionsFromMainThread() -{ - ASSERT(isMainThread()); - - if (callbacksPaused) - return; - - double startTime = currentTime(); - - FunctionWithContext invocation; - while (true) { - { - MutexLocker locker(mainThreadFunctionQueueMutex()); - if (!functionQueue().size()) - break; - invocation = functionQueue().takeFirst(); - } - - invocation.function(invocation.context); - if (invocation.syncFlag) - invocation.syncFlag->signal(); - - // If we are running accumulated functions for too long so UI may become unresponsive, we need to - // yield so the user input can be processed. Otherwise user may not be able to even close the window. - // This code has effect only in case the scheduleDispatchFunctionsOnMainThread() is implemented in a way that - // allows input events to be processed before we are back here. - if (currentTime() - startTime > maxRunLoopSuspensionTime) { - scheduleDispatchFunctionsOnMainThread(); - break; - } - } -} - -void callOnMainThread(MainThreadFunction* function, void* context) -{ - ASSERT(function); - bool needToSchedule = false; - { - MutexLocker locker(mainThreadFunctionQueueMutex()); - needToSchedule = functionQueue().size() == 0; - functionQueue().append(FunctionWithContext(function, context)); - } - if (needToSchedule) - scheduleDispatchFunctionsOnMainThread(); -} - -void callOnMainThreadAndWait(MainThreadFunction* function, void* context) -{ - ASSERT(function); - - if (isMainThread()) { - function(context); - return; - } - - ThreadCondition syncFlag; - Mutex& functionQueueMutex = mainThreadFunctionQueueMutex(); - MutexLocker locker(functionQueueMutex); - functionQueue().append(FunctionWithContext(function, context, &syncFlag)); - if (functionQueue().size() == 1) - scheduleDispatchFunctionsOnMainThread(); - syncFlag.wait(functionQueueMutex); -} - -void cancelCallOnMainThread(MainThreadFunction* function, void* context) -{ - ASSERT(function); - - MutexLocker locker(mainThreadFunctionQueueMutex()); - - FunctionWithContextFinder pred(FunctionWithContext(function, context)); - - while (true) { - // We must redefine 'i' each pass, because the itererator's operator= - // requires 'this' to be valid, and remove() invalidates all iterators - FunctionQueue::iterator i(functionQueue().findIf(pred)); - if (i == functionQueue().end()) - break; - functionQueue().remove(i); - } -} - -void setMainThreadCallbacksPaused(bool paused) -{ - ASSERT(isMainThread()); - - if (callbacksPaused == paused) - return; - - callbacksPaused = paused; - - if (!callbacksPaused) - scheduleDispatchFunctionsOnMainThread(); -} - -#if !PLATFORM(MAC) && !PLATFORM(QT) && !PLATFORM(BREWMP) -bool isMainThread() -{ - return currentThread() == mainThreadIdentifier; -} -#endif - -} // namespace WTF diff --git a/JavaScriptCore/wtf/MainThread.h b/JavaScriptCore/wtf/MainThread.h deleted file mode 100644 index 7703f3e..0000000 --- a/JavaScriptCore/wtf/MainThread.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MainThread_h -#define MainThread_h - -#include <stdint.h> - -namespace WTF { - -typedef uint32_t ThreadIdentifier; -typedef void MainThreadFunction(void*); - -// Must be called from the main thread. -void initializeMainThread(); - -void callOnMainThread(MainThreadFunction*, void* context); -void callOnMainThreadAndWait(MainThreadFunction*, void* context); -void cancelCallOnMainThread(MainThreadFunction*, void* context); - -void setMainThreadCallbacksPaused(bool paused); - -bool isMainThread(); - -// NOTE: these functions are internal to the callOnMainThread implementation. -void initializeMainThreadPlatform(); -void scheduleDispatchFunctionsOnMainThread(); -void dispatchFunctionsFromMainThread(); - -#if PLATFORM(MAC) -// This version of initializeMainThread sets up the main thread as corresponding -// to the process's main thread, and not necessarily the thread that calls this -// function. It should only be used as a legacy aid for Mac WebKit. -void initializeMainThreadToProcessMainThread(); -void initializeMainThreadToProcessMainThreadPlatform(); -#endif - -} // namespace WTF - -using WTF::callOnMainThread; -using WTF::callOnMainThreadAndWait; -using WTF::cancelCallOnMainThread; -using WTF::setMainThreadCallbacksPaused; -using WTF::isMainThread; -#endif // MainThread_h diff --git a/JavaScriptCore/wtf/MallocZoneSupport.h b/JavaScriptCore/wtf/MallocZoneSupport.h deleted file mode 100644 index 62df145..0000000 --- a/JavaScriptCore/wtf/MallocZoneSupport.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MallocZoneSupport_h -#define MallocZoneSupport_h - -#include <malloc/malloc.h> - -namespace WTF { - -class RemoteMemoryReader { - task_t m_task; - memory_reader_t* m_reader; - -public: - RemoteMemoryReader(task_t task, memory_reader_t* reader) - : m_task(task) - , m_reader(reader) - { } - - void* operator()(vm_address_t address, size_t size) const - { - void* output; - kern_return_t err = (*m_reader)(m_task, address, size, static_cast<void**>(&output)); - ASSERT(!err); - if (err) - output = 0; - return output; - } - - template <typename T> - T* operator()(T* address, size_t size=sizeof(T)) const - { - return static_cast<T*>((*this)(reinterpret_cast<vm_address_t>(address), size)); - } -}; - -} // namespace WTF - -#endif // MallocZoneSupport_h diff --git a/JavaScriptCore/wtf/MathExtras.h b/JavaScriptCore/wtf/MathExtras.h deleted file mode 100644 index 095549e..0000000 --- a/JavaScriptCore/wtf/MathExtras.h +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_MathExtras_h -#define WTF_MathExtras_h - -#include <cmath> -#include <float.h> -#include <stdlib.h> - -#if OS(SOLARIS) -#include <ieeefp.h> -#endif - -#if OS(OPENBSD) -#include <sys/types.h> -#include <machine/ieee.h> -#endif - -#if COMPILER(MSVC) -#if OS(WINCE) -#include <stdlib.h> -#endif -#include <limits> -#endif - -#ifndef M_PI -const double piDouble = 3.14159265358979323846; -const float piFloat = 3.14159265358979323846f; -#else -const double piDouble = M_PI; -const float piFloat = static_cast<float>(M_PI); -#endif - -#ifndef M_PI_2 -const double piOverTwoDouble = 1.57079632679489661923; -const float piOverTwoFloat = 1.57079632679489661923f; -#else -const double piOverTwoDouble = M_PI_2; -const float piOverTwoFloat = static_cast<float>(M_PI_2); -#endif - -#ifndef M_PI_4 -const double piOverFourDouble = 0.785398163397448309616; -const float piOverFourFloat = 0.785398163397448309616f; -#else -const double piOverFourDouble = M_PI_4; -const float piOverFourFloat = static_cast<float>(M_PI_4); -#endif - -#if OS(DARWIN) - -// Work around a bug in the Mac OS X libc where ceil(-0.1) return +0. -inline double wtf_ceil(double x) { return copysign(ceil(x), x); } - -#define ceil(x) wtf_ceil(x) - -#endif - -#if OS(SOLARIS) - -#ifndef isfinite -inline bool isfinite(double x) { return finite(x) && !isnand(x); } -#endif -#ifndef isinf -inline bool isinf(double x) { return !finite(x) && !isnand(x); } -#endif -#ifndef signbit -inline bool signbit(double x) { return x < 0.0; } // FIXME: Wrong for negative 0. -#endif - -#endif - -#if OS(OPENBSD) - -#ifndef isfinite -inline bool isfinite(double x) { return finite(x); } -#endif -#ifndef signbit -inline bool signbit(double x) { struct ieee_double *p = (struct ieee_double *)&x; return p->dbl_sign; } -#endif - -#endif - -#if COMPILER(MSVC) || COMPILER(RVCT) - -// We must not do 'num + 0.5' or 'num - 0.5' because they can cause precision loss. -static double round(double num) -{ - double integer = ceil(num); - if (num > 0) - return integer - num > 0.5 ? integer - 1.0 : integer; - return integer - num >= 0.5 ? integer - 1.0 : integer; -} -static float roundf(float num) -{ - float integer = ceilf(num); - if (num > 0) - return integer - num > 0.5f ? integer - 1.0f : integer; - return integer - num >= 0.5f ? integer - 1.0f : integer; -} -inline long long llround(double num) { return static_cast<long long>(round(num)); } -inline long long llroundf(float num) { return static_cast<long long>(roundf(num)); } -inline long lround(double num) { return static_cast<long>(round(num)); } -inline long lroundf(float num) { return static_cast<long>(roundf(num)); } -inline double trunc(double num) { return num > 0 ? floor(num) : ceil(num); } - -#endif - -#if COMPILER(MSVC) -// The 64bit version of abs() is already defined in stdlib.h which comes with VC10 -#if COMPILER(MSVC9_OR_LOWER) -inline long long abs(long long num) { return _abs64(num); } -#endif - -inline bool isinf(double num) { return !_finite(num) && !_isnan(num); } -inline bool isnan(double num) { return !!_isnan(num); } -inline bool signbit(double num) { return _copysign(1.0, num) < 0; } - -inline double nextafter(double x, double y) { return _nextafter(x, y); } -inline float nextafterf(float x, float y) { return x > y ? x - FLT_EPSILON : x + FLT_EPSILON; } - -inline double copysign(double x, double y) { return _copysign(x, y); } -inline int isfinite(double x) { return _finite(x); } - -// MSVC's math.h does not currently supply log2. -inline double log2(double num) -{ - // This constant is roughly M_LN2, which is not provided by default on Windows. - return log(num) / 0.693147180559945309417232121458176568; -} - -// Work around a bug in Win, where atan2(+-infinity, +-infinity) yields NaN instead of specific values. -inline double wtf_atan2(double x, double y) -{ - double posInf = std::numeric_limits<double>::infinity(); - double negInf = -std::numeric_limits<double>::infinity(); - double nan = std::numeric_limits<double>::quiet_NaN(); - - double result = nan; - - if (x == posInf && y == posInf) - result = piOverFourDouble; - else if (x == posInf && y == negInf) - result = 3 * piOverFourDouble; - else if (x == negInf && y == posInf) - result = -piOverFourDouble; - else if (x == negInf && y == negInf) - result = -3 * piOverFourDouble; - else - result = ::atan2(x, y); - - return result; -} - -// Work around a bug in the Microsoft CRT, where fmod(x, +-infinity) yields NaN instead of x. -inline double wtf_fmod(double x, double y) { return (!isinf(x) && isinf(y)) ? x : fmod(x, y); } - -// Work around a bug in the Microsoft CRT, where pow(NaN, 0) yields NaN instead of 1. -inline double wtf_pow(double x, double y) { return y == 0 ? 1 : pow(x, y); } - -#define atan2(x, y) wtf_atan2(x, y) -#define fmod(x, y) wtf_fmod(x, y) -#define pow(x, y) wtf_pow(x, y) - -#endif // COMPILER(MSVC) - -inline double deg2rad(double d) { return d * piDouble / 180.0; } -inline double rad2deg(double r) { return r * 180.0 / piDouble; } -inline double deg2grad(double d) { return d * 400.0 / 360.0; } -inline double grad2deg(double g) { return g * 360.0 / 400.0; } -inline double turn2deg(double t) { return t * 360.0; } -inline double deg2turn(double d) { return d / 360.0; } -inline double rad2grad(double r) { return r * 200.0 / piDouble; } -inline double grad2rad(double g) { return g * piDouble / 200.0; } - -inline float deg2rad(float d) { return d * piFloat / 180.0f; } -inline float rad2deg(float r) { return r * 180.0f / piFloat; } -inline float deg2grad(float d) { return d * 400.0f / 360.0f; } -inline float grad2deg(float g) { return g * 360.0f / 400.0f; } -inline float turn2deg(float t) { return t * 360.0f; } -inline float deg2turn(float d) { return d / 360.0f; } -inline float rad2grad(float r) { return r * 200.0f / piFloat; } -inline float grad2rad(float g) { return g * piFloat / 200.0f; } - -#if !COMPILER(MSVC) && !COMPILER(WINSCW) && !(COMPILER(RVCT) && (OS(SYMBIAN) || PLATFORM(BREWMP))) -using std::isfinite; -using std::isinf; -using std::isnan; -using std::signbit; -#endif - -#endif // #ifndef WTF_MathExtras_h diff --git a/JavaScriptCore/wtf/MessageQueue.h b/JavaScriptCore/wtf/MessageQueue.h deleted file mode 100644 index 14100c9..0000000 --- a/JavaScriptCore/wtf/MessageQueue.h +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef MessageQueue_h -#define MessageQueue_h - -#include <limits> -#include <wtf/Assertions.h> -#include <wtf/Deque.h> -#include <wtf/Noncopyable.h> -#include <wtf/Threading.h> - -namespace WTF { - - enum MessageQueueWaitResult { - MessageQueueTerminated, // Queue was destroyed while waiting for message. - MessageQueueTimeout, // Timeout was specified and it expired. - MessageQueueMessageReceived, // A message was successfully received and returned. - }; - - // The queue takes ownership of messages and transfer it to the new owner - // when messages are fetched from the queue. - // Essentially, MessageQueue acts as a queue of OwnPtr<DataType>. - template<typename DataType> - class MessageQueue : public Noncopyable { - public: - MessageQueue() : m_killed(false) { } - ~MessageQueue(); - - void append(PassOwnPtr<DataType>); - bool appendAndCheckEmpty(PassOwnPtr<DataType>); - void prepend(PassOwnPtr<DataType>); - - PassOwnPtr<DataType> waitForMessage(); - PassOwnPtr<DataType> tryGetMessage(); - template<typename Predicate> - PassOwnPtr<DataType> waitForMessageFilteredWithTimeout(MessageQueueWaitResult&, Predicate&, double absoluteTime); - - template<typename Predicate> - void removeIf(Predicate&); - - void kill(); - bool killed() const; - - // The result of isEmpty() is only valid if no other thread is manipulating the queue at the same time. - bool isEmpty(); - - static double infiniteTime() { return std::numeric_limits<double>::max(); } - - private: - static bool alwaysTruePredicate(DataType*) { return true; } - - mutable Mutex m_mutex; - ThreadCondition m_condition; - Deque<DataType*> m_queue; - bool m_killed; - }; - - template<typename DataType> - MessageQueue<DataType>::~MessageQueue() - { - deleteAllValues(m_queue); - } - - template<typename DataType> - inline void MessageQueue<DataType>::append(PassOwnPtr<DataType> message) - { - MutexLocker lock(m_mutex); - m_queue.append(message.leakPtr()); - m_condition.signal(); - } - - // Returns true if the queue was empty before the item was added. - template<typename DataType> - inline bool MessageQueue<DataType>::appendAndCheckEmpty(PassOwnPtr<DataType> message) - { - MutexLocker lock(m_mutex); - bool wasEmpty = m_queue.isEmpty(); - m_queue.append(message.leakPtr()); - m_condition.signal(); - return wasEmpty; - } - - template<typename DataType> - inline void MessageQueue<DataType>::prepend(PassOwnPtr<DataType> message) - { - MutexLocker lock(m_mutex); - m_queue.prepend(message.leakPtr()); - m_condition.signal(); - } - - template<typename DataType> - inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessage() - { - MessageQueueWaitResult exitReason; - PassOwnPtr<DataType> result = waitForMessageFilteredWithTimeout(exitReason, MessageQueue<DataType>::alwaysTruePredicate, infiniteTime()); - ASSERT(exitReason == MessageQueueTerminated || exitReason == MessageQueueMessageReceived); - return result; - } - - template<typename DataType> - template<typename Predicate> - inline PassOwnPtr<DataType> MessageQueue<DataType>::waitForMessageFilteredWithTimeout(MessageQueueWaitResult& result, Predicate& predicate, double absoluteTime) - { - MutexLocker lock(m_mutex); - bool timedOut = false; - - DequeConstIterator<DataType*> found = m_queue.end(); - while (!m_killed && !timedOut && (found = m_queue.findIf(predicate)) == m_queue.end()) - timedOut = !m_condition.timedWait(m_mutex, absoluteTime); - - ASSERT(!timedOut || absoluteTime != infiniteTime()); - - if (m_killed) { - result = MessageQueueTerminated; - return 0; - } - - if (timedOut) { - result = MessageQueueTimeout; - return 0; - } - - ASSERT(found != m_queue.end()); - DataType* message = *found; - m_queue.remove(found); - result = MessageQueueMessageReceived; - return message; - } - - template<typename DataType> - inline PassOwnPtr<DataType> MessageQueue<DataType>::tryGetMessage() - { - MutexLocker lock(m_mutex); - if (m_killed) - return 0; - if (m_queue.isEmpty()) - return 0; - - return m_queue.takeFirst(); - } - - template<typename DataType> - template<typename Predicate> - inline void MessageQueue<DataType>::removeIf(Predicate& predicate) - { - MutexLocker lock(m_mutex); - // See bug 31657 for why this loop looks so weird - while (true) { - DequeConstIterator<DataType*> found = m_queue.findIf(predicate); - if (found == m_queue.end()) - break; - - DataType* message = *found; - m_queue.remove(found); - delete message; - } - } - - template<typename DataType> - inline bool MessageQueue<DataType>::isEmpty() - { - MutexLocker lock(m_mutex); - if (m_killed) - return true; - return m_queue.isEmpty(); - } - - template<typename DataType> - inline void MessageQueue<DataType>::kill() - { - MutexLocker lock(m_mutex); - m_killed = true; - m_condition.broadcast(); - } - - template<typename DataType> - inline bool MessageQueue<DataType>::killed() const - { - MutexLocker lock(m_mutex); - return m_killed; - } -} // namespace WTF - -using WTF::MessageQueue; -// MessageQueueWaitResult enum and all its values. -using WTF::MessageQueueWaitResult; -using WTF::MessageQueueTerminated; -using WTF::MessageQueueTimeout; -using WTF::MessageQueueMessageReceived; - -#endif // MessageQueue_h diff --git a/JavaScriptCore/wtf/NonCopyingSort.h b/JavaScriptCore/wtf/NonCopyingSort.h deleted file mode 100644 index fd611bd..0000000 --- a/JavaScriptCore/wtf/NonCopyingSort.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef WTF_NonCopyingSort_h -#define WTF_NonCopyingSort_h - -namespace WTF { - -using std::swap; - -template<typename RandomAccessIterator, typename Predicate> -inline void siftDown(RandomAccessIterator array, ptrdiff_t start, ptrdiff_t end, Predicate compareLess) -{ - ptrdiff_t root = start; - - while (root * 2 + 1 <= end) { - ptrdiff_t child = root * 2 + 1; - if (child < end && compareLess(array[child], array[child + 1])) - child++; - - if (compareLess(array[root], array[child])) { - swap(array[root], array[child]); - root = child; - } else - return; - } -} - -template<typename RandomAccessIterator, typename Predicate> -inline void heapify(RandomAccessIterator array, ptrdiff_t count, Predicate compareLess) -{ - ptrdiff_t start = (count - 2) / 2; - - while (start >= 0) { - siftDown(array, start, count - 1, compareLess); - start--; - } -} - -template<typename RandomAccessIterator, typename Predicate> -void heapSort(RandomAccessIterator start, RandomAccessIterator end, Predicate compareLess) -{ - ptrdiff_t count = end - start; - heapify(start, count, compareLess); - - ptrdiff_t endIndex = count - 1; - while (endIndex > 0) { - swap(start[endIndex], start[0]); - siftDown(start, 0, endIndex - 1, compareLess); - endIndex--; - } -} - -template<typename RandomAccessIterator, typename Predicate> -inline void nonCopyingSort(RandomAccessIterator start, RandomAccessIterator end, Predicate compareLess) -{ - // heapsort happens to use only swaps, not copies, but the essential thing about - // this function is the fact that it does not copy, not the specific algorithm - heapSort(start, end, compareLess); -} - -} // namespace WTF - -using WTF::nonCopyingSort; - -#endif // WTF_NonCopyingSort_h diff --git a/JavaScriptCore/wtf/Noncopyable.h b/JavaScriptCore/wtf/Noncopyable.h deleted file mode 100644 index 285ed2e..0000000 --- a/JavaScriptCore/wtf/Noncopyable.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_Noncopyable_h -#define WTF_Noncopyable_h - -#ifndef __has_feature - #define __has_feature(x) 0 -#endif - -#if __has_feature(cxx_deleted_functions) - #define WTF_MAKE_NONCOPYABLE(ClassName) \ - _Pragma("clang diagnostic push") \ - _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") \ - _Pragma("clang diagnostic ignored \"-Wc++0x-extensions\"") \ - private: \ - ClassName(const ClassName&) = delete; \ - ClassName& operator=(const ClassName&) = delete; \ - _Pragma("clang diagnostic pop") -#else - #define WTF_MAKE_NONCOPYABLE(ClassName) \ - private: \ - ClassName(const ClassName&); \ - ClassName& operator=(const ClassName&) -#endif - -// We don't want argument-dependent lookup to pull in everything from the WTF -// namespace when you use Noncopyable, so put it in its own namespace. - -#include "FastAllocBase.h" - -namespace WTFNoncopyable { - - class Noncopyable : public FastAllocBase { - Noncopyable(const Noncopyable&); - Noncopyable& operator=(const Noncopyable&); - protected: - Noncopyable() { } - ~Noncopyable() { } - }; - -} // namespace WTFNoncopyable - -using WTFNoncopyable::Noncopyable; - -#endif // WTF_Noncopyable_h diff --git a/JavaScriptCore/wtf/NotFound.h b/JavaScriptCore/wtf/NotFound.h deleted file mode 100644 index 4263bce..0000000 --- a/JavaScriptCore/wtf/NotFound.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef NotFound_h -#define NotFound_h - -namespace WTF { - - const size_t notFound = static_cast<size_t>(-1); - -} // namespace WTF - -using WTF::notFound; - -#endif // NotFound_h diff --git a/JavaScriptCore/wtf/NullPtr.cpp b/JavaScriptCore/wtf/NullPtr.cpp deleted file mode 100644 index e7d94b2..0000000 --- a/JavaScriptCore/wtf/NullPtr.cpp +++ /dev/null @@ -1,33 +0,0 @@ -/* - -Copyright (C) 2010 Apple Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#include "NullPtr.h" - -#if !__has_feature(cxx_nullptr) - -std::nullptr_t nullptr; - -#endif diff --git a/JavaScriptCore/wtf/NullPtr.h b/JavaScriptCore/wtf/NullPtr.h deleted file mode 100644 index 10a5814..0000000 --- a/JavaScriptCore/wtf/NullPtr.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - -Copyright (C) 2010 Apple Inc. All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -*/ - -#ifndef NullPtr_h -#define NullPtr_h - -// For compilers and standard libraries that do not yet include it, this adds the -// nullptr_t type and nullptr object. They are defined in the same namespaces they -// would be in compiler and library that had the support. - -#ifndef __has_feature - #define __has_feature(feature) 0 -#endif - -#if !__has_feature(cxx_nullptr) - -namespace std { - class nullptr_t { }; -} - -extern std::nullptr_t nullptr; - -#endif - -#endif diff --git a/JavaScriptCore/wtf/OSAllocator.h b/JavaScriptCore/wtf/OSAllocator.h deleted file mode 100644 index 577a6b8..0000000 --- a/JavaScriptCore/wtf/OSAllocator.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef OSAllocator_h -#define OSAllocator_h - -#include <wtf/UnusedParam.h> -#include <wtf/VMTags.h> -#include <wtf/VMTags.h> - -namespace WTF { - -class OSAllocator { -public: - enum Usage { - UnknownUsage = -1, - FastMallocPages = VM_TAG_FOR_TCMALLOC_MEMORY, - JSGCHeapPages = VM_TAG_FOR_COLLECTOR_MEMORY, - JSVMStackPages = VM_TAG_FOR_REGISTERFILE_MEMORY, - JSJITCodePages = VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY, - }; - - // These methods are symmetric; reserveUncommitted allocates VM in an uncommitted state, - // releaseDecommitted should be called on a region of VM allocated by a single reservation, - // the memory must all currently be in a decommitted state. - static void* reserveUncommitted(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false); - static void releaseDecommitted(void*, size_t); - - // These methods are symmetric; they commit or decommit a region of VM (uncommitted VM should - // never be accessed, since the OS may not have attached physical memory for these regions). - // Clients should only call commit on uncommitted regions and decommit on committed regions. - static void commit(void*, size_t, bool writable, bool executable); - static void decommit(void*, size_t); - - // These methods are symmetric; reserveAndCommit allocates VM in an committed state, - // decommitAndRelease should be called on a region of VM allocated by a single reservation, - // the memory must all currently be in a committed state. - static void* reserveAndCommit(size_t, Usage = UnknownUsage, bool writable = true, bool executable = false); - static void decommitAndRelease(void* base, size_t size); - - // These methods are akin to reserveAndCommit/decommitAndRelease, above - however rather than - // committing/decommitting the entire region additional parameters allow a subregion to be - // specified. - static void* reserveAndCommit(size_t reserveSize, size_t commitSize, Usage = UnknownUsage, bool writable = true, bool executable = false); - static void decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize); -}; - -inline void* OSAllocator::reserveAndCommit(size_t reserveSize, size_t commitSize, Usage usage, bool writable, bool executable) -{ - void* base = reserveUncommitted(reserveSize, usage, writable, executable); - commit(base, commitSize, writable, executable); - return base; -} - -inline void OSAllocator::decommitAndRelease(void* releaseBase, size_t releaseSize, void* decommitBase, size_t decommitSize) -{ - ASSERT(decommitBase >= releaseBase && (static_cast<char*>(decommitBase) + decommitSize) <= (static_cast<char*>(releaseBase) + releaseSize)); -#if OS(WINCE) - // On most platforms we can actually skip this final decommit; releasing the VM will - // implicitly decommit any physical memory in the region. This is not true on WINCE. - decommit(decommitBase, decommitSize); -#else - UNUSED_PARAM(decommitBase); - UNUSED_PARAM(decommitSize); -#endif - releaseDecommitted(releaseBase, releaseSize); -} - -inline void OSAllocator::decommitAndRelease(void* base, size_t size) -{ - decommitAndRelease(base, size, base, size); -} - -} // namespace WTF - -using WTF::OSAllocator; - -#endif // OSAllocator_h diff --git a/JavaScriptCore/wtf/OSAllocatorPosix.cpp b/JavaScriptCore/wtf/OSAllocatorPosix.cpp deleted file mode 100644 index 5546cef..0000000 --- a/JavaScriptCore/wtf/OSAllocatorPosix.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "OSAllocator.h" - -#include <errno.h> -#include <sys/mman.h> -#include <wtf/Assertions.h> -#include <wtf/UnusedParam.h> - -namespace WTF { - -void* OSAllocator::reserveUncommitted(size_t bytes, Usage usage, bool writable, bool executable) -{ - void* result = reserveAndCommit(bytes, usage, writable, executable); -#if HAVE(MADV_FREE_REUSE) - // To support the "reserve then commit" model, we have to initially decommit. - while (madvise(result, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { } -#endif - return result; -} - -void* OSAllocator::reserveAndCommit(size_t bytes, Usage usage, bool writable, bool executable) -{ - // All POSIX reservations start out logically committed. - int protection = PROT_READ; - if (writable) - protection |= PROT_WRITE; - if (executable) - protection |= PROT_EXEC; - - int flags = MAP_PRIVATE | MAP_ANON; - -#if OS(DARWIN) && !defined(BUILDING_ON_TIGER) - int fd = usage; -#else - int fd = -1; -#endif - - void* result = 0; -#if (OS(DARWIN) && CPU(X86_64)) - if (executable) { - // Cook up an address to allocate at, using the following recipe: - // 17 bits of zero, stay in userspace kids. - // 26 bits of randomness for ASLR. - // 21 bits of zero, at least stay aligned within one level of the pagetables. - // - // But! - as a temporary workaround for some plugin problems (rdar://problem/6812854), - // for now instead of 2^26 bits of ASLR lets stick with 25 bits of randomization plus - // 2^24, which should put up somewhere in the middle of userspace (in the address range - // 0x200000000000 .. 0x5fffffffffff). - intptr_t randomLocation = 0; - randomLocation = arc4random() & ((1 << 25) - 1); - randomLocation += (1 << 24); - randomLocation <<= 21; - result = reinterpret_cast<void*>(randomLocation); - } -#endif - - result = mmap(result, bytes, protection, flags, fd, 0); - if (result == MAP_FAILED) - CRASH(); - return result; -} - -void OSAllocator::commit(void* address, size_t bytes, bool, bool) -{ -#if HAVE(MADV_FREE_REUSE) - while (madvise(address, bytes, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { } -#else - // Non-MADV_FREE_REUSE reservations automatically commit on demand. - UNUSED_PARAM(address); - UNUSED_PARAM(bytes); -#endif -} - -void OSAllocator::decommit(void* address, size_t bytes) -{ -#if HAVE(MADV_FREE_REUSE) - while (madvise(address, bytes, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { } -#elif HAVE(MADV_FREE) - while (madvise(address, bytes, MADV_FREE) == -1 && errno == EAGAIN) { } -#elif HAVE(MADV_DONTNEED) - while (madvise(address, bytes, MADV_DONTNEED) == -1 && errno == EAGAIN) { } -#else - UNUSED_PARAM(address); - UNUSED_PARAM(bytes); -#endif -} - -void OSAllocator::releaseDecommitted(void* address, size_t bytes) -{ - int result = munmap(address, bytes); - if (result == -1) - CRASH(); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/OSAllocatorSymbian.cpp b/JavaScriptCore/wtf/OSAllocatorSymbian.cpp deleted file mode 100644 index e746fde..0000000 --- a/JavaScriptCore/wtf/OSAllocatorSymbian.cpp +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "OSAllocator.h" - -#include <wtf/FastMalloc.h> - -namespace WTF { - -void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool, bool) -{ - return fastMalloc(bytes); -} - -void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool, bool) -{ - return fastMalloc(bytes); -} - -void OSAllocator::commit(void*, size_t, bool, bool) -{ -} - -void OSAllocator::decommit(void*, size_t) -{ -} - -void OSAllocator::releaseDecommitted(void* address, size_t) -{ - fastFree(address); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/OSAllocatorWin.cpp b/JavaScriptCore/wtf/OSAllocatorWin.cpp deleted file mode 100644 index e7beb8a..0000000 --- a/JavaScriptCore/wtf/OSAllocatorWin.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "OSAllocator.h" - -#include "windows.h" -#include <wtf/Assertions.h> - -namespace WTF { - -static inline DWORD protection(bool writable, bool executable) -{ - return executable ? - (writable ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ) : - (writable ? PAGE_READWRITE : PAGE_READONLY); -} - -void* OSAllocator::reserveUncommitted(size_t bytes, Usage, bool writable, bool executable) -{ - void* result = VirtualAlloc(0, bytes, MEM_RESERVE, protection(writable, executable)); - if (!result) - CRASH(); - return result; -} - -void* OSAllocator::reserveAndCommit(size_t bytes, Usage, bool writable, bool executable) -{ - void* result = VirtualAlloc(0, bytes, MEM_RESERVE | MEM_COMMIT, protection(writable, executable)); - if (!result) - CRASH(); - return result; -} - -void OSAllocator::commit(void* address, size_t bytes, bool writable, bool executable) -{ - void* result = VirtualAlloc(address, bytes, MEM_COMMIT, protection(writable, executable)); - if (!result) - CRASH(); -} - -void OSAllocator::decommit(void* address, size_t bytes) -{ - bool result = VirtualFree(address, bytes, MEM_DECOMMIT); - if (!result) - CRASH(); -} - -void OSAllocator::releaseDecommitted(void* address, size_t bytes) -{ - // According to http://msdn.microsoft.com/en-us/library/aa366892(VS.85).aspx, - // dwSize must be 0 if dwFreeType is MEM_RELEASE. - bool result = VirtualFree(address, 0, MEM_RELEASE); - if (!result) - CRASH(); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/OwnArrayPtr.h b/JavaScriptCore/wtf/OwnArrayPtr.h deleted file mode 100644 index 643b90b..0000000 --- a/JavaScriptCore/wtf/OwnArrayPtr.h +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_OwnArrayPtr_h -#define WTF_OwnArrayPtr_h - -#include "Assertions.h" -#include "Noncopyable.h" -#include "NullPtr.h" -#include "OwnArrayPtrCommon.h" -#include <algorithm> - -// Remove this once we make all WebKit code compatible with stricter rules about OwnArrayPtr. -#define LOOSE_OWN_ARRAY_PTR - -namespace WTF { - -template<typename T> class PassOwnArrayPtr; -template<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*); - -template <typename T> class OwnArrayPtr : public Noncopyable { -public: - typedef T* PtrType; - - OwnArrayPtr() : m_ptr(0) { } - - // See comment in PassOwnArrayPtr.h for why this takes a const reference. - template<typename U> OwnArrayPtr(const PassOwnArrayPtr<U>& o); - - // This copy constructor is used implicitly by gcc when it generates - // transients for assigning a PassOwnArrayPtr<T> object to a stack-allocated - // OwnArrayPtr<T> object. It should never be called explicitly and gcc - // should optimize away the constructor when generating code. - OwnArrayPtr(const OwnArrayPtr<T>&); - - ~OwnArrayPtr() { deleteOwnedArrayPtr(m_ptr); } - - PtrType get() const { return m_ptr; } - - void clear(); - PassOwnArrayPtr<T> release(); - PtrType leakPtr() WARN_UNUSED_RETURN; - - T& operator*() const { ASSERT(m_ptr); return *m_ptr; } - PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } - - T& operator[](std::ptrdiff_t i) const { ASSERT(m_ptr); ASSERT(i >= 0); return m_ptr[i]; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. -#if COMPILER(WINSCW) - operator bool() const { return m_ptr; } -#else - typedef T* OwnArrayPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &OwnArrayPtr::m_ptr : 0; } -#endif - - OwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); - OwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; } - template<typename U> OwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); - - void swap(OwnArrayPtr& o) { std::swap(m_ptr, o.m_ptr); } - -#ifdef LOOSE_OWN_ARRAY_PTR - explicit OwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } - void set(PtrType); -#endif - -private: - PtrType m_ptr; -}; - -template<typename T> template<typename U> inline OwnArrayPtr<T>::OwnArrayPtr(const PassOwnArrayPtr<U>& o) - : m_ptr(o.leakPtr()) -{ -} - -template<typename T> inline void OwnArrayPtr<T>::clear() -{ - PtrType ptr = m_ptr; - m_ptr = 0; - deleteOwnedArrayPtr(ptr); -} - -template<typename T> inline PassOwnArrayPtr<T> OwnArrayPtr<T>::release() -{ - PtrType ptr = m_ptr; - m_ptr = 0; - return adoptArrayPtr(ptr); -} - -template<typename T> inline typename OwnArrayPtr<T>::PtrType OwnArrayPtr<T>::leakPtr() -{ - PtrType ptr = m_ptr; - m_ptr = 0; - return ptr; -} - -#ifdef LOOSE_OWN_ARRAY_PTR -template<typename T> inline void OwnArrayPtr<T>::set(PtrType ptr) -{ - ASSERT(!ptr || m_ptr != ptr); - PtrType oldPtr = m_ptr; - m_ptr = ptr; - deleteOwnedPtr(oldPtr); -} -#endif - -template<typename T> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& o) -{ - PtrType ptr = m_ptr; - m_ptr = o.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - deleteOwnedArrayPtr(ptr); - return *this; -} - -template<typename T> template<typename U> inline OwnArrayPtr<T>& OwnArrayPtr<T>::operator=(const PassOwnArrayPtr<U>& o) -{ - PtrType ptr = m_ptr; - m_ptr = o.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - deleteOwnedArrayPtr(ptr); - return *this; -} - -template <typename T> inline void swap(OwnArrayPtr<T>& a, OwnArrayPtr<T>& b) -{ - a.swap(b); -} - -template<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, U* b) -{ - return a.get() == b; -} - -template<typename T, typename U> inline bool operator==(T* a, const OwnArrayPtr<U>& b) -{ - return a == b.get(); -} - -template<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, U* b) -{ - return a.get() != b; -} - -template<typename T, typename U> inline bool operator!=(T* a, const OwnArrayPtr<U>& b) -{ - return a != b.get(); -} - -template <typename T> inline T* getPtr(const OwnArrayPtr<T>& p) -{ - return p.get(); -} - -} // namespace WTF - -using WTF::OwnArrayPtr; - -#endif // WTF_OwnArrayPtr_h diff --git a/JavaScriptCore/wtf/OwnArrayPtrCommon.h b/JavaScriptCore/wtf/OwnArrayPtrCommon.h deleted file mode 100644 index 0113aff..0000000 --- a/JavaScriptCore/wtf/OwnArrayPtrCommon.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_OwnArrayPtrCommon_h -#define WTF_OwnArrayPtrCommon_h - -namespace WTF { - -template<typename T> inline void deleteOwnedArrayPtr(T* ptr) -{ - typedef char known[sizeof(T) ? 1 : -1]; - if (sizeof(known)) - delete [] ptr; -} - -} // namespace WTF - -#endif // WTF_OwnArrayPtrCommon_h diff --git a/JavaScriptCore/wtf/OwnFastMallocPtr.h b/JavaScriptCore/wtf/OwnFastMallocPtr.h deleted file mode 100644 index 8b6cbf4..0000000 --- a/JavaScriptCore/wtf/OwnFastMallocPtr.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef OwnFastMallocPtr_h -#define OwnFastMallocPtr_h - -#include "FastMalloc.h" -#include "Noncopyable.h" - -namespace WTF { - - template<class T> class OwnFastMallocPtr : public Noncopyable { - public: - explicit OwnFastMallocPtr(T* ptr) : m_ptr(ptr) - { - } - - ~OwnFastMallocPtr() - { - fastFree(const_cast<void*>(static_cast<const void*>(const_cast<const T*>(m_ptr)))); - } - - T* get() const { return m_ptr; } - T* release() { T* ptr = m_ptr; m_ptr = 0; return ptr; } - - private: - T* m_ptr; - }; - -} // namespace WTF - -using WTF::OwnFastMallocPtr; - -#endif // OwnFastMallocPtr_h diff --git a/JavaScriptCore/wtf/OwnPtr.h b/JavaScriptCore/wtf/OwnPtr.h deleted file mode 100644 index cdc277c..0000000 --- a/JavaScriptCore/wtf/OwnPtr.h +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_OwnPtr_h -#define WTF_OwnPtr_h - -#include "Assertions.h" -#include "Noncopyable.h" -#include "NullPtr.h" -#include "OwnPtrCommon.h" -#include "TypeTraits.h" -#include <algorithm> -#include <memory> - -// Remove this once we make all WebKit code compatible with stricter rules about OwnPtr. -#define LOOSE_OWN_PTR - -namespace WTF { - - // Unlike most of our smart pointers, OwnPtr can take either the pointer type or the pointed-to type. - - template<typename T> class PassOwnPtr; - template<typename T> PassOwnPtr<T> adoptPtr(T*); - - template<typename T> class OwnPtr : public Noncopyable { - public: - typedef typename RemovePointer<T>::Type ValueType; - typedef ValueType* PtrType; - - OwnPtr() : m_ptr(0) { } - - // See comment in PassOwnPtr.h for why this takes a const reference. - template<typename U> OwnPtr(const PassOwnPtr<U>& o); - - // This copy constructor is used implicitly by gcc when it generates - // transients for assigning a PassOwnPtr<T> object to a stack-allocated - // OwnPtr<T> object. It should never be called explicitly and gcc - // should optimize away the constructor when generating code. - OwnPtr(const OwnPtr<ValueType>&); - - ~OwnPtr() { deleteOwnedPtr(m_ptr); } - - PtrType get() const { return m_ptr; } - - void clear(); - PassOwnPtr<T> release(); - PtrType leakPtr() WARN_UNUSED_RETURN; - - ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } - PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef PtrType OwnPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &OwnPtr::m_ptr : 0; } - - OwnPtr& operator=(const PassOwnPtr<T>&); - OwnPtr& operator=(std::nullptr_t) { clear(); return *this; } - template<typename U> OwnPtr& operator=(const PassOwnPtr<U>&); - - void swap(OwnPtr& o) { std::swap(m_ptr, o.m_ptr); } - -#ifdef LOOSE_OWN_PTR - explicit OwnPtr(PtrType ptr) : m_ptr(ptr) { } - void set(PtrType); -#endif - - private: - PtrType m_ptr; - }; - - template<typename T> template<typename U> inline OwnPtr<T>::OwnPtr(const PassOwnPtr<U>& o) - : m_ptr(o.leakPtr()) - { - } - - template<typename T> inline void OwnPtr<T>::clear() - { - PtrType ptr = m_ptr; - m_ptr = 0; - deleteOwnedPtr(ptr); - } - - template<typename T> inline PassOwnPtr<T> OwnPtr<T>::release() - { - PtrType ptr = m_ptr; - m_ptr = 0; - return adoptPtr(ptr); - } - - template<typename T> inline typename OwnPtr<T>::PtrType OwnPtr<T>::leakPtr() - { - PtrType ptr = m_ptr; - m_ptr = 0; - return ptr; - } - -#ifdef LOOSE_OWN_PTR - template<typename T> inline void OwnPtr<T>::set(PtrType ptr) - { - ASSERT(!ptr || m_ptr != ptr); - PtrType oldPtr = m_ptr; - m_ptr = ptr; - deleteOwnedPtr(oldPtr); - } -#endif - - template<typename T> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<T>& o) - { - PtrType ptr = m_ptr; - m_ptr = o.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - deleteOwnedPtr(ptr); - return *this; - } - - template<typename T> template<typename U> inline OwnPtr<T>& OwnPtr<T>::operator=(const PassOwnPtr<U>& o) - { - PtrType ptr = m_ptr; - m_ptr = o.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - deleteOwnedPtr(ptr); - return *this; - } - - template<typename T> inline void swap(OwnPtr<T>& a, OwnPtr<T>& b) - { - a.swap(b); - } - - template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, U* b) - { - return a.get() == b; - } - - template<typename T, typename U> inline bool operator==(T* a, const OwnPtr<U>& b) - { - return a == b.get(); - } - - template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, U* b) - { - return a.get() != b; - } - - template<typename T, typename U> inline bool operator!=(T* a, const OwnPtr<U>& b) - { - return a != b.get(); - } - - template<typename T> inline typename OwnPtr<T>::PtrType getPtr(const OwnPtr<T>& p) - { - return p.get(); - } - -} // namespace WTF - -using WTF::OwnPtr; - -#endif // WTF_OwnPtr_h diff --git a/JavaScriptCore/wtf/OwnPtrCommon.h b/JavaScriptCore/wtf/OwnPtrCommon.h deleted file mode 100644 index 19256ea..0000000 --- a/JavaScriptCore/wtf/OwnPtrCommon.h +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * Copyright (C) 2009 Torch Mobile, Inc. - * Copyright (C) 2010 Company 100 Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_OwnPtrCommon_h -#define WTF_OwnPtrCommon_h - -#if PLATFORM(WIN) -typedef struct HBITMAP__* HBITMAP; -typedef struct HBRUSH__* HBRUSH; -typedef struct HDC__* HDC; -typedef struct HFONT__* HFONT; -typedef struct HPALETTE__* HPALETTE; -typedef struct HPEN__* HPEN; -typedef struct HRGN__* HRGN; -#endif - -#if PLATFORM(BREWMP) -// Forward delcarations at this point avoid the need to include BREW includes -// in WTF headers. -typedef struct _ISocket ISocket; -typedef struct _IFileMgr IFileMgr; -typedef struct _IFile IFile; -typedef struct IBitmap IBitmap; -typedef struct ISSL ISSL; -typedef struct IMemGroup IMemGroup; -typedef struct IMemSpace IMemSpace; -#endif - -namespace WTF { - - template <typename T> inline void deleteOwnedPtr(T* ptr) - { - typedef char known[sizeof(T) ? 1 : -1]; - if (sizeof(known)) - delete ptr; - } - -#if PLATFORM(WIN) - void deleteOwnedPtr(HBITMAP); - void deleteOwnedPtr(HBRUSH); - void deleteOwnedPtr(HDC); - void deleteOwnedPtr(HFONT); - void deleteOwnedPtr(HPALETTE); - void deleteOwnedPtr(HPEN); - void deleteOwnedPtr(HRGN); -#endif - -#if PLATFORM(BREWMP) - void deleteOwnedPtr(IFileMgr*); - void deleteOwnedPtr(IFile*); - void deleteOwnedPtr(IBitmap*); - void deleteOwnedPtr(ISSL*); - void deleteOwnedPtr(ISocket*); - void deleteOwnedPtr(IMemGroup*); - void deleteOwnedPtr(IMemSpace*); -#endif - -} // namespace WTF - -#endif // WTF_OwnPtrCommon_h diff --git a/JavaScriptCore/wtf/PageAllocation.h b/JavaScriptCore/wtf/PageAllocation.h deleted file mode 100644 index 232cd20..0000000 --- a/JavaScriptCore/wtf/PageAllocation.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PageAllocation_h -#define PageAllocation_h - -#include <wtf/Assertions.h> -#include <wtf/OSAllocator.h> -#include <wtf/PageBlock.h> -#include <wtf/UnusedParam.h> -#include <wtf/VMTags.h> -#include <algorithm> - -#if OS(DARWIN) -#include <mach/mach_init.h> -#include <mach/vm_map.h> -#endif - -#if OS(HAIKU) -#include <OS.h> -#endif - -#if OS(WINDOWS) -#include <malloc.h> -#include <windows.h> -#endif - -#if OS(SYMBIAN) -#include <e32hal.h> -#include <e32std.h> -#endif - -#if HAVE(ERRNO_H) -#include <errno.h> -#endif - -#if HAVE(MMAP) -#include <sys/mman.h> -#include <unistd.h> -#endif - -namespace WTF { - -/* - PageAllocation - - The PageAllocation class provides a cross-platform memory allocation interface - with similar capabilities to posix mmap/munmap. Memory is allocated by calling - PageAllocation::allocate, and deallocated by calling deallocate on the - PageAllocation object. The PageAllocation holds the allocation's base pointer - and size. - - The allocate method is passed the size required (which must be a multiple of - the system page size, which can be accessed using PageAllocation::pageSize). - Callers may also optinally provide a flag indicating the usage (for use by - system memory usage tracking tools, where implemented), and boolean values - specifying the required protection (defaulting to writable, non-executable). -*/ - -class PageAllocation : private PageBlock { -public: - PageAllocation() - { - } - - using PageBlock::operator bool; - using PageBlock::size; - using PageBlock::base; - - static PageAllocation allocate(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false) - { - ASSERT(isPageAligned(size)); - return PageAllocation(OSAllocator::reserveAndCommit(size, usage, writable, executable), size); - } - - void deallocate() - { - // Clear base & size before calling release; if this is *inside* allocation - // then we won't be able to clear then after deallocating the memory. - PageAllocation tmp; - std::swap(tmp, *this); - - ASSERT(tmp); - ASSERT(!*this); - - OSAllocator::decommitAndRelease(tmp.base(), tmp.size()); - } - -private: - PageAllocation(void* base, size_t size) - : PageBlock(base, size) - { - } -}; - -} // namespace WTF - -using WTF::PageAllocation; - -#endif // PageAllocation_h diff --git a/JavaScriptCore/wtf/PageAllocationAligned.cpp b/JavaScriptCore/wtf/PageAllocationAligned.cpp deleted file mode 100644 index 6f54710..0000000 --- a/JavaScriptCore/wtf/PageAllocationAligned.cpp +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PageAllocationAligned.h" - -namespace WTF { - -PageAllocationAligned PageAllocationAligned::allocate(size_t size, size_t alignment, OSAllocator::Usage usage, bool writable, bool executable) -{ - ASSERT(isPageAligned(size)); - ASSERT(isPageAligned(alignment)); - ASSERT(isPowerOfTwo(alignment)); - ASSERT(size >= alignment); - size_t alignmentMask = alignment - 1; - -#if OS(DARWIN) - int flags = VM_FLAGS_ANYWHERE; - if (usage != OSAllocator::UnknownUsage) - flags |= usage; - int protection = PROT_READ; - if (writable) - protection |= PROT_WRITE; - if (executable) - protection |= PROT_EXEC; - - vm_address_t address = 0; - vm_map(current_task(), &address, size, alignmentMask, flags, MEMORY_OBJECT_NULL, 0, FALSE, protection, PROT_READ | PROT_WRITE | PROT_EXEC, VM_INHERIT_DEFAULT); - return PageAllocationAligned(reinterpret_cast<void*>(address), size); -#else - size_t alignmentDelta = alignment - pageSize(); - - // Resererve with suffcient additional VM to correctly align. - size_t reservationSize = size + alignmentDelta; - void* reservationBase = OSAllocator::reserveUncommitted(reservationSize, usage, writable, executable); - - // Select an aligned region within the reservation and commit. - void* alignedBase = reinterpret_cast<uintptr_t>(reservationBase) & alignmentMask - ? reinterpret_cast<void*>((reinterpret_cast<uintptr_t>(reservationBase) & ~alignmentMask) + alignment) - : reservationBase; - OSAllocator::commit(alignedBase, size, writable, executable); - - return PageAllocationAligned(alignedBase, size, reservationBase, reservationSize); -#endif -} - -void PageAllocationAligned::deallocate() -{ - // Clear base & size before calling release; if this is *inside* allocation - // then we won't be able to clear then after deallocating the memory. - PageAllocationAligned tmp; - std::swap(tmp, *this); - - ASSERT(tmp); - ASSERT(!*this); - -#if OS(DARWIN) - vm_deallocate(current_task(), reinterpret_cast<vm_address_t>(tmp.base()), tmp.size()); -#else - ASSERT(tmp.m_reservation.contains(tmp.base(), tmp.size())); - OSAllocator::decommitAndRelease(tmp.m_reservation.base(), tmp.m_reservation.size(), tmp.base(), tmp.size()); -#endif -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/PageAllocationAligned.h b/JavaScriptCore/wtf/PageAllocationAligned.h deleted file mode 100644 index 282c9e3..0000000 --- a/JavaScriptCore/wtf/PageAllocationAligned.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PageAllocationAligned_h -#define PageAllocationAligned_h - -#include <wtf/OSAllocator.h> -#include <wtf/PageReservation.h> - -namespace WTF { - -class PageAllocationAligned : private PageBlock { -public: - PageAllocationAligned() - { - } - - using PageBlock::operator bool; - using PageBlock::size; - using PageBlock::base; - - static PageAllocationAligned allocate(size_t size, size_t alignment, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false); - - void deallocate(); - -private: -#if OS(DARWIN) - PageAllocationAligned(void* base, size_t size) - : PageBlock(base, size) - { - } -#else - PageAllocationAligned(void* base, size_t size, void* reservationBase, size_t reservationSize) - : PageBlock(base, size) - , m_reservation(reservationBase, reservationSize) - { - } - - PageBlock m_reservation; -#endif -}; - - -} // namespace WTF - -using WTF::PageAllocationAligned; - -#endif // PageAllocationAligned_h diff --git a/JavaScriptCore/wtf/PageBlock.cpp b/JavaScriptCore/wtf/PageBlock.cpp deleted file mode 100644 index 6fb68e5..0000000 --- a/JavaScriptCore/wtf/PageBlock.cpp +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PageBlock.h" - -#if OS(UNIX) && !OS(SYMBIAN) -#include <unistd.h> -#endif - -#if OS(WINDOWS) -#include <malloc.h> -#include <windows.h> -#endif - -#if OS(SYMBIAN) -#include <e32hal.h> -#include <e32std.h> -#endif - -namespace WTF { - -static size_t s_pageSize; - -#if OS(UNIX) && !OS(SYMBIAN) - -inline size_t systemPageSize() -{ - return getpagesize(); -} - -#elif OS(WINDOWS) - -inline size_t systemPageSize() -{ - static size_t size = 0; - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - size = system_info.dwPageSize; - return size; -} - -#elif OS(SYMBIAN) - -inline size_t systemPageSize() -{ - static TInt page_size = 0; - UserHal::PageSizeInBytes(page_size); - return page_size; -} - -#endif - -size_t pageSize() -{ - if (!s_pageSize) - s_pageSize = systemPageSize(); - ASSERT(isPowerOfTwo(s_pageSize)); - return s_pageSize; -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/PageBlock.h b/JavaScriptCore/wtf/PageBlock.h deleted file mode 100644 index 07452b3..0000000 --- a/JavaScriptCore/wtf/PageBlock.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, - * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF - * THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PageBlock_h -#define PageBlock_h - -namespace WTF { - -size_t pageSize(); -inline bool isPageAligned(void* address) { return !(reinterpret_cast<intptr_t>(address) & (pageSize() - 1)); } -inline bool isPageAligned(size_t size) { return !(size & (pageSize() - 1)); } -inline bool isPowerOfTwo(size_t size) { return !(size & (size - 1)); } - -class PageBlock { -public: - PageBlock(); - PageBlock(const PageBlock&); - PageBlock(void*, size_t); - - void* base() const { return m_base; } - size_t size() const { return m_size; } - - operator bool() const { return !!m_base; } - - bool contains(void* containedBase, size_t containedSize) - { - return containedBase >= m_base - && (static_cast<char*>(containedBase) + containedSize) <= (static_cast<char*>(m_base) + m_size); - } - -private: - void* m_base; - size_t m_size; -}; - -inline PageBlock::PageBlock() - : m_base(0) - , m_size(0) -{ -} - -inline PageBlock::PageBlock(const PageBlock& other) - : m_base(other.m_base) - , m_size(other.m_size) -{ -} - -inline PageBlock::PageBlock(void* base, size_t size) - : m_base(base) - , m_size(size) -{ -} - -} // namespace WTF - -using WTF::pageSize; -using WTF::isPageAligned; -using WTF::isPageAligned; -using WTF::isPowerOfTwo; - -#endif // PageBlock_h diff --git a/JavaScriptCore/wtf/PageReservation.h b/JavaScriptCore/wtf/PageReservation.h deleted file mode 100644 index 8c097a4..0000000 --- a/JavaScriptCore/wtf/PageReservation.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PageReservation_h -#define PageReservation_h - -#include <wtf/PageAllocation.h> - -namespace WTF { - -/* - PageReservation - - Like PageAllocation, the PageReservation class provides a cross-platform memory - allocation interface, but with a set of capabilities more similar to that of - VirtualAlloc than posix mmap. PageReservation can be used to allocate virtual - memory without committing physical memory pages using PageReservation::reserve. - Following a call to reserve all memory in the region is in a decommited state, - in which the memory should not be used (accessing the memory may cause a fault). - - Before using memory it must be committed by calling commit, which is passed start - and size values (both of which require system page size granularity). One the - committed memory is no longer needed 'decommit' may be called to return the - memory to its devommitted state. Commit should only be called on memory that is - currently decommitted, and decommit should only be called on memory regions that - are currently committed. All memory should be decommited before the reservation - is deallocated. Values in memory may not be retained accross a pair of calls if - the region of memory is decommitted and then committed again. - - Memory protection should not be changed on decommitted memory, and if protection - is changed on memory while it is committed it should be returned to the orignal - protection before decommit is called. -*/ - -class PageReservation : private PageBlock { -public: - PageReservation() - : m_writable(false) - , m_executable(false) -#ifndef NDEBUG - , m_committed(0) -#endif - { - } - - using PageBlock::operator bool; - using PageBlock::base; - using PageBlock::size; - - void commit(void* start, size_t size) - { - ASSERT(*this); - ASSERT(isPageAligned(start)); - ASSERT(isPageAligned(size)); - ASSERT(contains(start, size)); - -#ifndef NDEBUG - m_committed += size; -#endif - OSAllocator::commit(start, size, m_writable, m_executable); - } - - void decommit(void* start, size_t size) - { - ASSERT(*this); - ASSERT(isPageAligned(start)); - ASSERT(isPageAligned(size)); - ASSERT(contains(start, size)); - -#ifndef NDEBUG - m_committed -= size; -#endif - OSAllocator::decommit(start, size); - } - - static PageReservation reserve(size_t size, OSAllocator::Usage usage = OSAllocator::UnknownUsage, bool writable = true, bool executable = false) - { - ASSERT(isPageAligned(size)); - return PageReservation(OSAllocator::reserveUncommitted(size, usage, writable, executable), size, writable, executable); - } - - void deallocate() - { - ASSERT(!m_committed); - - // Clear base & size before calling release; if this is *inside* allocation - // then we won't be able to clear then after deallocating the memory. - PageReservation tmp; - std::swap(tmp, *this); - - ASSERT(tmp); - ASSERT(!*this); - - OSAllocator::releaseDecommitted(tmp.base(), tmp.size()); - } - -private: - PageReservation(void* base, size_t size, bool writable, bool executable) - : PageBlock(base, size) - , m_writable(writable) - , m_executable(executable) -#ifndef NDEBUG - , m_committed(0) -#endif - { - } - - bool m_writable; - bool m_executable; -#ifndef NDEBUG - size_t m_committed; -#endif -}; - -} - -using WTF::PageReservation; - -#endif // PageReservation_h diff --git a/JavaScriptCore/wtf/PassOwnArrayPtr.h b/JavaScriptCore/wtf/PassOwnArrayPtr.h deleted file mode 100644 index 6a55491..0000000 --- a/JavaScriptCore/wtf/PassOwnArrayPtr.h +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_PassOwnArrayPtr_h -#define WTF_PassOwnArrayPtr_h - -#include "Assertions.h" -#include "NullPtr.h" -#include "OwnArrayPtrCommon.h" -#include "TypeTraits.h" - -// Remove this once we make all WebKit code compatible with stricter rules about PassOwnArrayPtr. -#define LOOSE_PASS_OWN_ARRAY_PTR - -namespace WTF { - -template<typename T> class OwnArrayPtr; -template<typename T> class PassOwnArrayPtr; -template<typename T> PassOwnArrayPtr<T> adoptArrayPtr(T*); - -template<typename T> class PassOwnArrayPtr { -public: - typedef T* PtrType; - - PassOwnArrayPtr() : m_ptr(0) { } - - // It somewhat breaks the type system to allow transfer of ownership out of - // a const PassOwnArrayPtr. However, it makes it much easier to work with PassOwnArrayPtr - // temporaries, and we don't have a need to use real const PassOwnArrayPtrs anyway. - PassOwnArrayPtr(const PassOwnArrayPtr& o) : m_ptr(o.leakPtr()) { } - template<typename U> PassOwnArrayPtr(const PassOwnArrayPtr<U>& o) : m_ptr(o.leakPtr()) { } - - ~PassOwnArrayPtr() { deleteOwnedArrayPtr(m_ptr); } - - PtrType get() const { return m_ptr; } - - void clear(); - PtrType leakPtr() const WARN_UNUSED_RETURN; - - T& operator*() const { ASSERT(m_ptr); return *m_ptr; } - PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. -#if COMPILER(WINSCW) - operator bool() const { return m_ptr; } -#else - typedef PtrType PassOwnArrayPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnArrayPtr::m_ptr : 0; } -#endif - - PassOwnArrayPtr& operator=(const PassOwnArrayPtr<T>&); - PassOwnArrayPtr& operator=(std::nullptr_t) { clear(); return *this; } - template<typename U> PassOwnArrayPtr& operator=(const PassOwnArrayPtr<U>&); - - template<typename U> friend PassOwnArrayPtr<U> adoptArrayPtr(U*); - -#ifdef LOOSE_PASS_OWN_ARRAY_PTR - PassOwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } - PassOwnArrayPtr& operator=(PtrType); -#endif - -private: -#ifndef LOOSE_PASS_OWN_ARRAY_PTR - explicit PassOwnArrayPtr(PtrType ptr) : m_ptr(ptr) { } -#endif - - mutable PtrType m_ptr; -}; - -template<typename T> inline void PassOwnArrayPtr<T>::clear() -{ - PtrType ptr = m_ptr; - m_ptr = 0; - deleteOwnedArrayPtr(ptr); -} - -template<typename T> inline typename PassOwnArrayPtr<T>::PtrType PassOwnArrayPtr<T>::leakPtr() const -{ - PtrType ptr = m_ptr; - m_ptr = 0; - return ptr; -} - -#ifdef LOOSE_PASS_OWN_ARRAY_PTR -template<typename T> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(PtrType optr) -{ - PtrType ptr = m_ptr; - m_ptr = optr; - ASSERT(!ptr || m_ptr != ptr); - if (ptr) - deleteOwnedArrayPtr(ptr); - return *this; -} -#endif - -template<typename T> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(const PassOwnArrayPtr<T>& optr) -{ - PtrType ptr = m_ptr; - m_ptr = optr.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - if (ptr) - deleteOwnedArrayPtr(ptr); - return *this; -} - -template<typename T> template<typename U> inline PassOwnArrayPtr<T>& PassOwnArrayPtr<T>::operator=(const PassOwnArrayPtr<U>& optr) -{ - PtrType ptr = m_ptr; - m_ptr = optr.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - if (ptr) - deleteOwnedArrayPtr(ptr); - return *this; -} - -template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) -{ - return a.get() == b.get(); -} - -template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) -{ - return a.get() == b.get(); -} - -template<typename T, typename U> inline bool operator==(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) -{ - return a.get() == b.get(); -} - -template<typename T, typename U> inline bool operator==(const PassOwnArrayPtr<T>& a, U* b) -{ - return a.get() == b; -} - -template<typename T, typename U> inline bool operator==(T* a, const PassOwnArrayPtr<U>& b) -{ - return a == b.get(); -} - -template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) -{ - return a.get() != b.get(); -} - -template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, const OwnArrayPtr<U>& b) -{ - return a.get() != b.get(); -} - -template<typename T, typename U> inline bool operator!=(const OwnArrayPtr<T>& a, const PassOwnArrayPtr<U>& b) -{ - return a.get() != b.get(); -} - -template<typename T, typename U> inline bool operator!=(const PassOwnArrayPtr<T>& a, U* b) -{ - return a.get() != b; -} - -template<typename T, typename U> inline bool operator!=(T* a, const PassOwnArrayPtr<U>& b) -{ - return a != b.get(); -} - -template<typename T> inline PassOwnArrayPtr<T> adoptArrayPtr(T* ptr) -{ - return PassOwnArrayPtr<T>(ptr); -} - -template<typename T, typename U> inline PassOwnArrayPtr<T> static_pointer_cast(const PassOwnArrayPtr<U>& p) -{ - return adoptArrayPtr(static_cast<T*>(p.leakPtr())); -} - -template<typename T, typename U> inline PassOwnArrayPtr<T> const_pointer_cast(const PassOwnArrayPtr<U>& p) -{ - return adoptArrayPtr(const_cast<T*>(p.leakPtr())); -} - -template<typename T> inline T* getPtr(const PassOwnArrayPtr<T>& p) -{ - return p.get(); -} - -} // namespace WTF - -using WTF::PassOwnArrayPtr; -using WTF::adoptArrayPtr; -using WTF::const_pointer_cast; -using WTF::static_pointer_cast; - -#endif // WTF_PassOwnArrayPtr_h diff --git a/JavaScriptCore/wtf/PassOwnPtr.h b/JavaScriptCore/wtf/PassOwnPtr.h deleted file mode 100644 index 60453fc..0000000 --- a/JavaScriptCore/wtf/PassOwnPtr.h +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_PassOwnPtr_h -#define WTF_PassOwnPtr_h - -#include "Assertions.h" -#include "NullPtr.h" -#include "OwnPtrCommon.h" -#include "TypeTraits.h" - -// Remove this once we make all WebKit code compatible with stricter rules about PassOwnPtr. -#define LOOSE_PASS_OWN_PTR - -namespace WTF { - - // Unlike most of our smart pointers, PassOwnPtr can take either the pointer type or the pointed-to type. - - template<typename T> class OwnPtr; - template<typename T> class PassOwnPtr; - template<typename T> PassOwnPtr<T> adoptPtr(T*); - - template<typename T> class PassOwnPtr { - public: - typedef typename RemovePointer<T>::Type ValueType; - typedef ValueType* PtrType; - - PassOwnPtr() : m_ptr(0) { } - - // It somewhat breaks the type system to allow transfer of ownership out of - // a const PassOwnPtr. However, it makes it much easier to work with PassOwnPtr - // temporaries, and we don't have a need to use real const PassOwnPtrs anyway. - PassOwnPtr(const PassOwnPtr& o) : m_ptr(o.leakPtr()) { } - template<typename U> PassOwnPtr(const PassOwnPtr<U>& o) : m_ptr(o.leakPtr()) { } - - ~PassOwnPtr() { deleteOwnedPtr(m_ptr); } - - PtrType get() const { return m_ptr; } - - void clear(); - PtrType leakPtr() const WARN_UNUSED_RETURN; - - ValueType& operator*() const { ASSERT(m_ptr); return *m_ptr; } - PtrType operator->() const { ASSERT(m_ptr); return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef PtrType PassOwnPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &PassOwnPtr::m_ptr : 0; } - - PassOwnPtr& operator=(const PassOwnPtr<T>&); - PassOwnPtr& operator=(std::nullptr_t) { clear(); return *this; } - template<typename U> PassOwnPtr& operator=(const PassOwnPtr<U>&); - - template<typename U> friend PassOwnPtr<U> adoptPtr(U*); - -#ifdef LOOSE_PASS_OWN_PTR - PassOwnPtr(PtrType ptr) : m_ptr(ptr) { } - PassOwnPtr& operator=(PtrType); -#endif - - private: -#ifndef LOOSE_PASS_OWN_PTR - explicit PassOwnPtr(PtrType ptr) : m_ptr(ptr) { } -#endif - - mutable PtrType m_ptr; - }; - - template<typename T> inline void PassOwnPtr<T>::clear() - { - PtrType ptr = m_ptr; - m_ptr = 0; - deleteOwnedPtr(ptr); - } - - template<typename T> inline typename PassOwnPtr<T>::PtrType PassOwnPtr<T>::leakPtr() const - { - PtrType ptr = m_ptr; - m_ptr = 0; - return ptr; - } - -#ifdef LOOSE_PASS_OWN_PTR - template<typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(PtrType optr) - { - PtrType ptr = m_ptr; - m_ptr = optr; - ASSERT(!ptr || m_ptr != ptr); - if (ptr) - deleteOwnedPtr(ptr); - return *this; - } -#endif - - template<typename T> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<T>& optr) - { - PtrType ptr = m_ptr; - m_ptr = optr.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - if (ptr) - deleteOwnedPtr(ptr); - return *this; - } - - template<typename T> template<typename U> inline PassOwnPtr<T>& PassOwnPtr<T>::operator=(const PassOwnPtr<U>& optr) - { - PtrType ptr = m_ptr; - m_ptr = optr.leakPtr(); - ASSERT(!ptr || m_ptr != ptr); - if (ptr) - deleteOwnedPtr(ptr); - return *this; - } - - template<typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, const OwnPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const OwnPtr<T>& a, const PassOwnPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const PassOwnPtr<T>& a, U* b) - { - return a.get() == b; - } - - template<typename T, typename U> inline bool operator==(T* a, const PassOwnPtr<U>& b) - { - return a == b.get(); - } - - template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const PassOwnPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, const OwnPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const OwnPtr<T>& a, const PassOwnPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const PassOwnPtr<T>& a, U* b) - { - return a.get() != b; - } - - template<typename T, typename U> inline bool operator!=(T* a, const PassOwnPtr<U>& b) - { - return a != b.get(); - } - - template<typename T> inline PassOwnPtr<T> adoptPtr(T* ptr) - { - return PassOwnPtr<T>(ptr); - } - - template<typename T, typename U> inline PassOwnPtr<T> static_pointer_cast(const PassOwnPtr<U>& p) - { - return adoptPtr(static_cast<T*>(p.leakPtr())); - } - - template<typename T, typename U> inline PassOwnPtr<T> const_pointer_cast(const PassOwnPtr<U>& p) - { - return adoptPtr(const_cast<T*>(p.leakPtr())); - } - - template<typename T> inline T* getPtr(const PassOwnPtr<T>& p) - { - return p.get(); - } - -} // namespace WTF - -using WTF::PassOwnPtr; -using WTF::adoptPtr; -using WTF::const_pointer_cast; -using WTF::static_pointer_cast; - -#endif // WTF_PassOwnPtr_h diff --git a/JavaScriptCore/wtf/PassRefPtr.h b/JavaScriptCore/wtf/PassRefPtr.h deleted file mode 100644 index b179cef..0000000 --- a/JavaScriptCore/wtf/PassRefPtr.h +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_PassRefPtr_h -#define WTF_PassRefPtr_h - -#include "AlwaysInline.h" -#include "NullPtr.h" - -namespace WTF { - - template<typename T> class RefPtr; - template<typename T> class PassRefPtr; - template<typename T> PassRefPtr<T> adoptRef(T*); - - inline void adopted(const void*) { } - -#if !COMPILER(WINSCW) -#if !PLATFORM(QT) - #define REF_DEREF_INLINE ALWAYS_INLINE -#else - // Using ALWAYS_INLINE broke the Qt build. This may be a GCC bug. - // See https://bugs.webkit.org/show_bug.cgi?id=37253 for details. - #define REF_DEREF_INLINE inline -#endif -#else - // No inlining for WINSCW compiler to prevent the compiler agressively resolving - // T::ref() and T::deref(), which will fail compiling when PassRefPtr<T> is used as - // a class member or function arguments before T is defined. - #define REF_DEREF_INLINE -#endif - - template<typename T> REF_DEREF_INLINE void refIfNotNull(T* ptr) - { - if (LIKELY(ptr != 0)) - ptr->ref(); - } - - template<typename T> REF_DEREF_INLINE void derefIfNotNull(T* ptr) - { - if (LIKELY(ptr != 0)) - ptr->deref(); - } - - #undef REF_DEREF_INLINE - - template<typename T> class PassRefPtr { - public: - PassRefPtr() : m_ptr(0) { } - PassRefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } - // It somewhat breaks the type system to allow transfer of ownership out of - // a const PassRefPtr. However, it makes it much easier to work with PassRefPtr - // temporaries, and we don't have a need to use real const PassRefPtrs anyway. - PassRefPtr(const PassRefPtr& o) : m_ptr(o.leakRef()) { } - template<typename U> PassRefPtr(const PassRefPtr<U>& o) : m_ptr(o.leakRef()) { } - - ALWAYS_INLINE ~PassRefPtr() { derefIfNotNull(m_ptr); } - - template<typename U> PassRefPtr(const RefPtr<U>&); - - T* get() const { return m_ptr; } - - void clear(); - T* leakRef() const WARN_UNUSED_RETURN; - - T& operator*() const { return *m_ptr; } - T* operator->() const { return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef T* (PassRefPtr::*UnspecifiedBoolType); - operator UnspecifiedBoolType() const { return m_ptr ? &PassRefPtr::m_ptr : 0; } - - PassRefPtr& operator=(T*); - PassRefPtr& operator=(const PassRefPtr&); - PassRefPtr& operator=(std::nullptr_t) { clear(); return *this; } - template<typename U> PassRefPtr& operator=(const PassRefPtr<U>&); - template<typename U> PassRefPtr& operator=(const RefPtr<U>&); - - friend PassRefPtr adoptRef<T>(T*); - - // FIXME: Remove releaseRef once we change all callers to call leakRef instead. - T* releaseRef() const WARN_UNUSED_RETURN { return leakRef(); } - - private: - // adopting constructor - PassRefPtr(T* ptr, bool) : m_ptr(ptr) { } - - mutable T* m_ptr; - }; - - // NonNullPassRefPtr: Optimized for passing non-null pointers. A NonNullPassRefPtr - // begins life non-null, and can only become null through a call to leakRef() - // or clear(). - - // FIXME: NonNullPassRefPtr could just inherit from PassRefPtr. However, - // if we use inheritance, GCC's optimizer fails to realize that destruction - // of a released NonNullPassRefPtr is a no-op. So, for now, just copy the - // most important code from PassRefPtr. - template<typename T> class NonNullPassRefPtr { - public: - NonNullPassRefPtr(T* ptr) - : m_ptr(ptr) - { - ASSERT(m_ptr); - m_ptr->ref(); - } - - template<typename U> NonNullPassRefPtr(const RefPtr<U>& o) - : m_ptr(o.get()) - { - ASSERT(m_ptr); - m_ptr->ref(); - } - - NonNullPassRefPtr(const NonNullPassRefPtr& o) - : m_ptr(o.leakRef()) - { - ASSERT(m_ptr); - } - - template<typename U> NonNullPassRefPtr(const NonNullPassRefPtr<U>& o) - : m_ptr(o.leakRef()) - { - ASSERT(m_ptr); - } - - template<typename U> NonNullPassRefPtr(const PassRefPtr<U>& o) - : m_ptr(o.leakRef()) - { - ASSERT(m_ptr); - } - - ALWAYS_INLINE ~NonNullPassRefPtr() { derefIfNotNull(m_ptr); } - - T* get() const { return m_ptr; } - - void clear(); - T* leakRef() const WARN_UNUSED_RETURN { T* tmp = m_ptr; m_ptr = 0; return tmp; } - - T& operator*() const { return *m_ptr; } - T* operator->() const { return m_ptr; } - - // FIXME: Remove releaseRef once we change all callers to call leakRef instead. - T* releaseRef() const WARN_UNUSED_RETURN { return leakRef(); } - - private: - mutable T* m_ptr; - }; - - template<typename T> template<typename U> inline PassRefPtr<T>::PassRefPtr(const RefPtr<U>& o) - : m_ptr(o.get()) - { - T* ptr = m_ptr; - refIfNotNull(ptr); - } - - template<typename T> inline void PassRefPtr<T>::clear() - { - T* ptr = m_ptr; - m_ptr = 0; - derefIfNotNull(ptr); - } - - template<typename T> inline T* PassRefPtr<T>::leakRef() const - { - T* ptr = m_ptr; - m_ptr = 0; - return ptr; - } - - template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const RefPtr<U>& o) - { - T* optr = o.get(); - refIfNotNull(optr); - T* ptr = m_ptr; - m_ptr = optr; - derefIfNotNull(ptr); - return *this; - } - - template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(T* optr) - { - refIfNotNull(optr); - T* ptr = m_ptr; - m_ptr = optr; - derefIfNotNull(ptr); - return *this; - } - - template<typename T> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<T>& ref) - { - T* ptr = m_ptr; - m_ptr = ref.leakRef(); - derefIfNotNull(ptr); - return *this; - } - - template<typename T> template<typename U> inline PassRefPtr<T>& PassRefPtr<T>::operator=(const PassRefPtr<U>& ref) - { - T* ptr = m_ptr; - m_ptr = ref.leakRef(); - derefIfNotNull(ptr); - return *this; - } - - template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const PassRefPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, const RefPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const PassRefPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const PassRefPtr<T>& a, U* b) - { - return a.get() == b; - } - - template<typename T, typename U> inline bool operator==(T* a, const PassRefPtr<U>& b) - { - return a == b.get(); - } - - template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const PassRefPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, const RefPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const PassRefPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const PassRefPtr<T>& a, U* b) - { - return a.get() != b; - } - - template<typename T, typename U> inline bool operator!=(T* a, const PassRefPtr<U>& b) - { - return a != b.get(); - } - - template<typename T> inline PassRefPtr<T> adoptRef(T* p) - { - adopted(p); - return PassRefPtr<T>(p, true); - } - - template<typename T, typename U> inline PassRefPtr<T> static_pointer_cast(const PassRefPtr<U>& p) - { - return adoptRef(static_cast<T*>(p.leakRef())); - } - - template<typename T, typename U> inline PassRefPtr<T> const_pointer_cast(const PassRefPtr<U>& p) - { - return adoptRef(const_cast<T*>(p.leakRef())); - } - - template<typename T> inline T* getPtr(const PassRefPtr<T>& p) - { - return p.get(); - } - - template<typename T> inline void NonNullPassRefPtr<T>::clear() - { - T* ptr = m_ptr; - m_ptr = 0; - derefIfNotNull(ptr); - } - -} // namespace WTF - -using WTF::PassRefPtr; -using WTF::NonNullPassRefPtr; -using WTF::adoptRef; -using WTF::static_pointer_cast; -using WTF::const_pointer_cast; - -#endif // WTF_PassRefPtr_h diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h deleted file mode 100644 index 4143996..0000000 --- a/JavaScriptCore/wtf/Platform.h +++ /dev/null @@ -1,1142 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * Copyright (C) Research In Motion Limited 2010. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_Platform_h -#define WTF_Platform_h - -/* ==== PLATFORM handles OS, operating environment, graphics API, and - CPU. This macro will be phased out in favor of platform adaptation - macros, policy decision macros, and top-level port definitions. ==== */ -#define PLATFORM(WTF_FEATURE) (defined WTF_PLATFORM_##WTF_FEATURE && WTF_PLATFORM_##WTF_FEATURE) - - -/* ==== Platform adaptation macros: these describe properties of the target environment. ==== */ - -/* COMPILER() - the compiler being used to build the project */ -#define COMPILER(WTF_FEATURE) (defined WTF_COMPILER_##WTF_FEATURE && WTF_COMPILER_##WTF_FEATURE) -/* CPU() - the target CPU architecture */ -#define CPU(WTF_FEATURE) (defined WTF_CPU_##WTF_FEATURE && WTF_CPU_##WTF_FEATURE) -/* HAVE() - specific system features (headers, functions or similar) that are present or not */ -#define HAVE(WTF_FEATURE) (defined HAVE_##WTF_FEATURE && HAVE_##WTF_FEATURE) -/* OS() - underlying operating system; only to be used for mandated low-level services like - virtual memory, not to choose a GUI toolkit */ -#define OS(WTF_FEATURE) (defined WTF_OS_##WTF_FEATURE && WTF_OS_##WTF_FEATURE) - - -/* ==== Policy decision macros: these define policy choices for a particular port. ==== */ - -/* USE() - use a particular third-party library or optional OS service */ -#define USE(WTF_FEATURE) (defined WTF_USE_##WTF_FEATURE && WTF_USE_##WTF_FEATURE) -/* ENABLE() - turn on a specific feature of WebKit */ -#define ENABLE(WTF_FEATURE) (defined ENABLE_##WTF_FEATURE && ENABLE_##WTF_FEATURE) - - - -/* ==== COMPILER() - the compiler being used to build the project ==== */ - -/* COMPILER(MSVC) Microsoft Visual C++ */ -/* COMPILER(MSVC7_OR_LOWER) Microsoft Visual C++ 2003 or lower*/ -/* COMPILER(MSVC9_OR_LOWER) Microsoft Visual C++ 2008 or lower*/ -#if defined(_MSC_VER) -#define WTF_COMPILER_MSVC 1 -#if _MSC_VER < 1400 -#define WTF_COMPILER_MSVC7_OR_LOWER 1 -#elif _MSC_VER < 1600 -#define WTF_COMPILER_MSVC9_OR_LOWER 1 -#endif -#endif - -/* COMPILER(RVCT) - ARM RealView Compilation Tools */ -#if defined(__CC_ARM) || defined(__ARMCC__) -#define WTF_COMPILER_RVCT 1 -#endif - -/* COMPILER(GCC) - GNU Compiler Collection */ -/* --gnu option of the RVCT compiler also defines __GNUC__ */ -#if defined(__GNUC__) && !COMPILER(RVCT) -#define WTF_COMPILER_GCC 1 -#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) -#define GCC_VERSION_AT_LEAST(major, minor, patch) (GCC_VERSION >= (major * 10000 + minor * 100 + patch)) -#else -/* define this for !GCC compilers, just so we can write things like COMPILER(GCC) && GCC_VERSION_AT_LEAST(4,1,0) */ -#define GCC_VERSION_AT_LEAST(major, minor, patch) 0 -#endif - -/* COMPILER(MINGW) - MinGW GCC */ -/* COMPILER(MINGW64) - mingw-w64 GCC - only used as additional check to exclude mingw.org specific functions */ -#if defined(__MINGW32__) -#define WTF_COMPILER_MINGW 1 -#include <_mingw.h> /* private MinGW header */ - #if defined(__MINGW64_VERSION_MAJOR) /* best way to check for mingw-w64 vs mingw.org */ - #define WTF_COMPILER_MINGW64 1 - #endif /* __MINGW64_VERSION_MAJOR */ -#endif /* __MINGW32__ */ - -/* COMPILER(WINSCW) - CodeWarrior for Symbian emulator */ -#if defined(__WINSCW__) -#define WTF_COMPILER_WINSCW 1 -/* cross-compiling, it is not really windows */ -#undef WIN32 -#undef _WIN32 -#endif - -/* COMPILER(INTEL) - Intel C++ Compiler */ -#if defined(__INTEL_COMPILER) -#define WTF_COMPILER_INTEL 1 -#endif - -/* ==== CPU() - the target CPU architecture ==== */ - -/* This also defines CPU(BIG_ENDIAN) or CPU(MIDDLE_ENDIAN) or neither, as appropriate. */ - -/* CPU(ALPHA) - DEC Alpha */ -#if defined(__alpha__) -#define WTF_CPU_ALPHA 1 -#endif - -/* CPU(IA64) - Itanium / IA-64 */ -#if defined(__ia64__) -#define WTF_CPU_IA64 1 -/* 32-bit mode on Itanium */ -#if !defined(__LP64__) -#define WTF_CPU_IA64_32 1 -#endif -#endif - -/* CPU(MIPS) - MIPS 32-bit */ -/* Note: Only O32 ABI is tested, so we enable it for O32 ABI for now. */ -#if (defined(mips) || defined(__mips__)) \ - && defined(_ABIO32) -#define WTF_CPU_MIPS 1 -#if defined(__MIPSEB__) -#define WTF_CPU_BIG_ENDIAN 1 -#endif -#define WTF_MIPS_PIC (defined __PIC__) -#define WTF_MIPS_ARCH __mips -#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v) -#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v) -#define WTF_MIPS_ARCH_REV __mips_isa_rev -#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v) -#define WTF_MIPS_DOUBLE_FLOAT (defined __mips_hard_float && !defined __mips_single_float) -#define WTF_MIPS_FP64 (defined __mips_fpr && __mips_fpr == 64) -/* MIPS requires allocators to use aligned memory */ -#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1 -#endif /* MIPS */ - -/* CPU(PPC) - PowerPC 32-bit */ -#if defined(__ppc__) \ - || defined(__PPC__) \ - || defined(__powerpc__) \ - || defined(__powerpc) \ - || defined(__POWERPC__) \ - || defined(_M_PPC) \ - || defined(__PPC) -#define WTF_CPU_PPC 1 -#define WTF_CPU_BIG_ENDIAN 1 -#endif - -/* CPU(PPC64) - PowerPC 64-bit */ -#if defined(__ppc64__) \ - || defined(__PPC64__) -#define WTF_CPU_PPC64 1 -#define WTF_CPU_BIG_ENDIAN 1 -#endif - -/* CPU(SH4) - SuperH SH-4 */ -#if defined(__SH4__) -#define WTF_CPU_SH4 1 -#endif - -/* CPU(SPARC32) - SPARC 32-bit */ -#if defined(__sparc) && !defined(__arch64__) || defined(__sparcv8) -#define WTF_CPU_SPARC32 1 -#define WTF_CPU_BIG_ENDIAN 1 -#endif - -/* CPU(SPARC64) - SPARC 64-bit */ -#if defined(__sparc__) && defined(__arch64__) || defined (__sparcv9) -#define WTF_CPU_SPARC64 1 -#define WTF_CPU_BIG_ENDIAN 1 -#endif - -/* CPU(SPARC) - any SPARC, true for CPU(SPARC32) and CPU(SPARC64) */ -#if CPU(SPARC32) || CPU(SPARC64) -#define WTF_CPU_SPARC 1 -#endif - -/* CPU(S390X) - S390 64-bit */ -#if defined(__s390x__) -#define WTF_CPU_S390X 1 -#define WTF_CPU_BIG_ENDIAN 1 -#endif - -/* CPU(S390) - S390 32-bit */ -#if defined(__s390__) -#define WTF_CPU_S390 1 -#define WTF_CPU_BIG_ENDIAN 1 -#endif - -/* CPU(X86) - i386 / x86 32-bit */ -#if defined(__i386__) \ - || defined(i386) \ - || defined(_M_IX86) \ - || defined(_X86_) \ - || defined(__THW_INTEL) -#define WTF_CPU_X86 1 -#endif - -/* CPU(X86_64) - AMD64 / Intel64 / x86_64 64-bit */ -#if defined(__x86_64__) \ - || defined(_M_X64) -#define WTF_CPU_X86_64 1 -#endif - -/* CPU(ARM) - ARM, any version*/ -#if defined(arm) \ - || defined(__arm__) \ - || defined(ARM) \ - || defined(_ARM_) -#define WTF_CPU_ARM 1 - -#if defined(__ARMEB__) || (COMPILER(RVCT) && defined(__BIG_ENDIAN)) -#define WTF_CPU_BIG_ENDIAN 1 - -#elif !defined(__ARM_EABI__) \ - && !defined(__EABI__) \ - && !defined(__VFP_FP__) \ - && !defined(_WIN32_WCE) \ - && !defined(ANDROID) -#define WTF_CPU_MIDDLE_ENDIAN 1 - -#endif - -#define WTF_ARM_ARCH_AT_LEAST(N) (CPU(ARM) && WTF_ARM_ARCH_VERSION >= N) - -/* Set WTF_ARM_ARCH_VERSION */ -#if defined(__ARM_ARCH_4__) \ - || defined(__ARM_ARCH_4T__) \ - || defined(__MARM_ARMV4__) \ - || defined(_ARMV4I_) -#define WTF_ARM_ARCH_VERSION 4 - -#elif defined(__ARM_ARCH_5__) \ - || defined(__ARM_ARCH_5T__) \ - || defined(__MARM_ARMV5__) -#define WTF_ARM_ARCH_VERSION 5 - -#elif defined(__ARM_ARCH_5E__) \ - || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) -#define WTF_ARM_ARCH_VERSION 5 -/*ARMv5TE requires allocators to use aligned memory*/ -#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1 - -#elif defined(__ARM_ARCH_6__) \ - || defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) \ - || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6T2__) \ - || defined(__ARMV6__) -#define WTF_ARM_ARCH_VERSION 6 - -#elif defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) -#define WTF_ARM_ARCH_VERSION 7 - -/* RVCT sets _TARGET_ARCH_ARM */ -#elif defined(__TARGET_ARCH_ARM) -#define WTF_ARM_ARCH_VERSION __TARGET_ARCH_ARM - -#if defined(__TARGET_ARCH_5E) \ - || defined(__TARGET_ARCH_5TE) \ - || defined(__TARGET_ARCH_5TEJ) -/*ARMv5TE requires allocators to use aligned memory*/ -#define WTF_USE_ARENA_ALLOC_ALIGNMENT_INTEGER 1 -#endif - -#else -#define WTF_ARM_ARCH_VERSION 0 - -#endif - -/* Set WTF_THUMB_ARCH_VERSION */ -#if defined(__ARM_ARCH_4T__) -#define WTF_THUMB_ARCH_VERSION 1 - -#elif defined(__ARM_ARCH_5T__) \ - || defined(__ARM_ARCH_5TE__) \ - || defined(__ARM_ARCH_5TEJ__) -#define WTF_THUMB_ARCH_VERSION 2 - -#elif defined(__ARM_ARCH_6J__) \ - || defined(__ARM_ARCH_6K__) \ - || defined(__ARM_ARCH_6Z__) \ - || defined(__ARM_ARCH_6ZK__) \ - || defined(__ARM_ARCH_6M__) -#define WTF_THUMB_ARCH_VERSION 3 - -#elif defined(__ARM_ARCH_6T2__) \ - || defined(__ARM_ARCH_7__) \ - || defined(__ARM_ARCH_7A__) \ - || defined(__ARM_ARCH_7R__) \ - || defined(__ARM_ARCH_7M__) -#define WTF_THUMB_ARCH_VERSION 4 - -/* RVCT sets __TARGET_ARCH_THUMB */ -#elif defined(__TARGET_ARCH_THUMB) -#define WTF_THUMB_ARCH_VERSION __TARGET_ARCH_THUMB - -#else -#define WTF_THUMB_ARCH_VERSION 0 -#endif - - -/* CPU(ARMV5_OR_LOWER) - ARM instruction set v5 or earlier */ -/* On ARMv5 and below the natural alignment is required. - And there are some other differences for v5 or earlier. */ -#if !defined(ARMV5_OR_LOWER) && !WTF_ARM_ARCH_AT_LEAST(6) -#define WTF_CPU_ARMV5_OR_LOWER 1 -#endif - - -/* CPU(ARM_TRADITIONAL) - Thumb2 is not available, only traditional ARM (v4 or greater) */ -/* CPU(ARM_THUMB2) - Thumb2 instruction set is available */ -/* Only one of these will be defined. */ -#if !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) -# if defined(thumb2) || defined(__thumb2__) \ - || ((defined(__thumb) || defined(__thumb__)) && WTF_THUMB_ARCH_VERSION == 4) -# define WTF_CPU_ARM_TRADITIONAL 0 -# define WTF_CPU_ARM_THUMB2 1 -# elif WTF_ARM_ARCH_AT_LEAST(4) -# define WTF_CPU_ARM_TRADITIONAL 1 -# define WTF_CPU_ARM_THUMB2 0 -# else -# error "Not supported ARM architecture" -# endif -#elif CPU(ARM_TRADITIONAL) && CPU(ARM_THUMB2) /* Sanity Check */ -# error "Cannot use both of WTF_CPU_ARM_TRADITIONAL and WTF_CPU_ARM_THUMB2 platforms" -#endif /* !defined(WTF_CPU_ARM_TRADITIONAL) && !defined(WTF_CPU_ARM_THUMB2) */ - -#endif /* ARM */ - - - -/* ==== OS() - underlying operating system; only to be used for mandated low-level services like - virtual memory, not to choose a GUI toolkit ==== */ - -/* OS(ANDROID) - Android */ -#ifdef ANDROID -#define WTF_OS_ANDROID 1 -#endif - -/* OS(AIX) - AIX */ -#ifdef _AIX -#define WTF_OS_AIX 1 -#endif - -/* OS(DARWIN) - Any Darwin-based OS, including Mac OS X and iPhone OS */ -#ifdef __APPLE__ -#define WTF_OS_DARWIN 1 - -/* FIXME: BUILDING_ON_.., and TARGETING... macros should be folded into the OS() system */ -#include <AvailabilityMacros.h> -#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5 -#define BUILDING_ON_TIGER 1 -#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6 -#define BUILDING_ON_LEOPARD 1 -#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 -#define BUILDING_ON_SNOW_LEOPARD 1 -#endif -#if !defined(MAC_OS_X_VERSION_10_5) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5 -#define TARGETING_TIGER 1 -#elif !defined(MAC_OS_X_VERSION_10_6) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6 -#define TARGETING_LEOPARD 1 -#elif !defined(MAC_OS_X_VERSION_10_7) || MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_7 -#define TARGETING_SNOW_LEOPARD 1 -#endif -#include <TargetConditionals.h> - -#endif - -/* OS(IOS) - iOS */ -/* OS(MAC_OS_X) - Mac OS X (not including iOS) */ -#if OS(DARWIN) && ((defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) \ - || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) \ - || (defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR)) -#define WTF_OS_IOS 1 -#elif OS(DARWIN) && defined(TARGET_OS_MAC) && TARGET_OS_MAC -#define WTF_OS_MAC_OS_X 1 -#endif - -/* OS(FREEBSD) - FreeBSD */ -#ifdef __FreeBSD__ -#define WTF_OS_FREEBSD 1 -#endif - -/* OS(HAIKU) - Haiku */ -#ifdef __HAIKU__ -#define WTF_OS_HAIKU 1 -#endif - -/* OS(LINUX) - Linux */ -#ifdef __linux__ -#define WTF_OS_LINUX 1 -#endif - -/* OS(NETBSD) - NetBSD */ -#if defined(__NetBSD__) -#define WTF_OS_NETBSD 1 -#endif - -/* OS(OPENBSD) - OpenBSD */ -#ifdef __OpenBSD__ -#define WTF_OS_OPENBSD 1 -#endif - -/* OS(QNX) - QNX */ -#if defined(__QNXNTO__) -#define WTF_OS_QNX 1 -#endif - -/* OS(SOLARIS) - Solaris */ -#if defined(sun) || defined(__sun) -#define WTF_OS_SOLARIS 1 -#endif - -/* OS(WINCE) - Windows CE; note that for this platform OS(WINDOWS) is also defined */ -#if defined(_WIN32_WCE) -#define WTF_OS_WINCE 1 -#endif - -/* OS(WINDOWS) - Any version of Windows */ -#if defined(WIN32) || defined(_WIN32) -#define WTF_OS_WINDOWS 1 -#endif - -/* OS(SYMBIAN) - Symbian */ -#if defined (__SYMBIAN32__) -#define WTF_OS_SYMBIAN 1 -#endif - -/* OS(UNIX) - Any Unix-like system */ -#if OS(AIX) \ - || OS(ANDROID) \ - || OS(DARWIN) \ - || OS(FREEBSD) \ - || OS(HAIKU) \ - || OS(LINUX) \ - || OS(NETBSD) \ - || OS(OPENBSD) \ - || OS(QNX) \ - || OS(SOLARIS) \ - || OS(SYMBIAN) \ - || defined(unix) \ - || defined(__unix) \ - || defined(__unix__) -#define WTF_OS_UNIX 1 -#endif - -/* Operating environments */ - -/* FIXME: these are all mixes of OS, operating environment and policy choices. */ -/* PLATFORM(CHROMIUM) */ -/* PLATFORM(QT) */ -/* PLATFORM(WX) */ -/* PLATFORM(GTK) */ -/* PLATFORM(HAIKU) */ -/* PLATFORM(MAC) */ -/* PLATFORM(WIN) */ -#if defined(BUILDING_CHROMIUM__) -#define WTF_PLATFORM_CHROMIUM 1 -#elif defined(BUILDING_QT__) -#define WTF_PLATFORM_QT 1 -#elif defined(BUILDING_WX__) -#define WTF_PLATFORM_WX 1 -#elif defined(BUILDING_GTK__) -#define WTF_PLATFORM_GTK 1 -#elif defined(BUILDING_HAIKU__) -#define WTF_PLATFORM_HAIKU 1 -#elif defined(BUILDING_BREWMP__) -#define WTF_PLATFORM_BREWMP 1 -#if defined(AEE_SIMULATOR) -#define WTF_PLATFORM_BREWMP_SIMULATOR 1 -#else -#define WTF_PLATFORM_BREWMP_SIMULATOR 0 -#endif -#undef WTF_OS_WINDOWS -#undef WTF_PLATFORM_WIN -#elif OS(DARWIN) -#define WTF_PLATFORM_MAC 1 -#elif OS(WINDOWS) -#define WTF_PLATFORM_WIN 1 -#endif - -/* PLATFORM(IOS) */ -/* FIXME: this is sometimes used as an OS switch and sometimes for higher-level things */ -#if (defined(TARGET_OS_EMBEDDED) && TARGET_OS_EMBEDDED) || (defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE) -#define WTF_PLATFORM_IOS 1 -#endif - -/* PLATFORM(IOS_SIMULATOR) */ -#if defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR -#define WTF_PLATFORM_IOS 1 -#define WTF_PLATFORM_IOS_SIMULATOR 1 -#else -#define WTF_PLATFORM_IOS_SIMULATOR 0 -#endif - -#if !defined(WTF_PLATFORM_IOS) -#define WTF_PLATFORM_IOS 0 -#endif - -/* PLATFORM(ANDROID) */ -/* FIXME: this is sometimes used as an OS() switch, and other times to drive - policy choices */ -#if defined(ANDROID) -#define WTF_PLATFORM_ANDROID 1 -#endif - -/* Graphics engines */ - -/* PLATFORM(CG) and PLATFORM(CI) */ -#if PLATFORM(MAC) || PLATFORM(IOS) -#define WTF_PLATFORM_CG 1 -#endif -#if PLATFORM(MAC) && !PLATFORM(IOS) -#define WTF_PLATFORM_CI 1 -#endif -#if PLATFORM(MAC) || PLATFORM(IOS) || (PLATFORM(WIN) && PLATFORM(CG)) -#define WTF_PLATFORM_CA 1 -#endif - -/* PLATFORM(SKIA) for Win/Linux, CG/CI for Mac */ -#if PLATFORM(CHROMIUM) -#if OS(DARWIN) -#define WTF_PLATFORM_CG 1 -#define WTF_PLATFORM_CI 1 -#define WTF_USE_ATSUI 1 -#define WTF_USE_CORE_TEXT 1 -#define WTF_USE_ICCJPEG 1 -#else -#define WTF_PLATFORM_SKIA 1 -#define WTF_USE_CHROMIUM_NET 1 -#endif -#endif - -#if PLATFORM(BREWMP) -#define WTF_PLATFORM_SKIA 1 -#endif - -#if PLATFORM(GTK) -#define WTF_PLATFORM_CAIRO 1 -#endif - - -#if OS(WINCE) -#include <ce_time.h> -#endif - -#if (PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || (PLATFORM(QT) && OS(DARWIN) && !ENABLE(SINGLE_THREADED))) && !defined(ENABLE_JSC_MULTIPLE_THREADS) -#define ENABLE_JSC_MULTIPLE_THREADS 1 -#endif - -/* On Windows, use QueryPerformanceCounter by default */ -#if OS(WINDOWS) -#define WTF_USE_QUERY_PERFORMANCE_COUNTER 1 -#endif - -#if OS(WINCE) && !PLATFORM(QT) -#define NOMINMAX /* Windows min and max conflict with standard macros */ -#define NOSHLWAPI /* shlwapi.h not available on WinCe */ - -/* MSDN documentation says these functions are provided with uspce.lib. But we cannot find this file. */ -#define __usp10__ /* disable "usp10.h" */ - -#define _INC_ASSERT /* disable "assert.h" */ -#define assert(x) - -#endif /* OS(WINCE) && !PLATFORM(QT) */ - -#if PLATFORM(QT) -#define WTF_USE_QT4_UNICODE 1 -#elif OS(WINCE) -#define WTF_USE_WINCE_UNICODE 1 -#elif PLATFORM(BREWMP) -#define WTF_USE_BREWMP_UNICODE 1 -#elif PLATFORM(GTK) -/* The GTK+ Unicode backend is configurable */ -#else -#define WTF_USE_ICU_UNICODE 1 -#endif - -#if PLATFORM(MAC) && !PLATFORM(IOS) -#define WTF_PLATFORM_CF 1 -#define WTF_USE_PTHREADS 1 -#define HAVE_PTHREAD_RWLOCK 1 -#if !defined(BUILDING_ON_LEOPARD) && !defined(BUILDING_ON_TIGER) && CPU(X86_64) -#define WTF_USE_PLUGIN_HOST_PROCESS 1 -#endif -#if !defined(ENABLE_JAVA_BRIDGE) -#define ENABLE_JAVA_BRIDGE 1 -#endif -#if !defined(ENABLE_DASHBOARD_SUPPORT) -#define ENABLE_DASHBOARD_SUPPORT 1 -#endif -#define HAVE_READLINE 1 -#define HAVE_RUNLOOP_TIMER 1 -#define ENABLE_FULLSCREEN_API 1 -#define ENABLE_SMOOTH_SCROLLING 1 -#endif /* PLATFORM(MAC) && !PLATFORM(IOS) */ - -#if PLATFORM(ANDROID) -#define ENABLE_FULLSCREEN_API 1 -#endif - -#if PLATFORM(MAC) -#define WTF_USE_CARBON_SECURE_INPUT_MODE 1 -#endif - -#if PLATFORM(CHROMIUM) && OS(DARWIN) -#define WTF_PLATFORM_CF 1 -#define WTF_USE_PTHREADS 1 -#define HAVE_PTHREAD_RWLOCK 1 -#define WTF_USE_CARBON_SECURE_INPUT_MODE 1 -#endif - -#if PLATFORM(BREWMP) -#define ENABLE_SINGLE_THREADED 1 -#endif - -#if PLATFORM(QT) && OS(DARWIN) -#define WTF_PLATFORM_CF 1 -#endif - -#if OS(DARWIN) && !defined(BUILDING_ON_TIGER) && !PLATFORM(GTK) && !PLATFORM(QT) -#define ENABLE_PURGEABLE_MEMORY 1 -#endif - -#if PLATFORM(IOS) -#define ENABLE_CONTEXT_MENUS 0 -#define ENABLE_DRAG_SUPPORT 0 -#define ENABLE_FTPDIR 1 -#define ENABLE_GEOLOCATION 1 -#define ENABLE_ICONDATABASE 0 -#define ENABLE_INSPECTOR 0 -#define ENABLE_JAVA_BRIDGE 0 -#define ENABLE_NETSCAPE_PLUGIN_API 0 -#define ENABLE_ORIENTATION_EVENTS 1 -#define ENABLE_REPAINT_THROTTLING 1 -#define HAVE_READLINE 1 -#define WTF_PLATFORM_CF 1 -#define WTF_USE_PTHREADS 1 -#define HAVE_PTHREAD_RWLOCK 1 -#endif - -#if PLATFORM(ANDROID) -#define WTF_USE_PTHREADS 1 -#define WTF_PLATFORM_SKIA 1 -#define USE_SYSTEM_MALLOC 1 -#define ENABLE_JAVA_BRIDGE 1 -#define LOG_DISABLED 1 -/* Prevents Webkit from drawing the caret in textfields and textareas - This prevents unnecessary invals. */ -#define ENABLE_TEXT_CARET 1 -#define ENABLE_JAVASCRIPT_DEBUGGER 0 -#define ENABLE_ORIENTATION_EVENTS 1 -#if !defined(ENABLE_JIT) && !ENABLE(ANDROID_JSC_JIT) -#define ENABLE_JIT 0 -#endif -#endif - -#if PLATFORM(WIN) && !OS(WINCE) -#define WTF_PLATFORM_CF 1 -#define WTF_USE_PTHREADS 0 -#endif - -#if PLATFORM(WX) -#define ENABLE_ASSEMBLER 1 -#define ENABLE_GLOBAL_FASTMALLOC_NEW 0 -#if OS(DARWIN) -#define WTF_PLATFORM_CF 1 -#ifndef BUILDING_ON_TIGER -#define WTF_USE_CORE_TEXT 1 -#else -#define WTF_USE_ATSUI 1 -#endif -#endif -#endif - -#if PLATFORM(GTK) -#if HAVE(PTHREAD_H) -#define WTF_USE_PTHREADS 1 -#define HAVE_PTHREAD_RWLOCK 1 -#endif -#endif - -#if PLATFORM(HAIKU) -#define HAVE_POSIX_MEMALIGN 1 -#define WTF_USE_CURL 1 -#define WTF_USE_PTHREADS 1 -#define HAVE_PTHREAD_RWLOCK 1 -#define USE_SYSTEM_MALLOC 1 -#define ENABLE_NETSCAPE_PLUGIN_API 0 -#endif - -#if PLATFORM(BREWMP) -#define USE_SYSTEM_MALLOC 1 -#endif - -#if PLATFORM(BREWMP_SIMULATOR) -#define ENABLE_JIT 0 -#endif - -#if !defined(HAVE_ACCESSIBILITY) -#if PLATFORM(IOS) || PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(GTK) || PLATFORM(CHROMIUM) -#define HAVE_ACCESSIBILITY 1 -#endif -#endif /* !defined(HAVE_ACCESSIBILITY) */ - -#if OS(UNIX) && !OS(SYMBIAN) -#define HAVE_SIGNAL_H 1 -#endif - -#if !OS(WINDOWS) && !OS(SOLARIS) && !OS(QNX) \ - && !OS(SYMBIAN) && !OS(HAIKU) && !OS(RVCT) \ - && !OS(ANDROID) && !PLATFORM(BREWMP) -#define HAVE_TM_GMTOFF 1 -#define HAVE_TM_ZONE 1 -#define HAVE_TIMEGM 1 -#endif - -#if OS(DARWIN) - -#define HAVE_ERRNO_H 1 -#define HAVE_LANGINFO_H 1 -#define HAVE_MMAP 1 -#define HAVE_MERGESORT 1 -#define HAVE_SBRK 1 -#define HAVE_STRINGS_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TIMEB_H 1 - -#if !defined(TARGETING_TIGER) && !defined(TARGETING_LEOPARD) - -#define HAVE_DISPATCH_H 1 -#define HAVE_HOSTED_CORE_ANIMATION 1 - -#if !PLATFORM(IOS) -#define HAVE_MADV_FREE_REUSE 1 -#define HAVE_MADV_FREE 1 -#define HAVE_PTHREAD_SETNAME_NP 1 -#endif - -#endif - -#if PLATFORM(IOS) -#define HAVE_MADV_FREE 1 -#endif - -#elif OS(WINDOWS) - -#if OS(WINCE) -#define HAVE_ERRNO_H 0 -#else -#define HAVE_SYS_TIMEB_H 1 -#define HAVE_ALIGNED_MALLOC 1 -#define HAVE_ISDEBUGGERPRESENT 1 -#endif -#define HAVE_VIRTUALALLOC 1 - -#elif OS(SYMBIAN) - -#define HAVE_ERRNO_H 1 -#define HAVE_MMAP 0 -#define HAVE_SBRK 1 - -#define HAVE_SYS_TIME_H 1 -#define HAVE_STRINGS_H 1 - -#if !COMPILER(RVCT) -#define HAVE_SYS_PARAM_H 1 -#endif - -#elif PLATFORM(BREWMP) - -#define HAVE_ERRNO_H 1 - -#elif OS(QNX) - -#define HAVE_ERRNO_H 1 -#define HAVE_MMAP 1 -#define HAVE_SBRK 1 -#define HAVE_STRINGS_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_TIME_H 1 - -#elif OS(ANDROID) - -#define HAVE_ERRNO_H 1 -#define HAVE_LANGINFO_H 0 -#define HAVE_MMAP 1 -#define HAVE_SBRK 1 -#define HAVE_STRINGS_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_TIME_H 1 - -#else - -/* FIXME: is this actually used or do other platforms generate their own config.h? */ - -#define HAVE_ERRNO_H 1 -/* As long as Haiku doesn't have a complete support of locale this will be disabled. */ -#if !OS(HAIKU) -#define HAVE_LANGINFO_H 1 -#endif -#define HAVE_MMAP 1 -#define HAVE_SBRK 1 -#define HAVE_STRINGS_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_TIME_H 1 - -#endif - -/* ENABLE macro defaults */ - -#if PLATFORM(QT) -/* We must not customize the global operator new and delete for the Qt port. */ -#define ENABLE_GLOBAL_FASTMALLOC_NEW 0 -#endif - -/* fastMalloc match validation allows for runtime verification that - new is matched by delete, fastMalloc is matched by fastFree, etc. */ -#if !defined(ENABLE_FAST_MALLOC_MATCH_VALIDATION) -#define ENABLE_FAST_MALLOC_MATCH_VALIDATION 0 -#endif - -#if !defined(ENABLE_ICONDATABASE) -#define ENABLE_ICONDATABASE 1 -#endif - -#if !defined(ENABLE_DATABASE) -#define ENABLE_DATABASE 1 -#endif - -#if !defined(ENABLE_JAVASCRIPT_DEBUGGER) -#define ENABLE_JAVASCRIPT_DEBUGGER 1 -#endif - -#if !defined(ENABLE_FTPDIR) -#define ENABLE_FTPDIR 1 -#endif - -#if !defined(ENABLE_CONTEXT_MENUS) -#define ENABLE_CONTEXT_MENUS 1 -#endif - -#if !defined(ENABLE_DRAG_SUPPORT) -#define ENABLE_DRAG_SUPPORT 1 -#endif - -#if !defined(ENABLE_DASHBOARD_SUPPORT) -#define ENABLE_DASHBOARD_SUPPORT 0 -#endif - -#if !defined(ENABLE_INSPECTOR) -#define ENABLE_INSPECTOR 1 -#endif - -#if !defined(ENABLE_JAVA_BRIDGE) -#define ENABLE_JAVA_BRIDGE 0 -#endif - -#if !defined(ENABLE_NETSCAPE_PLUGIN_API) -#define ENABLE_NETSCAPE_PLUGIN_API 1 -#endif - -#if !defined(ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE) -#define ENABLE_NETSCAPE_PLUGIN_METADATA_CACHE 0 -#endif - -#if !defined(ENABLE_PURGEABLE_MEMORY) -#define ENABLE_PURGEABLE_MEMORY 0 -#endif - -#if !defined(WTF_USE_PLUGIN_HOST_PROCESS) -#define WTF_USE_PLUGIN_HOST_PROCESS 0 -#endif - -#if !defined(ENABLE_ORIENTATION_EVENTS) -#define ENABLE_ORIENTATION_EVENTS 0 -#endif - -#if !defined(ENABLE_OPCODE_STATS) -#define ENABLE_OPCODE_STATS 0 -#endif - -#if !defined(ENABLE_GLOBAL_FASTMALLOC_NEW) -#define ENABLE_GLOBAL_FASTMALLOC_NEW 1 -#endif - -#define ENABLE_DEBUG_WITH_BREAKPOINT 0 -#define ENABLE_SAMPLING_COUNTERS 0 -#define ENABLE_SAMPLING_FLAGS 0 -#define ENABLE_OPCODE_SAMPLING 0 -#define ENABLE_CODEBLOCK_SAMPLING 0 -#if ENABLE(CODEBLOCK_SAMPLING) && !ENABLE(OPCODE_SAMPLING) -#error "CODEBLOCK_SAMPLING requires OPCODE_SAMPLING" -#endif -#if ENABLE(OPCODE_SAMPLING) || ENABLE(SAMPLING_FLAGS) -#define ENABLE_SAMPLING_THREAD 1 -#endif - -#if !defined(ENABLE_GEOLOCATION) -#define ENABLE_GEOLOCATION 0 -#endif - -#if !defined(ENABLE_NOTIFICATIONS) -#define ENABLE_NOTIFICATIONS 0 -#endif - -#if PLATFORM(IOS) -#define ENABLE_TEXT_CARET 0 -#endif - -#if !defined(ENABLE_TEXT_CARET) -#define ENABLE_TEXT_CARET 1 -#endif - -#if !defined(ENABLE_COMPOSITED_FIXED_ELEMENTS) -#define ENABLE_COMPOSITED_FIXED_ELEMENTS 0 -#endif - -// ENABLE_ARCHIVE is an Android addition. We need this default value to allow -// us to build on Mac. -// FIXME: Upstream to webkit.org. -#if !defined(ENABLE_ARCHIVE) -#define ENABLE_ARCHIVE 1 -#endif - -#if !defined(ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL) -#define ENABLE_ON_FIRST_TEXTAREA_FOCUS_SELECT_ALL 0 -#endif - -#if !defined(ENABLE_FULLSCREEN_API) -#define ENABLE_FULLSCREEN_API 0 -#endif - -#if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) -#if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) \ - || (CPU(IA64) && !CPU(IA64_32)) \ - || CPU(ALPHA) \ - || CPU(SPARC64) \ - || CPU(S390X) \ - || CPU(PPC64) -#define WTF_USE_JSVALUE64 1 -#else -#define WTF_USE_JSVALUE32_64 1 -#endif -#endif /* !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32_64) */ - -#if !defined(ENABLE_REPAINT_THROTTLING) -#define ENABLE_REPAINT_THROTTLING 0 -#endif - -/* Disable the JIT on versiond of GCC prior to 4.1 */ -#if !defined(ENABLE_JIT) && COMPILER(GCC) && !GCC_VERSION_AT_LEAST(4,1,0) -#define ENABLE_JIT 0 -#endif - -/* JIT is not implemented for 64 bit on MSVC */ -#if !defined(ENABLE_JIT) && COMPILER(MSVC) && CPU(X86_64) -#define ENABLE_JIT 0 -#endif - -/* The JIT is enabled by default on all x86, x64-64, ARM & MIPS platforms. */ -#if !defined(ENABLE_JIT) \ - && (CPU(X86) || CPU(X86_64) || CPU(ARM) || CPU(MIPS)) \ - && (OS(DARWIN) || !COMPILER(GCC) || GCC_VERSION_AT_LEAST(4,1,0)) \ - && !OS(WINCE) -#define ENABLE_JIT 1 -#endif - -/* Ensure that either the JIT or the interpreter has been enabled. */ -#if !defined(ENABLE_INTERPRETER) && !ENABLE(JIT) -#define ENABLE_INTERPRETER 1 -#endif -#if !(ENABLE(JIT) || ENABLE(INTERPRETER)) -#error You have to have at least one execution model enabled to build JSC -#endif - -/* Configure the JIT */ -#if ENABLE(JIT) - #if CPU(ARM) - #if !defined(ENABLE_JIT_USE_SOFT_MODULO) && WTF_ARM_ARCH_AT_LEAST(5) - #define ENABLE_JIT_USE_SOFT_MODULO 1 - #endif - #endif - - #ifndef ENABLE_JIT_OPTIMIZE_CALL - #define ENABLE_JIT_OPTIMIZE_CALL 1 - #endif - #ifndef ENABLE_JIT_OPTIMIZE_NATIVE_CALL - #define ENABLE_JIT_OPTIMIZE_NATIVE_CALL 1 - #endif - #ifndef ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS - #define ENABLE_JIT_OPTIMIZE_PROPERTY_ACCESS 1 - #endif - #ifndef ENABLE_JIT_OPTIMIZE_METHOD_CALLS - #define ENABLE_JIT_OPTIMIZE_METHOD_CALLS 1 - #endif -#endif - -#if CPU(X86) && COMPILER(MSVC) -#define JSC_HOST_CALL __fastcall -#elif CPU(X86) && COMPILER(GCC) -#define JSC_HOST_CALL __attribute__ ((fastcall)) -#else -#define JSC_HOST_CALL -#endif - -/* Configure the interpreter */ -#if COMPILER(GCC) -#define HAVE_COMPUTED_GOTO 1 -#endif -#if HAVE(COMPUTED_GOTO) && ENABLE(INTERPRETER) -#define ENABLE_COMPUTED_GOTO_INTERPRETER 1 -#endif - -/* Regular Expression Tracing - Set to 1 to trace RegExp's in jsc. Results dumped at exit */ -#define ENABLE_REGEXP_TRACING 0 - -/* Yet Another Regex Runtime - turned on by default for JIT enabled ports. */ -#if ENABLE(JIT) && !defined(ENABLE_YARR_JIT) -#define ENABLE_YARR_JIT 1 -#endif - -#if ENABLE(JIT) || ENABLE(YARR_JIT) -#define ENABLE_ASSEMBLER 1 -#endif -/* Setting this flag prevents the assembler from using RWX memory; this may improve - security but currectly comes at a significant performance cost. */ -#if PLATFORM(IOS) -#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 1 -#else -#define ENABLE_ASSEMBLER_WX_EXCLUSIVE 0 -#endif - -/* Pick which allocator to use; we only need an executable allocator if the assembler is compiled in. - On x86-64 we use a single fixed mmap, on other platforms we mmap on demand. */ -#if ENABLE(ASSEMBLER) -#if CPU(X86_64) -#define ENABLE_EXECUTABLE_ALLOCATOR_FIXED 1 -#else -#define ENABLE_EXECUTABLE_ALLOCATOR_DEMAND 1 -#endif -#endif - -#if !defined(ENABLE_PAN_SCROLLING) && OS(WINDOWS) -#define ENABLE_PAN_SCROLLING 1 -#endif - -#if !defined(ENABLE_SMOOTH_SCROLLING) -#define ENABLE_SMOOTH_SCROLLING 0 -#endif - -/* Use the QXmlStreamReader implementation for XMLDocumentParser */ -/* Use the QXmlQuery implementation for XSLTProcessor */ -#if PLATFORM(QT) -#define WTF_USE_QXMLSTREAM 1 -#define WTF_USE_QXMLQUERY 1 -#endif - -#if PLATFORM(MAC) -/* Complex text framework */ -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) -#define WTF_USE_ATSUI 0 -#define WTF_USE_CORE_TEXT 1 -#else -#define WTF_USE_ATSUI 1 -#define WTF_USE_CORE_TEXT 0 -#endif -#endif - -/* Accelerated compositing */ -#if PLATFORM(ANDROID) && !defined WTF_USE_ACCELERATED_COMPOSITING -#define WTF_USE_ACCELERATED_COMPOSITING 1 -#define ENABLE_3D_RENDERING 1 -#endif - -#if (PLATFORM(MAC) && !defined(BUILDING_ON_TIGER)) || PLATFORM(IOS) || PLATFORM(QT) || (PLATFORM(WIN) && !OS(WINCE) &&!defined(WIN_CAIRO)) -#define WTF_USE_ACCELERATED_COMPOSITING 1 -#endif - -#if (PLATFORM(MAC) && !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD)) || PLATFORM(IOS) -#define WTF_USE_PROTECTION_SPACE_AUTH_CALLBACK 1 -#endif - -#if COMPILER(GCC) -#define WARN_UNUSED_RETURN __attribute__ ((warn_unused_result)) -#else -#define WARN_UNUSED_RETURN -#endif - -#if !ENABLE(NETSCAPE_PLUGIN_API) || (ENABLE(NETSCAPE_PLUGIN_API) && ((OS(UNIX) && (PLATFORM(QT) || PLATFORM(WX))) || PLATFORM(GTK))) -#define ENABLE_PLUGIN_PACKAGE_SIMPLE_HASH 1 -#endif - -/* Set up a define for a common error that is intended to cause a build error -- thus the space after Error. */ -#define WTF_PLATFORM_CFNETWORK Error USE_macro_should_be_used_with_CFNETWORK - -#define ENABLE_JSC_ZOMBIES 0 - -/* FIXME: Eventually we should enable this for all platforms and get rid of the define. */ -#if PLATFORM(MAC) || PLATFORM(WIN) || PLATFORM(QT) -#define WTF_USE_PLATFORM_STRATEGIES 1 -#endif - -#if PLATFORM(WIN) -#define WTF_USE_CROSS_PLATFORM_CONTEXT_MENUS 1 -#endif - -/* Geolocation request policy. pre-emptive policy is to acquire user permission before acquiring location. - Client based implementations will have option to choose between pre-emptive and nonpre-emptive permission policy. - pre-emptive permission policy is enabled by default for all client-based implementations. */ -#if ENABLE(CLIENT_BASED_GEOLOCATION) -#define WTF_USE_PREEMPT_GEOLOCATION_PERMISSION 1 -#endif - -#if CPU(ARM_THUMB2) -#define ENABLE_BRANCH_COMPACTION 1 -#endif - -#if ENABLE(GLIB_SUPPORT) -#include "GTypedefs.h" -#endif - -#endif /* WTF_Platform_h */ diff --git a/JavaScriptCore/wtf/PlatformRefPtr.h b/JavaScriptCore/wtf/PlatformRefPtr.h deleted file mode 100644 index e4f1314..0000000 --- a/JavaScriptCore/wtf/PlatformRefPtr.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora Ltd. - * Copyright (C) 2009 Martin Robinson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef PlatformRefPtr_h -#define PlatformRefPtr_h - -#include "AlwaysInline.h" -#include "RefPtr.h" -#include <algorithm> - -namespace WTF { - -enum PlatformRefPtrAdoptType { PlatformRefPtrAdopt }; -template <typename T> inline T* refPlatformPtr(T*); -template <typename T> inline void derefPlatformPtr(T*); -template <typename T> class PlatformRefPtr; -template <typename T> PlatformRefPtr<T> adoptPlatformRef(T*); - -template <typename T> class PlatformRefPtr { -public: - PlatformRefPtr() : m_ptr(0) { } - - PlatformRefPtr(T* ptr) - : m_ptr(ptr) - { - if (ptr) - refPlatformPtr(ptr); - } - - PlatformRefPtr(const PlatformRefPtr& o) - : m_ptr(o.m_ptr) - { - if (T* ptr = m_ptr) - refPlatformPtr(ptr); - } - - template <typename U> PlatformRefPtr(const PlatformRefPtr<U>& o) - : m_ptr(o.get()) - { - if (T* ptr = m_ptr) - refPlatformPtr(ptr); - } - - ~PlatformRefPtr() - { - if (T* ptr = m_ptr) - derefPlatformPtr(ptr); - } - - void clear() - { - T* ptr = m_ptr; - m_ptr = 0; - if (ptr) - derefPlatformPtr(ptr); - } - - T* leakRef() WARN_UNUSED_RETURN - { - T* ptr = m_ptr; - m_ptr = 0; - return ptr; - } - - // Hash table deleted values, which are only constructed and never copied or destroyed. - PlatformRefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } - bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } - - T* get() const { return m_ptr; } - T& operator*() const { return *m_ptr; } - ALWAYS_INLINE T* operator->() const { return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef T* PlatformRefPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &PlatformRefPtr::m_ptr : 0; } - - PlatformRefPtr& operator=(const PlatformRefPtr&); - PlatformRefPtr& operator=(T*); - template <typename U> PlatformRefPtr& operator=(const PlatformRefPtr<U>&); - - void swap(PlatformRefPtr&); - friend PlatformRefPtr adoptPlatformRef<T>(T*); - -private: - static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } - // Adopting constructor. - PlatformRefPtr(T* ptr, PlatformRefPtrAdoptType) : m_ptr(ptr) {} - - T* m_ptr; -}; - -template <typename T> inline PlatformRefPtr<T>& PlatformRefPtr<T>::operator=(const PlatformRefPtr<T>& o) -{ - T* optr = o.get(); - if (optr) - refPlatformPtr(optr); - T* ptr = m_ptr; - m_ptr = optr; - if (ptr) - derefPlatformPtr(ptr); - return *this; -} - -template <typename T> inline PlatformRefPtr<T>& PlatformRefPtr<T>::operator=(T* optr) -{ - T* ptr = m_ptr; - if (optr) - refPlatformPtr(optr); - m_ptr = optr; - if (ptr) - derefPlatformPtr(ptr); - return *this; -} - -template <class T> inline void PlatformRefPtr<T>::swap(PlatformRefPtr<T>& o) -{ - std::swap(m_ptr, o.m_ptr); -} - -template <class T> inline void swap(PlatformRefPtr<T>& a, PlatformRefPtr<T>& b) -{ - a.swap(b); -} - -template <typename T, typename U> inline bool operator==(const PlatformRefPtr<T>& a, const PlatformRefPtr<U>& b) -{ - return a.get() == b.get(); -} - -template <typename T, typename U> inline bool operator==(const PlatformRefPtr<T>& a, U* b) -{ - return a.get() == b; -} - -template <typename T, typename U> inline bool operator==(T* a, const PlatformRefPtr<U>& b) -{ - return a == b.get(); -} - -template <typename T, typename U> inline bool operator!=(const PlatformRefPtr<T>& a, const PlatformRefPtr<U>& b) -{ - return a.get() != b.get(); -} - -template <typename T, typename U> inline bool operator!=(const PlatformRefPtr<T>& a, U* b) -{ - return a.get() != b; -} - -template <typename T, typename U> inline bool operator!=(T* a, const PlatformRefPtr<U>& b) -{ - return a != b.get(); -} - -template <typename T, typename U> inline PlatformRefPtr<T> static_pointer_cast(const PlatformRefPtr<U>& p) -{ - return PlatformRefPtr<T>(static_cast<T*>(p.get())); -} - -template <typename T, typename U> inline PlatformRefPtr<T> const_pointer_cast(const PlatformRefPtr<U>& p) -{ - return PlatformRefPtr<T>(const_cast<T*>(p.get())); -} - -template <typename T> inline T* getPtr(const PlatformRefPtr<T>& p) -{ - return p.get(); -} - -template <typename T> PlatformRefPtr<T> adoptPlatformRef(T* p) -{ - return PlatformRefPtr<T>(p, PlatformRefPtrAdopt); -} - -} // namespace WTF - -using WTF::PlatformRefPtr; -using WTF::refPlatformPtr; -using WTF::derefPlatformPtr; -using WTF::adoptPlatformRef; -using WTF::static_pointer_cast; -using WTF::const_pointer_cast; - -#endif // PlatformRefPtr_h diff --git a/JavaScriptCore/wtf/PossiblyNull.h b/JavaScriptCore/wtf/PossiblyNull.h deleted file mode 100644 index 79c4d82..0000000 --- a/JavaScriptCore/wtf/PossiblyNull.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef PossiblyNull_h -#define PossiblyNull_h - -#include "Assertions.h" - -namespace WTF { - -template <typename T> struct PossiblyNull { - PossiblyNull(T data) - : m_data(data) - { - } - PossiblyNull(const PossiblyNull<T>& source) - : m_data(source.m_data) - { - source.m_data = 0; - } - ~PossiblyNull() { ASSERT(!m_data); } - bool getValue(T& out) WARN_UNUSED_RETURN; -private: - mutable T m_data; -}; - -template <typename T> bool PossiblyNull<T>::getValue(T& out) -{ - out = m_data; - bool result = !!m_data; - m_data = 0; - return result; -} - -} - -#endif diff --git a/JavaScriptCore/wtf/RandomNumber.cpp b/JavaScriptCore/wtf/RandomNumber.cpp deleted file mode 100644 index 7a9b6a8..0000000 --- a/JavaScriptCore/wtf/RandomNumber.cpp +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "RandomNumber.h" - -#include "RandomNumberSeed.h" - -#include <limits> -#include <limits.h> -#include <stdint.h> -#include <stdlib.h> - -#if OS(WINCE) -extern "C" { -#include "wince/mt19937ar.c" -} -#endif - -#if PLATFORM(BREWMP) -#include <AEEAppGen.h> -#include <AEESource.h> -#include <AEEStdLib.h> -#include <wtf/brew/RefPtrBrew.h> -#include <wtf/brew/ShellBrew.h> -#endif - -namespace WTF { - -double randomNumber() -{ -#if !ENABLE(JSC_MULTIPLE_THREADS) - static bool s_initialized = false; - if (!s_initialized) { - initializeRandomNumberGenerator(); - s_initialized = true; - } -#endif - -#if COMPILER(MSVC) && defined(_CRT_RAND_S) - uint32_t bits; - rand_s(&bits); - return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); -#elif OS(DARWIN) - uint32_t bits = arc4random(); - return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); -#elif OS(UNIX) - uint32_t part1 = random() & (RAND_MAX - 1); - uint32_t part2 = random() & (RAND_MAX - 1); - // random only provides 31 bits - uint64_t fullRandom = part1; - fullRandom <<= 31; - fullRandom |= part2; - - // Mask off the low 53bits - fullRandom &= (1LL << 53) - 1; - return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); -#elif OS(WINCE) - return genrand_res53(); -#elif OS(WINDOWS) - uint32_t part1 = rand() & (RAND_MAX - 1); - uint32_t part2 = rand() & (RAND_MAX - 1); - uint32_t part3 = rand() & (RAND_MAX - 1); - uint32_t part4 = rand() & (RAND_MAX - 1); - // rand only provides 15 bits on Win32 - uint64_t fullRandom = part1; - fullRandom <<= 15; - fullRandom |= part2; - fullRandom <<= 15; - fullRandom |= part3; - fullRandom <<= 15; - fullRandom |= part4; - - // Mask off the low 53bits - fullRandom &= (1LL << 53) - 1; - return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); -#elif PLATFORM(BREWMP) - uint32_t bits; - PlatformRefPtr<ISource> randomSource = createRefPtrInstance<ISource>(AEECLSID_RANDOM); - ISOURCE_Read(randomSource.get(), reinterpret_cast<char*>(&bits), 4); - - return static_cast<double>(bits) / (static_cast<double>(std::numeric_limits<uint32_t>::max()) + 1.0); -#else - uint32_t part1 = rand() & (RAND_MAX - 1); - uint32_t part2 = rand() & (RAND_MAX - 1); - // rand only provides 31 bits, and the low order bits of that aren't very random - // so we take the high 26 bits of part 1, and the high 27 bits of part2. - part1 >>= 5; // drop the low 5 bits - part2 >>= 4; // drop the low 4 bits - uint64_t fullRandom = part1; - fullRandom <<= 27; - fullRandom |= part2; - - // Mask off the low 53bits - fullRandom &= (1LL << 53) - 1; - return static_cast<double>(fullRandom)/static_cast<double>(1LL << 53); -#endif -} - -} diff --git a/JavaScriptCore/wtf/RandomNumber.h b/JavaScriptCore/wtf/RandomNumber.h deleted file mode 100644 index f2e7e8f..0000000 --- a/JavaScriptCore/wtf/RandomNumber.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_RandomNumber_h -#define WTF_RandomNumber_h - -namespace WTF { - - // Returns a pseudo-random number in the range [0, 1), attempts to be - // cryptographically secure if possible on the target platform - double randomNumber(); - -} - -using WTF::randomNumber; - -#endif diff --git a/JavaScriptCore/wtf/RandomNumberSeed.h b/JavaScriptCore/wtf/RandomNumberSeed.h deleted file mode 100644 index 9ea7c71..0000000 --- a/JavaScriptCore/wtf/RandomNumberSeed.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_RandomNumberSeed_h -#define WTF_RandomNumberSeed_h - -#include <stdlib.h> -#include <time.h> - -#if HAVE(SYS_TIME_H) -#include <sys/time.h> -#endif - -#if OS(UNIX) -#include <sys/types.h> -#include <unistd.h> -#endif - -#if OS(WINCE) -extern "C" { -void init_by_array(unsigned long init_key[],int key_length); -} -#endif - -// Internal JavaScriptCore usage only -namespace WTF { - -inline void initializeRandomNumberGenerator() -{ -#if OS(DARWIN) - // On Darwin we use arc4random which initialises itself. -#elif OS(WINCE) - // initialize rand() - srand(GetTickCount()); - - // use rand() to initialize the real RNG - unsigned long initializationBuffer[4]; - initializationBuffer[0] = (rand() << 16) | rand(); - initializationBuffer[1] = (rand() << 16) | rand(); - initializationBuffer[2] = (rand() << 16) | rand(); - initializationBuffer[3] = (rand() << 16) | rand(); - init_by_array(initializationBuffer, 4); -#elif COMPILER(MSVC) && defined(_CRT_RAND_S) - // On Windows we use rand_s which initialises itself -#elif PLATFORM(BREWMP) - // On Brew MP we use AEECLSID_RANDOM which initialises itself -#elif OS(UNIX) - // srandomdev is not guaranteed to exist on linux so we use this poor seed, this should be improved - timeval time; - gettimeofday(&time, 0); - srandom(static_cast<unsigned>(time.tv_usec * getpid())); -#else - srand(static_cast<unsigned>(time(0))); -#endif -} - -} - -#endif diff --git a/JavaScriptCore/wtf/RefCounted.h b/JavaScriptCore/wtf/RefCounted.h deleted file mode 100644 index 8d8b302..0000000 --- a/JavaScriptCore/wtf/RefCounted.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef RefCounted_h -#define RefCounted_h - -#include "Assertions.h" -#include "Noncopyable.h" - -namespace WTF { - -// This base class holds the non-template methods and attributes. -// The RefCounted class inherits from it reducing the template bloat -// generated by the compiler (technique called template hoisting). -class RefCountedBase { -public: - void ref() - { - ASSERT(!m_deletionHasBegun); - ASSERT(!m_adoptionIsRequired); - ++m_refCount; - } - - bool hasOneRef() const - { - ASSERT(!m_deletionHasBegun); - return m_refCount == 1; - } - - int refCount() const - { - return m_refCount; - } - - void relaxAdoptionRequirement() - { -#ifndef NDEBUG - ASSERT(!m_deletionHasBegun); - ASSERT(m_adoptionIsRequired); - m_adoptionIsRequired = false; -#endif - } - -protected: - RefCountedBase() - : m_refCount(1) -#ifndef NDEBUG - , m_deletionHasBegun(false) - , m_adoptionIsRequired(true) -#endif - { - } - - ~RefCountedBase() - { - ASSERT(m_deletionHasBegun); - ASSERT(!m_adoptionIsRequired); - } - - // Returns whether the pointer should be freed or not. - bool derefBase() - { - ASSERT(!m_deletionHasBegun); - ASSERT(!m_adoptionIsRequired); - - ASSERT(m_refCount > 0); - if (m_refCount == 1) { -#ifndef NDEBUG - m_deletionHasBegun = true; -#endif - return true; - } - - --m_refCount; - return false; - } - - // Helper for generating JIT code. Please do not use for non-JIT purposes. - int* addressOfCount() - { - return &m_refCount; - } - -#ifndef NDEBUG - bool deletionHasBegun() const - { - return m_deletionHasBegun; - } -#endif - -private: - template<typename T> friend class CrossThreadRefCounted; - -#ifndef NDEBUG - friend void adopted(RefCountedBase*); -#endif - - int m_refCount; -#ifndef NDEBUG - bool m_deletionHasBegun; - bool m_adoptionIsRequired; -#endif -}; - -#ifndef NDEBUG - -inline void adopted(RefCountedBase* object) -{ - if (!object) - return; - ASSERT(!object->m_deletionHasBegun); - object->m_adoptionIsRequired = false; -} - -#endif - -template<typename T> class RefCounted : public RefCountedBase, public Noncopyable { -public: - void deref() - { - if (derefBase()) - delete static_cast<T*>(this); - } - -protected: - ~RefCounted() - { - } -}; - -template<typename T> class RefCountedCustomAllocated : public RefCountedBase { - WTF_MAKE_NONCOPYABLE(RefCountedCustomAllocated); - -public: - void deref() - { - if (derefBase()) - delete static_cast<T*>(this); - } - -protected: - ~RefCountedCustomAllocated() - { - } -}; - -} // namespace WTF - -using WTF::RefCounted; -using WTF::RefCountedCustomAllocated; - -#endif // RefCounted_h diff --git a/JavaScriptCore/wtf/RefCountedLeakCounter.cpp b/JavaScriptCore/wtf/RefCountedLeakCounter.cpp deleted file mode 100644 index 80922d3..0000000 --- a/JavaScriptCore/wtf/RefCountedLeakCounter.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "RefCountedLeakCounter.h" - -#include <wtf/HashCountedSet.h> - -namespace WTF { - -#ifdef NDEBUG - -void RefCountedLeakCounter::suppressMessages(const char*) { } -void RefCountedLeakCounter::cancelMessageSuppression(const char*) { } - -RefCountedLeakCounter::RefCountedLeakCounter(const char*) { } -RefCountedLeakCounter::~RefCountedLeakCounter() { } - -void RefCountedLeakCounter::increment() { } -void RefCountedLeakCounter::decrement() { } - -#else - -#define LOG_CHANNEL_PREFIX Log -static WTFLogChannel LogRefCountedLeaks = { 0x00000000, "", WTFLogChannelOn }; - -typedef HashCountedSet<const char*, PtrHash<const char*> > ReasonSet; -static ReasonSet* leakMessageSuppressionReasons; - -void RefCountedLeakCounter::suppressMessages(const char* reason) -{ - if (!leakMessageSuppressionReasons) - leakMessageSuppressionReasons = new ReasonSet; - leakMessageSuppressionReasons->add(reason); -} - -void RefCountedLeakCounter::cancelMessageSuppression(const char* reason) -{ - ASSERT(leakMessageSuppressionReasons); - ASSERT(leakMessageSuppressionReasons->contains(reason)); - leakMessageSuppressionReasons->remove(reason); -} - -RefCountedLeakCounter::RefCountedLeakCounter(const char* description) - : m_description(description) -{ -} - -RefCountedLeakCounter::~RefCountedLeakCounter() -{ - static bool loggedSuppressionReason; - if (m_count) { - if (!leakMessageSuppressionReasons || leakMessageSuppressionReasons->isEmpty()) - LOG(RefCountedLeaks, "LEAK: %u %s", m_count, m_description); - else if (!loggedSuppressionReason) { - // This logs only one reason. Later we could change it so we log all the reasons. - LOG(RefCountedLeaks, "No leak checking done: %s", leakMessageSuppressionReasons->begin()->first); - loggedSuppressionReason = true; - } - } -} - -void RefCountedLeakCounter::increment() -{ -#if ENABLE(JSC_MULTIPLE_THREADS) - atomicIncrement(&m_count); -#else - ++m_count; -#endif -} - -void RefCountedLeakCounter::decrement() -{ -#if ENABLE(JSC_MULTIPLE_THREADS) - atomicDecrement(&m_count); -#else - --m_count; -#endif -} - -#endif - -} // namespace WTF diff --git a/JavaScriptCore/wtf/RefCountedLeakCounter.h b/JavaScriptCore/wtf/RefCountedLeakCounter.h deleted file mode 100644 index 57cc283..0000000 --- a/JavaScriptCore/wtf/RefCountedLeakCounter.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef RefCountedLeakCounter_h -#define RefCountedLeakCounter_h - -#include "Assertions.h" -#include "Threading.h" - -namespace WTF { - - struct RefCountedLeakCounter { - static void suppressMessages(const char*); - static void cancelMessageSuppression(const char*); - - explicit RefCountedLeakCounter(const char* description); - ~RefCountedLeakCounter(); - - void increment(); - void decrement(); - -#ifndef NDEBUG - private: - volatile int m_count; - const char* m_description; -#endif - }; - -} // namespace WTF - -#endif diff --git a/JavaScriptCore/wtf/RefPtr.h b/JavaScriptCore/wtf/RefPtr.h deleted file mode 100644 index 6afa886..0000000 --- a/JavaScriptCore/wtf/RefPtr.h +++ /dev/null @@ -1,229 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -// RefPtr and PassRefPtr are documented at http://webkit.org/coding/RefPtr.html - -#ifndef WTF_RefPtr_h -#define WTF_RefPtr_h - -#include <algorithm> -#include "FastAllocBase.h" -#include "PassRefPtr.h" - -namespace WTF { - - enum PlacementNewAdoptType { PlacementNewAdopt }; - - template<typename T> class PassRefPtr; - template<typename T> class NonNullPassRefPtr; - - enum HashTableDeletedValueType { HashTableDeletedValue }; - - template<typename T> class RefPtr : public FastAllocBase { - public: - ALWAYS_INLINE RefPtr() : m_ptr(0) { } - ALWAYS_INLINE RefPtr(T* ptr) : m_ptr(ptr) { refIfNotNull(ptr); } - ALWAYS_INLINE RefPtr(const RefPtr& o) : m_ptr(o.m_ptr) { refIfNotNull(m_ptr); } - template<typename U> RefPtr(const RefPtr<U>& o) : m_ptr(o.get()) { refIfNotNull(m_ptr); } - - // See comments in PassRefPtr.h for an explanation of why these takes const references. - template<typename U> RefPtr(const PassRefPtr<U>&); - template<typename U> RefPtr(const NonNullPassRefPtr<U>&); - - // Special constructor for cases where we overwrite an object in place. - ALWAYS_INLINE RefPtr(PlacementNewAdoptType) { } - - // Hash table deleted values, which are only constructed and never copied or destroyed. - RefPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } - bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } - - ALWAYS_INLINE ~RefPtr() { derefIfNotNull(m_ptr); } - - T* get() const { return m_ptr; } - - void clear(); - PassRefPtr<T> release() { PassRefPtr<T> tmp = adoptRef(m_ptr); m_ptr = 0; return tmp; } - - T& operator*() const { return *m_ptr; } - ALWAYS_INLINE T* operator->() const { return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef T* (RefPtr::*UnspecifiedBoolType); - operator UnspecifiedBoolType() const { return m_ptr ? &RefPtr::m_ptr : 0; } - - RefPtr& operator=(const RefPtr&); - RefPtr& operator=(T*); - RefPtr& operator=(const PassRefPtr<T>&); - RefPtr& operator=(const NonNullPassRefPtr<T>&); - RefPtr& operator=(std::nullptr_t) { clear(); return *this; } - template<typename U> RefPtr& operator=(const RefPtr<U>&); - template<typename U> RefPtr& operator=(const PassRefPtr<U>&); - template<typename U> RefPtr& operator=(const NonNullPassRefPtr<U>&); - - void swap(RefPtr&); - - static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } - - private: - T* m_ptr; - }; - - template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const PassRefPtr<U>& o) - : m_ptr(o.leakRef()) - { - } - - template<typename T> template<typename U> inline RefPtr<T>::RefPtr(const NonNullPassRefPtr<U>& o) - : m_ptr(o.leakRef()) - { - } - - template<typename T> inline void RefPtr<T>::clear() - { - T* ptr = m_ptr; - m_ptr = 0; - derefIfNotNull(ptr); - } - - template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<T>& o) - { - T* optr = o.get(); - refIfNotNull(optr); - T* ptr = m_ptr; - m_ptr = optr; - derefIfNotNull(ptr); - return *this; - } - - template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const RefPtr<U>& o) - { - T* optr = o.get(); - refIfNotNull(optr); - T* ptr = m_ptr; - m_ptr = optr; - derefIfNotNull(ptr); - return *this; - } - - template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(T* optr) - { - refIfNotNull(optr); - T* ptr = m_ptr; - m_ptr = optr; - derefIfNotNull(ptr); - return *this; - } - - template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<T>& o) - { - T* ptr = m_ptr; - m_ptr = o.leakRef(); - derefIfNotNull(ptr); - return *this; - } - - template<typename T> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<T>& o) - { - T* ptr = m_ptr; - m_ptr = o.leakRef(); - derefIfNotNull(ptr); - return *this; - } - - template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const PassRefPtr<U>& o) - { - T* ptr = m_ptr; - m_ptr = o.leakRef(); - derefIfNotNull(ptr); - return *this; - } - - template<typename T> template<typename U> inline RefPtr<T>& RefPtr<T>::operator=(const NonNullPassRefPtr<U>& o) - { - T* ptr = m_ptr; - m_ptr = o.leakRef(); - derefIfNotNull(ptr); - return *this; - } - - template<class T> inline void RefPtr<T>::swap(RefPtr<T>& o) - { - std::swap(m_ptr, o.m_ptr); - } - - template<class T> inline void swap(RefPtr<T>& a, RefPtr<T>& b) - { - a.swap(b); - } - - template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, const RefPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const RefPtr<T>& a, U* b) - { - return a.get() == b; - } - - template<typename T, typename U> inline bool operator==(T* a, const RefPtr<U>& b) - { - return a == b.get(); - } - - template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, const RefPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const RefPtr<T>& a, U* b) - { - return a.get() != b; - } - - template<typename T, typename U> inline bool operator!=(T* a, const RefPtr<U>& b) - { - return a != b.get(); - } - - template<typename T, typename U> inline RefPtr<T> static_pointer_cast(const RefPtr<U>& p) - { - return RefPtr<T>(static_cast<T*>(p.get())); - } - - template<typename T, typename U> inline RefPtr<T> const_pointer_cast(const RefPtr<U>& p) - { - return RefPtr<T>(const_cast<T*>(p.get())); - } - - template<typename T> inline T* getPtr(const RefPtr<T>& p) - { - return p.get(); - } - -} // namespace WTF - -using WTF::RefPtr; -using WTF::static_pointer_cast; -using WTF::const_pointer_cast; - -#endif // WTF_RefPtr_h diff --git a/JavaScriptCore/wtf/RefPtrHashMap.h b/JavaScriptCore/wtf/RefPtrHashMap.h deleted file mode 100644 index 7f6ebfe..0000000 --- a/JavaScriptCore/wtf/RefPtrHashMap.h +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -namespace WTF { - - // This specialization is a direct copy of HashMap, with overloaded functions - // to allow for lookup by pointer instead of RefPtr, avoiding ref-count churn. - - // FIXME: Find a better way that doesn't require an entire copy of the HashMap template. - - template<typename RawKeyType, typename ValueType, typename ValueTraits, typename HashFunctions> - struct RefPtrHashMapRawKeyTranslator { - typedef typename ValueType::first_type KeyType; - typedef typename ValueType::second_type MappedType; - typedef typename ValueTraits::FirstTraits KeyTraits; - typedef typename ValueTraits::SecondTraits MappedTraits; - - static unsigned hash(RawKeyType key) { return HashFunctions::hash(key); } - static bool equal(const KeyType& a, RawKeyType b) { return HashFunctions::equal(a, b); } - static void translate(ValueType& location, RawKeyType key, const MappedType& mapped) - { - location.first = key; - location.second = mapped; - } - }; - - template<typename T, typename MappedArg, typename HashArg, typename KeyTraitsArg, typename MappedTraitsArg> - class HashMap<RefPtr<T>, MappedArg, HashArg, KeyTraitsArg, MappedTraitsArg> : public FastAllocBase { - private: - typedef KeyTraitsArg KeyTraits; - typedef MappedTraitsArg MappedTraits; - typedef PairHashTraits<KeyTraits, MappedTraits> ValueTraits; - - public: - typedef typename KeyTraits::TraitType KeyType; - typedef T* RawKeyType; - typedef typename MappedTraits::TraitType MappedType; - typedef typename ValueTraits::TraitType ValueType; - - private: - typedef HashArg HashFunctions; - - typedef HashTable<KeyType, ValueType, PairFirstExtractor<ValueType>, - HashFunctions, ValueTraits, KeyTraits> HashTableType; - - typedef RefPtrHashMapRawKeyTranslator<RawKeyType, ValueType, ValueTraits, HashFunctions> - RawKeyTranslator; - - public: - typedef HashTableIteratorAdapter<HashTableType, ValueType> iterator; - typedef HashTableConstIteratorAdapter<HashTableType, ValueType> const_iterator; - - void swap(HashMap&); - - int size() const; - int capacity() const; - bool isEmpty() const; - - // iterators iterate over pairs of keys and values - iterator begin(); - iterator end(); - const_iterator begin() const; - const_iterator end() const; - - iterator find(const KeyType&); - iterator find(RawKeyType); - const_iterator find(const KeyType&) const; - const_iterator find(RawKeyType) const; - bool contains(const KeyType&) const; - bool contains(RawKeyType) const; - MappedType get(const KeyType&) const; - MappedType get(RawKeyType) const; - MappedType inlineGet(RawKeyType) const; - - // replaces value but not key if key is already present - // return value is a pair of the iterator to the key location, - // and a boolean that's true if a new value was actually added - pair<iterator, bool> set(const KeyType&, const MappedType&); - pair<iterator, bool> set(RawKeyType, const MappedType&); - - // does nothing if key is already present - // return value is a pair of the iterator to the key location, - // and a boolean that's true if a new value was actually added - pair<iterator, bool> add(const KeyType&, const MappedType&); - pair<iterator, bool> add(RawKeyType, const MappedType&); - - void remove(const KeyType&); - void remove(RawKeyType); - void remove(iterator); - void clear(); - - MappedType take(const KeyType&); // efficient combination of get with remove - MappedType take(RawKeyType); // efficient combination of get with remove - - private: - pair<iterator, bool> inlineAdd(const KeyType&, const MappedType&); - pair<iterator, bool> inlineAdd(RawKeyType, const MappedType&); - - HashTableType m_impl; - }; - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<RefPtr<T>, U, V, W, X>::swap(HashMap& other) - { - m_impl.swap(other.m_impl); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline int HashMap<RefPtr<T>, U, V, W, X>::size() const - { - return m_impl.size(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline int HashMap<RefPtr<T>, U, V, W, X>::capacity() const - { - return m_impl.capacity(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline bool HashMap<RefPtr<T>, U, V, W, X>::isEmpty() const - { - return m_impl.isEmpty(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::begin() - { - return m_impl.begin(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::end() - { - return m_impl.end(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::begin() const - { - return m_impl.begin(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::end() const - { - return m_impl.end(); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) - { - return m_impl.find(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) - { - return m_impl.template find<RawKeyType, RawKeyTranslator>(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(const KeyType& key) const - { - return m_impl.find(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline typename HashMap<RefPtr<T>, U, V, W, X>::const_iterator HashMap<RefPtr<T>, U, V, W, X>::find(RawKeyType key) const - { - return m_impl.template find<RawKeyType, RawKeyTranslator>(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(const KeyType& key) const - { - return m_impl.contains(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline bool HashMap<RefPtr<T>, U, V, W, X>::contains(RawKeyType key) const - { - return m_impl.template contains<RawKeyType, RawKeyTranslator>(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool> - HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(const KeyType& key, const MappedType& mapped) - { - typedef HashMapTranslator<ValueType, ValueTraits, HashFunctions> TranslatorType; - return m_impl.template add<KeyType, MappedType, TranslatorType>(key, mapped); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool> - HashMap<RefPtr<T>, U, V, W, X>::inlineAdd(RawKeyType key, const MappedType& mapped) - { - return m_impl.template add<RawKeyType, MappedType, RawKeyTranslator>(key, mapped); - } - - template<typename T, typename U, typename V, typename W, typename X> - pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool> - HashMap<RefPtr<T>, U, V, W, X>::set(const KeyType& key, const MappedType& mapped) - { - pair<iterator, bool> result = inlineAdd(key, mapped); - if (!result.second) { - // add call above didn't change anything, so set the mapped value - result.first->second = mapped; - } - return result; - } - - template<typename T, typename U, typename V, typename W, typename X> - pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool> - HashMap<RefPtr<T>, U, V, W, X>::set(RawKeyType key, const MappedType& mapped) - { - pair<iterator, bool> result = inlineAdd(key, mapped); - if (!result.second) { - // add call above didn't change anything, so set the mapped value - result.first->second = mapped; - } - return result; - } - - template<typename T, typename U, typename V, typename W, typename X> - pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool> - HashMap<RefPtr<T>, U, V, W, X>::add(const KeyType& key, const MappedType& mapped) - { - return inlineAdd(key, mapped); - } - - template<typename T, typename U, typename V, typename W, typename X> - pair<typename HashMap<RefPtr<T>, U, V, W, X>::iterator, bool> - HashMap<RefPtr<T>, U, V, W, X>::add(RawKeyType key, const MappedType& mapped) - { - return inlineAdd(key, mapped); - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType - HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(const KeyType& key) const - { - ValueType* entry = const_cast<HashTableType&>(m_impl).lookup(key); - if (!entry) - return MappedTraits::emptyValue(); - return entry->second; - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType - inline HashMap<RefPtr<T>, U, V, W, MappedTraits>::inlineGet(RawKeyType key) const - { - ValueType* entry = const_cast<HashTableType&>(m_impl).template lookup<RawKeyType, RawKeyTranslator>(key); - if (!entry) - return MappedTraits::emptyValue(); - return entry->second; - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType - HashMap<RefPtr<T>, U, V, W, MappedTraits>::get(RawKeyType key) const - { - return inlineGet(key); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<RefPtr<T>, U, V, W, X>::remove(iterator it) - { - if (it.m_impl == m_impl.end()) - return; - m_impl.internalCheckTableConsistency(); - m_impl.removeWithoutEntryConsistencyCheck(it.m_impl); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<RefPtr<T>, U, V, W, X>::remove(const KeyType& key) - { - remove(find(key)); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<RefPtr<T>, U, V, W, X>::remove(RawKeyType key) - { - remove(find(key)); - } - - template<typename T, typename U, typename V, typename W, typename X> - inline void HashMap<RefPtr<T>, U, V, W, X>::clear() - { - m_impl.clear(); - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType - HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(const KeyType& key) - { - // This can probably be made more efficient to avoid ref/deref churn. - iterator it = find(key); - if (it == end()) - return MappedTraits::emptyValue(); - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType result = it->second; - remove(it); - return result; - } - - template<typename T, typename U, typename V, typename W, typename MappedTraits> - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType - HashMap<RefPtr<T>, U, V, W, MappedTraits>::take(RawKeyType key) - { - // This can probably be made more efficient to avoid ref/deref churn. - iterator it = find(key); - if (it == end()) - return MappedTraits::emptyValue(); - typename HashMap<RefPtr<T>, U, V, W, MappedTraits>::MappedType result = it->second; - remove(it); - return result; - } - -} // namespace WTF diff --git a/JavaScriptCore/wtf/RetainPtr.h b/JavaScriptCore/wtf/RetainPtr.h deleted file mode 100644 index 8a14cfe..0000000 --- a/JavaScriptCore/wtf/RetainPtr.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef RetainPtr_h -#define RetainPtr_h - -#include "HashTraits.h" -#include "NullPtr.h" -#include "TypeTraits.h" -#include <algorithm> -#include <CoreFoundation/CoreFoundation.h> - -#ifdef __OBJC__ -#import <Foundation/Foundation.h> -#endif - -namespace WTF { - - // Unlike most most of our smart pointers, RetainPtr can take either the pointer type or the pointed-to type, - // so both RetainPtr<NSDictionary> and RetainPtr<CFDictionaryRef> will work. - - enum AdoptCFTag { AdoptCF }; - enum AdoptNSTag { AdoptNS }; - -#ifdef __OBJC__ - inline void adoptNSReference(id ptr) - { - if (ptr) { - CFRetain(ptr); - [ptr release]; - } - } -#endif - - template<typename T> class RetainPtr { - public: - typedef typename RemovePointer<T>::Type ValueType; - typedef ValueType* PtrType; - - RetainPtr() : m_ptr(0) {} - RetainPtr(PtrType ptr) : m_ptr(ptr) { if (ptr) CFRetain(ptr); } - - RetainPtr(AdoptCFTag, PtrType ptr) : m_ptr(ptr) { } - RetainPtr(AdoptNSTag, PtrType ptr) : m_ptr(ptr) { adoptNSReference(ptr); } - - RetainPtr(const RetainPtr& o) : m_ptr(o.m_ptr) { if (PtrType ptr = m_ptr) CFRetain(ptr); } - - // Hash table deleted values, which are only constructed and never copied or destroyed. - RetainPtr(HashTableDeletedValueType) : m_ptr(hashTableDeletedValue()) { } - bool isHashTableDeletedValue() const { return m_ptr == hashTableDeletedValue(); } - - ~RetainPtr() { if (PtrType ptr = m_ptr) CFRelease(ptr); } - - template<typename U> RetainPtr(const RetainPtr<U>&); - - PtrType get() const { return m_ptr; } - - void clear(); - PtrType leakRef() WARN_UNUSED_RETURN; - - PtrType operator->() const { return m_ptr; } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef PtrType RetainPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &RetainPtr::m_ptr : 0; } - - RetainPtr& operator=(const RetainPtr&); - template<typename U> RetainPtr& operator=(const RetainPtr<U>&); - RetainPtr& operator=(PtrType); - template<typename U> RetainPtr& operator=(U*); - RetainPtr& operator=(std::nullptr_t) { clear(); return *this; } - - void adoptCF(PtrType); - void adoptNS(PtrType); - - void swap(RetainPtr&); - - // FIXME: Remove releaseRef once we change all callers to call leakRef instead. - PtrType releaseRef() { return leakRef(); } - - private: - static T* hashTableDeletedValue() { return reinterpret_cast<T*>(-1); } - - PtrType m_ptr; - }; - - template<typename T> template<typename U> inline RetainPtr<T>::RetainPtr(const RetainPtr<U>& o) - : m_ptr(o.get()) - { - if (PtrType ptr = m_ptr) - CFRetain(ptr); - } - - template<typename T> inline void RetainPtr<T>::clear() - { - if (PtrType ptr = m_ptr) { - m_ptr = 0; - CFRelease(ptr); - } - } - - template<typename T> inline typename RetainPtr<T>::PtrType RetainPtr<T>::leakRef() - { - PtrType ptr = m_ptr; - m_ptr = 0; - return ptr; - } - - template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<T>& o) - { - PtrType optr = o.get(); - if (optr) - CFRetain(optr); - PtrType ptr = m_ptr; - m_ptr = optr; - if (ptr) - CFRelease(ptr); - return *this; - } - - template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(const RetainPtr<U>& o) - { - PtrType optr = o.get(); - if (optr) - CFRetain(optr); - PtrType ptr = m_ptr; - m_ptr = optr; - if (ptr) - CFRelease(ptr); - return *this; - } - - template<typename T> inline RetainPtr<T>& RetainPtr<T>::operator=(PtrType optr) - { - if (optr) - CFRetain(optr); - PtrType ptr = m_ptr; - m_ptr = optr; - if (ptr) - CFRelease(ptr); - return *this; - } - - template<typename T> inline void RetainPtr<T>::adoptCF(PtrType optr) - { - PtrType ptr = m_ptr; - m_ptr = optr; - if (ptr) - CFRelease(ptr); - } - - template<typename T> inline void RetainPtr<T>::adoptNS(PtrType optr) - { - adoptNSReference(optr); - - PtrType ptr = m_ptr; - m_ptr = optr; - if (ptr) - CFRelease(ptr); - } - - template<typename T> template<typename U> inline RetainPtr<T>& RetainPtr<T>::operator=(U* optr) - { - if (optr) - CFRetain(optr); - PtrType ptr = m_ptr; - m_ptr = optr; - if (ptr) - CFRelease(ptr); - return *this; - } - - template<typename T> inline void RetainPtr<T>::swap(RetainPtr<T>& o) - { - std::swap(m_ptr, o.m_ptr); - } - - template<typename T> inline void swap(RetainPtr<T>& a, RetainPtr<T>& b) - { - a.swap(b); - } - - template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, const RetainPtr<U>& b) - { - return a.get() == b.get(); - } - - template<typename T, typename U> inline bool operator==(const RetainPtr<T>& a, U* b) - { - return a.get() == b; - } - - template<typename T, typename U> inline bool operator==(T* a, const RetainPtr<U>& b) - { - return a == b.get(); - } - - template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, const RetainPtr<U>& b) - { - return a.get() != b.get(); - } - - template<typename T, typename U> inline bool operator!=(const RetainPtr<T>& a, U* b) - { - return a.get() != b; - } - - template<typename T, typename U> inline bool operator!=(T* a, const RetainPtr<U>& b) - { - return a != b.get(); - } - - template<typename P> struct HashTraits<RetainPtr<P> > : GenericHashTraits<RetainPtr<P> > { - static const bool emptyValueIsZero = true; - static void constructDeletedValue(RetainPtr<P>& slot) { new (&slot) RetainPtr<P>(HashTableDeletedValue); } - static bool isDeletedValue(const RetainPtr<P>& value) { return value == reinterpret_cast<P*>(-1); } - }; - - template<typename P> struct PtrHash<RetainPtr<P> > : PtrHash<P*> { - using PtrHash<P*>::hash; - static unsigned hash(const RetainPtr<P>& key) { return hash(key.get()); } - using PtrHash<P*>::equal; - static bool equal(const RetainPtr<P>& a, const RetainPtr<P>& b) { return a == b; } - static bool equal(P* a, const RetainPtr<P>& b) { return a == b; } - static bool equal(const RetainPtr<P>& a, P* b) { return a == b; } - }; - - template<typename P> struct DefaultHash<RetainPtr<P> > { typedef PtrHash<RetainPtr<P> > Hash; }; - -} // namespace WTF - -using WTF::AdoptCF; -using WTF::AdoptNS; -using WTF::RetainPtr; - -#endif // WTF_RetainPtr_h diff --git a/JavaScriptCore/wtf/SegmentedVector.h b/JavaScriptCore/wtf/SegmentedVector.h deleted file mode 100644 index b1cbc4d..0000000 --- a/JavaScriptCore/wtf/SegmentedVector.h +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SegmentedVector_h -#define SegmentedVector_h - -#include <wtf/Vector.h> - -namespace WTF { - - // An iterator for SegmentedVector. It supports only the pre ++ operator - template <typename T, size_t SegmentSize> class SegmentedVector; - template <typename T, size_t SegmentSize> class SegmentedVectorIterator { - private: - friend class SegmentedVector<T, SegmentSize>; - public: - typedef SegmentedVectorIterator<T, SegmentSize> Iterator; - - ~SegmentedVectorIterator() { } - - T& operator*() const { return m_vector.m_segments.at(m_segment)->at(m_index); } - T* operator->() const { return &m_vector.m_segments.at(m_segment)->at(m_index); } - - // Only prefix ++ operator supported - Iterator& operator++() - { - ASSERT(m_index != SegmentSize); - ++m_index; - if (m_index >= m_vector.m_segments.at(m_segment)->size()) { - if (m_segment + 1 < m_vector.m_segments.size()) { - ASSERT(m_vector.m_segments.at(m_segment)->size() > 0); - ++m_segment; - m_index = 0; - } else { - // Points to the "end" symbol - m_segment = 0; - m_index = SegmentSize; - } - } - return *this; - } - - bool operator==(const Iterator& other) const - { - return (m_index == other.m_index && m_segment = other.m_segment && &m_vector == &other.m_vector); - } - - bool operator!=(const Iterator& other) const - { - return (m_index != other.m_index || m_segment != other.m_segment || &m_vector != &other.m_vector); - } - - SegmentedVectorIterator& operator=(const SegmentedVectorIterator<T, SegmentSize>& other) - { - m_vector = other.m_vector; - m_segment = other.m_segment; - m_index = other.m_index; - return *this; - } - - private: - SegmentedVectorIterator(SegmentedVector<T, SegmentSize>& vector, size_t segment, size_t index) - : m_vector(vector) - , m_segment(segment) - , m_index(index) - { - } - - SegmentedVector<T, SegmentSize>& m_vector; - size_t m_segment; - size_t m_index; - }; - - // SegmentedVector is just like Vector, but it doesn't move the values - // stored in its buffer when it grows. Therefore, it is safe to keep - // pointers into a SegmentedVector. - template <typename T, size_t SegmentSize> class SegmentedVector { - friend class SegmentedVectorIterator<T, SegmentSize>; - public: - typedef SegmentedVectorIterator<T, SegmentSize> Iterator; - - SegmentedVector() - : m_size(0) - { - m_segments.append(&m_inlineSegment); - } - - ~SegmentedVector() - { - deleteAllSegments(); - } - - size_t size() const { return m_size; } - bool isEmpty() const { return !size(); } - - T& at(size_t index) - { - if (index < SegmentSize) - return m_inlineSegment[index]; - return segmentFor(index)->at(subscriptFor(index)); - } - - T& operator[](size_t index) - { - return at(index); - } - - T& last() - { - return at(size() - 1); - } - - template <typename U> void append(const U& value) - { - ++m_size; - - if (m_size <= SegmentSize) { - m_inlineSegment.uncheckedAppend(value); - return; - } - - if (!segmentExistsFor(m_size - 1)) - m_segments.append(new Segment); - segmentFor(m_size - 1)->uncheckedAppend(value); - } - - T& alloc() - { - append<T>(T()); - return last(); - } - - void removeLast() - { - if (m_size <= SegmentSize) - m_inlineSegment.removeLast(); - else - segmentFor(m_size - 1)->removeLast(); - --m_size; - } - - void grow(size_t size) - { - ASSERT(size > m_size); - ensureSegmentsFor(size); - m_size = size; - } - - void clear() - { - deleteAllSegments(); - m_segments.resize(1); - m_inlineSegment.clear(); - m_size = 0; - } - - Iterator begin() - { - return Iterator(*this, 0, m_size ? 0 : SegmentSize); - } - - Iterator end() - { - return Iterator(*this, 0, SegmentSize); - } - - private: - typedef Vector<T, SegmentSize> Segment; - - void deleteAllSegments() - { - // Skip the first segment, because it's our inline segment, which was - // not created by new. - for (size_t i = 1; i < m_segments.size(); i++) - delete m_segments[i]; - } - - bool segmentExistsFor(size_t index) - { - return index / SegmentSize < m_segments.size(); - } - - Segment* segmentFor(size_t index) - { - return m_segments[index / SegmentSize]; - } - - size_t subscriptFor(size_t index) - { - return index % SegmentSize; - } - - void ensureSegmentsFor(size_t size) - { - size_t segmentCount = m_size / SegmentSize; - if (m_size % SegmentSize) - ++segmentCount; - segmentCount = std::max<size_t>(segmentCount, 1); // We always have at least our inline segment. - - size_t neededSegmentCount = size / SegmentSize; - if (size % SegmentSize) - ++neededSegmentCount; - - // Fill up to N - 1 segments. - size_t end = neededSegmentCount - 1; - for (size_t i = segmentCount - 1; i < end; ++i) - ensureSegment(i, SegmentSize); - - // Grow segment N to accomodate the remainder. - ensureSegment(end, subscriptFor(size - 1) + 1); - } - - void ensureSegment(size_t segmentIndex, size_t size) - { - ASSERT(segmentIndex <= m_segments.size()); - if (segmentIndex == m_segments.size()) - m_segments.append(new Segment); - m_segments[segmentIndex]->grow(size); - } - - size_t m_size; - Segment m_inlineSegment; - Vector<Segment*, 32> m_segments; - }; - -} // namespace WTF - -using WTF::SegmentedVector; - -#endif // SegmentedVector_h diff --git a/JavaScriptCore/wtf/SizeLimits.cpp b/JavaScriptCore/wtf/SizeLimits.cpp deleted file mode 100644 index 4e481bb..0000000 --- a/JavaScriptCore/wtf/SizeLimits.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2010 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include <wtf/Assertions.h> -#include <wtf/CrossThreadRefCounted.h> -#include <wtf/OwnPtr.h> -#include <wtf/PassRefPtr.h> -#include <wtf/RefCounted.h> -#include <wtf/RefPtr.h> -#include <wtf/Vector.h> - -namespace WTF { - -#ifndef NDEBUG -struct StructWithIntAndTwoBools { int a; bool b; bool c; }; -static const size_t refCountedExtraDebugSize = sizeof(StructWithIntAndTwoBools) - sizeof(int); -#else -static const size_t refCountedExtraDebugSize = 0; -#endif - -COMPILE_ASSERT(sizeof(OwnPtr<int>) == sizeof(int*), OwnPtr_should_stay_small); -COMPILE_ASSERT(sizeof(PassRefPtr<RefCounted<int> >) == sizeof(int*), PassRefPtr_should_stay_small); -COMPILE_ASSERT(sizeof(RefCounted<int>) == sizeof(int) + refCountedExtraDebugSize, RefCounted_should_stay_small); -COMPILE_ASSERT(sizeof(RefCountedCustomAllocated<int>) == sizeof(int) + refCountedExtraDebugSize, RefCountedCustomAllocated_should_stay_small); -COMPILE_ASSERT(sizeof(RefPtr<RefCounted<int> >) == sizeof(int*), RefPtr_should_stay_small); -COMPILE_ASSERT(sizeof(Vector<int>) == 3 * sizeof(int*), Vector_should_stay_small); - -} diff --git a/JavaScriptCore/wtf/StackBounds.cpp b/JavaScriptCore/wtf/StackBounds.cpp deleted file mode 100644 index 2691db1..0000000 --- a/JavaScriptCore/wtf/StackBounds.cpp +++ /dev/null @@ -1,283 +0,0 @@ -/* - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Eric Seidel <eric@webkit.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - */ - -#include "config.h" -#include "StackBounds.h" - -#if OS(DARWIN) - -#include <mach/task.h> -#include <mach/thread_act.h> -#include <pthread.h> - -#elif OS(WINDOWS) - -#include <windows.h> - -#elif OS(HAIKU) - -#include <OS.h> - -#elif OS(SOLARIS) - -#include <thread.h> - -#elif OS(QNX) - -#include <fcntl.h> -#include <sys/procfs.h> -#include <stdio.h> -#include <errno.h> - -#elif OS(UNIX) - -#include <pthread.h> -#if HAVE(PTHREAD_NP_H) -#include <pthread_np.h> -#endif - -#endif - -namespace WTF { - -// Bug 26276 - Need a mechanism to determine stack extent -// -// These platforms should now be working correctly: -// DARWIN, QNX, UNIX -// These platforms are not: -// WINDOWS, SOLARIS, OPENBSD, SYMBIAN, HAIKU, WINCE -// -// FIXME: remove this! - this code unsafely guesses at stack sizes! -#if OS(WINDOWS) || OS(SOLARIS) || OS(OPENBSD) || OS(SYMBIAN) || OS(HAIKU) || OS(WINCE) -// Based on the current limit used by the JSC parser, guess the stack size. -static const ptrdiff_t estimatedStackSize = 128 * sizeof(void*) * 1024; -// This method assumes the stack is growing downwards. -static void* estimateStackBound(void* origin) -{ - return static_cast<char*>(origin) - estimatedStackSize; -} -#endif - -#if OS(DARWIN) - -void StackBounds::initialize() -{ - pthread_t thread = pthread_self(); - m_origin = pthread_get_stackaddr_np(thread); - m_bound = static_cast<char*>(m_origin) - pthread_get_stacksize_np(thread); -} - -#elif OS(WINDOWS) - -void StackBounds::initialize() -{ -#if CPU(X86) && COMPILER(MSVC) - // offset 0x18 from the FS segment register gives a pointer to - // the thread information block for the current thread - NT_TIB* pTib; - __asm { - MOV EAX, FS:[18h] - MOV pTib, EAX - } - m_origin = static_cast<void*>(pTib->StackBase); -#elif OS(WINDOWS) && CPU(X86) && COMPILER(GCC) - // offset 0x18 from the FS segment register gives a pointer to - // the thread information block for the current thread - NT_TIB* pTib; - asm ( "movl %%fs:0x18, %0\n" - : "=r" (pTib) - ); - m_origin = static_cast<void*>(pTib->StackBase); -#elif OS(WINDOWS) && CPU(X86_64) - PNT_TIB64 pTib = reinterpret_cast<PNT_TIB64>(NtCurrentTeb()); - m_origin = reinterpret_cast<void*>(pTib->StackBase); -#else -#error Need a way to get the stack bounds on this platform (Windows) -#endif - // Looks like we should be able to get pTib->StackLimit - m_bound = estimateStackBound(m_origin); -} - -#elif OS(QNX) - -void StackBounds::initialize() -{ - void* stackBase = 0; - size_t stackSize = 0; - pthread_t thread = pthread_self(); - - struct _debug_thread_info threadInfo; - memset(&threadInfo, 0, sizeof(threadInfo)); - threadInfo.tid = pthread_self(); - int fd = open("/proc/self", O_RDONLY); - if (fd == -1) { - LOG_ERROR("Unable to open /proc/self (errno: %d)", errno); - CRASH(); - } - devctl(fd, DCMD_PROC_TIDSTATUS, &threadInfo, sizeof(threadInfo), 0); - close(fd); - stackBase = reinterpret_cast<void*>(threadInfo.stkbase); - stackSize = threadInfo.stksize; - ASSERT(stackBase); - - m_bound = stackBase; - m_origin = static_cast<char*>(stackBase) + stackSize; -} - -#elif OS(SOLARIS) - -void StackBounds::initialize() -{ - stack_t s; - thr_stksegment(&s); - m_origin = s.ss_sp; - m_bound = estimateStackBound(m_origin); -} - -#elif OS(OPENBSD) - -void StackBounds::initialize() -{ - pthread_t thread = pthread_self(); - stack_t stack; - pthread_stackseg_np(thread, &stack); - m_origin = stack.ss_sp; - m_bound = estimateStackBound(m_origin); -} - -#elif OS(SYMBIAN) - -void StackBounds::initialize() -{ - TThreadStackInfo info; - RThread thread; - thread.StackInfo(info); - m_origin = (void*)info.iBase; - m_bound = estimateStackBound(m_origin); -} - -#elif OS(HAIKU) - -void StackBounds::initialize() -{ - thread_info threadInfo; - get_thread_info(find_thread(NULL), &threadInfo); - m_origin = threadInfo.stack_end; - m_bound = estimateStackBound(m_origin); -} - -#elif OS(UNIX) - -void StackBounds::initialize() -{ - void* stackBase = 0; - size_t stackSize = 0; - - pthread_t thread = pthread_self(); - pthread_attr_t sattr; - pthread_attr_init(&sattr); -#if HAVE(PTHREAD_NP_H) || OS(NETBSD) - // e.g. on FreeBSD 5.4, neundorf@kde.org - pthread_attr_get_np(thread, &sattr); -#else - // FIXME: this function is non-portable; other POSIX systems may have different np alternatives - pthread_getattr_np(thread, &sattr); -#endif - int rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize); - (void)rc; // FIXME: Deal with error code somehow? Seems fatal. - ASSERT(stackBase); - pthread_attr_destroy(&sattr); - m_bound = stackBase; - m_origin = static_cast<char*>(stackBase) + stackSize; -} - -#elif OS(WINCE) - -} // namespace WTF -// FIXME: this is not threadsafe, and should probably be removed. -namespace JSC { JS_EXPORTDATA void* g_stackBase = 0; } -namespace WTF { - -inline bool isPageWritable(void* page) -{ - MEMORY_BASIC_INFORMATION memoryInformation; - DWORD result = VirtualQuery(page, &memoryInformation, sizeof(memoryInformation)); - - // return false on error, including ptr outside memory - if (result != sizeof(memoryInformation)) - return false; - - DWORD protect = memoryInformation.Protect & ~(PAGE_GUARD | PAGE_NOCACHE); - return protect == PAGE_READWRITE - || protect == PAGE_WRITECOPY - || protect == PAGE_EXECUTE_READWRITE - || protect == PAGE_EXECUTE_WRITECOPY; -} - -static void* getStackMax(void* previousFrame, bool& isGrowingDownward) -{ - // find the address of this stack frame by taking the address of a local variable - void* thisFrame = &thisFrame; - isGrowingDownward = previousFrame < &thisFrame; - - if (JSC::g_stackBase) - return JSC::g_stackBase; - - SYSTEM_INFO systemInfo; - GetSystemInfo(&systemInfo); - DWORD pageSize = systemInfo.dwPageSize; - - // scan all of memory starting from this frame, and return the last writeable page found - register char* currentPage = (char*)((DWORD)thisFrame & ~(pageSize - 1)); - if (isGrowingDownward) { - while (currentPage > 0) { - // check for underflow - if (currentPage >= (char*)pageSize) - currentPage -= pageSize; - else - currentPage = 0; - if (!isPageWritable(currentPage)) - return currentPage + pageSize; - } - return 0; - } else { - while (true) { - // guaranteed to complete because isPageWritable returns false at end of memory - currentPage += pageSize; - if (!isPageWritable(currentPage)) - return currentPage; - } - } -} - -void StackBounds::initialize() -{ - bool isGrowingDownward - m_origin = getStackMax(isGrowingDownward); - m_bound = isGrowingDownward - ? static_cast<char*>(m_origin) - estimatedStackSize - : static_cast<char*>(m_origin) + estimatedStackSize; -} - -#else -#error Need a way to get the stack bounds on this platform -#endif - -} // namespace WTF diff --git a/JavaScriptCore/wtf/StackBounds.h b/JavaScriptCore/wtf/StackBounds.h deleted file mode 100644 index afce860..0000000 --- a/JavaScriptCore/wtf/StackBounds.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef StackBounds_h -#define StackBounds_h - -namespace WTF { - -class StackBounds { - // recursionCheck() / recursionLimit() tests (by default) - // that we are at least this far from the end of the stack. - const static size_t s_defaultAvailabilityDelta = 4096; - -public: - StackBounds() - : m_origin(0) - , m_bound(0) - { - } - - static StackBounds currentThreadStackBounds() - { - StackBounds bounds; - bounds.initialize(); - bounds.checkConsistency(); - return bounds; - } - - void* origin() const - { - ASSERT(m_origin); - return m_origin; - } - - void* current() const - { - checkConsistency(); - void* currentPosition = ¤tPosition; - return currentPosition; - } - - void* recursionLimit(size_t minAvailableDelta = s_defaultAvailabilityDelta) const - { - checkConsistency(); - return isGrowingDownward() - ? static_cast<char*>(m_bound) + minAvailableDelta - : static_cast<char*>(m_bound) - minAvailableDelta; - } - - bool recursionCheck(size_t minAvailableDelta = s_defaultAvailabilityDelta) const - { - checkConsistency(); - return isGrowingDownward() - ? current() >= recursionLimit(minAvailableDelta) - : current() <= recursionLimit(minAvailableDelta); - } - -private: - void initialize(); - - - bool isGrowingDownward() const - { - ASSERT(m_origin && m_bound); -#if OS(WINCE) - return m_origin > m_bound; -#else - return true; -#endif - } - - void checkConsistency() const - { -#if !ASSERT_DISABLED - void* currentPosition = ¤tPosition; - ASSERT(m_origin != m_bound); - ASSERT(isGrowingDownward() - ? (currentPosition < m_origin && currentPosition > m_bound) - : (currentPosition > m_origin && currentPosition < m_bound)); -#endif - } - - void* m_origin; - void* m_bound; -}; - -} // namespace WTF - -using WTF::StackBounds; - -#endif diff --git a/JavaScriptCore/wtf/StaticConstructors.h b/JavaScriptCore/wtf/StaticConstructors.h deleted file mode 100644 index 8b2df9d..0000000 --- a/JavaScriptCore/wtf/StaticConstructors.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef StaticConstructors_h -#define StaticConstructors_h - -// We need to avoid having static constructors. We achieve this -// with two separate methods for GCC and MSVC. Both methods prevent the static -// initializers from being registered and called on program startup. On GCC, we -// declare the global objects with a different type that can be POD default -// initialized by the linker/loader. On MSVC we use a special compiler feature -// to have the CRT ignore our static initializers. The constructors will never -// be called and the objects will be left uninitialized. -// -// With both of these approaches, we must define and explicitly call an init -// routine that uses placement new to create the objects and overwrite the -// uninitialized placeholders. -// -// This is not completely portable, but is what we have for now without -// changing how a lot of code accesses these global objects. - -#ifdef SKIP_STATIC_CONSTRUCTORS_ON_MSVC -// - Assume that all includes of this header want ALL of their static -// initializers ignored. This is currently the case. This means that if -// a .cc includes this header (or it somehow gets included), all static -// initializers after the include will not be executed. -// - We do this with a pragma, so that all of the static initializer pointers -// go into our own section, and the CRT won't call them. Eventually it would -// be nice if the section was discarded, because we don't want the pointers. -// See: http://msdn.microsoft.com/en-us/library/7977wcck(VS.80).aspx -#pragma warning(disable:4075) -#pragma init_seg(".unwantedstaticinits") -#endif - -#ifndef SKIP_STATIC_CONSTRUCTORS_ON_GCC - // Define an global in the normal way. -#if COMPILER(MSVC7_OR_LOWER) -#define DEFINE_GLOBAL(type, name) \ - const type name; -#elif COMPILER(WINSCW) -#define DEFINE_GLOBAL(type, name, arg...) \ - const type name; -#else -#define DEFINE_GLOBAL(type, name, ...) \ - const type name; -#endif - -#else -// Define an correctly-sized array of pointers to avoid static initialization. -// Use an array of pointers instead of an array of char in case there is some alignment issue. -#if COMPILER(MSVC7_OR_LOWER) -#define DEFINE_GLOBAL(type, name) \ - void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)]; -#elif COMPILER(WINSCW) -#define DEFINE_GLOBAL(type, name, arg...) \ - void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)]; -#else -#define DEFINE_GLOBAL(type, name, ...) \ - void * name[(sizeof(type) + sizeof(void *) - 1) / sizeof(void *)]; -#endif -#endif - -#endif // StaticConstructors_h diff --git a/JavaScriptCore/wtf/StdLibExtras.h b/JavaScriptCore/wtf/StdLibExtras.h deleted file mode 100644 index 4bb0076..0000000 --- a/JavaScriptCore/wtf/StdLibExtras.h +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_StdLibExtras_h -#define WTF_StdLibExtras_h - -#include <wtf/Assertions.h> - -// Use these to declare and define a static local variable (static T;) so that -// it is leaked so that its destructors are not called at exit. Using this -// macro also allows workarounds a compiler bug present in Apple's version of GCC 4.0.1. -#ifndef DEFINE_STATIC_LOCAL -#if COMPILER(GCC) && defined(__APPLE_CC__) && __GNUC__ == 4 && __GNUC_MINOR__ == 0 && __GNUC_PATCHLEVEL__ == 1 -#define DEFINE_STATIC_LOCAL(type, name, arguments) \ - static type* name##Ptr = new type arguments; \ - type& name = *name##Ptr -#else -#define DEFINE_STATIC_LOCAL(type, name, arguments) \ - static type& name = *new type arguments -#endif -#endif - -// OBJECT_OFFSETOF: Like the C++ offsetof macro, but you can use it with classes. -// The magic number 0x4000 is insignificant. We use it to avoid using NULL, since -// NULL can cause compiler problems, especially in cases of multiple inheritance. -#define OBJECT_OFFSETOF(class, field) (reinterpret_cast<ptrdiff_t>(&(reinterpret_cast<class*>(0x4000)->field)) - 0x4000) - -// STRINGIZE: Can convert any value to quoted string, even expandable macros -#define STRINGIZE(exp) #exp -#define STRINGIZE_VALUE_OF(exp) STRINGIZE(exp) - -/* - * The reinterpret_cast<Type1*>([pointer to Type2]) expressions - where - * sizeof(Type1) > sizeof(Type2) - cause the following warning on ARM with GCC: - * increases required alignment of target type. - * - * An implicit or an extra static_cast<void*> bypasses the warning. - * For more info see the following bugzilla entries: - * - https://bugs.webkit.org/show_bug.cgi?id=38045 - * - http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43976 - */ -#if (CPU(ARM) || CPU(MIPS)) && COMPILER(GCC) -template<typename Type> -bool isPointerTypeAlignmentOkay(Type* ptr) -{ - return !(reinterpret_cast<intptr_t>(ptr) % __alignof__(Type)); -} - -template<typename TypePtr> -TypePtr reinterpret_cast_ptr(void* ptr) -{ - ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); - return reinterpret_cast<TypePtr>(ptr); -} - -template<typename TypePtr> -TypePtr reinterpret_cast_ptr(const void* ptr) -{ - ASSERT(isPointerTypeAlignmentOkay(reinterpret_cast<TypePtr>(ptr))); - return reinterpret_cast<TypePtr>(ptr); -} -#else -#define reinterpret_cast_ptr reinterpret_cast -#endif - -namespace WTF { - -/* - * C++'s idea of a reinterpret_cast lacks sufficient cojones. - */ -template<typename TO, typename FROM> -inline TO bitwise_cast(FROM from) -{ - COMPILE_ASSERT(sizeof(TO) == sizeof(FROM), WTF_bitwise_cast_sizeof_casted_types_is_equal); - union { - FROM from; - TO to; - } u; - u.from = from; - return u.to; -} - -// Returns a count of the number of bits set in 'bits'. -inline size_t bitCount(unsigned bits) -{ - bits = bits - ((bits >> 1) & 0x55555555); - bits = (bits & 0x33333333) + ((bits >> 2) & 0x33333333); - return (((bits + (bits >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; -} - -// Macro that returns a compile time constant with the length of an array, but gives an error if passed a non-array. -template<typename T, size_t Size> char (&ArrayLengthHelperFunction(T (&)[Size]))[Size]; -#define WTF_ARRAY_LENGTH(array) sizeof(::WTF::ArrayLengthHelperFunction(array)) - -} // namespace WTF - -#endif // WTF_StdLibExtras_h diff --git a/JavaScriptCore/wtf/StringExtras.cpp b/JavaScriptCore/wtf/StringExtras.cpp deleted file mode 100644 index 1b96417..0000000 --- a/JavaScriptCore/wtf/StringExtras.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2009 Company 100, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if COMPILER(RVCT) && __ARMCC_VERSION < 400000 - -#include "StringExtras.h" - -#include "ASCIICType.h" - -int strcasecmp(const char* s1, const char* s2) -{ - while (toASCIIUpper(*s1) == toASCIIUpper(*s2)) { - if (*s1 == '\0') - return 0; - s1++; - s2++; - } - - return toASCIIUpper(*s1) - toASCIIUpper(*s2); -} - -int strncasecmp(const char* s1, const char* s2, size_t len) -{ - while (len > 0 && toASCIIUpper(*s1) == toASCIIUpper(*s2)) { - if (*s1 == '\0') - return 0; - s1++; - s2++; - len--; - } - - if (!len) - return 0; - - return toASCIIUpper(*s1) - toASCIIUpper(*s2); -} - -#endif diff --git a/JavaScriptCore/wtf/StringExtras.h b/JavaScriptCore/wtf/StringExtras.h deleted file mode 100644 index 473bb22..0000000 --- a/JavaScriptCore/wtf/StringExtras.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright (C) 2006, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_StringExtras_h -#define WTF_StringExtras_h - -#include <stdarg.h> -#include <stdio.h> -#include <string.h> - -#if HAVE(STRINGS_H) -#include <strings.h> -#endif - -#if COMPILER(MSVC) -// FIXME: why a COMPILER check instead of OS? also, these should be HAVE checks - -inline int snprintf(char* buffer, size_t count, const char* format, ...) -{ - int result; - va_list args; - va_start(args, format); - result = _vsnprintf(buffer, count, format, args); - va_end(args); - - // In the case where the string entirely filled the buffer, _vsnprintf will not - // null-terminate it, but snprintf must. - if (count > 0) - buffer[count - 1] = '\0'; - - return result; -} - -inline double wtf_vsnprintf(char* buffer, size_t count, const char* format, va_list args) -{ - int result = _vsnprintf(buffer, count, format, args); - - // In the case where the string entirely filled the buffer, _vsnprintf will not - // null-terminate it, but vsnprintf must. - if (count > 0) - buffer[count - 1] = '\0'; - - return result; -} - -// Work around a difference in Microsoft's implementation of vsnprintf, where -// vsnprintf does not null terminate the buffer. WebKit can rely on the null termination. -#define vsnprintf(buffer, count, format, args) wtf_vsnprintf(buffer, count, format, args) - -#if OS(WINCE) - -inline int strnicmp(const char* string1, const char* string2, size_t count) -{ - return _strnicmp(string1, string2, count); -} - -inline int stricmp(const char* string1, const char* string2) -{ - return _stricmp(string1, string2); -} - -inline char* strdup(const char* strSource) -{ - return _strdup(strSource); -} - -#endif - -inline int strncasecmp(const char* s1, const char* s2, size_t len) -{ - return _strnicmp(s1, s2, len); -} - -inline int strcasecmp(const char* s1, const char* s2) -{ - return _stricmp(s1, s2); -} - -#endif - -#if COMPILER(MSVC) || COMPILER(RVCT) || OS(WINDOWS) || OS(LINUX) || OS(SOLARIS) -// FIXME: should check HAVE_STRNSTR - -inline char* strnstr(const char* buffer, const char* target, size_t bufferLength) -{ - size_t targetLength = strlen(target); - if (targetLength == 0) - return const_cast<char*>(buffer); - for (const char* start = buffer; *start && start + targetLength <= buffer + bufferLength; start++) { - if (*start == *target && strncmp(start + 1, target + 1, targetLength - 1) == 0) - return const_cast<char*>(start); - } - return 0; -} - -#endif - -#if COMPILER(RVCT) && __ARMCC_VERSION < 400000 - -int strcasecmp(const char* s1, const char* s2); -int strncasecmp(const char* s1, const char* s2, size_t len); - -#endif - -#endif // WTF_StringExtras_h diff --git a/JavaScriptCore/wtf/StringHasher.h b/JavaScriptCore/wtf/StringHasher.h deleted file mode 100644 index 63ce74f..0000000 --- a/JavaScriptCore/wtf/StringHasher.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ -#ifndef WTF_StringHasher_h -#define WTF_StringHasher_h - -#include <wtf/unicode/Unicode.h> - -namespace WTF { - -// Golden ratio - arbitrary start value to avoid mapping all 0's to all 0's -static const unsigned stringHashingStartValue = 0x9e3779b9U; - -// Paul Hsieh's SuperFastHash -// http://www.azillionmonkeys.com/qed/hash.html -// char* data is interpreted as latin-encoded (zero extended to 16 bits). -class StringHasher { -public: - inline StringHasher() - : m_hash(stringHashingStartValue) - , m_hasPendingCharacter(false) - , m_pendingCharacter(0) - { - } - - inline void addCharacters(UChar a, UChar b) - { - ASSERT(!m_hasPendingCharacter); - addCharactersToHash(a, b); - } - - inline void addCharacter(UChar ch) - { - if (m_hasPendingCharacter) { - addCharactersToHash(m_pendingCharacter, ch); - m_hasPendingCharacter = false; - return; - } - - m_pendingCharacter = ch; - m_hasPendingCharacter = true; - } - - inline unsigned hash() const - { - unsigned result = m_hash; - - // Handle end case. - if (m_hasPendingCharacter) { - result += m_pendingCharacter; - result ^= result << 11; - result += result >> 17; - } - - // Force "avalanching" of final 31 bits. - result ^= result << 3; - result += result >> 5; - result ^= result << 2; - result += result >> 15; - result ^= result << 10; - - // First bit is used in UStringImpl for m_isIdentifier. - result &= 0x7fffffff; - - // This avoids ever returning a hash code of 0, since that is used to - // signal "hash not computed yet", using a value that is likely to be - // effectively the same as 0 when the low bits are masked. - if (!result) - return 0x40000000; - - return result; - } - - template<typename T, UChar Converter(T)> static inline unsigned createHash(const T* data, unsigned length) - { - StringHasher hasher; - bool rem = length & 1; - length >>= 1; - - while (length--) { - hasher.addCharacters(Converter(data[0]), Converter(data[1])); - data += 2; - } - - if (rem) - hasher.addCharacter(Converter(*data)); - - return hasher.hash(); - } - - template<typename T, UChar Converter(T)> static inline unsigned createHash(const T* data) - { - StringHasher hasher; - - while (true) { - UChar b0 = Converter(*data++); - if (!b0) - break; - UChar b1 = Converter(*data++); - if (!b1) { - hasher.addCharacter(b0); - break; - } - - hasher.addCharacters(b0, b1); - } - - return hasher.hash(); - } - - template<typename T> static inline unsigned createHash(const T* data, unsigned length) - { - return createHash<T, defaultCoverter>(data, length); - } - - template<typename T> static inline unsigned createHash(const T* data) - { - return createHash<T, defaultCoverter>(data); - } - - template<size_t length> static inline unsigned createBlobHash(const void* data) - { - COMPILE_ASSERT(!(length % 4), length_must_be_a_multible_of_four); - return createHash<UChar>(static_cast<const UChar*>(data), length / sizeof(UChar)); - } - -private: - static inline UChar defaultCoverter(UChar ch) - { - return ch; - } - - static inline UChar defaultCoverter(char ch) - { - return static_cast<unsigned char>(ch); - } - - inline void addCharactersToHash(UChar a, UChar b) - { - m_hash += a; - unsigned tmp = (b << 11) ^ m_hash; - m_hash = (m_hash << 16) ^ tmp; - m_hash += m_hash >> 11; - } - - unsigned m_hash; - bool m_hasPendingCharacter; - UChar m_pendingCharacter; -}; - -} // namespace WTF - -#endif // WTF_StringHasher_h diff --git a/JavaScriptCore/wtf/TCPackedCache.h b/JavaScriptCore/wtf/TCPackedCache.h deleted file mode 100644 index 0464f8f..0000000 --- a/JavaScriptCore/wtf/TCPackedCache.h +++ /dev/null @@ -1,234 +0,0 @@ -// Copyright (c) 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Geoff Pike -// -// This file provides a minimal cache that can hold a <key, value> pair -// with little if any wasted space. The types of the key and value -// must be unsigned integral types or at least have unsigned semantics -// for >>, casting, and similar operations. -// -// Synchronization is not provided. However, the cache is implemented -// as an array of cache entries whose type is chosen at compile time. -// If a[i] is atomic on your hardware for the chosen array type then -// raciness will not necessarily lead to bugginess. The cache entries -// must be large enough to hold a partial key and a value packed -// together. The partial keys are bit strings of length -// kKeybits - kHashbits, and the values are bit strings of length kValuebits. -// -// In an effort to use minimal space, every cache entry represents -// some <key, value> pair; the class provides no way to mark a cache -// entry as empty or uninitialized. In practice, you may want to have -// reserved keys or values to get around this limitation. For example, in -// tcmalloc's PageID-to-sizeclass cache, a value of 0 is used as -// "unknown sizeclass." -// -// Usage Considerations -// -------------------- -// -// kHashbits controls the size of the cache. The best value for -// kHashbits will of course depend on the application. Perhaps try -// tuning the value of kHashbits by measuring different values on your -// favorite benchmark. Also remember not to be a pig; other -// programs that need resources may suffer if you are. -// -// The main uses for this class will be when performance is -// critical and there's a convenient type to hold the cache's -// entries. As described above, the number of bits required -// for a cache entry is (kKeybits - kHashbits) + kValuebits. Suppose -// kKeybits + kValuebits is 43. Then it probably makes sense to -// chose kHashbits >= 11 so that cache entries fit in a uint32. -// -// On the other hand, suppose kKeybits = kValuebits = 64. Then -// using this class may be less worthwhile. You'll probably -// be using 128 bits for each entry anyway, so maybe just pick -// a hash function, H, and use an array indexed by H(key): -// void Put(K key, V value) { a_[H(key)] = pair<K, V>(key, value); } -// V GetOrDefault(K key, V default) { const pair<K, V> &p = a_[H(key)]; ... } -// etc. -// -// Further Details -// --------------- -// -// For caches used only by one thread, the following is true: -// 1. For a cache c, -// (c.Put(key, value), c.GetOrDefault(key, 0)) == value -// and -// (c.Put(key, value), <...>, c.GetOrDefault(key, 0)) == value -// if the elided code contains no c.Put calls. -// -// 2. Has(key) will return false if no <key, value> pair with that key -// has ever been Put. However, a newly initialized cache will have -// some <key, value> pairs already present. When you create a new -// cache, you must specify an "initial value." The initialization -// procedure is equivalent to Clear(initial_value), which is -// equivalent to Put(k, initial_value) for all keys k from 0 to -// 2^kHashbits - 1. -// -// 3. If key and key' differ then the only way Put(key, value) may -// cause Has(key') to change is that Has(key') may change from true to -// false. Furthermore, a Put() call that doesn't change Has(key') -// doesn't change GetOrDefault(key', ...) either. -// -// Implementation details: -// -// This is a direct-mapped cache with 2^kHashbits entries; -// the hash function simply takes the low bits of the key. -// So, we don't have to store the low bits of the key in the entries. -// Instead, an entry is the high bits of a key and a value, packed -// together. E.g., a 20 bit key and a 7 bit value only require -// a uint16 for each entry if kHashbits >= 11. -// -// Alternatives to this scheme will be added as needed. - -#ifndef TCMALLOC_PACKED_CACHE_INL_H__ -#define TCMALLOC_PACKED_CACHE_INL_H__ - -#ifndef WTF_CHANGES -#include "base/basictypes.h" // for COMPILE_ASSERT -#include "base/logging.h" // for DCHECK -#endif - -#ifndef DCHECK_EQ -#define DCHECK_EQ(val1, val2) ASSERT((val1) == (val2)) -#endif - -// A safe way of doing "(1 << n) - 1" -- without worrying about overflow -// Note this will all be resolved to a constant expression at compile-time -#define N_ONES_(IntType, N) \ - ( (N) == 0 ? 0 : ((static_cast<IntType>(1) << ((N)-1))-1 + \ - (static_cast<IntType>(1) << ((N)-1))) ) - -// The types K and V provide upper bounds on the number of valid keys -// and values, but we explicitly require the keys to be less than -// 2^kKeybits and the values to be less than 2^kValuebits. The size of -// the table is controlled by kHashbits, and the type of each entry in -// the cache is T. See also the big comment at the top of the file. -template <int kKeybits, typename T> -class PackedCache { - public: - typedef uintptr_t K; - typedef size_t V; - static const size_t kHashbits = 12; - static const size_t kValuebits = 8; - - explicit PackedCache(V initial_value) { - COMPILE_ASSERT(kKeybits <= sizeof(K) * 8, key_size); - COMPILE_ASSERT(kValuebits <= sizeof(V) * 8, value_size); - COMPILE_ASSERT(kHashbits <= kKeybits, hash_function); - COMPILE_ASSERT(kKeybits - kHashbits + kValuebits <= kTbits, - entry_size_must_be_big_enough); - Clear(initial_value); - } - - void Put(K key, V value) { - DCHECK_EQ(key, key & kKeyMask); - DCHECK_EQ(value, value & kValueMask); - array_[Hash(key)] = static_cast<T>(KeyToUpper(key) | value); - } - - bool Has(K key) const { - DCHECK_EQ(key, key & kKeyMask); - return KeyMatch(array_[Hash(key)], key); - } - - V GetOrDefault(K key, V default_value) const { - // As with other code in this class, we touch array_ as few times - // as we can. Assuming entries are read atomically (e.g., their - // type is uintptr_t on most hardware) then certain races are - // harmless. - DCHECK_EQ(key, key & kKeyMask); - T entry = array_[Hash(key)]; - return KeyMatch(entry, key) ? EntryToValue(entry) : default_value; - } - - void Clear(V value) { - DCHECK_EQ(value, value & kValueMask); - for (int i = 0; i < 1 << kHashbits; i++) { - array_[i] = static_cast<T>(value); - } - } - - private: - // We are going to pack a value and the upper part of a key into - // an entry of type T. The UPPER type is for the upper part of a key, - // after the key has been masked and shifted for inclusion in an entry. - typedef T UPPER; - - static V EntryToValue(T t) { return t & kValueMask; } - - static UPPER EntryToUpper(T t) { return t & kUpperMask; } - - // If v is a V and u is an UPPER then you can create an entry by - // doing u | v. kHashbits determines where in a K to find the upper - // part of the key, and kValuebits determines where in the entry to put - // it. - static UPPER KeyToUpper(K k) { - const int shift = kHashbits - kValuebits; - // Assume kHashbits >= kValuebits. It would be easy to lift this assumption. - return static_cast<T>(k >> shift) & kUpperMask; - } - - // This is roughly the inverse of KeyToUpper(). Some of the key has been - // thrown away, since KeyToUpper() masks off the low bits of the key. - static K UpperToPartialKey(UPPER u) { - DCHECK_EQ(u, u & kUpperMask); - const int shift = kHashbits - kValuebits; - // Assume kHashbits >= kValuebits. It would be easy to lift this assumption. - return static_cast<K>(u) << shift; - } - - static size_t Hash(K key) { - return static_cast<size_t>(key) & N_ONES_(size_t, kHashbits); - } - - // Does the entry's partial key match the relevant part of the given key? - static bool KeyMatch(T entry, K key) { - return ((KeyToUpper(key) ^ entry) & kUpperMask) == 0; - } - - static const size_t kTbits = 8 * sizeof(T); - static const int kUpperbits = kKeybits - kHashbits; - - // For masking a K. - static const K kKeyMask = N_ONES_(K, kKeybits); - - // For masking a T. - static const T kUpperMask = N_ONES_(T, kUpperbits) << kValuebits; - - // For masking a V or a T. - static const V kValueMask = N_ONES_(V, kValuebits); - - T array_[1 << kHashbits]; -}; - -#undef N_ONES_ - -#endif // TCMALLOC_PACKED_CACHE_INL_H__ diff --git a/JavaScriptCore/wtf/TCPageMap.h b/JavaScriptCore/wtf/TCPageMap.h deleted file mode 100644 index 99bdc40..0000000 --- a/JavaScriptCore/wtf/TCPageMap.h +++ /dev/null @@ -1,316 +0,0 @@ -// Copyright (c) 2005, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Sanjay Ghemawat <opensource@google.com> -// -// A data structure used by the caching malloc. It maps from page# to -// a pointer that contains info about that page. We use two -// representations: one for 32-bit addresses, and another for 64 bit -// addresses. Both representations provide the same interface. The -// first representation is implemented as a flat array, the seconds as -// a three-level radix tree that strips away approximately 1/3rd of -// the bits every time. -// -// The BITS parameter should be the number of bits required to hold -// a page number. E.g., with 32 bit pointers and 4K pages (i.e., -// page offset fits in lower 12 bits), BITS == 20. - -#ifndef TCMALLOC_PAGEMAP_H__ -#define TCMALLOC_PAGEMAP_H__ - -#if HAVE(STDINT_H) -#include <stdint.h> -#elif HAVE(INTTYPES_H) -#include <inttypes.h> -#else -#include <sys/types.h> -#endif - -#include <string.h> -#include "Assertions.h" - -// Single-level array -template <int BITS> -class TCMalloc_PageMap1 { - private: - void** array_; - - public: - typedef uintptr_t Number; - - void init(void* (*allocator)(size_t)) { - array_ = reinterpret_cast<void**>((*allocator)(sizeof(void*) << BITS)); - memset(array_, 0, sizeof(void*) << BITS); - } - - // Ensure that the map contains initialized entries "x .. x+n-1". - // Returns true if successful, false if we could not allocate memory. - bool Ensure(Number, size_t) { - // Nothing to do since flat array was allocate at start - return true; - } - - void PreallocateMoreMemory() {} - - // REQUIRES "k" is in range "[0,2^BITS-1]". - // REQUIRES "k" has been ensured before. - // - // Return the current value for KEY. Returns "Value()" if not - // yet set. - void* get(Number k) const { - return array_[k]; - } - - // REQUIRES "k" is in range "[0,2^BITS-1]". - // REQUIRES "k" has been ensured before. - // - // Sets the value for KEY. - void set(Number k, void* v) { - array_[k] = v; - } -}; - -// Two-level radix tree -template <int BITS> -class TCMalloc_PageMap2 { - private: - // Put 32 entries in the root and (2^BITS)/32 entries in each leaf. - static const int ROOT_BITS = 5; - static const int ROOT_LENGTH = 1 << ROOT_BITS; - - static const int LEAF_BITS = BITS - ROOT_BITS; - static const int LEAF_LENGTH = 1 << LEAF_BITS; - - // Leaf node - struct Leaf { - void* values[LEAF_LENGTH]; - }; - - Leaf* root_[ROOT_LENGTH]; // Pointers to 32 child nodes - void* (*allocator_)(size_t); // Memory allocator - - public: - typedef uintptr_t Number; - - void init(void* (*allocator)(size_t)) { - allocator_ = allocator; - memset(root_, 0, sizeof(root_)); - } - - void* get(Number k) const { - ASSERT(k >> BITS == 0); - const Number i1 = k >> LEAF_BITS; - const Number i2 = k & (LEAF_LENGTH-1); - return root_[i1]->values[i2]; - } - - void set(Number k, void* v) { - ASSERT(k >> BITS == 0); - const Number i1 = k >> LEAF_BITS; - const Number i2 = k & (LEAF_LENGTH-1); - root_[i1]->values[i2] = v; - } - - bool Ensure(Number start, size_t n) { - for (Number key = start; key <= start + n - 1; ) { - const Number i1 = key >> LEAF_BITS; - - // Make 2nd level node if necessary - if (root_[i1] == NULL) { - Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf))); - if (leaf == NULL) return false; - memset(leaf, 0, sizeof(*leaf)); - root_[i1] = leaf; - } - - // Advance key past whatever is covered by this leaf node - key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; - } - return true; - } - - void PreallocateMoreMemory() { - // Allocate enough to keep track of all possible pages - Ensure(0, 1 << BITS); - } - -#ifdef WTF_CHANGES - template<class Visitor, class MemoryReader> - void visitValues(Visitor& visitor, const MemoryReader& reader) - { - for (int i = 0; i < ROOT_LENGTH; i++) { - if (!root_[i]) - continue; - - Leaf* l = reader(reinterpret_cast<Leaf*>(root_[i])); - for (int j = 0; j < LEAF_LENGTH; j += visitor.visit(l->values[j])) - ; - } - } - - template<class Visitor, class MemoryReader> - void visitAllocations(Visitor& visitor, const MemoryReader&) { - for (int i = 0; i < ROOT_LENGTH; i++) { - if (root_[i]) - visitor.visit(root_[i], sizeof(Leaf)); - } - } -#endif -}; - -// Three-level radix tree -template <int BITS> -class TCMalloc_PageMap3 { - private: - // How many bits should we consume at each interior level - static const int INTERIOR_BITS = (BITS + 2) / 3; // Round-up - static const int INTERIOR_LENGTH = 1 << INTERIOR_BITS; - - // How many bits should we consume at leaf level - static const int LEAF_BITS = BITS - 2*INTERIOR_BITS; - static const int LEAF_LENGTH = 1 << LEAF_BITS; - - // Interior node - struct Node { - Node* ptrs[INTERIOR_LENGTH]; - }; - - // Leaf node - struct Leaf { - void* values[LEAF_LENGTH]; - }; - - Node* root_; // Root of radix tree - void* (*allocator_)(size_t); // Memory allocator - - Node* NewNode() { - Node* result = reinterpret_cast<Node*>((*allocator_)(sizeof(Node))); - if (result != NULL) { - memset(result, 0, sizeof(*result)); - } - return result; - } - - public: - typedef uintptr_t Number; - - void init(void* (*allocator)(size_t)) { - allocator_ = allocator; - root_ = NewNode(); - } - - void* get(Number k) const { - ASSERT(k >> BITS == 0); - const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS); - const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1); - const Number i3 = k & (LEAF_LENGTH-1); - return reinterpret_cast<Leaf*>(root_->ptrs[i1]->ptrs[i2])->values[i3]; - } - - void set(Number k, void* v) { - ASSERT(k >> BITS == 0); - const Number i1 = k >> (LEAF_BITS + INTERIOR_BITS); - const Number i2 = (k >> LEAF_BITS) & (INTERIOR_LENGTH-1); - const Number i3 = k & (LEAF_LENGTH-1); - reinterpret_cast<Leaf*>(root_->ptrs[i1]->ptrs[i2])->values[i3] = v; - } - - bool Ensure(Number start, size_t n) { - for (Number key = start; key <= start + n - 1; ) { - const Number i1 = key >> (LEAF_BITS + INTERIOR_BITS); - const Number i2 = (key >> LEAF_BITS) & (INTERIOR_LENGTH-1); - - // Make 2nd level node if necessary - if (root_->ptrs[i1] == NULL) { - Node* n = NewNode(); - if (n == NULL) return false; - root_->ptrs[i1] = n; - } - - // Make leaf node if necessary - if (root_->ptrs[i1]->ptrs[i2] == NULL) { - Leaf* leaf = reinterpret_cast<Leaf*>((*allocator_)(sizeof(Leaf))); - if (leaf == NULL) return false; - memset(leaf, 0, sizeof(*leaf)); - root_->ptrs[i1]->ptrs[i2] = reinterpret_cast<Node*>(leaf); - } - - // Advance key past whatever is covered by this leaf node - key = ((key >> LEAF_BITS) + 1) << LEAF_BITS; - } - return true; - } - - void PreallocateMoreMemory() { - } - -#ifdef WTF_CHANGES - template<class Visitor, class MemoryReader> - void visitValues(Visitor& visitor, const MemoryReader& reader) { - Node* root = reader(root_); - for (int i = 0; i < INTERIOR_LENGTH; i++) { - if (!root->ptrs[i]) - continue; - - Node* n = reader(root->ptrs[i]); - for (int j = 0; j < INTERIOR_LENGTH; j++) { - if (!n->ptrs[j]) - continue; - - Leaf* l = reader(reinterpret_cast<Leaf*>(n->ptrs[j])); - for (int k = 0; k < LEAF_LENGTH; k += visitor.visit(l->values[k])) - ; - } - } - } - - template<class Visitor, class MemoryReader> - void visitAllocations(Visitor& visitor, const MemoryReader& reader) { - visitor.visit(root_, sizeof(Node)); - - Node* root = reader(root_); - for (int i = 0; i < INTERIOR_LENGTH; i++) { - if (!root->ptrs[i]) - continue; - - visitor.visit(root->ptrs[i], sizeof(Node)); - Node* n = reader(root->ptrs[i]); - for (int j = 0; j < INTERIOR_LENGTH; j++) { - if (!n->ptrs[j]) - continue; - - visitor.visit(n->ptrs[j], sizeof(Leaf)); - } - } - } -#endif -}; - -#endif // TCMALLOC_PAGEMAP_H__ diff --git a/JavaScriptCore/wtf/TCSpinLock.h b/JavaScriptCore/wtf/TCSpinLock.h deleted file mode 100644 index 81b7d0c..0000000 --- a/JavaScriptCore/wtf/TCSpinLock.h +++ /dev/null @@ -1,284 +0,0 @@ -// Copyright (c) 2005, 2006, Google Inc. -// Copyright (c) 2010, Patrick Gansterer <paroga@paroga.com> -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Sanjay Ghemawat <opensource@google.com> - -#ifndef TCMALLOC_INTERNAL_SPINLOCK_H__ -#define TCMALLOC_INTERNAL_SPINLOCK_H__ - -#if (CPU(X86) || CPU(X86_64) || CPU(PPC)) && (COMPILER(GCC) || COMPILER(MSVC)) - -#include <time.h> /* For nanosleep() */ - -#if HAVE(STDINT_H) -#include <stdint.h> -#elif HAVE(INTTYPES_H) -#include <inttypes.h> -#else -#include <sys/types.h> -#endif - -#if OS(WINDOWS) -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> -#else -#include <sched.h> /* For sched_yield() */ -#endif - -static void TCMalloc_SlowLock(volatile unsigned int* lockword); - -// The following is a struct so that it can be initialized at compile time -struct TCMalloc_SpinLock { - - inline void Lock() { - int r; -#if COMPILER(GCC) -#if CPU(X86) || CPU(X86_64) - __asm__ __volatile__ - ("xchgl %0, %1" - : "=r"(r), "=m"(lockword_) - : "0"(1), "m"(lockword_) - : "memory"); -#else - volatile unsigned int *lockword_ptr = &lockword_; - __asm__ __volatile__ - ("1: lwarx %0, 0, %1\n\t" - "stwcx. %2, 0, %1\n\t" - "bne- 1b\n\t" - "isync" - : "=&r" (r), "=r" (lockword_ptr) - : "r" (1), "1" (lockword_ptr) - : "memory"); -#endif -#elif COMPILER(MSVC) - __asm { - mov eax, this ; store &lockword_ (which is this+0) in eax - mov ebx, 1 ; store 1 in ebx - xchg [eax], ebx ; exchange lockword_ and 1 - mov r, ebx ; store old value of lockword_ in r - } -#endif - if (r) TCMalloc_SlowLock(&lockword_); - } - - inline void Unlock() { -#if COMPILER(GCC) -#if CPU(X86) || CPU(X86_64) - __asm__ __volatile__ - ("movl $0, %0" - : "=m"(lockword_) - : "m" (lockword_) - : "memory"); -#else - __asm__ __volatile__ - ("isync\n\t" - "eieio\n\t" - "stw %1, %0" -#if OS(DARWIN) || CPU(PPC) - : "=o" (lockword_) -#else - : "=m" (lockword_) -#endif - : "r" (0) - : "memory"); -#endif -#elif COMPILER(MSVC) - __asm { - mov eax, this ; store &lockword_ (which is this+0) in eax - mov [eax], 0 ; set lockword_ to 0 - } -#endif - } - // Report if we think the lock can be held by this thread. - // When the lock is truly held by the invoking thread - // we will always return true. - // Indended to be used as CHECK(lock.IsHeld()); - inline bool IsHeld() const { - return lockword_ != 0; - } - - inline void Init() { lockword_ = 0; } - - volatile unsigned int lockword_; -}; - -#define SPINLOCK_INITIALIZER { 0 } - -static void TCMalloc_SlowLock(volatile unsigned int* lockword) { -// Yield immediately since fast path failed -#if OS(WINDOWS) - Sleep(0); -#else - sched_yield(); -#endif - while (true) { - int r; -#if COMPILER(GCC) -#if CPU(X86) || CPU(X86_64) - __asm__ __volatile__ - ("xchgl %0, %1" - : "=r"(r), "=m"(*lockword) - : "0"(1), "m"(*lockword) - : "memory"); - -#else - int tmp = 1; - __asm__ __volatile__ - ("1: lwarx %0, 0, %1\n\t" - "stwcx. %2, 0, %1\n\t" - "bne- 1b\n\t" - "isync" - : "=&r" (r), "=r" (lockword) - : "r" (tmp), "1" (lockword) - : "memory"); -#endif -#elif COMPILER(MSVC) - __asm { - mov eax, lockword ; assign lockword into eax - mov ebx, 1 ; assign 1 into ebx - xchg [eax], ebx ; exchange *lockword and 1 - mov r, ebx ; store old value of *lockword in r - } -#endif - if (!r) { - return; - } - - // This code was adapted from the ptmalloc2 implementation of - // spinlocks which would sched_yield() upto 50 times before - // sleeping once for a few milliseconds. Mike Burrows suggested - // just doing one sched_yield() outside the loop and always - // sleeping after that. This change helped a great deal on the - // performance of spinlocks under high contention. A test program - // with 10 threads on a dual Xeon (four virtual processors) went - // from taking 30 seconds to 16 seconds. - - // Sleep for a few milliseconds -#if OS(WINDOWS) - Sleep(2); -#else - struct timespec tm; - tm.tv_sec = 0; - tm.tv_nsec = 2000001; - nanosleep(&tm, NULL); -#endif - } -} - -#elif OS(WINDOWS) - -#ifndef WIN32_LEAN_AND_MEAN -#define WIN32_LEAN_AND_MEAN -#endif -#include <windows.h> - -static void TCMalloc_SlowLock(LPLONG lockword); - -// The following is a struct so that it can be initialized at compile time -struct TCMalloc_SpinLock { - - inline void Lock() { - if (InterlockedExchange(&m_lockword, 1)) - TCMalloc_SlowLock(&m_lockword); - } - - inline void Unlock() { - InterlockedExchange(&m_lockword, 0); - } - - inline bool IsHeld() const { - return m_lockword != 0; - } - - inline void Init() { m_lockword = 0; } - - LONG m_lockword; -}; - -#define SPINLOCK_INITIALIZER { 0 } - -static void TCMalloc_SlowLock(LPLONG lockword) { - Sleep(0); // Yield immediately since fast path failed - while (InterlockedExchange(lockword, 1)) - Sleep(2); -} - -#else - -#include <pthread.h> - -// Portable version -struct TCMalloc_SpinLock { - pthread_mutex_t private_lock_; - - inline void Init() { - if (pthread_mutex_init(&private_lock_, NULL) != 0) CRASH(); - } - inline void Finalize() { - if (pthread_mutex_destroy(&private_lock_) != 0) CRASH(); - } - inline void Lock() { - if (pthread_mutex_lock(&private_lock_) != 0) CRASH(); - } - inline void Unlock() { - if (pthread_mutex_unlock(&private_lock_) != 0) CRASH(); - } - bool IsHeld() { - if (pthread_mutex_trylock(&private_lock_)) - return true; - - Unlock(); - return false; - } -}; - -#define SPINLOCK_INITIALIZER { PTHREAD_MUTEX_INITIALIZER } - -#endif - -// Corresponding locker object that arranges to acquire a spinlock for -// the duration of a C++ scope. -class TCMalloc_SpinLockHolder { - private: - TCMalloc_SpinLock* lock_; - public: - inline explicit TCMalloc_SpinLockHolder(TCMalloc_SpinLock* l) - : lock_(l) { l->Lock(); } - inline ~TCMalloc_SpinLockHolder() { lock_->Unlock(); } -}; - -// Short-hands for convenient use by tcmalloc.cc -typedef TCMalloc_SpinLock SpinLock; -typedef TCMalloc_SpinLockHolder SpinLockHolder; - -#endif // TCMALLOC_INTERNAL_SPINLOCK_H__ diff --git a/JavaScriptCore/wtf/TCSystemAlloc.cpp b/JavaScriptCore/wtf/TCSystemAlloc.cpp deleted file mode 100644 index 0b7ecc9..0000000 --- a/JavaScriptCore/wtf/TCSystemAlloc.cpp +++ /dev/null @@ -1,521 +0,0 @@ -// Copyright (c) 2005, 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Sanjay Ghemawat - -#include "config.h" -#include "TCSystemAlloc.h" - -#include <algorithm> -#include "Assertions.h" -#include "TCSpinLock.h" -#include "UnusedParam.h" -#include "VMTags.h" - -#if HAVE(STDINT_H) -#include <stdint.h> -#elif HAVE(INTTYPES_H) -#include <inttypes.h> -#else -#include <sys/types.h> -#endif - -#if OS(WINDOWS) -#include "windows.h" -#else -#include <errno.h> -#include <unistd.h> -#include <sys/mman.h> -#endif - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - -using namespace std; - -// Structure for discovering alignment -union MemoryAligner { - void* p; - double d; - size_t s; -}; - -static SpinLock spinlock = SPINLOCK_INITIALIZER; - -// Page size is initialized on demand -static size_t pagesize = 0; - -// Configuration parameters. -// -// if use_devmem is true, either use_sbrk or use_mmap must also be true. -// For 2.2 kernels, it looks like the sbrk address space (500MBish) and -// the mmap address space (1300MBish) are disjoint, so we need both allocators -// to get as much virtual memory as possible. -#ifndef WTF_CHANGES -static bool use_devmem = false; -#endif - -#if HAVE(SBRK) -static bool use_sbrk = false; -#endif - -#if HAVE(MMAP) -static bool use_mmap = true; -#endif - -#if HAVE(VIRTUALALLOC) -static bool use_VirtualAlloc = true; -#endif - -// Flags to keep us from retrying allocators that failed. -static bool devmem_failure = false; -static bool sbrk_failure = false; -static bool mmap_failure = false; -static bool VirtualAlloc_failure = false; - -#ifndef WTF_CHANGES -DEFINE_int32(malloc_devmem_start, 0, - "Physical memory starting location in MB for /dev/mem allocation." - " Setting this to 0 disables /dev/mem allocation"); -DEFINE_int32(malloc_devmem_limit, 0, - "Physical memory limit location in MB for /dev/mem allocation." - " Setting this to 0 means no limit."); -#else -static const int32_t FLAGS_malloc_devmem_start = 0; -static const int32_t FLAGS_malloc_devmem_limit = 0; -#endif - -#if HAVE(SBRK) - -static void* TrySbrk(size_t size, size_t *actual_size, size_t alignment) { - size = ((size + alignment - 1) / alignment) * alignment; - - // could theoretically return the "extra" bytes here, but this - // is simple and correct. - if (actual_size) - *actual_size = size; - - void* result = sbrk(size); - if (result == reinterpret_cast<void*>(-1)) { - sbrk_failure = true; - return NULL; - } - - // Is it aligned? - uintptr_t ptr = reinterpret_cast<uintptr_t>(result); - if ((ptr & (alignment-1)) == 0) return result; - - // Try to get more memory for alignment - size_t extra = alignment - (ptr & (alignment-1)); - void* r2 = sbrk(extra); - if (reinterpret_cast<uintptr_t>(r2) == (ptr + size)) { - // Contiguous with previous result - return reinterpret_cast<void*>(ptr + extra); - } - - // Give up and ask for "size + alignment - 1" bytes so - // that we can find an aligned region within it. - result = sbrk(size + alignment - 1); - if (result == reinterpret_cast<void*>(-1)) { - sbrk_failure = true; - return NULL; - } - ptr = reinterpret_cast<uintptr_t>(result); - if ((ptr & (alignment-1)) != 0) { - ptr += alignment - (ptr & (alignment-1)); - } - return reinterpret_cast<void*>(ptr); -} - -#endif /* HAVE(SBRK) */ - -#if HAVE(MMAP) - -static void* TryMmap(size_t size, size_t *actual_size, size_t alignment) { - // Enforce page alignment - if (pagesize == 0) pagesize = getpagesize(); - if (alignment < pagesize) alignment = pagesize; - size = ((size + alignment - 1) / alignment) * alignment; - - // could theoretically return the "extra" bytes here, but this - // is simple and correct. - if (actual_size) - *actual_size = size; - - // Ask for extra memory if alignment > pagesize - size_t extra = 0; - if (alignment > pagesize) { - extra = alignment - pagesize; - } - void* result = mmap(NULL, size + extra, - PROT_READ | PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, - VM_TAG_FOR_TCMALLOC_MEMORY, 0); - if (result == reinterpret_cast<void*>(MAP_FAILED)) { - mmap_failure = true; - return NULL; - } - - // Adjust the return memory so it is aligned - uintptr_t ptr = reinterpret_cast<uintptr_t>(result); - size_t adjust = 0; - if ((ptr & (alignment - 1)) != 0) { - adjust = alignment - (ptr & (alignment - 1)); - } - - // Return the unused memory to the system - if (adjust > 0) { - munmap(reinterpret_cast<void*>(ptr), adjust); - } - if (adjust < extra) { - munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust); - } - - ptr += adjust; - return reinterpret_cast<void*>(ptr); -} - -#endif /* HAVE(MMAP) */ - -#if HAVE(VIRTUALALLOC) - -static void* TryVirtualAlloc(size_t size, size_t *actual_size, size_t alignment) { - // Enforce page alignment - if (pagesize == 0) { - SYSTEM_INFO system_info; - GetSystemInfo(&system_info); - pagesize = system_info.dwPageSize; - } - - if (alignment < pagesize) alignment = pagesize; - size = ((size + alignment - 1) / alignment) * alignment; - - // could theoretically return the "extra" bytes here, but this - // is simple and correct. - if (actual_size) - *actual_size = size; - - // Ask for extra memory if alignment > pagesize - size_t extra = 0; - if (alignment > pagesize) { - extra = alignment - pagesize; - } - void* result = VirtualAlloc(NULL, size + extra, - MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN, - PAGE_READWRITE); - - if (result == NULL) { - VirtualAlloc_failure = true; - return NULL; - } - - // Adjust the return memory so it is aligned - uintptr_t ptr = reinterpret_cast<uintptr_t>(result); - size_t adjust = 0; - if ((ptr & (alignment - 1)) != 0) { - adjust = alignment - (ptr & (alignment - 1)); - } - - // Return the unused memory to the system - we'd like to release but the best we can do - // is decommit, since Windows only lets you free the whole allocation. - if (adjust > 0) { - VirtualFree(reinterpret_cast<void*>(ptr), adjust, MEM_DECOMMIT); - } - if (adjust < extra) { - VirtualFree(reinterpret_cast<void*>(ptr + adjust + size), extra-adjust, MEM_DECOMMIT); - } - - ptr += adjust; - return reinterpret_cast<void*>(ptr); -} - -#endif /* HAVE(MMAP) */ - -#ifndef WTF_CHANGES -static void* TryDevMem(size_t size, size_t *actual_size, size_t alignment) { - static bool initialized = false; - static off_t physmem_base; // next physical memory address to allocate - static off_t physmem_limit; // maximum physical address allowed - static int physmem_fd; // file descriptor for /dev/mem - - // Check if we should use /dev/mem allocation. Note that it may take - // a while to get this flag initialized, so meanwhile we fall back to - // the next allocator. (It looks like 7MB gets allocated before - // this flag gets initialized -khr.) - if (FLAGS_malloc_devmem_start == 0) { - // NOTE: not a devmem_failure - we'd like TCMalloc_SystemAlloc to - // try us again next time. - return NULL; - } - - if (!initialized) { - physmem_fd = open("/dev/mem", O_RDWR); - if (physmem_fd < 0) { - devmem_failure = true; - return NULL; - } - physmem_base = FLAGS_malloc_devmem_start*1024LL*1024LL; - physmem_limit = FLAGS_malloc_devmem_limit*1024LL*1024LL; - initialized = true; - } - - // Enforce page alignment - if (pagesize == 0) pagesize = getpagesize(); - if (alignment < pagesize) alignment = pagesize; - size = ((size + alignment - 1) / alignment) * alignment; - - // could theoretically return the "extra" bytes here, but this - // is simple and correct. - if (actual_size) - *actual_size = size; - - // Ask for extra memory if alignment > pagesize - size_t extra = 0; - if (alignment > pagesize) { - extra = alignment - pagesize; - } - - // check to see if we have any memory left - if (physmem_limit != 0 && physmem_base + size + extra > physmem_limit) { - devmem_failure = true; - return NULL; - } - void *result = mmap(0, size + extra, PROT_READ | PROT_WRITE, - MAP_SHARED, physmem_fd, physmem_base); - if (result == reinterpret_cast<void*>(MAP_FAILED)) { - devmem_failure = true; - return NULL; - } - uintptr_t ptr = reinterpret_cast<uintptr_t>(result); - - // Adjust the return memory so it is aligned - size_t adjust = 0; - if ((ptr & (alignment - 1)) != 0) { - adjust = alignment - (ptr & (alignment - 1)); - } - - // Return the unused virtual memory to the system - if (adjust > 0) { - munmap(reinterpret_cast<void*>(ptr), adjust); - } - if (adjust < extra) { - munmap(reinterpret_cast<void*>(ptr + adjust + size), extra - adjust); - } - - ptr += adjust; - physmem_base += adjust + size; - - return reinterpret_cast<void*>(ptr); -} -#endif - -void* TCMalloc_SystemAlloc(size_t size, size_t *actual_size, size_t alignment) { - // Discard requests that overflow - if (size + alignment < size) return NULL; - - SpinLockHolder lock_holder(&spinlock); - - // Enforce minimum alignment - if (alignment < sizeof(MemoryAligner)) alignment = sizeof(MemoryAligner); - - // Try twice, once avoiding allocators that failed before, and once - // more trying all allocators even if they failed before. - for (int i = 0; i < 2; i++) { - -#ifndef WTF_CHANGES - if (use_devmem && !devmem_failure) { - void* result = TryDevMem(size, actual_size, alignment); - if (result != NULL) return result; - } -#endif - -#if HAVE(SBRK) - if (use_sbrk && !sbrk_failure) { - void* result = TrySbrk(size, actual_size, alignment); - if (result != NULL) return result; - } -#endif - -#if HAVE(MMAP) - if (use_mmap && !mmap_failure) { - void* result = TryMmap(size, actual_size, alignment); - if (result != NULL) return result; - } -#endif - -#if HAVE(VIRTUALALLOC) - if (use_VirtualAlloc && !VirtualAlloc_failure) { - void* result = TryVirtualAlloc(size, actual_size, alignment); - if (result != NULL) return result; - } -#endif - - // nothing worked - reset failure flags and try again - devmem_failure = false; - sbrk_failure = false; - mmap_failure = false; - VirtualAlloc_failure = false; - } - return NULL; -} - -#if HAVE(MADV_FREE_REUSE) - -void TCMalloc_SystemRelease(void* start, size_t length) -{ - while (madvise(start, length, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN) { } -} - -#elif HAVE(MADV_FREE) || HAVE(MADV_DONTNEED) - -void TCMalloc_SystemRelease(void* start, size_t length) -{ - // MADV_FREE clears the modified bit on pages, which allows - // them to be discarded immediately. -#if HAVE(MADV_FREE) - const int advice = MADV_FREE; -#else - const int advice = MADV_DONTNEED; -#endif - if (FLAGS_malloc_devmem_start) { - // It's not safe to use MADV_DONTNEED if we've been mapping - // /dev/mem for heap memory - return; - } - if (pagesize == 0) pagesize = getpagesize(); - const size_t pagemask = pagesize - 1; - - size_t new_start = reinterpret_cast<size_t>(start); - size_t end = new_start + length; - size_t new_end = end; - - // Round up the starting address and round down the ending address - // to be page aligned: - new_start = (new_start + pagesize - 1) & ~pagemask; - new_end = new_end & ~pagemask; - - ASSERT((new_start & pagemask) == 0); - ASSERT((new_end & pagemask) == 0); - ASSERT(new_start >= reinterpret_cast<size_t>(start)); - ASSERT(new_end <= end); - - if (new_end > new_start) { - // Note -- ignoring most return codes, because if this fails it - // doesn't matter... - while (madvise(reinterpret_cast<char*>(new_start), new_end - new_start, - advice) == -1 && - errno == EAGAIN) { - // NOP - } - } -} - -#elif HAVE(MMAP) - -void TCMalloc_SystemRelease(void* start, size_t length) -{ - void* newAddress = mmap(start, length, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED, -1, 0); - // If the mmap failed then that's ok, we just won't return the memory to the system. - ASSERT_UNUSED(newAddress, newAddress == start || newAddress == reinterpret_cast<void*>(MAP_FAILED)); -} - -#elif HAVE(VIRTUALALLOC) - -void TCMalloc_SystemRelease(void* start, size_t length) -{ - if (VirtualFree(start, length, MEM_DECOMMIT)) - return; - - // The decommit may fail if the memory region consists of allocations - // from more than one call to VirtualAlloc. In this case, fall back to - // using VirtualQuery to retrieve the allocation boundaries and decommit - // them each individually. - - char* ptr = static_cast<char*>(start); - char* end = ptr + length; - MEMORY_BASIC_INFORMATION info; - while (ptr < end) { - size_t resultSize = VirtualQuery(ptr, &info, sizeof(info)); - ASSERT_UNUSED(resultSize, resultSize == sizeof(info)); - - size_t decommitSize = min<size_t>(info.RegionSize, end - ptr); - BOOL success = VirtualFree(ptr, decommitSize, MEM_DECOMMIT); - ASSERT_UNUSED(success, success); - ptr += decommitSize; - } -} - -#else - -// Platforms that don't support returning memory use an empty inline version of TCMalloc_SystemRelease -// declared in TCSystemAlloc.h - -#endif - -#if HAVE(MADV_FREE_REUSE) - -void TCMalloc_SystemCommit(void* start, size_t length) -{ - while (madvise(start, length, MADV_FREE_REUSE) == -1 && errno == EAGAIN) { } -} - -#elif HAVE(VIRTUALALLOC) - -void TCMalloc_SystemCommit(void* start, size_t length) -{ - if (VirtualAlloc(start, length, MEM_COMMIT, PAGE_READWRITE) == start) - return; - - // The commit may fail if the memory region consists of allocations - // from more than one call to VirtualAlloc. In this case, fall back to - // using VirtualQuery to retrieve the allocation boundaries and commit them - // each individually. - - char* ptr = static_cast<char*>(start); - char* end = ptr + length; - MEMORY_BASIC_INFORMATION info; - while (ptr < end) { - size_t resultSize = VirtualQuery(ptr, &info, sizeof(info)); - ASSERT_UNUSED(resultSize, resultSize == sizeof(info)); - - size_t commitSize = min<size_t>(info.RegionSize, end - ptr); - void* newAddress = VirtualAlloc(ptr, commitSize, MEM_COMMIT, PAGE_READWRITE); - ASSERT_UNUSED(newAddress, newAddress == ptr); - ptr += commitSize; - } -} - -#else - -// Platforms that don't need to explicitly commit memory use an empty inline version of TCMalloc_SystemCommit -// declared in TCSystemAlloc.h - -#endif diff --git a/JavaScriptCore/wtf/TCSystemAlloc.h b/JavaScriptCore/wtf/TCSystemAlloc.h deleted file mode 100644 index 1c67788..0000000 --- a/JavaScriptCore/wtf/TCSystemAlloc.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (c) 2005, 2007, Google Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -// --- -// Author: Sanjay Ghemawat -// -// Routine that uses sbrk/mmap to allocate memory from the system. -// Useful for implementing malloc. - -#ifndef TCMALLOC_SYSTEM_ALLOC_H__ -#define TCMALLOC_SYSTEM_ALLOC_H__ - -// REQUIRES: "alignment" is a power of two or "0" to indicate default alignment -// -// Allocate and return "N" bytes of zeroed memory. -// -// If actual_bytes is NULL then the returned memory is exactly the -// requested size. If actual bytes is non-NULL then the allocator -// may optionally return more bytes than asked for (i.e. return an -// entire "huge" page if a huge page allocator is in use). -// -// The returned pointer is a multiple of "alignment" if non-zero. -// -// Returns NULL when out of memory. -extern void* TCMalloc_SystemAlloc(size_t bytes, size_t *actual_bytes, - size_t alignment = 0); - -// This call is a hint to the operating system that the pages -// contained in the specified range of memory will not be used for a -// while, and can be released for use by other processes or the OS. -// Pages which are released in this way may be destroyed (zeroed) by -// the OS. The benefit of this function is that it frees memory for -// use by the system, the cost is that the pages are faulted back into -// the address space next time they are touched, which can impact -// performance. (Only pages fully covered by the memory region will -// be released, partial pages will not.) -extern void TCMalloc_SystemRelease(void* start, size_t length); - -extern void TCMalloc_SystemCommit(void* start, size_t length); - -#if !HAVE(MADV_FREE_REUSE) && !HAVE(MADV_DONTNEED) && !HAVE(MMAP) && !HAVE(VIRTUALALLOC) -inline void TCMalloc_SystemRelease(void*, size_t) { } -#endif - -#if !HAVE(VIRTUALALLOC) && !HAVE(MADV_FREE_REUSE) -inline void TCMalloc_SystemCommit(void*, size_t) { } -#endif - -#endif /* TCMALLOC_SYSTEM_ALLOC_H__ */ diff --git a/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp b/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp deleted file mode 100644 index 042d49e..0000000 --- a/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#if USE(PTHREADS) - -#include "ThreadIdentifierDataPthreads.h" - -#include "Threading.h" - -namespace WTF { - -pthread_key_t ThreadIdentifierData::m_key; - -void clearPthreadHandleForIdentifier(ThreadIdentifier); - -ThreadIdentifierData::~ThreadIdentifierData() -{ - clearPthreadHandleForIdentifier(m_identifier); -} - -ThreadIdentifier ThreadIdentifierData::identifier() -{ - initializeKeyOnce(); - ThreadIdentifierData* threadIdentifierData = static_cast<ThreadIdentifierData*>(pthread_getspecific(m_key)); - - return threadIdentifierData ? threadIdentifierData->m_identifier : 0; -} - -void ThreadIdentifierData::initialize(ThreadIdentifier id) -{ - ASSERT(!identifier()); - - initializeKeyOnce(); - pthread_setspecific(m_key, new ThreadIdentifierData(id)); -} - -void ThreadIdentifierData::destruct(void* data) -{ - ThreadIdentifierData* threadIdentifierData = static_cast<ThreadIdentifierData*>(data); - ASSERT(threadIdentifierData); - - if (threadIdentifierData->m_isDestroyedOnce) { - delete threadIdentifierData; - return; - } - - threadIdentifierData->m_isDestroyedOnce = true; - // Re-setting the value for key causes another destruct() call after all other thread-specific destructors were called. - pthread_setspecific(m_key, threadIdentifierData); -} - -void ThreadIdentifierData::initializeKeyOnceHelper() -{ - if (pthread_key_create(&m_key, destruct)) - CRASH(); -} - -void ThreadIdentifierData::initializeKeyOnce() -{ - static pthread_once_t onceControl = PTHREAD_ONCE_INIT; - if (pthread_once(&onceControl, initializeKeyOnceHelper)) - CRASH(); -} - -} // namespace WTF - -#endif // USE(PTHREADS) - diff --git a/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h b/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h deleted file mode 100644 index 3af87a8..0000000 --- a/JavaScriptCore/wtf/ThreadIdentifierDataPthreads.h +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ThreadIdentifierDataPthreads_h -#define ThreadIdentifierDataPthreads_h - -#include <wtf/Noncopyable.h> -#include <wtf/Threading.h> - -namespace WTF { - -// Holds ThreadIdentifier in the thread-specific storage and employs pthreads-specific 2-pass destruction to reliably remove -// ThreadIdentifier from threadMap. It assumes regular ThreadSpecific types don't use multiple-pass destruction. -class ThreadIdentifierData : public Noncopyable { -public: - ~ThreadIdentifierData(); - - // Creates and puts an instance of ThreadIdentifierData into thread-specific storage. - static void initialize(ThreadIdentifier identifier); - - // Returns 0 if thread-specific storage was not initialized. - static ThreadIdentifier identifier(); - -private: - ThreadIdentifierData(ThreadIdentifier identifier) - : m_identifier(identifier) - , m_isDestroyedOnce(false) - { - } - - // This thread-specific destructor is called 2 times when thread terminates: - // - first, when all the other thread-specific destructors are called, it simply remembers it was 'destroyed once' - // and re-sets itself into the thread-specific slot to make Pthreads to call it again later. - // - second, after all thread-specific destructors were invoked, it gets called again - this time, we remove the - // ThreadIdentifier from the threadMap, completing the cleanup. - static void destruct(void* data); - - static void initializeKeyOnceHelper(); - static void initializeKeyOnce(); - - ThreadIdentifier m_identifier; - bool m_isDestroyedOnce; - static pthread_key_t m_key; -}; - -} // namespace WTF - -#endif // ThreadIdentifierDataPthreads_h - - diff --git a/JavaScriptCore/wtf/ThreadSafeShared.h b/JavaScriptCore/wtf/ThreadSafeShared.h deleted file mode 100644 index 33c6612..0000000 --- a/JavaScriptCore/wtf/ThreadSafeShared.h +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based - * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license - * is virtually identical to the Apple license above but is included here for completeness. - * - * Boost Software License - Version 1.0 - August 17th, 2003 - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef ThreadSafeShared_h -#define ThreadSafeShared_h - -#include "Platform.h" - -#include <wtf/Atomics.h> -#include <wtf/Noncopyable.h> -#include <wtf/ThreadingPrimitives.h> - -namespace WTF { - -class ThreadSafeSharedBase : public Noncopyable { -public: - ThreadSafeSharedBase(int initialRefCount = 1) - : m_refCount(initialRefCount) - { - } - - void ref() - { -#if USE(LOCKFREE_THREADSAFESHARED) - atomicIncrement(&m_refCount); -#else - MutexLocker locker(m_mutex); - ++m_refCount; -#endif - } - - bool hasOneRef() - { - return refCount() == 1; - } - - int refCount() const - { -#if !USE(LOCKFREE_THREADSAFESHARED) - MutexLocker locker(m_mutex); -#endif - return static_cast<int const volatile &>(m_refCount); - } - -protected: - // Returns whether the pointer should be freed or not. - bool derefBase() - { -#if USE(LOCKFREE_THREADSAFESHARED) - if (atomicDecrement(&m_refCount) <= 0) - return true; -#else - int refCount; - { - MutexLocker locker(m_mutex); - --m_refCount; - refCount = m_refCount; - } - if (refCount <= 0) - return true; -#endif - return false; - } - -private: - template<class T> - friend class CrossThreadRefCounted; - - int m_refCount; -#if !USE(LOCKFREE_THREADSAFESHARED) - mutable Mutex m_mutex; -#endif -}; - -template<class T> class ThreadSafeShared : public ThreadSafeSharedBase { -public: - void deref() - { - if (derefBase()) - delete static_cast<T*>(this); - } - -protected: - ThreadSafeShared() - { - } -}; - -} // namespace WTF - -using WTF::ThreadSafeShared; - -#endif // ThreadSafeShared_h diff --git a/JavaScriptCore/wtf/ThreadSpecific.h b/JavaScriptCore/wtf/ThreadSpecific.h deleted file mode 100644 index 93ed466..0000000 --- a/JavaScriptCore/wtf/ThreadSpecific.h +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Jian Li <jianli@chromium.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* Thread local storage is implemented by using either pthread API or Windows - * native API. There is subtle semantic discrepancy for the cleanup function - * implementation as noted below: - * @ In pthread implementation, the destructor function will be called - * repeatedly if there is still non-NULL value associated with the function. - * @ In Windows native implementation, the destructor function will be called - * only once. - * This semantic discrepancy does not impose any problem because nowhere in - * WebKit the repeated call bahavior is utilized. - */ - -#ifndef WTF_ThreadSpecific_h -#define WTF_ThreadSpecific_h - -#include <wtf/Noncopyable.h> - -#if USE(PTHREADS) -#include <pthread.h> -#elif PLATFORM(QT) -#include <QThreadStorage> -#elif PLATFORM(GTK) -#include <glib.h> -#elif OS(WINDOWS) -#include <windows.h> -#endif - -namespace WTF { - -#if !USE(PTHREADS) && !PLATFORM(QT) && !PLATFORM(GTK) && OS(WINDOWS) -// ThreadSpecificThreadExit should be called each time when a thread is detached. -// This is done automatically for threads created with WTF::createThread. -void ThreadSpecificThreadExit(); -#endif - -template<typename T> class ThreadSpecific : public Noncopyable { -public: - ThreadSpecific(); - T* operator->(); - operator T*(); - T& operator*(); - -private: -#if !USE(PTHREADS) && !PLATFORM(QT) && !PLATFORM(GTK) && OS(WINDOWS) - friend void ThreadSpecificThreadExit(); -#endif - - // Not implemented. It's technically possible to destroy a thread specific key, but one would need - // to make sure that all values have been destroyed already (usually, that all threads that used it - // have exited). It's unlikely that any user of this call will be in that situation - and having - // a destructor defined can be confusing, given that it has such strong pre-requisites to work correctly. - ~ThreadSpecific(); - - T* get(); - void set(T*); - void static destroy(void* ptr); - -#if USE(PTHREADS) || PLATFORM(QT) || PLATFORM(GTK) || OS(WINDOWS) - struct Data : Noncopyable { - Data(T* value, ThreadSpecific<T>* owner) : value(value), owner(owner) {} -#if PLATFORM(QT) - ~Data() { owner->destroy(this); } -#endif - - T* value; - ThreadSpecific<T>* owner; -#if !USE(PTHREADS) && !PLATFORM(QT) && !PLATFORM(GTK) - void (*destructor)(void*); -#endif - }; -#endif - -#if ENABLE(SINGLE_THREADED) - T* m_value; -#else -#if USE(PTHREADS) - pthread_key_t m_key; -#elif PLATFORM(QT) - QThreadStorage<Data*> m_key; -#elif PLATFORM(GTK) - GStaticPrivate m_key; -#elif OS(WINDOWS) - int m_index; -#endif -#endif -}; - -#if ENABLE(SINGLE_THREADED) -template<typename T> -inline ThreadSpecific<T>::ThreadSpecific() - : m_value(0) -{ -} - -template<typename T> -inline T* ThreadSpecific<T>::get() -{ - return m_value; -} - -template<typename T> -inline void ThreadSpecific<T>::set(T* ptr) -{ - ASSERT(!get()); - m_value = ptr; -} -#else -#if USE(PTHREADS) -template<typename T> -inline ThreadSpecific<T>::ThreadSpecific() -{ - int error = pthread_key_create(&m_key, destroy); - if (error) - CRASH(); -} - -template<typename T> -inline T* ThreadSpecific<T>::get() -{ - Data* data = static_cast<Data*>(pthread_getspecific(m_key)); - return data ? data->value : 0; -} - -template<typename T> -inline void ThreadSpecific<T>::set(T* ptr) -{ - ASSERT(!get()); - pthread_setspecific(m_key, new Data(ptr, this)); -} - -#elif PLATFORM(QT) - -template<typename T> -inline ThreadSpecific<T>::ThreadSpecific() -{ -} - -template<typename T> -inline T* ThreadSpecific<T>::get() -{ - Data* data = static_cast<Data*>(m_key.localData()); - return data ? data->value : 0; -} - -template<typename T> -inline void ThreadSpecific<T>::set(T* ptr) -{ - ASSERT(!get()); - Data* data = new Data(ptr, this); - m_key.setLocalData(data); -} - -#elif PLATFORM(GTK) - -template<typename T> -inline ThreadSpecific<T>::ThreadSpecific() -{ - g_static_private_init(&m_key); -} - -template<typename T> -inline T* ThreadSpecific<T>::get() -{ - Data* data = static_cast<Data*>(g_static_private_get(&m_key)); - return data ? data->value : 0; -} - -template<typename T> -inline void ThreadSpecific<T>::set(T* ptr) -{ - ASSERT(!get()); - Data* data = new Data(ptr, this); - g_static_private_set(&m_key, data, destroy); -} - -#elif OS(WINDOWS) - -// TLS_OUT_OF_INDEXES is not defined on WinCE. -#ifndef TLS_OUT_OF_INDEXES -#define TLS_OUT_OF_INDEXES 0xffffffff -#endif - -// The maximum number of TLS keys that can be created. For simplification, we assume that: -// 1) Once the instance of ThreadSpecific<> is created, it will not be destructed until the program dies. -// 2) We do not need to hold many instances of ThreadSpecific<> data. This fixed number should be far enough. -const int kMaxTlsKeySize = 256; - -long& tlsKeyCount(); -DWORD* tlsKeys(); - -template<typename T> -inline ThreadSpecific<T>::ThreadSpecific() - : m_index(-1) -{ - DWORD tlsKey = TlsAlloc(); - if (tlsKey == TLS_OUT_OF_INDEXES) - CRASH(); - - m_index = InterlockedIncrement(&tlsKeyCount()) - 1; - if (m_index >= kMaxTlsKeySize) - CRASH(); - tlsKeys()[m_index] = tlsKey; -} - -template<typename T> -inline ThreadSpecific<T>::~ThreadSpecific() -{ - // Does not invoke destructor functions. They will be called from ThreadSpecificThreadExit when the thread is detached. - TlsFree(tlsKeys()[m_index]); -} - -template<typename T> -inline T* ThreadSpecific<T>::get() -{ - Data* data = static_cast<Data*>(TlsGetValue(tlsKeys()[m_index])); - return data ? data->value : 0; -} - -template<typename T> -inline void ThreadSpecific<T>::set(T* ptr) -{ - ASSERT(!get()); - Data* data = new Data(ptr, this); - data->destructor = &ThreadSpecific<T>::destroy; - TlsSetValue(tlsKeys()[m_index], data); -} - -#else -#error ThreadSpecific is not implemented for this platform. -#endif -#endif - -template<typename T> -inline void ThreadSpecific<T>::destroy(void* ptr) -{ -#if !ENABLE(SINGLE_THREADED) - Data* data = static_cast<Data*>(ptr); - -#if USE(PTHREADS) - // We want get() to keep working while data destructor works, because it can be called indirectly by the destructor. - // Some pthreads implementations zero out the pointer before calling destroy(), so we temporarily reset it. - pthread_setspecific(data->owner->m_key, ptr); -#elif PLATFORM(GTK) - // See comment as above - g_static_private_set(&data->owner->m_key, data, 0); -#endif -#if PLATFORM(QT) - // See comment as above - data->owner->m_key.setLocalData(data); -#endif - - data->value->~T(); - fastFree(data->value); - -#if USE(PTHREADS) - pthread_setspecific(data->owner->m_key, 0); -#elif PLATFORM(QT) - // Do nothing here -#elif PLATFORM(GTK) - g_static_private_set(&data->owner->m_key, 0, 0); -#elif OS(WINDOWS) - TlsSetValue(tlsKeys()[data->owner->m_index], 0); -#else -#error ThreadSpecific is not implemented for this platform. -#endif - -#if !PLATFORM(QT) - delete data; -#endif -#endif -} - -template<typename T> -inline ThreadSpecific<T>::operator T*() -{ - T* ptr = static_cast<T*>(get()); - if (!ptr) { - // Set up thread-specific value's memory pointer before invoking constructor, in case any function it calls - // needs to access the value, to avoid recursion. - ptr = static_cast<T*>(fastZeroedMalloc(sizeof(T))); - set(ptr); - new (ptr) T; - } - return ptr; -} - -template<typename T> -inline T* ThreadSpecific<T>::operator->() -{ - return operator T*(); -} - -template<typename T> -inline T& ThreadSpecific<T>::operator*() -{ - return *operator T*(); -} - -} - -#endif diff --git a/JavaScriptCore/wtf/ThreadSpecificWin.cpp b/JavaScriptCore/wtf/ThreadSpecificWin.cpp deleted file mode 100644 index f2c0cad..0000000 --- a/JavaScriptCore/wtf/ThreadSpecificWin.cpp +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2009 Jian Li <jianli@chromium.org> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include "ThreadSpecific.h" -#include <wtf/Noncopyable.h> - -#if USE(PTHREADS) -#error This file should not be compiled by ports that do not use Windows native ThreadSpecific implementation. -#endif - -namespace WTF { - -long& tlsKeyCount() -{ - static long count; - return count; -} - -DWORD* tlsKeys() -{ - static DWORD keys[kMaxTlsKeySize]; - return keys; -} - -void ThreadSpecificThreadExit() -{ - for (long i = 0; i < tlsKeyCount(); i++) { - // The layout of ThreadSpecific<T>::Data does not depend on T. So we are safe to do the static cast to ThreadSpecific<int> in order to access its data member. - ThreadSpecific<int>::Data* data = static_cast<ThreadSpecific<int>::Data*>(TlsGetValue(tlsKeys()[i])); - if (data) - data->destructor(data); - } -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/Threading.cpp b/JavaScriptCore/wtf/Threading.cpp deleted file mode 100644 index 49de59e..0000000 --- a/JavaScriptCore/wtf/Threading.cpp +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2008, 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Threading.h" - -#include <string.h> - -namespace WTF { - -struct NewThreadContext : FastAllocBase { - NewThreadContext(ThreadFunction entryPoint, void* data, const char* name) - : entryPoint(entryPoint) - , data(data) - , name(name) - { - } - - ThreadFunction entryPoint; - void* data; - const char* name; - - Mutex creationMutex; -}; - -static void* threadEntryPoint(void* contextData) -{ - NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData); - - // Block until our creating thread has completed any extra setup work, including - // establishing ThreadIdentifier. - { - MutexLocker locker(context->creationMutex); - } - - initializeCurrentThreadInternal(context->name); - - // Grab the info that we need out of the context, then deallocate it. - ThreadFunction entryPoint = context->entryPoint; - void* data = context->data; - delete context; - - return entryPoint(data); -} - -ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name) -{ - // Visual Studio has a 31-character limit on thread names. Longer names will - // be truncated silently, but we'd like callers to know about the limit. -#if !LOG_DISABLED - if (strlen(name) > 31) - LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name); -#endif - - NewThreadContext* context = new NewThreadContext(entryPoint, data, name); - - // Prevent the thread body from executing until we've established the thread identifier. - MutexLocker locker(context->creationMutex); - - return createThreadInternal(threadEntryPoint, context, name); -} - -#if PLATFORM(MAC) || PLATFORM(WIN) - -// This function is deprecated but needs to be kept around for backward -// compatibility. Use the 3-argument version of createThread above. - -ThreadIdentifier createThread(ThreadFunction entryPoint, void* data); - -ThreadIdentifier createThread(ThreadFunction entryPoint, void* data) -{ - return createThread(entryPoint, data, 0); -} -#endif - -} // namespace WTF diff --git a/JavaScriptCore/wtf/Threading.h b/JavaScriptCore/wtf/Threading.h deleted file mode 100644 index 044365f..0000000 --- a/JavaScriptCore/wtf/Threading.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * - * Note: The implementations of InterlockedIncrement and InterlockedDecrement are based - * on atomic_increment and atomic_exchange_and_add from the Boost C++ Library. The license - * is virtually identical to the Apple license above but is included here for completeness. - * - * Boost Software License - Version 1.0 - August 17th, 2003 - * - * Permission is hereby granted, free of charge, to any person or organization - * obtaining a copy of the software and accompanying documentation covered by - * this license (the "Software") to use, reproduce, display, distribute, - * execute, and transmit the Software, and to prepare derivative works of the - * Software, and to permit third-parties to whom the Software is furnished to - * do so, all subject to the following: - * - * The copyright notices in the Software and this entire statement, including - * the above license grant, this restriction and the following disclaimer, - * must be included in all copies of the Software, in whole or in part, and - * all derivative works of the Software, unless such copies or derivative - * works are solely in the form of machine-executable object code generated by - * a source language processor. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT - * SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE - * FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef Threading_h -#define Threading_h - -#include "Platform.h" - -#include <stdint.h> -#include <wtf/Assertions.h> -#include <wtf/Atomics.h> -#include <wtf/Locker.h> -#include <wtf/MainThread.h> -#include <wtf/Noncopyable.h> -#include <wtf/ThreadSafeShared.h> -#include <wtf/ThreadingPrimitives.h> - -// For portability, we do not use thread-safe statics natively supported by some compilers (e.g. gcc). -#define AtomicallyInitializedStatic(T, name) \ - WTF::lockAtomicallyInitializedStaticMutex(); \ - static T name; \ - WTF::unlockAtomicallyInitializedStaticMutex(); - -namespace WTF { - -typedef uint32_t ThreadIdentifier; -typedef void* (*ThreadFunction)(void* argument); - -// This function must be called from the main thread. It is safe to call it repeatedly. -// Darwin is an exception to this rule: it is OK to call it from any thread, the only -// requirement is that the calls are not reentrant. -void initializeThreading(); - -// Returns 0 if thread creation failed. -// The thread name must be a literal since on some platforms it's passed in to the thread. -ThreadIdentifier createThread(ThreadFunction, void*, const char* threadName); - -// Internal platform-specific createThread implementation. -ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char* threadName); - -// Called in the thread during initialization. -// Helpful for platforms where the thread name must be set from within the thread. -void initializeCurrentThreadInternal(const char* threadName); - -ThreadIdentifier currentThread(); -int waitForThreadCompletion(ThreadIdentifier, void**); -void detachThread(ThreadIdentifier); - -void yield(); - -void lockAtomicallyInitializedStaticMutex(); -void unlockAtomicallyInitializedStaticMutex(); - -} // namespace WTF - -using WTF::ThreadIdentifier; -using WTF::createThread; -using WTF::currentThread; -using WTF::detachThread; -using WTF::waitForThreadCompletion; -using WTF::yield; - -#endif // Threading_h diff --git a/JavaScriptCore/wtf/ThreadingNone.cpp b/JavaScriptCore/wtf/ThreadingNone.cpp deleted file mode 100644 index 2e8a259..0000000 --- a/JavaScriptCore/wtf/ThreadingNone.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Threading.h" - -#if ENABLE(SINGLE_THREADED) - -namespace WTF { - -void initializeThreading() { } -ThreadIdentifier createThreadInternal(ThreadFunction, void*, const char*) { return ThreadIdentifier(); } -void initializeCurrentThreadInternal(const char*) { } -int waitForThreadCompletion(ThreadIdentifier, void**) { return 0; } -void detachThread(ThreadIdentifier) { } -ThreadIdentifier currentThread() { return ThreadIdentifier(); } -bool isMainThread() { return true; } - -Mutex::Mutex() { } -Mutex::~Mutex() { } -void Mutex::lock() { } -bool Mutex::tryLock() { return false; } -void Mutex::unlock() { } - -ThreadCondition::ThreadCondition() { } -ThreadCondition::~ThreadCondition() { } -void ThreadCondition::wait(Mutex&) { } -bool ThreadCondition::timedWait(Mutex&, double) { return false; } -void ThreadCondition::signal() { } -void ThreadCondition::broadcast() { } - -void lockAtomicallyInitializedStaticMutex() { } -void unlockAtomicallyInitializedStaticMutex() { } - -} // namespace WebCore - -#endif diff --git a/JavaScriptCore/wtf/ThreadingPrimitives.h b/JavaScriptCore/wtf/ThreadingPrimitives.h deleted file mode 100644 index c11a6cb..0000000 --- a/JavaScriptCore/wtf/ThreadingPrimitives.h +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (C) 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef ThreadingPrimitives_h -#define ThreadingPrimitives_h - -#include "Platform.h" - -#include <wtf/Assertions.h> -#include <wtf/Locker.h> -#include <wtf/Noncopyable.h> - -#if OS(WINDOWS) -#include <windows.h> -#endif - -#if USE(PTHREADS) -#include <pthread.h> -#elif PLATFORM(GTK) -#include "GOwnPtr.h" -#endif - -#if PLATFORM(QT) -#include <qglobal.h> -QT_BEGIN_NAMESPACE -class QMutex; -class QWaitCondition; -QT_END_NAMESPACE -#endif - -namespace WTF { - -#if USE(PTHREADS) -typedef pthread_mutex_t PlatformMutex; -#if HAVE(PTHREAD_RWLOCK) -typedef pthread_rwlock_t PlatformReadWriteLock; -#else -typedef void* PlatformReadWriteLock; -#endif -typedef pthread_cond_t PlatformCondition; -#elif PLATFORM(GTK) -typedef GOwnPtr<GMutex> PlatformMutex; -typedef void* PlatformReadWriteLock; // FIXME: Implement. -typedef GOwnPtr<GCond> PlatformCondition; -#elif PLATFORM(QT) -typedef QT_PREPEND_NAMESPACE(QMutex)* PlatformMutex; -typedef void* PlatformReadWriteLock; // FIXME: Implement. -typedef QT_PREPEND_NAMESPACE(QWaitCondition)* PlatformCondition; -#elif OS(WINDOWS) -struct PlatformMutex { - CRITICAL_SECTION m_internalMutex; - size_t m_recursionCount; -}; -typedef void* PlatformReadWriteLock; // FIXME: Implement. -struct PlatformCondition { - size_t m_waitersGone; - size_t m_waitersBlocked; - size_t m_waitersToUnblock; - HANDLE m_blockLock; - HANDLE m_blockQueue; - HANDLE m_unblockLock; - - bool timedWait(PlatformMutex&, DWORD durationMilliseconds); - void signal(bool unblockAll); -}; -#else -typedef void* PlatformMutex; -typedef void* PlatformReadWriteLock; -typedef void* PlatformCondition; -#endif - -class Mutex : public Noncopyable { -public: - Mutex(); - ~Mutex(); - - void lock(); - bool tryLock(); - void unlock(); - -public: - PlatformMutex& impl() { return m_mutex; } -private: - PlatformMutex m_mutex; -}; - -typedef Locker<Mutex> MutexLocker; - -class ReadWriteLock : public Noncopyable { -public: - ReadWriteLock(); - ~ReadWriteLock(); - - void readLock(); - bool tryReadLock(); - - void writeLock(); - bool tryWriteLock(); - - void unlock(); - -private: - PlatformReadWriteLock m_readWriteLock; -}; - -class ThreadCondition : public Noncopyable { -public: - ThreadCondition(); - ~ThreadCondition(); - - void wait(Mutex& mutex); - // Returns true if the condition was signaled before absoluteTime, false if the absoluteTime was reached or is in the past. - // The absoluteTime is in seconds, starting on January 1, 1970. The time is assumed to use the same time zone as WTF::currentTime(). - bool timedWait(Mutex&, double absoluteTime); - void signal(); - void broadcast(); - -private: - PlatformCondition m_condition; -}; - -} // namespace WTF - -using WTF::Mutex; -using WTF::MutexLocker; -using WTF::ThreadCondition; - -#endif // ThreadingPrimitives_h diff --git a/JavaScriptCore/wtf/ThreadingPthreads.cpp b/JavaScriptCore/wtf/ThreadingPthreads.cpp deleted file mode 100644 index 0017a6f..0000000 --- a/JavaScriptCore/wtf/ThreadingPthreads.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (C) 2007, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Threading.h" - -#if USE(PTHREADS) - -#include "CurrentTime.h" -#include "HashMap.h" -#include "MainThread.h" -#include "RandomNumberSeed.h" -#include "StdLibExtras.h" -#include "ThreadIdentifierDataPthreads.h" -#include "ThreadSpecific.h" -#include "UnusedParam.h" -#include <errno.h> - -#if !COMPILER(MSVC) -#include <limits.h> -#include <sched.h> -#include <sys/time.h> -#endif - -#if OS(ANDROID) -#include "JNIUtility.h" -#endif - -namespace WTF { - -typedef HashMap<ThreadIdentifier, pthread_t> ThreadMap; - -static Mutex* atomicallyInitializedStaticMutex; - -void clearPthreadHandleForIdentifier(ThreadIdentifier); - -static Mutex& threadMapMutex() -{ - DEFINE_STATIC_LOCAL(Mutex, mutex, ()); - return mutex; -} - -void initializeThreading() -{ - if (atomicallyInitializedStaticMutex) - return; - - atomicallyInitializedStaticMutex = new Mutex; - threadMapMutex(); - initializeRandomNumberGenerator(); -} - -void lockAtomicallyInitializedStaticMutex() -{ - ASSERT(atomicallyInitializedStaticMutex); - atomicallyInitializedStaticMutex->lock(); -} - -void unlockAtomicallyInitializedStaticMutex() -{ - atomicallyInitializedStaticMutex->unlock(); -} - -static ThreadMap& threadMap() -{ - DEFINE_STATIC_LOCAL(ThreadMap, map, ()); - return map; -} - -static ThreadIdentifier identifierByPthreadHandle(const pthread_t& pthreadHandle) -{ - MutexLocker locker(threadMapMutex()); - - ThreadMap::iterator i = threadMap().begin(); - for (; i != threadMap().end(); ++i) { - if (pthread_equal(i->second, pthreadHandle)) - return i->first; - } - - return 0; -} - -static ThreadIdentifier establishIdentifierForPthreadHandle(const pthread_t& pthreadHandle) -{ - ASSERT(!identifierByPthreadHandle(pthreadHandle)); - - MutexLocker locker(threadMapMutex()); - - static ThreadIdentifier identifierCount = 1; - - threadMap().add(identifierCount, pthreadHandle); - - return identifierCount++; -} - -static pthread_t pthreadHandleForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - - return threadMap().get(id); -} - -void clearPthreadHandleForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - - ASSERT(threadMap().contains(id)); - - threadMap().remove(id); -} - -#if OS(ANDROID) -// On the Android platform, threads must be registered with the VM before they run. -struct ThreadData { - ThreadFunction entryPoint; - void* arg; -}; - -static void* runThreadWithRegistration(void* arg) -{ - ThreadData* data = static_cast<ThreadData*>(arg); - JavaVM* vm = JSC::Bindings::getJavaVM(); - JNIEnv* env; - void* ret = 0; - if (vm->AttachCurrentThread(&env, 0) == JNI_OK) { - ret = data->entryPoint(data->arg); - vm->DetachCurrentThread(); - } - delete data; - return ret; -} - -ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) -{ - pthread_t threadHandle; - ThreadData* threadData = new ThreadData(); - threadData->entryPoint = entryPoint; - threadData->arg = data; - - if (pthread_create(&threadHandle, 0, runThreadWithRegistration, static_cast<void*>(threadData))) { - LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data); - delete threadData; - return 0; - } - return establishIdentifierForPthreadHandle(threadHandle); -} -#else -ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) -{ - pthread_t threadHandle; - if (pthread_create(&threadHandle, 0, entryPoint, data)) { - LOG_ERROR("Failed to create pthread at entry point %p with data %p", entryPoint, data); - return 0; - } - - return establishIdentifierForPthreadHandle(threadHandle); -} -#endif - -void initializeCurrentThreadInternal(const char* threadName) -{ -#if HAVE(PTHREAD_SETNAME_NP) - pthread_setname_np(threadName); -#else - UNUSED_PARAM(threadName); -#endif - - ThreadIdentifier id = identifierByPthreadHandle(pthread_self()); - ASSERT(id); - ThreadIdentifierData::initialize(id); -} - -int waitForThreadCompletion(ThreadIdentifier threadID, void** result) -{ - ASSERT(threadID); - - pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); - if (!pthreadHandle) - return 0; - - int joinResult = pthread_join(pthreadHandle, result); - if (joinResult == EDEADLK) - LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); - - return joinResult; -} - -void detachThread(ThreadIdentifier threadID) -{ - ASSERT(threadID); - - pthread_t pthreadHandle = pthreadHandleForIdentifier(threadID); - if (!pthreadHandle) - return; - - pthread_detach(pthreadHandle); -} - -void yield() -{ - sched_yield(); -} - -ThreadIdentifier currentThread() -{ - ThreadIdentifier id = ThreadIdentifierData::identifier(); - if (id) - return id; - - // Not a WTF-created thread, ThreadIdentifier is not established yet. - id = establishIdentifierForPthreadHandle(pthread_self()); - ThreadIdentifierData::initialize(id); - return id; -} - -Mutex::Mutex() -{ - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); - - pthread_mutex_init(&m_mutex, &attr); - - pthread_mutexattr_destroy(&attr); -} - -Mutex::~Mutex() -{ - pthread_mutex_destroy(&m_mutex); -} - -void Mutex::lock() -{ - int result = pthread_mutex_lock(&m_mutex); - ASSERT_UNUSED(result, !result); -} - -bool Mutex::tryLock() -{ - int result = pthread_mutex_trylock(&m_mutex); - - if (result == 0) - return true; - if (result == EBUSY) - return false; - - ASSERT_NOT_REACHED(); - return false; -} - -void Mutex::unlock() -{ - int result = pthread_mutex_unlock(&m_mutex); - ASSERT_UNUSED(result, !result); -} - -#if HAVE(PTHREAD_RWLOCK) -ReadWriteLock::ReadWriteLock() -{ - pthread_rwlock_init(&m_readWriteLock, NULL); -} - -ReadWriteLock::~ReadWriteLock() -{ - pthread_rwlock_destroy(&m_readWriteLock); -} - -void ReadWriteLock::readLock() -{ - int result = pthread_rwlock_rdlock(&m_readWriteLock); - ASSERT_UNUSED(result, !result); -} - -bool ReadWriteLock::tryReadLock() -{ - int result = pthread_rwlock_tryrdlock(&m_readWriteLock); - - if (result == 0) - return true; - if (result == EBUSY || result == EAGAIN) - return false; - - ASSERT_NOT_REACHED(); - return false; -} - -void ReadWriteLock::writeLock() -{ - int result = pthread_rwlock_wrlock(&m_readWriteLock); - ASSERT_UNUSED(result, !result); -} - -bool ReadWriteLock::tryWriteLock() -{ - int result = pthread_rwlock_trywrlock(&m_readWriteLock); - - if (result == 0) - return true; - if (result == EBUSY || result == EAGAIN) - return false; - - ASSERT_NOT_REACHED(); - return false; -} - -void ReadWriteLock::unlock() -{ - int result = pthread_rwlock_unlock(&m_readWriteLock); - ASSERT_UNUSED(result, !result); -} -#endif // HAVE(PTHREAD_RWLOCK) - -ThreadCondition::ThreadCondition() -{ - pthread_cond_init(&m_condition, NULL); -} - -ThreadCondition::~ThreadCondition() -{ - pthread_cond_destroy(&m_condition); -} - -void ThreadCondition::wait(Mutex& mutex) -{ - int result = pthread_cond_wait(&m_condition, &mutex.impl()); - ASSERT_UNUSED(result, !result); -} - -bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) -{ - if (absoluteTime < currentTime()) - return false; - - if (absoluteTime > INT_MAX) { - wait(mutex); - return true; - } - - int timeSeconds = static_cast<int>(absoluteTime); - int timeNanoseconds = static_cast<int>((absoluteTime - timeSeconds) * 1E9); - - timespec targetTime; - targetTime.tv_sec = timeSeconds; - targetTime.tv_nsec = timeNanoseconds; - - return pthread_cond_timedwait(&m_condition, &mutex.impl(), &targetTime) == 0; -} - -void ThreadCondition::signal() -{ - int result = pthread_cond_signal(&m_condition); - ASSERT_UNUSED(result, !result); -} - -void ThreadCondition::broadcast() -{ - int result = pthread_cond_broadcast(&m_condition); - ASSERT_UNUSED(result, !result); -} - -} // namespace WTF - -#endif // USE(PTHREADS) diff --git a/JavaScriptCore/wtf/ThreadingWin.cpp b/JavaScriptCore/wtf/ThreadingWin.cpp deleted file mode 100644 index a29fbbb..0000000 --- a/JavaScriptCore/wtf/ThreadingWin.cpp +++ /dev/null @@ -1,489 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * Copyright (C) 2009 Torch Mobile, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * There are numerous academic and practical works on how to implement pthread_cond_wait/pthread_cond_signal/pthread_cond_broadcast - * functions on Win32. Here is one example: http://www.cs.wustl.edu/~schmidt/win32-cv-1.html which is widely credited as a 'starting point' - * of modern attempts. There are several more or less proven implementations, one in Boost C++ library (http://www.boost.org) and another - * in pthreads-win32 (http://sourceware.org/pthreads-win32/). - * - * The number of articles and discussions is the evidence of significant difficulties in implementing these primitives correctly. - * The brief search of revisions, ChangeLog entries, discussions in comp.programming.threads and other places clearly documents - * numerous pitfalls and performance problems the authors had to overcome to arrive to the suitable implementations. - * Optimally, WebKit would use one of those supported/tested libraries directly. To roll out our own implementation is impractical, - * if even for the lack of sufficient testing. However, a faithful reproduction of the code from one of the popular supported - * libraries seems to be a good compromise. - * - * The early Boost implementation (http://www.boxbackup.org/trac/browser/box/nick/win/lib/win32/boost_1_32_0/libs/thread/src/condition.cpp?rev=30) - * is identical to pthreads-win32 (http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32). - * Current Boost uses yet another (although seemingly equivalent) algorithm which came from their 'thread rewrite' effort. - * - * This file includes timedWait/signal/broadcast implementations translated to WebKit coding style from the latest algorithm by - * Alexander Terekhov and Louis Thomas, as captured here: http://sourceware.org/cgi-bin/cvsweb.cgi/pthreads/pthread_cond_wait.c?rev=1.10&content-type=text/x-cvsweb-markup&cvsroot=pthreads-win32 - * It replaces the implementation of their previous algorithm, also documented in the same source above. - * The naming and comments are left very close to original to enable easy cross-check. - * - * The corresponding Pthreads-win32 License is included below, and CONTRIBUTORS file which it refers to is added to - * source directory (as CONTRIBUTORS.pthreads-win32). - */ - -/* - * Pthreads-win32 - POSIX Threads Library for Win32 - * Copyright(C) 1998 John E. Bossom - * Copyright(C) 1999,2005 Pthreads-win32 contributors - * - * Contact Email: rpj@callisto.canberra.edu.au - * - * The current list of contributors is contained - * in the file CONTRIBUTORS included with the source - * code distribution. The list can also be seen at the - * following World Wide Web location: - * http://sources.redhat.com/pthreads-win32/contributors.html - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library in the file COPYING.LIB; - * if not, write to the Free Software Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#include "config.h" -#include "Threading.h" - -#include "MainThread.h" -#if !USE(PTHREADS) && OS(WINDOWS) -#include "ThreadSpecific.h" -#endif -#if !OS(WINCE) -#include <process.h> -#endif -#if HAVE(ERRNO_H) -#include <errno.h> -#else -#define NO_ERRNO -#endif -#include <windows.h> -#include <wtf/CurrentTime.h> -#include <wtf/HashMap.h> -#include <wtf/MathExtras.h> -#include <wtf/RandomNumberSeed.h> - -namespace WTF { - -// MS_VC_EXCEPTION, THREADNAME_INFO, and setThreadNameInternal all come from <http://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx>. -static const DWORD MS_VC_EXCEPTION = 0x406D1388; - -#pragma pack(push, 8) -typedef struct tagTHREADNAME_INFO { - DWORD dwType; // must be 0x1000 - LPCSTR szName; // pointer to name (in user addr space) - DWORD dwThreadID; // thread ID (-1=caller thread) - DWORD dwFlags; // reserved for future use, must be zero -} THREADNAME_INFO; -#pragma pack(pop) - -void initializeCurrentThreadInternal(const char* szThreadName) -{ - THREADNAME_INFO info; - info.dwType = 0x1000; - info.szName = szThreadName; - info.dwThreadID = GetCurrentThreadId(); - info.dwFlags = 0; - - __try { - RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), reinterpret_cast<ULONG_PTR*>(&info)); - } __except (EXCEPTION_CONTINUE_EXECUTION) { - } -} - -static Mutex* atomicallyInitializedStaticMutex; - -void lockAtomicallyInitializedStaticMutex() -{ - ASSERT(atomicallyInitializedStaticMutex); - atomicallyInitializedStaticMutex->lock(); -} - -void unlockAtomicallyInitializedStaticMutex() -{ - atomicallyInitializedStaticMutex->unlock(); -} - -static Mutex& threadMapMutex() -{ - static Mutex mutex; - return mutex; -} - -void initializeThreading() -{ - if (atomicallyInitializedStaticMutex) - return; - - atomicallyInitializedStaticMutex = new Mutex; - threadMapMutex(); - initializeRandomNumberGenerator(); -} - -static HashMap<DWORD, HANDLE>& threadMap() -{ - static HashMap<DWORD, HANDLE> map; - return map; -} - -static void storeThreadHandleByIdentifier(DWORD threadID, HANDLE threadHandle) -{ - MutexLocker locker(threadMapMutex()); - ASSERT(!threadMap().contains(threadID)); - threadMap().add(threadID, threadHandle); -} - -static HANDLE threadHandleForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - return threadMap().get(id); -} - -static void clearThreadHandleForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - ASSERT(threadMap().contains(id)); - threadMap().remove(id); -} - -struct ThreadFunctionInvocation { - ThreadFunctionInvocation(ThreadFunction function, void* data) : function(function), data(data) {} - - ThreadFunction function; - void* data; -}; - -static unsigned __stdcall wtfThreadEntryPoint(void* param) -{ - ThreadFunctionInvocation invocation = *static_cast<ThreadFunctionInvocation*>(param); - delete static_cast<ThreadFunctionInvocation*>(param); - - void* result = invocation.function(invocation.data); - -#if !USE(PTHREADS) && OS(WINDOWS) - // Do the TLS cleanup. - ThreadSpecificThreadExit(); -#endif - - return reinterpret_cast<unsigned>(result); -} - -ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char* threadName) -{ - unsigned threadIdentifier = 0; - ThreadIdentifier threadID = 0; - ThreadFunctionInvocation* invocation = new ThreadFunctionInvocation(entryPoint, data); -#if OS(WINCE) - // This is safe on WINCE, since CRT is in the core and innately multithreaded. - // On desktop Windows, need to use _beginthreadex (not available on WinCE) if using any CRT functions - HANDLE threadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)wtfThreadEntryPoint, invocation, 0, (LPDWORD)&threadIdentifier); -#else - HANDLE threadHandle = reinterpret_cast<HANDLE>(_beginthreadex(0, 0, wtfThreadEntryPoint, invocation, 0, &threadIdentifier)); -#endif - if (!threadHandle) { -#if OS(WINCE) - LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, ::GetLastError()); -#elif defined(NO_ERRNO) - LOG_ERROR("Failed to create thread at entry point %p with data %p.", entryPoint, data); -#else - LOG_ERROR("Failed to create thread at entry point %p with data %p: %ld", entryPoint, data, errno); -#endif - return 0; - } - - threadID = static_cast<ThreadIdentifier>(threadIdentifier); - storeThreadHandleByIdentifier(threadIdentifier, threadHandle); - - return threadID; -} - -int waitForThreadCompletion(ThreadIdentifier threadID, void** result) -{ - ASSERT(threadID); - - HANDLE threadHandle = threadHandleForIdentifier(threadID); - if (!threadHandle) - LOG_ERROR("ThreadIdentifier %u did not correspond to an active thread when trying to quit", threadID); - - DWORD joinResult = WaitForSingleObject(threadHandle, INFINITE); - if (joinResult == WAIT_FAILED) - LOG_ERROR("ThreadIdentifier %u was found to be deadlocked trying to quit", threadID); - - CloseHandle(threadHandle); - clearThreadHandleForIdentifier(threadID); - - return joinResult; -} - -void detachThread(ThreadIdentifier threadID) -{ - ASSERT(threadID); - - HANDLE threadHandle = threadHandleForIdentifier(threadID); - if (threadHandle) - CloseHandle(threadHandle); - clearThreadHandleForIdentifier(threadID); -} - -void yield() -{ - ::Sleep(1); -} - -ThreadIdentifier currentThread() -{ - return static_cast<ThreadIdentifier>(GetCurrentThreadId()); -} - -Mutex::Mutex() -{ - m_mutex.m_recursionCount = 0; - InitializeCriticalSection(&m_mutex.m_internalMutex); -} - -Mutex::~Mutex() -{ - DeleteCriticalSection(&m_mutex.m_internalMutex); -} - -void Mutex::lock() -{ - EnterCriticalSection(&m_mutex.m_internalMutex); - ++m_mutex.m_recursionCount; -} - -bool Mutex::tryLock() -{ - // This method is modeled after the behavior of pthread_mutex_trylock, - // which will return an error if the lock is already owned by the - // current thread. Since the primitive Win32 'TryEnterCriticalSection' - // treats this as a successful case, it changes the behavior of several - // tests in WebKit that check to see if the current thread already - // owned this mutex (see e.g., IconDatabase::getOrCreateIconRecord) - DWORD result = TryEnterCriticalSection(&m_mutex.m_internalMutex); - - if (result != 0) { // We got the lock - // If this thread already had the lock, we must unlock and - // return false so that we mimic the behavior of POSIX's - // pthread_mutex_trylock: - if (m_mutex.m_recursionCount > 0) { - LeaveCriticalSection(&m_mutex.m_internalMutex); - return false; - } - - ++m_mutex.m_recursionCount; - return true; - } - - return false; -} - -void Mutex::unlock() -{ - --m_mutex.m_recursionCount; - LeaveCriticalSection(&m_mutex.m_internalMutex); -} - -bool PlatformCondition::timedWait(PlatformMutex& mutex, DWORD durationMilliseconds) -{ - // Enter the wait state. - DWORD res = WaitForSingleObject(m_blockLock, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - ++m_waitersBlocked; - res = ReleaseSemaphore(m_blockLock, 1, 0); - ASSERT(res); - - LeaveCriticalSection(&mutex.m_internalMutex); - - // Main wait - use timeout. - bool timedOut = (WaitForSingleObject(m_blockQueue, durationMilliseconds) == WAIT_TIMEOUT); - - res = WaitForSingleObject(m_unblockLock, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - - int signalsLeft = m_waitersToUnblock; - - if (m_waitersToUnblock) - --m_waitersToUnblock; - else if (++m_waitersGone == (INT_MAX / 2)) { // timeout/canceled or spurious semaphore - // timeout or spurious wakeup occured, normalize the m_waitersGone count - // this may occur if many calls to wait with a timeout are made and - // no call to notify_* is made - res = WaitForSingleObject(m_blockLock, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - m_waitersBlocked -= m_waitersGone; - res = ReleaseSemaphore(m_blockLock, 1, 0); - ASSERT(res); - m_waitersGone = 0; - } - - res = ReleaseMutex(m_unblockLock); - ASSERT(res); - - if (signalsLeft == 1) { - res = ReleaseSemaphore(m_blockLock, 1, 0); // Open the gate. - ASSERT(res); - } - - EnterCriticalSection (&mutex.m_internalMutex); - - return !timedOut; -} - -void PlatformCondition::signal(bool unblockAll) -{ - unsigned signalsToIssue = 0; - - DWORD res = WaitForSingleObject(m_unblockLock, INFINITE); - ASSERT(res == WAIT_OBJECT_0); - - if (m_waitersToUnblock) { // the gate is already closed - if (!m_waitersBlocked) { // no-op - res = ReleaseMutex(m_unblockLock); - ASSERT(res); - return; - } - - if (unblockAll) { - signalsToIssue = m_waitersBlocked; - m_waitersToUnblock += m_waitersBlocked; - m_waitersBlocked = 0; - } else { - signalsToIssue = 1; - ++m_waitersToUnblock; - --m_waitersBlocked; - } - } else if (m_waitersBlocked > m_waitersGone) { - res = WaitForSingleObject(m_blockLock, INFINITE); // Close the gate. - ASSERT(res == WAIT_OBJECT_0); - if (m_waitersGone != 0) { - m_waitersBlocked -= m_waitersGone; - m_waitersGone = 0; - } - if (unblockAll) { - signalsToIssue = m_waitersBlocked; - m_waitersToUnblock = m_waitersBlocked; - m_waitersBlocked = 0; - } else { - signalsToIssue = 1; - m_waitersToUnblock = 1; - --m_waitersBlocked; - } - } else { // No-op. - res = ReleaseMutex(m_unblockLock); - ASSERT(res); - return; - } - - res = ReleaseMutex(m_unblockLock); - ASSERT(res); - - if (signalsToIssue) { - res = ReleaseSemaphore(m_blockQueue, signalsToIssue, 0); - ASSERT(res); - } -} - -static const long MaxSemaphoreCount = static_cast<long>(~0UL >> 1); - -ThreadCondition::ThreadCondition() -{ - m_condition.m_waitersGone = 0; - m_condition.m_waitersBlocked = 0; - m_condition.m_waitersToUnblock = 0; - m_condition.m_blockLock = CreateSemaphore(0, 1, 1, 0); - m_condition.m_blockQueue = CreateSemaphore(0, 0, MaxSemaphoreCount, 0); - m_condition.m_unblockLock = CreateMutex(0, 0, 0); - - if (!m_condition.m_blockLock || !m_condition.m_blockQueue || !m_condition.m_unblockLock) { - if (m_condition.m_blockLock) - CloseHandle(m_condition.m_blockLock); - if (m_condition.m_blockQueue) - CloseHandle(m_condition.m_blockQueue); - if (m_condition.m_unblockLock) - CloseHandle(m_condition.m_unblockLock); - } -} - -ThreadCondition::~ThreadCondition() -{ - CloseHandle(m_condition.m_blockLock); - CloseHandle(m_condition.m_blockQueue); - CloseHandle(m_condition.m_unblockLock); -} - -void ThreadCondition::wait(Mutex& mutex) -{ - m_condition.timedWait(mutex.impl(), INFINITE); -} - -bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) -{ - double currentTime = WTF::currentTime(); - - // Time is in the past - return immediately. - if (absoluteTime < currentTime) - return false; - - // Time is too far in the future (and would overflow unsigned long) - wait forever. - if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) { - wait(mutex); - return true; - } - - double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0; - return m_condition.timedWait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds)); -} - -void ThreadCondition::signal() -{ - m_condition.signal(false); // Unblock only 1 thread. -} - -void ThreadCondition::broadcast() -{ - m_condition.signal(true); // Unblock all threads. -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/TypeTraits.cpp b/JavaScriptCore/wtf/TypeTraits.cpp deleted file mode 100644 index afeaa5e..0000000 --- a/JavaScriptCore/wtf/TypeTraits.cpp +++ /dev/null @@ -1,142 +0,0 @@ - /* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009, 2010 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "TypeTraits.h" - -#include "Assertions.h" - -namespace WTF { - -COMPILE_ASSERT(IsInteger<bool>::value, WTF_IsInteger_bool_true); -COMPILE_ASSERT(IsInteger<char>::value, WTF_IsInteger_char_true); -COMPILE_ASSERT(IsInteger<signed char>::value, WTF_IsInteger_signed_char_true); -COMPILE_ASSERT(IsInteger<unsigned char>::value, WTF_IsInteger_unsigned_char_true); -COMPILE_ASSERT(IsInteger<short>::value, WTF_IsInteger_short_true); -COMPILE_ASSERT(IsInteger<unsigned short>::value, WTF_IsInteger_unsigned_short_true); -COMPILE_ASSERT(IsInteger<int>::value, WTF_IsInteger_int_true); -COMPILE_ASSERT(IsInteger<unsigned int>::value, WTF_IsInteger_unsigned_int_true); -COMPILE_ASSERT(IsInteger<long>::value, WTF_IsInteger_long_true); -COMPILE_ASSERT(IsInteger<unsigned long>::value, WTF_IsInteger_unsigned_long_true); -COMPILE_ASSERT(IsInteger<long long>::value, WTF_IsInteger_long_long_true); -COMPILE_ASSERT(IsInteger<unsigned long long>::value, WTF_IsInteger_unsigned_long_long_true); -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) -COMPILE_ASSERT(IsInteger<wchar_t>::value, WTF_IsInteger_wchar_t_true); -#endif -COMPILE_ASSERT(!IsInteger<char*>::value, WTF_IsInteger_char_pointer_false); -COMPILE_ASSERT(!IsInteger<const char*>::value, WTF_IsInteger_const_char_pointer_false); -COMPILE_ASSERT(!IsInteger<volatile char*>::value, WTF_IsInteger_volatile_char_pointer_false); -COMPILE_ASSERT(!IsInteger<double>::value, WTF_IsInteger_double_false); -COMPILE_ASSERT(!IsInteger<float>::value, WTF_IsInteger_float_false); - -COMPILE_ASSERT(IsFloatingPoint<float>::value, WTF_IsFloatingPoint_float_true); -COMPILE_ASSERT(IsFloatingPoint<double>::value, WTF_IsFloatingPoint_double_true); -COMPILE_ASSERT(IsFloatingPoint<long double>::value, WTF_IsFloatingPoint_long_double_true); -COMPILE_ASSERT(!IsFloatingPoint<int>::value, WTF_IsFloatingPoint_int_false); - -COMPILE_ASSERT(IsPod<bool>::value, WTF_IsPod_bool_true); -COMPILE_ASSERT(IsPod<char>::value, WTF_IsPod_char_true); -COMPILE_ASSERT(IsPod<signed char>::value, WTF_IsPod_signed_char_true); -COMPILE_ASSERT(IsPod<unsigned char>::value, WTF_IsPod_unsigned_char_true); -COMPILE_ASSERT(IsPod<short>::value, WTF_IsPod_short_true); -COMPILE_ASSERT(IsPod<unsigned short>::value, WTF_IsPod_unsigned_short_true); -COMPILE_ASSERT(IsPod<int>::value, WTF_IsPod_int_true); -COMPILE_ASSERT(IsPod<unsigned int>::value, WTF_IsPod_unsigned_int_true); -COMPILE_ASSERT(IsPod<long>::value, WTF_IsPod_long_true); -COMPILE_ASSERT(IsPod<unsigned long>::value, WTF_IsPod_unsigned_long_true); -COMPILE_ASSERT(IsPod<long long>::value, WTF_IsPod_long_long_true); -COMPILE_ASSERT(IsPod<unsigned long long>::value, WTF_IsPod_unsigned_long_long_true); -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) -COMPILE_ASSERT(IsPod<wchar_t>::value, WTF_IsPod_wchar_t_true); -#endif -COMPILE_ASSERT(IsPod<char*>::value, WTF_IsPod_char_pointer_true); -COMPILE_ASSERT(IsPod<const char*>::value, WTF_IsPod_const_char_pointer_true); -COMPILE_ASSERT(IsPod<volatile char*>::value, WTF_IsPod_volatile_char_pointer_true); -COMPILE_ASSERT(IsPod<double>::value, WTF_IsPod_double_true); -COMPILE_ASSERT(IsPod<long double>::value, WTF_IsPod_long_double_true); -COMPILE_ASSERT(IsPod<float>::value, WTF_IsPod_float_true); -COMPILE_ASSERT(!IsPod<IsPod<bool> >::value, WTF_IsPod_struct_false); - -enum IsConvertibleToIntegerCheck { }; -COMPILE_ASSERT(IsConvertibleToInteger<IsConvertibleToIntegerCheck>::value, WTF_IsConvertibleToInteger_enum_true); -COMPILE_ASSERT(IsConvertibleToInteger<bool>::value, WTF_IsConvertibleToInteger_bool_true); -COMPILE_ASSERT(IsConvertibleToInteger<char>::value, WTF_IsConvertibleToInteger_char_true); -COMPILE_ASSERT(IsConvertibleToInteger<signed char>::value, WTF_IsConvertibleToInteger_signed_char_true); -COMPILE_ASSERT(IsConvertibleToInteger<unsigned char>::value, WTF_IsConvertibleToInteger_unsigned_char_true); -COMPILE_ASSERT(IsConvertibleToInteger<short>::value, WTF_IsConvertibleToInteger_short_true); -COMPILE_ASSERT(IsConvertibleToInteger<unsigned short>::value, WTF_IsConvertibleToInteger_unsigned_short_true); -COMPILE_ASSERT(IsConvertibleToInteger<int>::value, WTF_IsConvertibleToInteger_int_true); -COMPILE_ASSERT(IsConvertibleToInteger<unsigned int>::value, WTF_IsConvertibleToInteger_unsigned_int_true); -COMPILE_ASSERT(IsConvertibleToInteger<long>::value, WTF_IsConvertibleToInteger_long_true); -COMPILE_ASSERT(IsConvertibleToInteger<unsigned long>::value, WTF_IsConvertibleToInteger_unsigned_long_true); -COMPILE_ASSERT(IsConvertibleToInteger<long long>::value, WTF_IsConvertibleToInteger_long_long_true); -COMPILE_ASSERT(IsConvertibleToInteger<unsigned long long>::value, WTF_IsConvertibleToInteger_unsigned_long_long_true); -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) -COMPILE_ASSERT(IsConvertibleToInteger<wchar_t>::value, WTF_IsConvertibleToInteger_wchar_t_true); -#endif -COMPILE_ASSERT(IsConvertibleToInteger<double>::value, WTF_IsConvertibleToInteger_double_true); -COMPILE_ASSERT(IsConvertibleToInteger<long double>::value, WTF_IsConvertibleToInteger_long_double_true); -COMPILE_ASSERT(IsConvertibleToInteger<float>::value, WTF_IsConvertibleToInteger_float_true); -COMPILE_ASSERT(!IsConvertibleToInteger<char*>::value, WTF_IsConvertibleToInteger_char_pointer_false); -COMPILE_ASSERT(!IsConvertibleToInteger<const char*>::value, WTF_IsConvertibleToInteger_const_char_pointer_false); -COMPILE_ASSERT(!IsConvertibleToInteger<volatile char*>::value, WTF_IsConvertibleToInteger_volatile_char_pointer_false); -COMPILE_ASSERT(!IsConvertibleToInteger<IsConvertibleToInteger<bool> >::value, WTF_IsConvertibleToInteger_struct_false); - -COMPILE_ASSERT((IsSameType<bool, bool>::value), WTF_IsSameType_bool_true); -COMPILE_ASSERT((IsSameType<int*, int*>::value), WTF_IsSameType_int_pointer_true); -COMPILE_ASSERT((!IsSameType<int, int*>::value), WTF_IsSameType_int_int_pointer_false); -COMPILE_ASSERT((!IsSameType<bool, const bool>::value), WTF_IsSameType_const_change_false); -COMPILE_ASSERT((!IsSameType<bool, volatile bool>::value), WTF_IsSameType_volatile_change_false); - -template <typename T> -class TestBaseClass { -}; - -class TestDerivedClass : public TestBaseClass<int> { -}; - -COMPILE_ASSERT((IsSubclass<TestDerivedClass, TestBaseClass<int> >::value), WTF_Test_IsSubclass_Derived_From_Base); -COMPILE_ASSERT((!IsSubclass<TestBaseClass<int>, TestDerivedClass>::value), WTF_Test_IsSubclass_Base_From_Derived); -COMPILE_ASSERT((IsSubclassOfTemplate<TestDerivedClass, TestBaseClass>::value), WTF_Test_IsSubclassOfTemplate_Base_From_Derived); -COMPILE_ASSERT((IsSameType<RemoveTemplate<TestBaseClass<int>, TestBaseClass>::Type, int>::value), WTF_Test_RemoveTemplate); -COMPILE_ASSERT((IsSameType<RemoveTemplate<int, TestBaseClass>::Type, int>::value), WTF_Test_RemoveTemplate_WithoutTemplate); - - -COMPILE_ASSERT((IsSameType<bool, RemoveConst<const bool>::Type>::value), WTF_test_RemoveConst_const_bool); -COMPILE_ASSERT((!IsSameType<bool, RemoveConst<volatile bool>::Type>::value), WTF_test_RemoveConst_volatile_bool); - -COMPILE_ASSERT((IsSameType<bool, RemoveVolatile<bool>::Type>::value), WTF_test_RemoveVolatile_bool); -COMPILE_ASSERT((!IsSameType<bool, RemoveVolatile<const bool>::Type>::value), WTF_test_RemoveVolatile_const_bool); -COMPILE_ASSERT((IsSameType<bool, RemoveVolatile<volatile bool>::Type>::value), WTF_test_RemoveVolatile_volatile_bool); - -COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<bool>::Type>::value), WTF_test_RemoveConstVolatile_bool); -COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<const bool>::Type>::value), WTF_test_RemoveConstVolatile_const_bool); -COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<volatile bool>::Type>::value), WTF_test_RemoveConstVolatile_volatile_bool); -COMPILE_ASSERT((IsSameType<bool, RemoveConstVolatile<const volatile bool>::Type>::value), WTF_test_RemoveConstVolatile_const_volatile_bool); - -COMPILE_ASSERT((IsSameType<int, RemovePointer<int>::Type>::value), WTF_Test_RemovePointer_int); -COMPILE_ASSERT((IsSameType<int, RemovePointer<int*>::Type>::value), WTF_Test_RemovePointer_int_pointer); -COMPILE_ASSERT((!IsSameType<int, RemovePointer<int**>::Type>::value), WTF_Test_RemovePointer_int_pointer_pointer); - -COMPILE_ASSERT((IsSameType<int, RemoveReference<int>::Type>::value), WTF_Test_RemoveReference_int); -COMPILE_ASSERT((IsSameType<int, RemoveReference<int&>::Type>::value), WTF_Test_RemoveReference_int_reference); - -} // namespace WTF diff --git a/JavaScriptCore/wtf/TypeTraits.h b/JavaScriptCore/wtf/TypeTraits.h deleted file mode 100644 index 44103cd..0000000 --- a/JavaScriptCore/wtf/TypeTraits.h +++ /dev/null @@ -1,386 +0,0 @@ - /* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009, 2010 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef TypeTraits_h -#define TypeTraits_h - -#include "Platform.h" - -#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) -#include <type_traits> -#endif - -namespace WTF { - - // The following are provided in this file: - // - // IsInteger<T>::value - // IsPod<T>::value, see the definition for a note about its limitations - // IsConvertibleToInteger<T>::value - // - // IsSameType<T, U>::value - // - // RemovePointer<T>::Type - // RemoveReference<T>::Type - // RemoveConst<T>::Type - // RemoveVolatile<T>::Type - // RemoveConstVolatile<T>::Type - // - // COMPILE_ASSERT's in TypeTraits.cpp illustrate their usage and what they do. - - template<typename T> struct IsInteger { static const bool value = false; }; - template<> struct IsInteger<bool> { static const bool value = true; }; - template<> struct IsInteger<char> { static const bool value = true; }; - template<> struct IsInteger<signed char> { static const bool value = true; }; - template<> struct IsInteger<unsigned char> { static const bool value = true; }; - template<> struct IsInteger<short> { static const bool value = true; }; - template<> struct IsInteger<unsigned short> { static const bool value = true; }; - template<> struct IsInteger<int> { static const bool value = true; }; - template<> struct IsInteger<unsigned int> { static const bool value = true; }; - template<> struct IsInteger<long> { static const bool value = true; }; - template<> struct IsInteger<unsigned long> { static const bool value = true; }; - template<> struct IsInteger<long long> { static const bool value = true; }; - template<> struct IsInteger<unsigned long long> { static const bool value = true; }; -#if !COMPILER(MSVC) || defined(_NATIVE_WCHAR_T_DEFINED) - template<> struct IsInteger<wchar_t> { static const bool value = true; }; -#endif - - template<typename T> struct IsFloatingPoint { static const bool value = false; }; - template<> struct IsFloatingPoint<float> { static const bool value = true; }; - template<> struct IsFloatingPoint<double> { static const bool value = true; }; - template<> struct IsFloatingPoint<long double> { static const bool value = true; }; - - template<typename T> struct IsArithmetic { static const bool value = IsInteger<T>::value || IsFloatingPoint<T>::value; }; - - // IsPod is misnamed as it doesn't cover all plain old data (pod) types. - // Specifically, it doesn't allow for enums or for structs. - template <typename T> struct IsPod { static const bool value = IsArithmetic<T>::value; }; - template <typename P> struct IsPod<P*> { static const bool value = true; }; - - template<typename T> class IsConvertibleToInteger { - // Avoid "possible loss of data" warning when using Microsoft's C++ compiler - // by not converting int's to doubles. - template<bool performCheck, typename U> class IsConvertibleToDouble; - template<typename U> class IsConvertibleToDouble<false, U> { - public: - static const bool value = false; - }; - - template<typename U> class IsConvertibleToDouble<true, U> { - typedef char YesType; - struct NoType { - char padding[8]; - }; - - static YesType floatCheck(long double); - static NoType floatCheck(...); - static T& t; - public: - static const bool value = sizeof(floatCheck(t)) == sizeof(YesType); - }; - - public: - static const bool value = IsInteger<T>::value || IsConvertibleToDouble<!IsInteger<T>::value, T>::value; - }; - - template <typename T, typename U> struct IsSameType { - static const bool value = false; - }; - - template <typename T> struct IsSameType<T, T> { - static const bool value = true; - }; - - template <typename T, typename U> class IsSubclass { - typedef char YesType; - struct NoType { - char padding[8]; - }; - - static YesType subclassCheck(U*); - static NoType subclassCheck(...); - static T* t; - public: - static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); - }; - - template <typename T, template<class V> class U> class IsSubclassOfTemplate { - typedef char YesType; - struct NoType { - char padding[8]; - }; - - template<typename W> static YesType subclassCheck(U<W>*); - static NoType subclassCheck(...); - static T* t; - public: - static const bool value = sizeof(subclassCheck(t)) == sizeof(YesType); - }; - - template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate { - typedef T Type; - }; - - template <typename T, template <class V> class OuterTemplate> struct RemoveTemplate<OuterTemplate<T>, OuterTemplate> { - typedef T Type; - }; - - template <typename T> struct RemoveConst { - typedef T Type; - }; - - template <typename T> struct RemoveConst<const T> { - typedef T Type; - }; - - template <typename T> struct RemoveVolatile { - typedef T Type; - }; - - template <typename T> struct RemoveVolatile<volatile T> { - typedef T Type; - }; - - template <typename T> struct RemoveConstVolatile { - typedef typename RemoveVolatile<typename RemoveConst<T>::Type>::Type Type; - }; - - template <typename T> struct RemovePointer { - typedef T Type; - }; - - template <typename T> struct RemovePointer<T*> { - typedef T Type; - }; - - template <typename T> struct RemoveReference { - typedef T Type; - }; - - template <typename T> struct RemoveReference<T&> { - typedef T Type; - }; - -#if (defined(__GLIBCXX__) && (__GLIBCXX__ >= 20070724) && defined(__GXX_EXPERIMENTAL_CXX0X__)) || (defined(_MSC_VER) && (_MSC_VER >= 1600)) - - // GCC's libstdc++ 20070724 and later supports C++ TR1 type_traits in the std namespace. - // VC10 (VS2010) and later support C++ TR1 type_traits in the std::tr1 namespace. - template<typename T> struct HasTrivialConstructor : public std::tr1::has_trivial_constructor<T> { }; - template<typename T> struct HasTrivialDestructor : public std::tr1::has_trivial_destructor<T> { }; - -#else - - // This compiler doesn't provide type traits, so we provide basic HasTrivialConstructor - // and HasTrivialDestructor definitions. The definitions here include most built-in - // scalar types but do not include POD structs and classes. For the intended purposes of - // type_traits this results correct but potentially less efficient code. - template <typename T, T v> - struct IntegralConstant { - static const T value = v; - typedef T value_type; - typedef IntegralConstant<T, v> type; - }; - - typedef IntegralConstant<bool, true> true_type; - typedef IntegralConstant<bool, false> false_type; - -#if defined(_MSC_VER) && (_MSC_VER >= 1400) && !defined(__INTEL_COMPILER) - // VC8 (VS2005) and later have built-in compiler support for HasTrivialConstructor / HasTrivialDestructor, - // but for some unexplained reason it doesn't work on built-in types. - template <typename T> struct HasTrivialConstructor : public IntegralConstant<bool, __has_trivial_constructor(T)>{ }; - template <typename T> struct HasTrivialDestructor : public IntegralConstant<bool, __has_trivial_destructor(T)>{ }; -#else - template <typename T> struct HasTrivialConstructor : public false_type{ }; - template <typename T> struct HasTrivialDestructor : public false_type{ }; -#endif - - template <typename T> struct HasTrivialConstructor<T*> : public true_type{ }; - template <typename T> struct HasTrivialDestructor<T*> : public true_type{ }; - - template <> struct HasTrivialConstructor<float> : public true_type{ }; - template <> struct HasTrivialConstructor<const float> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile float> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile float> : public true_type{ }; - - template <> struct HasTrivialConstructor<double> : public true_type{ }; - template <> struct HasTrivialConstructor<const double> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile double> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile double> : public true_type{ }; - - template <> struct HasTrivialConstructor<long double> : public true_type{ }; - template <> struct HasTrivialConstructor<const long double> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile long double> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile long double> : public true_type{ }; - - template <> struct HasTrivialConstructor<unsigned char> : public true_type{ }; - template <> struct HasTrivialConstructor<const unsigned char> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile unsigned char> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile unsigned char> : public true_type{ }; - - template <> struct HasTrivialConstructor<unsigned short> : public true_type{ }; - template <> struct HasTrivialConstructor<const unsigned short> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile unsigned short> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile unsigned short> : public true_type{ }; - - template <> struct HasTrivialConstructor<unsigned int> : public true_type{ }; - template <> struct HasTrivialConstructor<const unsigned int> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile unsigned int> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile unsigned int> : public true_type{ }; - - template <> struct HasTrivialConstructor<unsigned long> : public true_type{ }; - template <> struct HasTrivialConstructor<const unsigned long> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile unsigned long> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile unsigned long> : public true_type{ }; - - template <> struct HasTrivialConstructor<unsigned long long> : public true_type{ }; - template <> struct HasTrivialConstructor<const unsigned long long> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile unsigned long long> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile unsigned long long> : public true_type{ }; - - template <> struct HasTrivialConstructor<signed char> : public true_type{ }; - template <> struct HasTrivialConstructor<const signed char> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile signed char> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile signed char> : public true_type{ }; - - template <> struct HasTrivialConstructor<signed short> : public true_type{ }; - template <> struct HasTrivialConstructor<const signed short> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile signed short> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile signed short> : public true_type{ }; - - template <> struct HasTrivialConstructor<signed int> : public true_type{ }; - template <> struct HasTrivialConstructor<const signed int> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile signed int> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile signed int> : public true_type{ }; - - template <> struct HasTrivialConstructor<signed long> : public true_type{ }; - template <> struct HasTrivialConstructor<const signed long> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile signed long> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile signed long> : public true_type{ }; - - template <> struct HasTrivialConstructor<signed long long> : public true_type{ }; - template <> struct HasTrivialConstructor<const signed long long> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile signed long long> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile signed long long> : public true_type{ }; - - template <> struct HasTrivialConstructor<bool> : public true_type{ }; - template <> struct HasTrivialConstructor<const bool> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile bool> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile bool> : public true_type{ }; - - template <> struct HasTrivialConstructor<char> : public true_type{ }; - template <> struct HasTrivialConstructor<const char> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile char> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile char> : public true_type{ }; - - #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) - template <> struct HasTrivialConstructor<wchar_t> : public true_type{ }; - template <> struct HasTrivialConstructor<const wchar_t> : public true_type{ }; - template <> struct HasTrivialConstructor<volatile wchar_t> : public true_type{ }; - template <> struct HasTrivialConstructor<const volatile wchar_t> : public true_type{ }; - #endif - - template <> struct HasTrivialDestructor<float> : public true_type{ }; - template <> struct HasTrivialDestructor<const float> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile float> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile float> : public true_type{ }; - - template <> struct HasTrivialDestructor<double> : public true_type{ }; - template <> struct HasTrivialDestructor<const double> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile double> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile double> : public true_type{ }; - - template <> struct HasTrivialDestructor<long double> : public true_type{ }; - template <> struct HasTrivialDestructor<const long double> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile long double> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile long double> : public true_type{ }; - - template <> struct HasTrivialDestructor<unsigned char> : public true_type{ }; - template <> struct HasTrivialDestructor<const unsigned char> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile unsigned char> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile unsigned char> : public true_type{ }; - - template <> struct HasTrivialDestructor<unsigned short> : public true_type{ }; - template <> struct HasTrivialDestructor<const unsigned short> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile unsigned short> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile unsigned short> : public true_type{ }; - - template <> struct HasTrivialDestructor<unsigned int> : public true_type{ }; - template <> struct HasTrivialDestructor<const unsigned int> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile unsigned int> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile unsigned int> : public true_type{ }; - - template <> struct HasTrivialDestructor<unsigned long> : public true_type{ }; - template <> struct HasTrivialDestructor<const unsigned long> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile unsigned long> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile unsigned long> : public true_type{ }; - - template <> struct HasTrivialDestructor<unsigned long long> : public true_type{ }; - template <> struct HasTrivialDestructor<const unsigned long long> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile unsigned long long> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile unsigned long long> : public true_type{ }; - - template <> struct HasTrivialDestructor<signed char> : public true_type{ }; - template <> struct HasTrivialDestructor<const signed char> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile signed char> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile signed char> : public true_type{ }; - - template <> struct HasTrivialDestructor<signed short> : public true_type{ }; - template <> struct HasTrivialDestructor<const signed short> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile signed short> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile signed short> : public true_type{ }; - - template <> struct HasTrivialDestructor<signed int> : public true_type{ }; - template <> struct HasTrivialDestructor<const signed int> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile signed int> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile signed int> : public true_type{ }; - - template <> struct HasTrivialDestructor<signed long> : public true_type{ }; - template <> struct HasTrivialDestructor<const signed long> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile signed long> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile signed long> : public true_type{ }; - - template <> struct HasTrivialDestructor<signed long long> : public true_type{ }; - template <> struct HasTrivialDestructor<const signed long long> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile signed long long> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile signed long long> : public true_type{ }; - - template <> struct HasTrivialDestructor<bool> : public true_type{ }; - template <> struct HasTrivialDestructor<const bool> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile bool> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile bool> : public true_type{ }; - - template <> struct HasTrivialDestructor<char> : public true_type{ }; - template <> struct HasTrivialDestructor<const char> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile char> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile char> : public true_type{ }; - - #if !defined(_MSC_VER) || defined(_NATIVE_WCHAR_T_DEFINED) - template <> struct HasTrivialDestructor<wchar_t> : public true_type{ }; - template <> struct HasTrivialDestructor<const wchar_t> : public true_type{ }; - template <> struct HasTrivialDestructor<volatile wchar_t> : public true_type{ }; - template <> struct HasTrivialDestructor<const volatile wchar_t> : public true_type{ }; - #endif - -#endif // __GLIBCXX__, etc. - -} // namespace WTF - -#endif // TypeTraits_h diff --git a/JavaScriptCore/wtf/UnusedParam.h b/JavaScriptCore/wtf/UnusedParam.h deleted file mode 100644 index 6ff6fd8..0000000 --- a/JavaScriptCore/wtf/UnusedParam.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_UnusedParam_h -#define WTF_UnusedParam_h - -/* don't use this for C++, it should only be used in plain C files or - ObjC methods, where leaving off the parameter name is not allowed. */ - -#include "Platform.h" - -#if COMPILER(INTEL) && !OS(WINDOWS) || COMPILER(RVCT) -template<typename T> -inline void unusedParam(T& x) { (void)x; } -#define UNUSED_PARAM(variable) unusedParam(variable) -#else -#define UNUSED_PARAM(variable) (void)variable -#endif - -#endif /* WTF_UnusedParam_h */ diff --git a/JavaScriptCore/wtf/VMTags.h b/JavaScriptCore/wtf/VMTags.h deleted file mode 100644 index 6600050..0000000 --- a/JavaScriptCore/wtf/VMTags.h +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2009 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef VMTags_h -#define VMTags_h - -// On Mac OS X, the VM subsystem allows tagging memory requested from mmap and vm_map -// in order to aid tools that inspect system memory use. -#if OS(DARWIN) - -#include <mach/vm_statistics.h> - -#if !defined(TARGETING_TIGER) - -#if defined(VM_MEMORY_TCMALLOC) -#define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(VM_MEMORY_TCMALLOC) -#else -#define VM_TAG_FOR_TCMALLOC_MEMORY VM_MAKE_TAG(53) -#endif // defined(VM_MEMORY_TCMALLOC) - -#if defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) -#else -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY VM_MAKE_TAG(64) -#endif // defined(VM_MEMORY_JAVASCRIPT_JIT_EXECUTABLE_ALLOCATOR) - -#if defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) -#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) -#else -#define VM_TAG_FOR_REGISTERFILE_MEMORY VM_MAKE_TAG(65) -#endif // defined(VM_MEMORY_JAVASCRIPT_JIT_REGISTER_FILE) - -#else // !defined(TARGETING_TIGER) - -// mmap on Tiger fails with tags that work on Leopard, so fall -// back to Tiger-compatible tags (that also work on Leopard) -// when targeting Tiger. -#define VM_TAG_FOR_TCMALLOC_MEMORY -1 -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1 -#define VM_TAG_FOR_REGISTERFILE_MEMORY -1 - -#endif // !defined(TARGETING_TIGER) - -// Tags for vm_map and vm_allocate work on both Tiger and Leopard. - -#if defined(VM_MEMORY_JAVASCRIPT_CORE) -#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(VM_MEMORY_JAVASCRIPT_CORE) -#else -#define VM_TAG_FOR_COLLECTOR_MEMORY VM_MAKE_TAG(63) -#endif // defined(VM_MEMORY_JAVASCRIPT_CORE) - -#if defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) -#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) -#else -#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY VM_MAKE_TAG(69) -#endif // defined(VM_MEMORY_WEBCORE_PURGEABLE_BUFFERS) - -#else // OS(DARWIN) - -#define VM_TAG_FOR_TCMALLOC_MEMORY -1 -#define VM_TAG_FOR_COLLECTOR_MEMORY -1 -#define VM_TAG_FOR_EXECUTABLEALLOCATOR_MEMORY -1 -#define VM_TAG_FOR_REGISTERFILE_MEMORY -1 -#define VM_TAG_FOR_WEBCORE_PURGEABLE_MEMORY -1 - -#endif // OS(DARWIN) - -#endif // VMTags_h diff --git a/JavaScriptCore/wtf/ValueCheck.h b/JavaScriptCore/wtf/ValueCheck.h deleted file mode 100644 index 2a86eb0..0000000 --- a/JavaScriptCore/wtf/ValueCheck.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ValueCheck_h -#define ValueCheck_h - -#include <wtf/FastMalloc.h> - -namespace WTF { - -template<typename T> struct ValueCheck { - typedef T TraitType; - static void checkConsistency(const T&) { } -}; - -#if !ASSERT_DISABLED -template<typename P> struct ValueCheck<P*> { - typedef P* TraitType; - static void checkConsistency(const P* p) - { - if (!p) - return; - ASSERT(fastMallocSize(p)); - ValueCheck<P>::checkConsistency(*p); - } -}; -#endif - -} - -#endif // ValueCheck_h diff --git a/JavaScriptCore/wtf/Vector.h b/JavaScriptCore/wtf/Vector.h deleted file mode 100644 index f73793f..0000000 --- a/JavaScriptCore/wtf/Vector.h +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_Vector_h -#define WTF_Vector_h - -#include "FastAllocBase.h" -#include "Noncopyable.h" -#include "NotFound.h" -#include "StdLibExtras.h" -#include "ValueCheck.h" -#include "VectorTraits.h" -#include <limits> -#include <utility> - -#if PLATFORM(QT) -#include <QDataStream> -#endif - -namespace WTF { - - using std::min; - using std::max; - - // WTF_ALIGN_OF / WTF_ALIGNED - #if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW) - #define WTF_ALIGN_OF(type) __alignof__(type) - #define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n))) - #elif COMPILER(MSVC) - #define WTF_ALIGN_OF(type) __alignof(type) - #define WTF_ALIGNED(variable_type, variable, n) __declspec(align(n)) variable_type variable - #else - #error WTF_ALIGN macros need alignment control. - #endif - - #if COMPILER(GCC) && !COMPILER(INTEL) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303) - typedef char __attribute__((__may_alias__)) AlignedBufferChar; - #else - typedef char AlignedBufferChar; - #endif - - template <size_t size, size_t alignment> struct AlignedBuffer; - template <size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; }; - template <size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2); }; - template <size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4); }; - template <size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8); }; - template <size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); }; - template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); }; - template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); }; - - template <size_t size, size_t alignment> - void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b) - { - for (size_t i = 0; i < size; ++i) - std::swap(a.buffer[i], b.buffer[i]); - } - - template <bool needsDestruction, typename T> - struct VectorDestructor; - - template<typename T> - struct VectorDestructor<false, T> - { - static void destruct(T*, T*) {} - }; - - template<typename T> - struct VectorDestructor<true, T> - { - static void destruct(T* begin, T* end) - { - for (T* cur = begin; cur != end; ++cur) - cur->~T(); - } - }; - - template <bool needsInitialization, bool canInitializeWithMemset, typename T> - struct VectorInitializer; - - template<bool ignore, typename T> - struct VectorInitializer<false, ignore, T> - { - static void initialize(T*, T*) {} - }; - - template<typename T> - struct VectorInitializer<true, false, T> - { - static void initialize(T* begin, T* end) - { - for (T* cur = begin; cur != end; ++cur) - new (cur) T; - } - }; - - template<typename T> - struct VectorInitializer<true, true, T> - { - static void initialize(T* begin, T* end) - { - memset(begin, 0, reinterpret_cast<char*>(end) - reinterpret_cast<char*>(begin)); - } - }; - - template <bool canMoveWithMemcpy, typename T> - struct VectorMover; - - template<typename T> - struct VectorMover<false, T> - { - static void move(const T* src, const T* srcEnd, T* dst) - { - while (src != srcEnd) { - new (dst) T(*src); - src->~T(); - ++dst; - ++src; - } - } - static void moveOverlapping(const T* src, const T* srcEnd, T* dst) - { - if (src > dst) - move(src, srcEnd, dst); - else { - T* dstEnd = dst + (srcEnd - src); - while (src != srcEnd) { - --srcEnd; - --dstEnd; - new (dstEnd) T(*srcEnd); - srcEnd->~T(); - } - } - } - }; - - template<typename T> - struct VectorMover<true, T> - { - static void move(const T* src, const T* srcEnd, T* dst) - { - memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src)); - } - static void moveOverlapping(const T* src, const T* srcEnd, T* dst) - { - memmove(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src)); - } - }; - - template <bool canCopyWithMemcpy, typename T> - struct VectorCopier; - - template<typename T> - struct VectorCopier<false, T> - { - static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) - { - while (src != srcEnd) { - new (dst) T(*src); - ++dst; - ++src; - } - } - }; - - template<typename T> - struct VectorCopier<true, T> - { - static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) - { - memcpy(dst, src, reinterpret_cast<const char*>(srcEnd) - reinterpret_cast<const char*>(src)); - } - }; - - template <bool canFillWithMemset, typename T> - struct VectorFiller; - - template<typename T> - struct VectorFiller<false, T> - { - static void uninitializedFill(T* dst, T* dstEnd, const T& val) - { - while (dst != dstEnd) { - new (dst) T(val); - ++dst; - } - } - }; - - template<typename T> - struct VectorFiller<true, T> - { - static void uninitializedFill(T* dst, T* dstEnd, const T& val) - { - ASSERT(sizeof(T) == sizeof(char)); - memset(dst, val, dstEnd - dst); - } - }; - - template<bool canCompareWithMemcmp, typename T> - struct VectorComparer; - - template<typename T> - struct VectorComparer<false, T> - { - static bool compare(const T* a, const T* b, size_t size) - { - for (size_t i = 0; i < size; ++i) - if (a[i] != b[i]) - return false; - return true; - } - }; - - template<typename T> - struct VectorComparer<true, T> - { - static bool compare(const T* a, const T* b, size_t size) - { - return memcmp(a, b, sizeof(T) * size) == 0; - } - }; - - template<typename T> - struct VectorTypeOperations - { - static void destruct(T* begin, T* end) - { - VectorDestructor<VectorTraits<T>::needsDestruction, T>::destruct(begin, end); - } - - static void initialize(T* begin, T* end) - { - VectorInitializer<VectorTraits<T>::needsInitialization, VectorTraits<T>::canInitializeWithMemset, T>::initialize(begin, end); - } - - static void move(const T* src, const T* srcEnd, T* dst) - { - VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::move(src, srcEnd, dst); - } - - static void moveOverlapping(const T* src, const T* srcEnd, T* dst) - { - VectorMover<VectorTraits<T>::canMoveWithMemcpy, T>::moveOverlapping(src, srcEnd, dst); - } - - static void uninitializedCopy(const T* src, const T* srcEnd, T* dst) - { - VectorCopier<VectorTraits<T>::canCopyWithMemcpy, T>::uninitializedCopy(src, srcEnd, dst); - } - - static void uninitializedFill(T* dst, T* dstEnd, const T& val) - { - VectorFiller<VectorTraits<T>::canFillWithMemset, T>::uninitializedFill(dst, dstEnd, val); - } - - static bool compare(const T* a, const T* b, size_t size) - { - return VectorComparer<VectorTraits<T>::canCompareWithMemcmp, T>::compare(a, b, size); - } - }; - - template<typename T> - class VectorBufferBase : public Noncopyable { - public: - void allocateBuffer(size_t newCapacity) - { - m_capacity = newCapacity; - if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T)) - CRASH(); - m_buffer = static_cast<T*>(fastMalloc(newCapacity * sizeof(T))); - } - - bool tryAllocateBuffer(size_t newCapacity) - { - if (newCapacity > std::numeric_limits<size_t>::max() / sizeof(T)) - return false; - - T* newBuffer; - if (tryFastMalloc(newCapacity * sizeof(T)).getValue(newBuffer)) { - m_capacity = newCapacity; - m_buffer = newBuffer; - return true; - } - return false; - } - - void deallocateBuffer(T* bufferToDeallocate) - { - if (m_buffer == bufferToDeallocate) { - m_buffer = 0; - m_capacity = 0; - } - fastFree(bufferToDeallocate); - } - - T* buffer() { return m_buffer; } - const T* buffer() const { return m_buffer; } - T** bufferSlot() { return &m_buffer; } - size_t capacity() const { return m_capacity; } - - T* releaseBuffer() - { - T* buffer = m_buffer; - m_buffer = 0; - m_capacity = 0; - return buffer; - } - - protected: - VectorBufferBase() - : m_buffer(0) - , m_capacity(0) - { - } - - VectorBufferBase(T* buffer, size_t capacity) - : m_buffer(buffer) - , m_capacity(capacity) - { - } - - ~VectorBufferBase() - { - // FIXME: It would be nice to find a way to ASSERT that m_buffer hasn't leaked here. - } - - T* m_buffer; - size_t m_capacity; - }; - - template<typename T, size_t inlineCapacity> - class VectorBuffer; - - template<typename T> - class VectorBuffer<T, 0> : private VectorBufferBase<T> { - private: - typedef VectorBufferBase<T> Base; - public: - VectorBuffer() - { - } - - VectorBuffer(size_t capacity) - { - allocateBuffer(capacity); - } - - ~VectorBuffer() - { - deallocateBuffer(buffer()); - } - - void swap(VectorBuffer<T, 0>& other) - { - std::swap(m_buffer, other.m_buffer); - std::swap(m_capacity, other.m_capacity); - } - - void restoreInlineBufferIfNeeded() { } - - using Base::allocateBuffer; - using Base::tryAllocateBuffer; - using Base::deallocateBuffer; - - using Base::buffer; - using Base::bufferSlot; - using Base::capacity; - - using Base::releaseBuffer; - private: - using Base::m_buffer; - using Base::m_capacity; - }; - - template<typename T, size_t inlineCapacity> - class VectorBuffer : private VectorBufferBase<T> { - private: - typedef VectorBufferBase<T> Base; - public: - VectorBuffer() - : Base(inlineBuffer(), inlineCapacity) - { - } - - VectorBuffer(size_t capacity) - : Base(inlineBuffer(), inlineCapacity) - { - if (capacity > inlineCapacity) - Base::allocateBuffer(capacity); - } - - ~VectorBuffer() - { - deallocateBuffer(buffer()); - } - - void allocateBuffer(size_t newCapacity) - { - if (newCapacity > inlineCapacity) - Base::allocateBuffer(newCapacity); - else { - m_buffer = inlineBuffer(); - m_capacity = inlineCapacity; - } - } - - bool tryAllocateBuffer(size_t newCapacity) - { - if (newCapacity > inlineCapacity) - return Base::tryAllocateBuffer(newCapacity); - m_buffer = inlineBuffer(); - m_capacity = inlineCapacity; - return true; - } - - void deallocateBuffer(T* bufferToDeallocate) - { - if (bufferToDeallocate == inlineBuffer()) - return; - Base::deallocateBuffer(bufferToDeallocate); - } - - void swap(VectorBuffer<T, inlineCapacity>& other) - { - if (buffer() == inlineBuffer() && other.buffer() == other.inlineBuffer()) { - WTF::swap(m_inlineBuffer, other.m_inlineBuffer); - std::swap(m_capacity, other.m_capacity); - } else if (buffer() == inlineBuffer()) { - m_buffer = other.m_buffer; - other.m_buffer = other.inlineBuffer(); - WTF::swap(m_inlineBuffer, other.m_inlineBuffer); - std::swap(m_capacity, other.m_capacity); - } else if (other.buffer() == other.inlineBuffer()) { - other.m_buffer = m_buffer; - m_buffer = inlineBuffer(); - WTF::swap(m_inlineBuffer, other.m_inlineBuffer); - std::swap(m_capacity, other.m_capacity); - } else { - std::swap(m_buffer, other.m_buffer); - std::swap(m_capacity, other.m_capacity); - } - } - - void restoreInlineBufferIfNeeded() - { - if (m_buffer) - return; - m_buffer = inlineBuffer(); - m_capacity = inlineCapacity; - } - - using Base::buffer; - using Base::bufferSlot; - using Base::capacity; - - T* releaseBuffer() - { - if (buffer() == inlineBuffer()) - return 0; - return Base::releaseBuffer(); - } - - private: - using Base::m_buffer; - using Base::m_capacity; - - static const size_t m_inlineBufferSize = inlineCapacity * sizeof(T); - T* inlineBuffer() { return reinterpret_cast_ptr<T*>(m_inlineBuffer.buffer); } - - AlignedBuffer<m_inlineBufferSize, WTF_ALIGN_OF(T)> m_inlineBuffer; - }; - - template<typename T, size_t inlineCapacity = 0> - class Vector : public FastAllocBase { - private: - typedef VectorBuffer<T, inlineCapacity> Buffer; - typedef VectorTypeOperations<T> TypeOperations; - - public: - typedef T ValueType; - - typedef T* iterator; - typedef const T* const_iterator; - - Vector() - : m_size(0) - { - } - - explicit Vector(size_t size) - : m_size(size) - , m_buffer(size) - { - if (begin()) - TypeOperations::initialize(begin(), end()); - } - - ~Vector() - { - if (m_size) shrink(0); - } - - Vector(const Vector&); - template<size_t otherCapacity> - Vector(const Vector<T, otherCapacity>&); - - Vector& operator=(const Vector&); - template<size_t otherCapacity> - Vector& operator=(const Vector<T, otherCapacity>&); - - size_t size() const { return m_size; } - size_t capacity() const { return m_buffer.capacity(); } - bool isEmpty() const { return !size(); } - - T& at(size_t i) - { - ASSERT(i < size()); - return m_buffer.buffer()[i]; - } - const T& at(size_t i) const - { - ASSERT(i < size()); - return m_buffer.buffer()[i]; - } - - T& operator[](size_t i) { return at(i); } - const T& operator[](size_t i) const { return at(i); } - - T* data() { return m_buffer.buffer(); } - const T* data() const { return m_buffer.buffer(); } - T** dataSlot() { return m_buffer.bufferSlot(); } - - iterator begin() { return data(); } - iterator end() { return begin() + m_size; } - const_iterator begin() const { return data(); } - const_iterator end() const { return begin() + m_size; } - - T& first() { return at(0); } - const T& first() const { return at(0); } - T& last() { return at(size() - 1); } - const T& last() const { return at(size() - 1); } - - template<typename U> size_t find(const U&) const; - template<typename U> size_t reverseFind(const U&) const; - - void shrink(size_t size); - void grow(size_t size); - void resize(size_t size); - void reserveCapacity(size_t newCapacity); - bool tryReserveCapacity(size_t newCapacity); - void reserveInitialCapacity(size_t initialCapacity); - void shrinkCapacity(size_t newCapacity); - void shrinkToFit() { shrinkCapacity(size()); } - - void clear() { shrinkCapacity(0); } - - template<typename U> void append(const U*, size_t); - template<typename U> void append(const U&); - template<typename U> void uncheckedAppend(const U& val); - template<size_t otherCapacity> void append(const Vector<T, otherCapacity>&); - template<typename U> bool tryAppend(const U*, size_t); - - template<typename U> void insert(size_t position, const U*, size_t); - template<typename U> void insert(size_t position, const U&); - template<typename U, size_t c> void insert(size_t position, const Vector<U, c>&); - - template<typename U> void prepend(const U*, size_t); - template<typename U> void prepend(const U&); - template<typename U, size_t c> void prepend(const Vector<U, c>&); - - void remove(size_t position); - void remove(size_t position, size_t length); - - void removeLast() - { - ASSERT(!isEmpty()); - shrink(size() - 1); - } - - Vector(size_t size, const T& val) - : m_size(size) - , m_buffer(size) - { - if (begin()) - TypeOperations::uninitializedFill(begin(), end(), val); - } - - void fill(const T&, size_t); - void fill(const T& val) { fill(val, size()); } - - template<typename Iterator> void appendRange(Iterator start, Iterator end); - - T* releaseBuffer(); - - void swap(Vector<T, inlineCapacity>& other) - { - std::swap(m_size, other.m_size); - m_buffer.swap(other.m_buffer); - } - - void checkConsistency(); - - private: - void expandCapacity(size_t newMinCapacity); - const T* expandCapacity(size_t newMinCapacity, const T*); - bool tryExpandCapacity(size_t newMinCapacity); - const T* tryExpandCapacity(size_t newMinCapacity, const T*); - template<typename U> U* expandCapacity(size_t newMinCapacity, U*); - - size_t m_size; - Buffer m_buffer; - }; - -#if PLATFORM(QT) - template<typename T> - QDataStream& operator<<(QDataStream& stream, const Vector<T>& data) - { - stream << qint64(data.size()); - foreach (const T& i, data) - stream << i; - return stream; - } - - template<typename T> - QDataStream& operator>>(QDataStream& stream, Vector<T>& data) - { - data.clear(); - qint64 count; - T item; - stream >> count; - data.reserveCapacity(count); - for (qint64 i = 0; i < count; ++i) { - stream >> item; - data.append(item); - } - return stream; - } -#endif - - template<typename T, size_t inlineCapacity> - Vector<T, inlineCapacity>::Vector(const Vector& other) - : m_size(other.size()) - , m_buffer(other.capacity()) - { - if (begin()) - TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); - } - - template<typename T, size_t inlineCapacity> - template<size_t otherCapacity> - Vector<T, inlineCapacity>::Vector(const Vector<T, otherCapacity>& other) - : m_size(other.size()) - , m_buffer(other.capacity()) - { - if (begin()) - TypeOperations::uninitializedCopy(other.begin(), other.end(), begin()); - } - - template<typename T, size_t inlineCapacity> - Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, inlineCapacity>& other) - { - if (&other == this) - return *this; - - if (size() > other.size()) - shrink(other.size()); - else if (other.size() > capacity()) { - clear(); - reserveCapacity(other.size()); - if (!begin()) - return *this; - } - -// Works around an assert in VS2010. See https://connect.microsoft.com/VisualStudio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last -#if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL - if (!begin()) - return *this; -#endif - - std::copy(other.begin(), other.begin() + size(), begin()); - TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); - m_size = other.size(); - - return *this; - } - - inline bool typelessPointersAreEqual(const void* a, const void* b) { return a == b; } - - template<typename T, size_t inlineCapacity> - template<size_t otherCapacity> - Vector<T, inlineCapacity>& Vector<T, inlineCapacity>::operator=(const Vector<T, otherCapacity>& other) - { - // If the inline capacities match, we should call the more specific - // template. If the inline capacities don't match, the two objects - // shouldn't be allocated the same address. - ASSERT(!typelessPointersAreEqual(&other, this)); - - if (size() > other.size()) - shrink(other.size()); - else if (other.size() > capacity()) { - clear(); - reserveCapacity(other.size()); - if (!begin()) - return *this; - } - -// Works around an assert in VS2010. See https://connect.microsoft.com/VisualStudio/feedback/details/558044/std-copy-should-not-check-dest-when-first-last -#if COMPILER(MSVC) && defined(_ITERATOR_DEBUG_LEVEL) && _ITERATOR_DEBUG_LEVEL - if (!begin()) - return *this; -#endif - - std::copy(other.begin(), other.begin() + size(), begin()); - TypeOperations::uninitializedCopy(other.begin() + size(), other.end(), end()); - m_size = other.size(); - - return *this; - } - - template<typename T, size_t inlineCapacity> - template<typename U> - size_t Vector<T, inlineCapacity>::find(const U& value) const - { - for (size_t i = 0; i < size(); ++i) { - if (at(i) == value) - return i; - } - return notFound; - } - - template<typename T, size_t inlineCapacity> - template<typename U> - size_t Vector<T, inlineCapacity>::reverseFind(const U& value) const - { - for (size_t i = 1; i <= size(); ++i) { - const size_t index = size() - i; - if (at(index) == value) - return index; - } - return notFound; - } - - template<typename T, size_t inlineCapacity> - void Vector<T, inlineCapacity>::fill(const T& val, size_t newSize) - { - if (size() > newSize) - shrink(newSize); - else if (newSize > capacity()) { - clear(); - reserveCapacity(newSize); - if (!begin()) - return; - } - - std::fill(begin(), end(), val); - TypeOperations::uninitializedFill(end(), begin() + newSize, val); - m_size = newSize; - } - - template<typename T, size_t inlineCapacity> - template<typename Iterator> - void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end) - { - for (Iterator it = start; it != end; ++it) - append(*it); - } - - template<typename T, size_t inlineCapacity> - void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity) - { - reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1))); - } - - template<typename T, size_t inlineCapacity> - const T* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, const T* ptr) - { - if (ptr < begin() || ptr >= end()) { - expandCapacity(newMinCapacity); - return ptr; - } - size_t index = ptr - begin(); - expandCapacity(newMinCapacity); - return begin() + index; - } - - template<typename T, size_t inlineCapacity> - bool Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity) - { - return tryReserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1))); - } - - template<typename T, size_t inlineCapacity> - const T* Vector<T, inlineCapacity>::tryExpandCapacity(size_t newMinCapacity, const T* ptr) - { - if (ptr < begin() || ptr >= end()) { - if (!tryExpandCapacity(newMinCapacity)) - return 0; - return ptr; - } - size_t index = ptr - begin(); - if (!tryExpandCapacity(newMinCapacity)) - return 0; - return begin() + index; - } - - template<typename T, size_t inlineCapacity> template<typename U> - inline U* Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity, U* ptr) - { - expandCapacity(newMinCapacity); - return ptr; - } - - template<typename T, size_t inlineCapacity> - inline void Vector<T, inlineCapacity>::resize(size_t size) - { - if (size <= m_size) - TypeOperations::destruct(begin() + size, end()); - else { - if (size > capacity()) - expandCapacity(size); - if (begin()) - TypeOperations::initialize(end(), begin() + size); - } - - m_size = size; - } - - template<typename T, size_t inlineCapacity> - void Vector<T, inlineCapacity>::shrink(size_t size) - { - ASSERT(size <= m_size); - TypeOperations::destruct(begin() + size, end()); - m_size = size; - } - - template<typename T, size_t inlineCapacity> - void Vector<T, inlineCapacity>::grow(size_t size) - { - ASSERT(size >= m_size); - if (size > capacity()) - expandCapacity(size); - if (begin()) - TypeOperations::initialize(end(), begin() + size); - m_size = size; - } - - template<typename T, size_t inlineCapacity> - void Vector<T, inlineCapacity>::reserveCapacity(size_t newCapacity) - { - if (newCapacity <= capacity()) - return; - T* oldBuffer = begin(); - T* oldEnd = end(); - m_buffer.allocateBuffer(newCapacity); - if (begin()) - TypeOperations::move(oldBuffer, oldEnd, begin()); - m_buffer.deallocateBuffer(oldBuffer); - } - - template<typename T, size_t inlineCapacity> - bool Vector<T, inlineCapacity>::tryReserveCapacity(size_t newCapacity) - { - if (newCapacity <= capacity()) - return true; - T* oldBuffer = begin(); - T* oldEnd = end(); - if (!m_buffer.tryAllocateBuffer(newCapacity)) - return false; - ASSERT(begin()); - TypeOperations::move(oldBuffer, oldEnd, begin()); - m_buffer.deallocateBuffer(oldBuffer); - return true; - } - - template<typename T, size_t inlineCapacity> - inline void Vector<T, inlineCapacity>::reserveInitialCapacity(size_t initialCapacity) - { - ASSERT(!m_size); - ASSERT(capacity() == inlineCapacity); - if (initialCapacity > inlineCapacity) - m_buffer.allocateBuffer(initialCapacity); - } - - template<typename T, size_t inlineCapacity> - void Vector<T, inlineCapacity>::shrinkCapacity(size_t newCapacity) - { - if (newCapacity >= capacity()) - return; - - if (newCapacity < size()) - shrink(newCapacity); - - T* oldBuffer = begin(); - if (newCapacity > 0) { - T* oldEnd = end(); - m_buffer.allocateBuffer(newCapacity); - if (begin() != oldBuffer) - TypeOperations::move(oldBuffer, oldEnd, begin()); - } - - m_buffer.deallocateBuffer(oldBuffer); - m_buffer.restoreInlineBufferIfNeeded(); - } - - // Templatizing these is better than just letting the conversion happen implicitly, - // because for instance it allows a PassRefPtr to be appended to a RefPtr vector - // without refcount thrash. - - template<typename T, size_t inlineCapacity> template<typename U> - void Vector<T, inlineCapacity>::append(const U* data, size_t dataSize) - { - size_t newSize = m_size + dataSize; - if (newSize > capacity()) { - data = expandCapacity(newSize, data); - if (!begin()) - return; - } - if (newSize < m_size) - CRASH(); - T* dest = end(); - for (size_t i = 0; i < dataSize; ++i) - new (&dest[i]) T(data[i]); - m_size = newSize; - } - - template<typename T, size_t inlineCapacity> template<typename U> - bool Vector<T, inlineCapacity>::tryAppend(const U* data, size_t dataSize) - { - size_t newSize = m_size + dataSize; - if (newSize > capacity()) { - data = tryExpandCapacity(newSize, data); - if (!data) - return false; - ASSERT(begin()); - } - if (newSize < m_size) - return false; - T* dest = end(); - for (size_t i = 0; i < dataSize; ++i) - new (&dest[i]) T(data[i]); - m_size = newSize; - return true; - } - - template<typename T, size_t inlineCapacity> template<typename U> - ALWAYS_INLINE void Vector<T, inlineCapacity>::append(const U& val) - { - const U* ptr = &val; - if (size() == capacity()) { - ptr = expandCapacity(size() + 1, ptr); - if (!begin()) - return; - } - -#if COMPILER(MSVC7_OR_LOWER) - // FIXME: MSVC7 generates compilation errors when trying to assign - // a pointer to a Vector of its base class (i.e. can't downcast). So far - // I've been unable to determine any logical reason for this, so I can - // only assume it is a bug with the compiler. Casting is a bad solution, - // however, because it subverts implicit conversions, so a better - // one is needed. - new (end()) T(static_cast<T>(*ptr)); -#else - new (end()) T(*ptr); -#endif - ++m_size; - } - - // This version of append saves a branch in the case where you know that the - // vector's capacity is large enough for the append to succeed. - - template<typename T, size_t inlineCapacity> template<typename U> - inline void Vector<T, inlineCapacity>::uncheckedAppend(const U& val) - { - ASSERT(size() < capacity()); - const U* ptr = &val; - new (end()) T(*ptr); - ++m_size; - } - - // This method should not be called append, a better name would be appendElements. - // It could also be eliminated entirely, and call sites could just use - // appendRange(val.begin(), val.end()). - template<typename T, size_t inlineCapacity> template<size_t otherCapacity> - inline void Vector<T, inlineCapacity>::append(const Vector<T, otherCapacity>& val) - { - append(val.begin(), val.size()); - } - - template<typename T, size_t inlineCapacity> template<typename U> - void Vector<T, inlineCapacity>::insert(size_t position, const U* data, size_t dataSize) - { - ASSERT(position <= size()); - size_t newSize = m_size + dataSize; - if (newSize > capacity()) { - data = expandCapacity(newSize, data); - if (!begin()) - return; - } - if (newSize < m_size) - CRASH(); - T* spot = begin() + position; - TypeOperations::moveOverlapping(spot, end(), spot + dataSize); - for (size_t i = 0; i < dataSize; ++i) - new (&spot[i]) T(data[i]); - m_size = newSize; - } - - template<typename T, size_t inlineCapacity> template<typename U> - inline void Vector<T, inlineCapacity>::insert(size_t position, const U& val) - { - ASSERT(position <= size()); - const U* data = &val; - if (size() == capacity()) { - data = expandCapacity(size() + 1, data); - if (!begin()) - return; - } - T* spot = begin() + position; - TypeOperations::moveOverlapping(spot, end(), spot + 1); - new (spot) T(*data); - ++m_size; - } - - template<typename T, size_t inlineCapacity> template<typename U, size_t c> - inline void Vector<T, inlineCapacity>::insert(size_t position, const Vector<U, c>& val) - { - insert(position, val.begin(), val.size()); - } - - template<typename T, size_t inlineCapacity> template<typename U> - void Vector<T, inlineCapacity>::prepend(const U* data, size_t dataSize) - { - insert(0, data, dataSize); - } - - template<typename T, size_t inlineCapacity> template<typename U> - inline void Vector<T, inlineCapacity>::prepend(const U& val) - { - insert(0, val); - } - - template<typename T, size_t inlineCapacity> template<typename U, size_t c> - inline void Vector<T, inlineCapacity>::prepend(const Vector<U, c>& val) - { - insert(0, val.begin(), val.size()); - } - - template<typename T, size_t inlineCapacity> - inline void Vector<T, inlineCapacity>::remove(size_t position) - { - ASSERT(position < size()); - T* spot = begin() + position; - spot->~T(); - TypeOperations::moveOverlapping(spot + 1, end(), spot); - --m_size; - } - - template<typename T, size_t inlineCapacity> - inline void Vector<T, inlineCapacity>::remove(size_t position, size_t length) - { - ASSERT(position < size()); - ASSERT(position + length <= size()); - T* beginSpot = begin() + position; - T* endSpot = beginSpot + length; - TypeOperations::destruct(beginSpot, endSpot); - TypeOperations::moveOverlapping(endSpot, end(), beginSpot); - m_size -= length; - } - - template<typename T, size_t inlineCapacity> - inline T* Vector<T, inlineCapacity>::releaseBuffer() - { - T* buffer = m_buffer.releaseBuffer(); - if (inlineCapacity && !buffer && m_size) { - // If the vector had some data, but no buffer to release, - // that means it was using the inline buffer. In that case, - // we create a brand new buffer so the caller always gets one. - size_t bytes = m_size * sizeof(T); - buffer = static_cast<T*>(fastMalloc(bytes)); - memcpy(buffer, data(), bytes); - } - m_size = 0; - return buffer; - } - - template<typename T, size_t inlineCapacity> - inline void Vector<T, inlineCapacity>::checkConsistency() - { -#if !ASSERT_DISABLED - for (size_t i = 0; i < size(); ++i) - ValueCheck<T>::checkConsistency(at(i)); -#endif - } - - template<typename T, size_t inlineCapacity> - void deleteAllValues(const Vector<T, inlineCapacity>& collection) - { - typedef typename Vector<T, inlineCapacity>::const_iterator iterator; - iterator end = collection.end(); - for (iterator it = collection.begin(); it != end; ++it) - delete *it; - } - - template<typename T, size_t inlineCapacity> - inline void swap(Vector<T, inlineCapacity>& a, Vector<T, inlineCapacity>& b) - { - a.swap(b); - } - - template<typename T, size_t inlineCapacity> - bool operator==(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b) - { - if (a.size() != b.size()) - return false; - - return VectorTypeOperations<T>::compare(a.data(), b.data(), a.size()); - } - - template<typename T, size_t inlineCapacity> - inline bool operator!=(const Vector<T, inlineCapacity>& a, const Vector<T, inlineCapacity>& b) - { - return !(a == b); - } - -#if !ASSERT_DISABLED - template<typename T> struct ValueCheck<Vector<T> > { - typedef Vector<T> TraitType; - static void checkConsistency(const Vector<T>& v) - { - v.checkConsistency(); - } - }; -#endif - -} // namespace WTF - -using WTF::Vector; - -#endif // WTF_Vector_h diff --git a/JavaScriptCore/wtf/VectorTraits.h b/JavaScriptCore/wtf/VectorTraits.h deleted file mode 100644 index 3f33b29..0000000 --- a/JavaScriptCore/wtf/VectorTraits.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_VectorTraits_h -#define WTF_VectorTraits_h - -#include "OwnPtr.h" -#include "RefPtr.h" -#include "TypeTraits.h" -#include <utility> -#include <memory> - -using std::pair; - -namespace WTF { - - template<bool isPod, typename T> - struct VectorTraitsBase; - - template<typename T> - struct VectorTraitsBase<false, T> - { - static const bool needsDestruction = true; - static const bool needsInitialization = true; - static const bool canInitializeWithMemset = false; - static const bool canMoveWithMemcpy = false; - static const bool canCopyWithMemcpy = false; - static const bool canFillWithMemset = false; - static const bool canCompareWithMemcmp = false; - }; - - template<typename T> - struct VectorTraitsBase<true, T> - { - static const bool needsDestruction = false; - static const bool needsInitialization = false; - static const bool canInitializeWithMemset = false; - static const bool canMoveWithMemcpy = true; - static const bool canCopyWithMemcpy = true; - static const bool canFillWithMemset = sizeof(T) == sizeof(char); - static const bool canCompareWithMemcmp = true; - }; - - template<typename T> - struct VectorTraits : VectorTraitsBase<IsPod<T>::value, T> { }; - - struct SimpleClassVectorTraits - { - static const bool needsDestruction = true; - static const bool needsInitialization = true; - static const bool canInitializeWithMemset = true; - static const bool canMoveWithMemcpy = true; - static const bool canCopyWithMemcpy = false; - static const bool canFillWithMemset = false; - static const bool canCompareWithMemcmp = true; - }; - - // we know OwnPtr and RefPtr are simple enough that initializing to 0 and moving with memcpy - // (and then not destructing the original) will totally work - template<typename P> - struct VectorTraits<RefPtr<P> > : SimpleClassVectorTraits { }; - - template<typename P> - struct VectorTraits<OwnPtr<P> > : SimpleClassVectorTraits { }; - - template<typename First, typename Second> - struct VectorTraits<pair<First, Second> > - { - typedef VectorTraits<First> FirstTraits; - typedef VectorTraits<Second> SecondTraits; - - static const bool needsDestruction = FirstTraits::needsDestruction || SecondTraits::needsDestruction; - static const bool needsInitialization = FirstTraits::needsInitialization || SecondTraits::needsInitialization; - static const bool canInitializeWithMemset = FirstTraits::canInitializeWithMemset && SecondTraits::canInitializeWithMemset; - static const bool canMoveWithMemcpy = FirstTraits::canMoveWithMemcpy && SecondTraits::canMoveWithMemcpy; - static const bool canCopyWithMemcpy = FirstTraits::canCopyWithMemcpy && SecondTraits::canCopyWithMemcpy; - static const bool canFillWithMemset = false; - static const bool canCompareWithMemcmp = FirstTraits::canCompareWithMemcmp && SecondTraits::canCompareWithMemcmp; - }; - -} // namespace WTF - -using WTF::VectorTraits; -using WTF::SimpleClassVectorTraits; - -#endif // WTF_VectorTraits_h diff --git a/JavaScriptCore/wtf/WTFThreadData.cpp b/JavaScriptCore/wtf/WTFThreadData.cpp deleted file mode 100644 index 05be8d1..0000000 --- a/JavaScriptCore/wtf/WTFThreadData.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2008, 2010 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include "config.h" -#include "WTFThreadData.h" - -namespace WTF { - -#if WTFTHREADDATA_MULTITHREADED -ThreadSpecific<WTFThreadData>* WTFThreadData::staticData; -#else -WTFThreadData* WTFThreadData::staticData; -#endif - -WTFThreadData::WTFThreadData() - : m_atomicStringTable(0) - , m_atomicStringTableDestructor(0) -#if USE(JSC) - , m_defaultIdentifierTable(new JSC::IdentifierTable()) - , m_currentIdentifierTable(m_defaultIdentifierTable) -#endif - , m_stackBounds(StackBounds::currentThreadStackBounds()) -{ -} - -WTFThreadData::~WTFThreadData() -{ - if (m_atomicStringTableDestructor) - m_atomicStringTableDestructor(m_atomicStringTable); -#if USE(JSC) - delete m_defaultIdentifierTable; -#endif -} - -} diff --git a/JavaScriptCore/wtf/WTFThreadData.h b/JavaScriptCore/wtf/WTFThreadData.h deleted file mode 100644 index da1b6eb..0000000 --- a/JavaScriptCore/wtf/WTFThreadData.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#ifndef WTFThreadData_h -#define WTFThreadData_h - -#include <wtf/HashMap.h> -#include <wtf/HashSet.h> -#include <wtf/Noncopyable.h> -#include <wtf/StackBounds.h> -#include <wtf/text/StringHash.h> - -// This was ENABLE(WORKERS) in WebCore, but this is not defined when compiling JSC. -// However this check was not correct anyway, re this comment: -// // FIXME: Workers are not necessarily the only feature that make per-thread global data necessary. -// // We need to check for e.g. database objects manipulating strings on secondary threads. -// Always enabling this is safe, and should be a better option until we can come up -// with a better define. -#define WTFTHREADDATA_MULTITHREADED 1 - -#if WTFTHREADDATA_MULTITHREADED -#include <wtf/ThreadSpecific.h> -#include <wtf/Threading.h> -#endif - -#if USE(JSC) -// FIXME: This is a temporary layering violation while we move more string code to WTF. -namespace JSC { - -typedef HashMap<const char*, RefPtr<StringImpl>, PtrHash<const char*> > LiteralIdentifierTable; - -class IdentifierTable : public FastAllocBase { -public: - ~IdentifierTable(); - - std::pair<HashSet<StringImpl*>::iterator, bool> add(StringImpl* value); - template<typename U, typename V> - std::pair<HashSet<StringImpl*>::iterator, bool> add(U value); - - bool remove(StringImpl* r) - { - HashSet<StringImpl*>::iterator iter = m_table.find(r); - if (iter == m_table.end()) - return false; - m_table.remove(iter); - return true; - } - - LiteralIdentifierTable& literalTable() { return m_literalTable; } - -private: - HashSet<StringImpl*> m_table; - LiteralIdentifierTable m_literalTable; -}; - -} -#endif - -namespace WTF { - -class AtomicStringTable; - -typedef void (*AtomicStringTableDestructor)(AtomicStringTable*); - -class WTFThreadData : public Noncopyable { -public: - WTFThreadData(); - ~WTFThreadData(); - - AtomicStringTable* atomicStringTable() - { - return m_atomicStringTable; - } - -#if USE(JSC) - JSC::IdentifierTable* currentIdentifierTable() - { - return m_currentIdentifierTable; - } - - JSC::IdentifierTable* setCurrentIdentifierTable(JSC::IdentifierTable* identifierTable) - { - JSC::IdentifierTable* oldIdentifierTable = m_currentIdentifierTable; - m_currentIdentifierTable = identifierTable; - return oldIdentifierTable; - } - - void resetCurrentIdentifierTable() - { - m_currentIdentifierTable = m_defaultIdentifierTable; - } -#endif - - const StackBounds& stack() const - { - return m_stackBounds; - } - -private: - AtomicStringTable* m_atomicStringTable; - AtomicStringTableDestructor m_atomicStringTableDestructor; - -#if USE(JSC) - JSC::IdentifierTable* m_defaultIdentifierTable; - JSC::IdentifierTable* m_currentIdentifierTable; -#endif - -#if WTFTHREADDATA_MULTITHREADED - static JS_EXPORTDATA ThreadSpecific<WTFThreadData>* staticData; -#else - static JS_EXPORTDATA WTFThreadData* staticData; -#endif - friend WTFThreadData& wtfThreadData(); - friend class AtomicStringTable; - - StackBounds m_stackBounds; -}; - -inline WTFThreadData& wtfThreadData() -{ -#if WTFTHREADDATA_MULTITHREADED - // WRT WebCore: - // WTFThreadData is used on main thread before it could possibly be used - // on secondary ones, so there is no need for synchronization here. - // WRT JavaScriptCore: - // wtfThreadData() is initially called from initializeThreading(), ensuring - // this is initially called in a pthread_once locked context. - if (!WTFThreadData::staticData) - WTFThreadData::staticData = new ThreadSpecific<WTFThreadData>; - return **WTFThreadData::staticData; -#else - if (!WTFThreadData::staticData) { - WTFThreadData::staticData = static_cast<WTFThreadData*>(fastMalloc(sizeof(WTFThreadData))); - // WTFThreadData constructor indirectly uses staticData, so we need to set up the memory before invoking it. - new (WTFThreadData::staticData) WTFThreadData; - } - return *WTFThreadData::staticData; -#endif -} - -} // namespace WTF - -using WTF::WTFThreadData; -using WTF::wtfThreadData; - -#endif // WTFThreadData_h diff --git a/JavaScriptCore/wtf/android/AndroidThreading.h b/JavaScriptCore/wtf/android/AndroidThreading.h deleted file mode 100644 index 27f548c..0000000 --- a/JavaScriptCore/wtf/android/AndroidThreading.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AndroidThreading_h -#define AndroidThreading_h - -namespace WTF { - -// An interface to the embedding layer, which provides threading support. -class AndroidThreading { -public: - static void scheduleDispatchFunctionsOnMainThread(); -}; - -} // namespace WTF - -#endif // AndroidThreading_h diff --git a/JavaScriptCore/wtf/android/MainThreadAndroid.cpp b/JavaScriptCore/wtf/android/MainThreadAndroid.cpp deleted file mode 100644 index 5e5f7b1..0000000 --- a/JavaScriptCore/wtf/android/MainThreadAndroid.cpp +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2009, The Android Open Source Project - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include "AndroidThreading.h" - -namespace WTF { - -void initializeMainThreadPlatform() -{ -} - -void scheduleDispatchFunctionsOnMainThread() -{ - AndroidThreading::scheduleDispatchFunctionsOnMainThread(); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/brew/MainThreadBrew.cpp b/JavaScriptCore/wtf/brew/MainThreadBrew.cpp deleted file mode 100644 index 2690ea5..0000000 --- a/JavaScriptCore/wtf/brew/MainThreadBrew.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2009 Company 100, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -namespace WTF { - -void initializeMainThreadPlatform() -{ - // not implemented -} - -void scheduleDispatchFunctionsOnMainThread() -{ - // not implemented -} - -} // namespace WTF - diff --git a/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp b/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp deleted file mode 100644 index ce10fc3..0000000 --- a/JavaScriptCore/wtf/brew/OwnPtrBrew.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2010 Company 100 Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "OwnPtr.h" - -#include <AEEBitmap.h> -#include <AEEFile.h> -#include <AEEIMemGroup.h> -#include <AEEIMemSpace.h> -#include <AEENet.h> -#include <AEESSL.h> -#include <AEEStdLib.h> - -namespace WTF { - -void deleteOwnedPtr(IFileMgr* ptr) -{ - if (ptr) - IFILEMGR_Release(ptr); -} - -void deleteOwnedPtr(IFile* ptr) -{ - if (ptr) - IFILE_Release(ptr); -} - -void deleteOwnedPtr(IBitmap* ptr) -{ - if (ptr) - IBitmap_Release(ptr); -} - -void deleteOwnedPtr(ISSL* ptr) -{ - if (ptr) - ISSL_Release(ptr); -} - -void deleteOwnedPtr(IMemGroup* ptr) -{ - if (ptr) - IMemGroup_Release(ptr); -} - -void deleteOwnedPtr(IMemSpace* ptr) -{ - if (ptr) - IMemSpace_Release(ptr); -} - -void deleteOwnedPtr(ISocket* ptr) -{ - if (ptr) - ISOCKET_Release(ptr); -} - -} diff --git a/JavaScriptCore/wtf/brew/RefPtrBrew.h b/JavaScriptCore/wtf/brew/RefPtrBrew.h deleted file mode 100644 index 7fb0b7c..0000000 --- a/JavaScriptCore/wtf/brew/RefPtrBrew.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora Ltd. - * Copyright (C) 2009 Martin Robinson - * Copyright (C) 2010 Company 100, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef RefPtrBrew_h -#define RefPtrBrew_h - -#include "AlwaysInline.h" -#include "PlatformRefPtr.h" -#include <AEEIBase.h> -#include <algorithm> - -namespace WTF { - -// All Brew MP classes are derived from either IBase or IQI. -// Technically, IBase and IQI are different types. However, it is -// okay to cast both types to IBase because they have AddRef and Release -// in the same method vtable slots. -template <typename T> inline T* refPlatformPtr(T* ptr) -{ - if (ptr) - IBase_AddRef(reinterpret_cast<IBase*>(ptr)); - return ptr; -} - -template <typename T> inline void derefPlatformPtr(T* ptr) -{ - if (ptr) - IBase_Release(reinterpret_cast<IBase*>(ptr)); -} - -} // namespace WTF - -#endif // RefPtrBrew_h diff --git a/JavaScriptCore/wtf/brew/ShellBrew.h b/JavaScriptCore/wtf/brew/ShellBrew.h deleted file mode 100644 index faccc75..0000000 --- a/JavaScriptCore/wtf/brew/ShellBrew.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2010 Company 100 Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ShellBrew_h -#define ShellBrew_h - -#include <AEEAppGen.h> -#include <AEEStdLib.h> - -#include <wtf/Assertions.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/PlatformRefPtr.h> - -namespace WTF { - -template <typename T> -static inline PassOwnPtr<T> createInstance(AEECLSID cls) -{ - T* instance = 0; - - IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell; - ISHELL_CreateInstance(shell, cls, reinterpret_cast<void**>(&instance)); - ASSERT(instance); - - return instance; -} - -template <typename T> -static inline PlatformRefPtr<T> createRefPtrInstance(AEECLSID cls) -{ - T* instance = 0; - - IShell* shell = reinterpret_cast<AEEApplet*>(GETAPPINSTANCE())->m_pIShell; - ISHELL_CreateInstance(shell, cls, reinterpret_cast<void**>(&instance)); - ASSERT(instance); - - return adoptPlatformRef(instance); -} - -} // namespace WTF - -using WTF::createInstance; -using WTF::createRefPtrInstance; - -#endif // ShellBrew_h diff --git a/JavaScriptCore/wtf/brew/StringBrew.cpp b/JavaScriptCore/wtf/brew/StringBrew.cpp deleted file mode 100644 index d8f2e59..0000000 --- a/JavaScriptCore/wtf/brew/StringBrew.cpp +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (C) 2010 Company 100, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PlatformString.h" - -#include <AEEstd.h> - -namespace WTF { - -// String conversions -String::String(const AECHAR* string) -{ - // It is safe to cast AECHAR to UChar as both of them use 16 bits representation. - const UChar* str = reinterpret_cast<const UChar*>(string); - const size_t len = std_wstrlen(string); - - m_impl = StringImpl::create(str, len); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/brew/SystemMallocBrew.h b/JavaScriptCore/wtf/brew/SystemMallocBrew.h deleted file mode 100644 index c973b30..0000000 --- a/JavaScriptCore/wtf/brew/SystemMallocBrew.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Copyright (C) 2010 Company 100, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef SystemMallocBrew_h -#define SystemMallocBrew_h - -#include <AEEStdLib.h> - -static inline void* mallocBrew(size_t n) -{ - // By default, memory allocated using MALLOC() is initialized - // to zero. This behavior can be disabled by performing a bitwise - // OR of the flag ALLOC_NO_ZMEM with the dwSize parameter. - return MALLOC(n | ALLOC_NO_ZMEM); -} - -static inline void* callocBrew(size_t numElements, size_t elementSize) -{ - return MALLOC(numElements * elementSize); -} - -static inline void freeBrew(void* p) -{ - return FREE(p); -} - -static inline void* reallocBrew(void* p, size_t n) -{ - return REALLOC(p, n | ALLOC_NO_ZMEM); -} - -// Use MALLOC macro instead of the standard malloc function. -// Although RVCT provides malloc, we can't use it in BREW -// because the loader does not initialize the base address properly. -#define malloc(n) mallocBrew(n) -#define calloc(n, s) callocBrew(n, s) -#define realloc(p, n) reallocBrew(p, n) -#define free(p) freeBrew(p) - -#endif // SystemMallocBrew_h diff --git a/JavaScriptCore/wtf/chromium/ChromiumThreading.h b/JavaScriptCore/wtf/chromium/ChromiumThreading.h deleted file mode 100644 index 3938621..0000000 --- a/JavaScriptCore/wtf/chromium/ChromiumThreading.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* Copyright (C) 2009 Google Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of Google Inc. nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#ifndef ChromiumThreading_h -#define ChromiumThreading_h - -namespace WTF { - -// An interface to the embedding layer, which provides threading support. -class ChromiumThreading { -public: - static void callOnMainThread(void (*func)(void*), void* context); -}; - -} // namespace WTF - -#endif // ChromiumThreading_h diff --git a/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp b/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp deleted file mode 100644 index 9e6592b..0000000 --- a/JavaScriptCore/wtf/chromium/MainThreadChromium.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* -* Copyright (C) 2009 Google Inc. All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions are -* met: -* -* * Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* * Redistributions in binary form must reproduce the above -* copyright notice, this list of conditions and the following disclaimer -* in the documentation and/or other materials provided with the -* distribution. -* * Neither the name of Google Inc. nor the names of its -* contributors may be used to endorse or promote products derived from -* this software without specific prior written permission. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "config.h" -#include "MainThread.h" - -#include "Assertions.h" -#include "ChromiumThreading.h" -#include "Threading.h" - -namespace WTF { - -static ThreadIdentifier mainThreadIdentifier; - -void initializeMainThread() -{ - static bool initializedMainThread; - if (initializedMainThread) - return; - initializedMainThread = true; - - mainThreadIdentifier = currentThread(); -} - -void callOnMainThread(MainThreadFunction* function, void* context) -{ - ChromiumThreading::callOnMainThread(function, context); -} - -void callOnMainThreadAndWait(MainThreadFunction*, void*) -{ - ASSERT_NOT_REACHED(); -} - -void setMainThreadCallbacksPaused(bool) -{ - ASSERT_NOT_REACHED(); -} - -bool isMainThread() -{ - return currentThread() == mainThreadIdentifier; -} - -} // namespace WTF - diff --git a/JavaScriptCore/wtf/dtoa.cpp b/JavaScriptCore/wtf/dtoa.cpp deleted file mode 100644 index c89c036..0000000 --- a/JavaScriptCore/wtf/dtoa.cpp +++ /dev/null @@ -1,1831 +0,0 @@ -/**************************************************************** - * - * The author of this software is David M. Gay. - * - * Copyright (c) 1991, 2000, 2001 by Lucent Technologies. - * Copyright (C) 2002, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. - * - * Permission to use, copy, modify, and distribute this software for any - * purpose without fee is hereby granted, provided that this entire notice - * is included in all copies of any software which is or includes a copy - * or modification of this software and in all copies of the supporting - * documentation for such software. - * - * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR IMPLIED - * WARRANTY. IN PARTICULAR, NEITHER THE AUTHOR NOR LUCENT MAKES ANY - * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE MERCHANTABILITY - * OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR PURPOSE. - * - ***************************************************************/ - -/* Please send bug reports to David M. Gay (dmg at acm dot org, - * with " at " changed at "@" and " dot " changed to "."). */ - -/* On a machine with IEEE extended-precision registers, it is - * necessary to specify double-precision (53-bit) rounding precision - * before invoking strtod or dtoa. If the machine uses (the equivalent - * of) Intel 80x87 arithmetic, the call - * _control87(PC_53, MCW_PC); - * does this with many compilers. Whether this or another call is - * appropriate depends on the compiler; for this to work, it may be - * necessary to #include "float.h" or another system-dependent header - * file. - */ - -/* strtod for IEEE-arithmetic machines. - * - * This strtod returns a nearest machine number to the input decimal - * string (or sets errno to ERANGE). With IEEE arithmetic, ties are - * broken by the IEEE round-even rule. Otherwise ties are broken by - * biased rounding (add half and chop). - * - * Inspired loosely by William D. Clinger's paper "How to Read Floating - * Point Numbers Accurately" [Proc. ACM SIGPLAN '90, pp. 92-101]. - * - * Modifications: - * - * 1. We only require IEEE double-precision arithmetic (not IEEE double-extended). - * 2. We get by with floating-point arithmetic in a case that - * Clinger missed -- when we're computing d * 10^n - * for a small integer d and the integer n is not too - * much larger than 22 (the maximum integer k for which - * we can represent 10^k exactly), we may be able to - * compute (d*10^k) * 10^(e-k) with just one roundoff. - * 3. Rather than a bit-at-a-time adjustment of the binary - * result in the hard case, we use floating-point - * arithmetic to determine the adjustment to within - * one bit; only in really hard cases do we need to - * compute a second residual. - * 4. Because of 3., we don't need a large table of powers of 10 - * for ten-to-e (just some small tables, e.g. of 10^k - * for 0 <= k <= 22). - */ - -#include "config.h" -#include "dtoa.h" - -#if HAVE(ERRNO_H) -#include <errno.h> -#endif -#include <float.h> -#include <math.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <wtf/AlwaysInline.h> -#include <wtf/Assertions.h> -#include <wtf/DecimalNumber.h> -#include <wtf/FastMalloc.h> -#include <wtf/MathExtras.h> -#include <wtf/Threading.h> -#include <wtf/UnusedParam.h> -#include <wtf/Vector.h> - -#if COMPILER(MSVC) -#pragma warning(disable: 4244) -#pragma warning(disable: 4245) -#pragma warning(disable: 4554) -#endif - -namespace WTF { - -#if ENABLE(JSC_MULTIPLE_THREADS) -Mutex* s_dtoaP5Mutex; -#endif - -typedef union { - double d; - uint32_t L[2]; -} U; - -#if CPU(BIG_ENDIAN) || CPU(MIDDLE_ENDIAN) -#define word0(x) (x)->L[0] -#define word1(x) (x)->L[1] -#else -#define word0(x) (x)->L[1] -#define word1(x) (x)->L[0] -#endif -#define dval(x) (x)->d - -/* The following definition of Storeinc is appropriate for MIPS processors. - * An alternative that might be better on some machines is - * *p++ = high << 16 | low & 0xffff; - */ -static ALWAYS_INLINE uint32_t* storeInc(uint32_t* p, uint16_t high, uint16_t low) -{ - uint16_t* p16 = reinterpret_cast<uint16_t*>(p); -#if CPU(BIG_ENDIAN) - p16[0] = high; - p16[1] = low; -#else - p16[1] = high; - p16[0] = low; -#endif - return p + 1; -} - -#define Exp_shift 20 -#define Exp_shift1 20 -#define Exp_msk1 0x100000 -#define Exp_msk11 0x100000 -#define Exp_mask 0x7ff00000 -#define P 53 -#define Bias 1023 -#define Emin (-1022) -#define Exp_1 0x3ff00000 -#define Exp_11 0x3ff00000 -#define Ebits 11 -#define Frac_mask 0xfffff -#define Frac_mask1 0xfffff -#define Ten_pmax 22 -#define Bletch 0x10 -#define Bndry_mask 0xfffff -#define Bndry_mask1 0xfffff -#define LSB 1 -#define Sign_bit 0x80000000 -#define Log2P 1 -#define Tiny0 0 -#define Tiny1 1 -#define Quick_max 14 -#define Int_max 14 - -#define rounded_product(a, b) a *= b -#define rounded_quotient(a, b) a /= b - -#define Big0 (Frac_mask1 | Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) -#define Big1 0xffffffff - -#if CPU(PPC64) || CPU(X86_64) -// FIXME: should we enable this on all 64-bit CPUs? -// 64-bit emulation provided by the compiler is likely to be slower than dtoa own code on 32-bit hardware. -#define USE_LONG_LONG -#endif - -struct BigInt { - BigInt() : sign(0) { } - int sign; - - void clear() - { - sign = 0; - m_words.clear(); - } - - size_t size() const - { - return m_words.size(); - } - - void resize(size_t s) - { - m_words.resize(s); - } - - uint32_t* words() - { - return m_words.data(); - } - - const uint32_t* words() const - { - return m_words.data(); - } - - void append(uint32_t w) - { - m_words.append(w); - } - - Vector<uint32_t, 16> m_words; -}; - -static void multadd(BigInt& b, int m, int a) /* multiply by m and add a */ -{ -#ifdef USE_LONG_LONG - unsigned long long carry; -#else - uint32_t carry; -#endif - - int wds = b.size(); - uint32_t* x = b.words(); - int i = 0; - carry = a; - do { -#ifdef USE_LONG_LONG - unsigned long long y = *x * (unsigned long long)m + carry; - carry = y >> 32; - *x++ = (uint32_t)y & 0xffffffffUL; -#else - uint32_t xi = *x; - uint32_t y = (xi & 0xffff) * m + carry; - uint32_t z = (xi >> 16) * m + (y >> 16); - carry = z >> 16; - *x++ = (z << 16) + (y & 0xffff); -#endif - } while (++i < wds); - - if (carry) - b.append((uint32_t)carry); -} - -static void s2b(BigInt& b, const char* s, int nd0, int nd, uint32_t y9) -{ - b.sign = 0; - b.resize(1); - b.words()[0] = y9; - - int i = 9; - if (9 < nd0) { - s += 9; - do { - multadd(b, 10, *s++ - '0'); - } while (++i < nd0); - s++; - } else - s += 10; - for (; i < nd; i++) - multadd(b, 10, *s++ - '0'); -} - -static int hi0bits(uint32_t x) -{ - int k = 0; - - if (!(x & 0xffff0000)) { - k = 16; - x <<= 16; - } - if (!(x & 0xff000000)) { - k += 8; - x <<= 8; - } - if (!(x & 0xf0000000)) { - k += 4; - x <<= 4; - } - if (!(x & 0xc0000000)) { - k += 2; - x <<= 2; - } - if (!(x & 0x80000000)) { - k++; - if (!(x & 0x40000000)) - return 32; - } - return k; -} - -static int lo0bits(uint32_t* y) -{ - int k; - uint32_t x = *y; - - if (x & 7) { - if (x & 1) - return 0; - if (x & 2) { - *y = x >> 1; - return 1; - } - *y = x >> 2; - return 2; - } - k = 0; - if (!(x & 0xffff)) { - k = 16; - x >>= 16; - } - if (!(x & 0xff)) { - k += 8; - x >>= 8; - } - if (!(x & 0xf)) { - k += 4; - x >>= 4; - } - if (!(x & 0x3)) { - k += 2; - x >>= 2; - } - if (!(x & 1)) { - k++; - x >>= 1; - if (!x) - return 32; - } - *y = x; - return k; -} - -static void i2b(BigInt& b, int i) -{ - b.sign = 0; - b.resize(1); - b.words()[0] = i; -} - -static void mult(BigInt& aRef, const BigInt& bRef) -{ - const BigInt* a = &aRef; - const BigInt* b = &bRef; - BigInt c; - int wa, wb, wc; - const uint32_t* x = 0; - const uint32_t* xa; - const uint32_t* xb; - const uint32_t* xae; - const uint32_t* xbe; - uint32_t* xc; - uint32_t* xc0; - uint32_t y; -#ifdef USE_LONG_LONG - unsigned long long carry, z; -#else - uint32_t carry, z; -#endif - - if (a->size() < b->size()) { - const BigInt* tmp = a; - a = b; - b = tmp; - } - - wa = a->size(); - wb = b->size(); - wc = wa + wb; - c.resize(wc); - - for (xc = c.words(), xa = xc + wc; xc < xa; xc++) - *xc = 0; - xa = a->words(); - xae = xa + wa; - xb = b->words(); - xbe = xb + wb; - xc0 = c.words(); -#ifdef USE_LONG_LONG - for (; xb < xbe; xc0++) { - if ((y = *xb++)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = *x++ * (unsigned long long)y + *xc + carry; - carry = z >> 32; - *xc++ = (uint32_t)z & 0xffffffffUL; - } while (x < xae); - *xc = (uint32_t)carry; - } - } -#else - for (; xb < xbe; xb++, xc0++) { - if ((y = *xb & 0xffff)) { - x = xa; - xc = xc0; - carry = 0; - do { - z = (*x & 0xffff) * y + (*xc & 0xffff) + carry; - carry = z >> 16; - uint32_t z2 = (*x++ >> 16) * y + (*xc >> 16) + carry; - carry = z2 >> 16; - xc = storeInc(xc, z2, z); - } while (x < xae); - *xc = carry; - } - if ((y = *xb >> 16)) { - x = xa; - xc = xc0; - carry = 0; - uint32_t z2 = *xc; - do { - z = (*x & 0xffff) * y + (*xc >> 16) + carry; - carry = z >> 16; - xc = storeInc(xc, z, z2); - z2 = (*x++ >> 16) * y + (*xc & 0xffff) + carry; - carry = z2 >> 16; - } while (x < xae); - *xc = z2; - } - } -#endif - for (xc0 = c.words(), xc = xc0 + wc; wc > 0 && !*--xc; --wc) { } - c.resize(wc); - aRef = c; -} - -struct P5Node : Noncopyable { - BigInt val; - P5Node* next; -}; - -static P5Node* p5s; -static int p5sCount; - -static ALWAYS_INLINE void pow5mult(BigInt& b, int k) -{ - static int p05[3] = { 5, 25, 125 }; - - if (int i = k & 3) - multadd(b, p05[i - 1], 0); - - if (!(k >>= 2)) - return; - -#if ENABLE(JSC_MULTIPLE_THREADS) - s_dtoaP5Mutex->lock(); -#endif - P5Node* p5 = p5s; - - if (!p5) { - /* first time */ - p5 = new P5Node; - i2b(p5->val, 625); - p5->next = 0; - p5s = p5; - p5sCount = 1; - } - - int p5sCountLocal = p5sCount; -#if ENABLE(JSC_MULTIPLE_THREADS) - s_dtoaP5Mutex->unlock(); -#endif - int p5sUsed = 0; - - for (;;) { - if (k & 1) - mult(b, p5->val); - - if (!(k >>= 1)) - break; - - if (++p5sUsed == p5sCountLocal) { -#if ENABLE(JSC_MULTIPLE_THREADS) - s_dtoaP5Mutex->lock(); -#endif - if (p5sUsed == p5sCount) { - ASSERT(!p5->next); - p5->next = new P5Node; - p5->next->next = 0; - p5->next->val = p5->val; - mult(p5->next->val, p5->next->val); - ++p5sCount; - } - - p5sCountLocal = p5sCount; -#if ENABLE(JSC_MULTIPLE_THREADS) - s_dtoaP5Mutex->unlock(); -#endif - } - p5 = p5->next; - } -} - -static ALWAYS_INLINE void lshift(BigInt& b, int k) -{ - int n = k >> 5; - - int origSize = b.size(); - int n1 = n + origSize + 1; - - if (k &= 0x1f) - b.resize(b.size() + n + 1); - else - b.resize(b.size() + n); - - const uint32_t* srcStart = b.words(); - uint32_t* dstStart = b.words(); - const uint32_t* src = srcStart + origSize - 1; - uint32_t* dst = dstStart + n1 - 1; - if (k) { - uint32_t hiSubword = 0; - int s = 32 - k; - for (; src >= srcStart; --src) { - *dst-- = hiSubword | *src >> s; - hiSubword = *src << k; - } - *dst = hiSubword; - ASSERT(dst == dstStart + n); - - b.resize(origSize + n + !!b.words()[n1 - 1]); - } - else { - do { - *--dst = *src--; - } while (src >= srcStart); - } - for (dst = dstStart + n; dst != dstStart; ) - *--dst = 0; - - ASSERT(b.size() <= 1 || b.words()[b.size() - 1]); -} - -static int cmp(const BigInt& a, const BigInt& b) -{ - const uint32_t *xa, *xa0, *xb, *xb0; - int i, j; - - i = a.size(); - j = b.size(); - ASSERT(i <= 1 || a.words()[i - 1]); - ASSERT(j <= 1 || b.words()[j - 1]); - if (i -= j) - return i; - xa0 = a.words(); - xa = xa0 + j; - xb0 = b.words(); - xb = xb0 + j; - for (;;) { - if (*--xa != *--xb) - return *xa < *xb ? -1 : 1; - if (xa <= xa0) - break; - } - return 0; -} - -static ALWAYS_INLINE void diff(BigInt& c, const BigInt& aRef, const BigInt& bRef) -{ - const BigInt* a = &aRef; - const BigInt* b = &bRef; - int i, wa, wb; - uint32_t* xc; - - i = cmp(*a, *b); - if (!i) { - c.sign = 0; - c.resize(1); - c.words()[0] = 0; - return; - } - if (i < 0) { - const BigInt* tmp = a; - a = b; - b = tmp; - i = 1; - } else - i = 0; - - wa = a->size(); - const uint32_t* xa = a->words(); - const uint32_t* xae = xa + wa; - wb = b->size(); - const uint32_t* xb = b->words(); - const uint32_t* xbe = xb + wb; - - c.resize(wa); - c.sign = i; - xc = c.words(); -#ifdef USE_LONG_LONG - unsigned long long borrow = 0; - do { - unsigned long long y = (unsigned long long)*xa++ - *xb++ - borrow; - borrow = y >> 32 & (uint32_t)1; - *xc++ = (uint32_t)y & 0xffffffffUL; - } while (xb < xbe); - while (xa < xae) { - unsigned long long y = *xa++ - borrow; - borrow = y >> 32 & (uint32_t)1; - *xc++ = (uint32_t)y & 0xffffffffUL; - } -#else - uint32_t borrow = 0; - do { - uint32_t y = (*xa & 0xffff) - (*xb & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - uint32_t z = (*xa++ >> 16) - (*xb++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - xc = storeInc(xc, z, y); - } while (xb < xbe); - while (xa < xae) { - uint32_t y = (*xa & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - uint32_t z = (*xa++ >> 16) - borrow; - borrow = (z & 0x10000) >> 16; - xc = storeInc(xc, z, y); - } -#endif - while (!*--xc) - wa--; - c.resize(wa); -} - -static double ulp(U *x) -{ - register int32_t L; - U u; - - L = (word0(x) & Exp_mask) - (P - 1) * Exp_msk1; - word0(&u) = L; - word1(&u) = 0; - return dval(&u); -} - -static double b2d(const BigInt& a, int* e) -{ - const uint32_t* xa; - const uint32_t* xa0; - uint32_t w; - uint32_t y; - uint32_t z; - int k; - U d; - -#define d0 word0(&d) -#define d1 word1(&d) - - xa0 = a.words(); - xa = xa0 + a.size(); - y = *--xa; - ASSERT(y); - k = hi0bits(y); - *e = 32 - k; - if (k < Ebits) { - d0 = Exp_1 | (y >> (Ebits - k)); - w = xa > xa0 ? *--xa : 0; - d1 = (y << (32 - Ebits + k)) | (w >> (Ebits - k)); - goto returnD; - } - z = xa > xa0 ? *--xa : 0; - if (k -= Ebits) { - d0 = Exp_1 | (y << k) | (z >> (32 - k)); - y = xa > xa0 ? *--xa : 0; - d1 = (z << k) | (y >> (32 - k)); - } else { - d0 = Exp_1 | y; - d1 = z; - } -returnD: -#undef d0 -#undef d1 - return dval(&d); -} - -static ALWAYS_INLINE void d2b(BigInt& b, U* d, int* e, int* bits) -{ - int de, k; - uint32_t* x; - uint32_t y, z; - int i; -#define d0 word0(d) -#define d1 word1(d) - - b.sign = 0; - b.resize(1); - x = b.words(); - - z = d0 & Frac_mask; - d0 &= 0x7fffffff; /* clear sign bit, which we ignore */ - if ((de = (int)(d0 >> Exp_shift))) - z |= Exp_msk1; - if ((y = d1)) { - if ((k = lo0bits(&y))) { - x[0] = y | (z << (32 - k)); - z >>= k; - } else - x[0] = y; - if (z) { - b.resize(2); - x[1] = z; - } - - i = b.size(); - } else { - k = lo0bits(&z); - x[0] = z; - i = 1; - b.resize(1); - k += 32; - } - if (de) { - *e = de - Bias - (P - 1) + k; - *bits = P - k; - } else { - *e = de - Bias - (P - 1) + 1 + k; - *bits = (32 * i) - hi0bits(x[i - 1]); - } -} -#undef d0 -#undef d1 - -static double ratio(const BigInt& a, const BigInt& b) -{ - U da, db; - int k, ka, kb; - - dval(&da) = b2d(a, &ka); - dval(&db) = b2d(b, &kb); - k = ka - kb + 32 * (a.size() - b.size()); - if (k > 0) - word0(&da) += k * Exp_msk1; - else { - k = -k; - word0(&db) += k * Exp_msk1; - } - return dval(&da) / dval(&db); -} - -static const double tens[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, - 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, - 1e20, 1e21, 1e22 -}; - -static const double bigtens[] = { 1e16, 1e32, 1e64, 1e128, 1e256 }; -static const double tinytens[] = { 1e-16, 1e-32, 1e-64, 1e-128, - 9007199254740992. * 9007199254740992.e-256 - /* = 2^106 * 1e-256 */ -}; - -/* The factor of 2^53 in tinytens[4] helps us avoid setting the underflow */ -/* flag unnecessarily. It leads to a song and dance at the end of strtod. */ -#define Scale_Bit 0x10 -#define n_bigtens 5 - -double strtod(const char* s00, char** se) -{ - int scale; - int bb2, bb5, bbe, bd2, bd5, bbbits, bs2, c, dsign, - e, e1, esign, i, j, k, nd, nd0, nf, nz, nz0, sign; - const char *s, *s0, *s1; - double aadj, aadj1; - U aadj2, adj, rv, rv0; - int32_t L; - uint32_t y, z; - BigInt bb, bb1, bd, bd0, bs, delta; - - sign = nz0 = nz = 0; - dval(&rv) = 0; - for (s = s00; ; s++) { - switch (*s) { - case '-': - sign = 1; - /* no break */ - case '+': - if (*++s) - goto break2; - /* no break */ - case 0: - goto ret0; - case '\t': - case '\n': - case '\v': - case '\f': - case '\r': - case ' ': - continue; - default: - goto break2; - } - } -break2: - if (*s == '0') { - nz0 = 1; - while (*++s == '0') { } - if (!*s) - goto ret; - } - s0 = s; - y = z = 0; - for (nd = nf = 0; (c = *s) >= '0' && c <= '9'; nd++, s++) - if (nd < 9) - y = (10 * y) + c - '0'; - else if (nd < 16) - z = (10 * z) + c - '0'; - nd0 = nd; - if (c == '.') { - c = *++s; - if (!nd) { - for (; c == '0'; c = *++s) - nz++; - if (c > '0' && c <= '9') { - s0 = s; - nf += nz; - nz = 0; - goto haveDig; - } - goto digDone; - } - for (; c >= '0' && c <= '9'; c = *++s) { -haveDig: - nz++; - if (c -= '0') { - nf += nz; - for (i = 1; i < nz; i++) - if (nd++ < 9) - y *= 10; - else if (nd <= DBL_DIG + 1) - z *= 10; - if (nd++ < 9) - y = (10 * y) + c; - else if (nd <= DBL_DIG + 1) - z = (10 * z) + c; - nz = 0; - } - } - } -digDone: - e = 0; - if (c == 'e' || c == 'E') { - if (!nd && !nz && !nz0) - goto ret0; - s00 = s; - esign = 0; - switch (c = *++s) { - case '-': - esign = 1; - case '+': - c = *++s; - } - if (c >= '0' && c <= '9') { - while (c == '0') - c = *++s; - if (c > '0' && c <= '9') { - L = c - '0'; - s1 = s; - while ((c = *++s) >= '0' && c <= '9') - L = (10 * L) + c - '0'; - if (s - s1 > 8 || L > 19999) - /* Avoid confusion from exponents - * so large that e might overflow. - */ - e = 19999; /* safe for 16 bit ints */ - else - e = (int)L; - if (esign) - e = -e; - } else - e = 0; - } else - s = s00; - } - if (!nd) { - if (!nz && !nz0) { -ret0: - s = s00; - sign = 0; - } - goto ret; - } - e1 = e -= nf; - - /* Now we have nd0 digits, starting at s0, followed by a - * decimal point, followed by nd-nd0 digits. The number we're - * after is the integer represented by those digits times - * 10**e */ - - if (!nd0) - nd0 = nd; - k = nd < DBL_DIG + 1 ? nd : DBL_DIG + 1; - dval(&rv) = y; - if (k > 9) - dval(&rv) = tens[k - 9] * dval(&rv) + z; - if (nd <= DBL_DIG) { - if (!e) - goto ret; - if (e > 0) { - if (e <= Ten_pmax) { - /* rv = */ rounded_product(dval(&rv), tens[e]); - goto ret; - } - i = DBL_DIG - nd; - if (e <= Ten_pmax + i) { - /* A fancier test would sometimes let us do - * this for larger i values. - */ - e -= i; - dval(&rv) *= tens[i]; - /* rv = */ rounded_product(dval(&rv), tens[e]); - goto ret; - } - } else if (e >= -Ten_pmax) { - /* rv = */ rounded_quotient(dval(&rv), tens[-e]); - goto ret; - } - } - e1 += nd - k; - - scale = 0; - - /* Get starting approximation = rv * 10**e1 */ - - if (e1 > 0) { - if ((i = e1 & 15)) - dval(&rv) *= tens[i]; - if (e1 &= ~15) { - if (e1 > DBL_MAX_10_EXP) { -ovfl: -#if HAVE(ERRNO_H) - errno = ERANGE; -#endif - /* Can't trust HUGE_VAL */ - word0(&rv) = Exp_mask; - word1(&rv) = 0; - goto ret; - } - e1 >>= 4; - for (j = 0; e1 > 1; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= bigtens[j]; - /* The last multiplication could overflow. */ - word0(&rv) -= P * Exp_msk1; - dval(&rv) *= bigtens[j]; - if ((z = word0(&rv) & Exp_mask) > Exp_msk1 * (DBL_MAX_EXP + Bias - P)) - goto ovfl; - if (z > Exp_msk1 * (DBL_MAX_EXP + Bias - 1 - P)) { - /* set to largest number */ - /* (Can't trust DBL_MAX) */ - word0(&rv) = Big0; - word1(&rv) = Big1; - } else - word0(&rv) += P * Exp_msk1; - } - } else if (e1 < 0) { - e1 = -e1; - if ((i = e1 & 15)) - dval(&rv) /= tens[i]; - if (e1 >>= 4) { - if (e1 >= 1 << n_bigtens) - goto undfl; - if (e1 & Scale_Bit) - scale = 2 * P; - for (j = 0; e1 > 0; j++, e1 >>= 1) - if (e1 & 1) - dval(&rv) *= tinytens[j]; - if (scale && (j = (2 * P) + 1 - ((word0(&rv) & Exp_mask) >> Exp_shift)) > 0) { - /* scaled rv is denormal; clear j low bits */ - if (j >= 32) { - word1(&rv) = 0; - if (j >= 53) - word0(&rv) = (P + 2) * Exp_msk1; - else - word0(&rv) &= 0xffffffff << (j - 32); - } else - word1(&rv) &= 0xffffffff << j; - } - if (!dval(&rv)) { -undfl: - dval(&rv) = 0.; -#if HAVE(ERRNO_H) - errno = ERANGE; -#endif - goto ret; - } - } - } - - /* Now the hard part -- adjusting rv to the correct value.*/ - - /* Put digits into bd: true value = bd * 10^e */ - - s2b(bd0, s0, nd0, nd, y); - - for (;;) { - bd = bd0; - d2b(bb, &rv, &bbe, &bbbits); /* rv = bb * 2^bbe */ - i2b(bs, 1); - - if (e >= 0) { - bb2 = bb5 = 0; - bd2 = bd5 = e; - } else { - bb2 = bb5 = -e; - bd2 = bd5 = 0; - } - if (bbe >= 0) - bb2 += bbe; - else - bd2 -= bbe; - bs2 = bb2; - j = bbe - scale; - i = j + bbbits - 1; /* logb(rv) */ - if (i < Emin) /* denormal */ - j += P - Emin; - else - j = P + 1 - bbbits; - bb2 += j; - bd2 += j; - bd2 += scale; - i = bb2 < bd2 ? bb2 : bd2; - if (i > bs2) - i = bs2; - if (i > 0) { - bb2 -= i; - bd2 -= i; - bs2 -= i; - } - if (bb5 > 0) { - pow5mult(bs, bb5); - mult(bb, bs); - } - if (bb2 > 0) - lshift(bb, bb2); - if (bd5 > 0) - pow5mult(bd, bd5); - if (bd2 > 0) - lshift(bd, bd2); - if (bs2 > 0) - lshift(bs, bs2); - diff(delta, bb, bd); - dsign = delta.sign; - delta.sign = 0; - i = cmp(delta, bs); - - if (i < 0) { - /* Error is less than half an ulp -- check for - * special case of mantissa a power of two. - */ - if (dsign || word1(&rv) || word0(&rv) & Bndry_mask - || (word0(&rv) & Exp_mask) <= (2 * P + 1) * Exp_msk1 - ) { - break; - } - if (!delta.words()[0] && delta.size() <= 1) { - /* exact result */ - break; - } - lshift(delta, Log2P); - if (cmp(delta, bs) > 0) - goto dropDown; - break; - } - if (!i) { - /* exactly half-way between */ - if (dsign) { - if ((word0(&rv) & Bndry_mask1) == Bndry_mask1 - && word1(&rv) == ( - (scale && (y = word0(&rv) & Exp_mask) <= 2 * P * Exp_msk1) - ? (0xffffffff & (0xffffffff << (2 * P + 1 - (y >> Exp_shift)))) : - 0xffffffff)) { - /*boundary case -- increment exponent*/ - word0(&rv) = (word0(&rv) & Exp_mask) + Exp_msk1; - word1(&rv) = 0; - dsign = 0; - break; - } - } else if (!(word0(&rv) & Bndry_mask) && !word1(&rv)) { -dropDown: - /* boundary case -- decrement exponent */ - if (scale) { - L = word0(&rv) & Exp_mask; - if (L <= (2 * P + 1) * Exp_msk1) { - if (L > (P + 2) * Exp_msk1) - /* round even ==> */ - /* accept rv */ - break; - /* rv = smallest denormal */ - goto undfl; - } - } - L = (word0(&rv) & Exp_mask) - Exp_msk1; - word0(&rv) = L | Bndry_mask1; - word1(&rv) = 0xffffffff; - break; - } - if (!(word1(&rv) & LSB)) - break; - if (dsign) - dval(&rv) += ulp(&rv); - else { - dval(&rv) -= ulp(&rv); - if (!dval(&rv)) - goto undfl; - } - dsign = 1 - dsign; - break; - } - if ((aadj = ratio(delta, bs)) <= 2.) { - if (dsign) - aadj = aadj1 = 1.; - else if (word1(&rv) || word0(&rv) & Bndry_mask) { - if (word1(&rv) == Tiny1 && !word0(&rv)) - goto undfl; - aadj = 1.; - aadj1 = -1.; - } else { - /* special case -- power of FLT_RADIX to be */ - /* rounded down... */ - - if (aadj < 2. / FLT_RADIX) - aadj = 1. / FLT_RADIX; - else - aadj *= 0.5; - aadj1 = -aadj; - } - } else { - aadj *= 0.5; - aadj1 = dsign ? aadj : -aadj; - } - y = word0(&rv) & Exp_mask; - - /* Check for overflow */ - - if (y == Exp_msk1 * (DBL_MAX_EXP + Bias - 1)) { - dval(&rv0) = dval(&rv); - word0(&rv) -= P * Exp_msk1; - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - if ((word0(&rv) & Exp_mask) >= Exp_msk1 * (DBL_MAX_EXP + Bias - P)) { - if (word0(&rv0) == Big0 && word1(&rv0) == Big1) - goto ovfl; - word0(&rv) = Big0; - word1(&rv) = Big1; - goto cont; - } - word0(&rv) += P * Exp_msk1; - } else { - if (scale && y <= 2 * P * Exp_msk1) { - if (aadj <= 0x7fffffff) { - if ((z = (uint32_t)aadj) <= 0) - z = 1; - aadj = z; - aadj1 = dsign ? aadj : -aadj; - } - dval(&aadj2) = aadj1; - word0(&aadj2) += (2 * P + 1) * Exp_msk1 - y; - aadj1 = dval(&aadj2); - } - adj.d = aadj1 * ulp(&rv); - dval(&rv) += adj.d; - } - z = word0(&rv) & Exp_mask; - if (!scale && y == z) { - /* Can we stop now? */ - L = (int32_t)aadj; - aadj -= L; - /* The tolerances below are conservative. */ - if (dsign || word1(&rv) || word0(&rv) & Bndry_mask) { - if (aadj < .4999999 || aadj > .5000001) - break; - } else if (aadj < .4999999 / FLT_RADIX) - break; - } -cont: - {} - } - if (scale) { - word0(&rv0) = Exp_1 - 2 * P * Exp_msk1; - word1(&rv0) = 0; - dval(&rv) *= dval(&rv0); -#if HAVE(ERRNO_H) - /* try to avoid the bug of testing an 8087 register value */ - if (!word0(&rv) && !word1(&rv)) - errno = ERANGE; -#endif - } -ret: - if (se) - *se = const_cast<char*>(s); - return sign ? -dval(&rv) : dval(&rv); -} - -static ALWAYS_INLINE int quorem(BigInt& b, BigInt& S) -{ - size_t n; - uint32_t* bx; - uint32_t* bxe; - uint32_t q; - uint32_t* sx; - uint32_t* sxe; -#ifdef USE_LONG_LONG - unsigned long long borrow, carry, y, ys; -#else - uint32_t borrow, carry, y, ys; - uint32_t si, z, zs; -#endif - ASSERT(b.size() <= 1 || b.words()[b.size() - 1]); - ASSERT(S.size() <= 1 || S.words()[S.size() - 1]); - - n = S.size(); - ASSERT_WITH_MESSAGE(b.size() <= n, "oversize b in quorem"); - if (b.size() < n) - return 0; - sx = S.words(); - sxe = sx + --n; - bx = b.words(); - bxe = bx + n; - q = *bxe / (*sxe + 1); /* ensure q <= true quotient */ - ASSERT_WITH_MESSAGE(q <= 9, "oversized quotient in quorem"); - if (q) { - borrow = 0; - carry = 0; - do { -#ifdef USE_LONG_LONG - ys = *sx++ * (unsigned long long)q + carry; - carry = ys >> 32; - y = *bx - (ys & 0xffffffffUL) - borrow; - borrow = y >> 32 & (uint32_t)1; - *bx++ = (uint32_t)y & 0xffffffffUL; -#else - si = *sx++; - ys = (si & 0xffff) * q + carry; - zs = (si >> 16) * q + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - bx = storeInc(bx, z, y); -#endif - } while (sx <= sxe); - if (!*bxe) { - bx = b.words(); - while (--bxe > bx && !*bxe) - --n; - b.resize(n); - } - } - if (cmp(b, S) >= 0) { - q++; - borrow = 0; - carry = 0; - bx = b.words(); - sx = S.words(); - do { -#ifdef USE_LONG_LONG - ys = *sx++ + carry; - carry = ys >> 32; - y = *bx - (ys & 0xffffffffUL) - borrow; - borrow = y >> 32 & (uint32_t)1; - *bx++ = (uint32_t)y & 0xffffffffUL; -#else - si = *sx++; - ys = (si & 0xffff) + carry; - zs = (si >> 16) + (ys >> 16); - carry = zs >> 16; - y = (*bx & 0xffff) - (ys & 0xffff) - borrow; - borrow = (y & 0x10000) >> 16; - z = (*bx >> 16) - (zs & 0xffff) - borrow; - borrow = (z & 0x10000) >> 16; - bx = storeInc(bx, z, y); -#endif - } while (sx <= sxe); - bx = b.words(); - bxe = bx + n; - if (!*bxe) { - while (--bxe > bx && !*bxe) - --n; - b.resize(n); - } - } - return q; -} - -/* dtoa for IEEE arithmetic (dmg): convert double to ASCII string. - * - * Inspired by "How to Print Floating-Point Numbers Accurately" by - * Guy L. Steele, Jr. and Jon L. White [Proc. ACM SIGPLAN '90, pp. 112-126]. - * - * Modifications: - * 1. Rather than iterating, we use a simple numeric overestimate - * to determine k = floor(log10(d)). We scale relevant - * quantities using O(log2(k)) rather than O(k) multiplications. - * 2. For some modes > 2 (corresponding to ecvt and fcvt), we don't - * try to generate digits strictly left to right. Instead, we - * compute with fewer bits and propagate the carry if necessary - * when rounding the final digit up. This is often faster. - * 3. Under the assumption that input will be rounded nearest, - * mode 0 renders 1e23 as 1e23 rather than 9.999999999999999e22. - * That is, we allow equality in stopping tests when the - * round-nearest rule will give the same floating-point value - * as would satisfaction of the stopping test with strict - * inequality. - * 4. We remove common factors of powers of 2 from relevant - * quantities. - * 5. When converting floating-point integers less than 1e16, - * we use floating-point arithmetic rather than resorting - * to multiple-precision integers. - * 6. When asked to produce fewer than 15 digits, we first try - * to get by with floating-point arithmetic; we resort to - * multiple-precision integer arithmetic only if we cannot - * guarantee that the floating-point calculation has given - * the correctly rounded result. For k requested digits and - * "uniformly" distributed input, the probability is - * something like 10^(k-15) that we must resort to the int32_t - * calculation. - * - * Note: 'leftright' translates to 'generate shortest possible string'. - */ -template<bool roundingNone, bool roundingSignificantFigures, bool roundingDecimalPlaces, bool leftright> -void dtoa(DtoaBuffer result, double dd, int ndigits, bool& signOut, int& exponentOut, unsigned& precisionOut) -{ - // Exactly one rounding mode must be specified. - ASSERT(roundingNone + roundingSignificantFigures + roundingDecimalPlaces == 1); - // roundingNone only allowed (only sensible?) with leftright set. - ASSERT(!roundingNone || leftright); - - ASSERT(!isnan(dd) && !isinf(dd)); - - int bbits, b2, b5, be, dig, i, ieps, ilim = 0, ilim0, ilim1 = 0, - j, j1, k, k0, k_check, m2, m5, s2, s5, - spec_case; - int32_t L; - int denorm; - uint32_t x; - BigInt b, delta, mlo, mhi, S; - U d2, eps, u; - double ds; - char* s; - char* s0; - - u.d = dd; - - /* Infinity or NaN */ - ASSERT((word0(&u) & Exp_mask) != Exp_mask); - - // JavaScript toString conversion treats -0 as 0. - if (!dval(&u)) { - signOut = false; - exponentOut = 0; - precisionOut = 1; - result[0] = '0'; - result[1] = '\0'; - return; - } - - if (word0(&u) & Sign_bit) { - signOut = true; - word0(&u) &= ~Sign_bit; // clear sign bit - } else - signOut = false; - - d2b(b, &u, &be, &bbits); - if ((i = (int)(word0(&u) >> Exp_shift1 & (Exp_mask >> Exp_shift1)))) { - dval(&d2) = dval(&u); - word0(&d2) &= Frac_mask1; - word0(&d2) |= Exp_11; - - /* log(x) ~=~ log(1.5) + (x-1.5)/1.5 - * log10(x) = log(x) / log(10) - * ~=~ log(1.5)/log(10) + (x-1.5)/(1.5*log(10)) - * log10(d) = (i-Bias)*log(2)/log(10) + log10(d2) - * - * This suggests computing an approximation k to log10(d) by - * - * k = (i - Bias)*0.301029995663981 - * + ( (d2-1.5)*0.289529654602168 + 0.176091259055681 ); - * - * We want k to be too large rather than too small. - * The error in the first-order Taylor series approximation - * is in our favor, so we just round up the constant enough - * to compensate for any error in the multiplication of - * (i - Bias) by 0.301029995663981; since |i - Bias| <= 1077, - * and 1077 * 0.30103 * 2^-52 ~=~ 7.2e-14, - * adding 1e-13 to the constant term more than suffices. - * Hence we adjust the constant term to 0.1760912590558. - * (We could get a more accurate k by invoking log10, - * but this is probably not worthwhile.) - */ - - i -= Bias; - denorm = 0; - } else { - /* d is denormalized */ - - i = bbits + be + (Bias + (P - 1) - 1); - x = (i > 32) ? (word0(&u) << (64 - i)) | (word1(&u) >> (i - 32)) - : word1(&u) << (32 - i); - dval(&d2) = x; - word0(&d2) -= 31 * Exp_msk1; /* adjust exponent */ - i -= (Bias + (P - 1) - 1) + 1; - denorm = 1; - } - ds = (dval(&d2) - 1.5) * 0.289529654602168 + 0.1760912590558 + (i * 0.301029995663981); - k = (int)ds; - if (ds < 0. && ds != k) - k--; /* want k = floor(ds) */ - k_check = 1; - if (k >= 0 && k <= Ten_pmax) { - if (dval(&u) < tens[k]) - k--; - k_check = 0; - } - j = bbits - i - 1; - if (j >= 0) { - b2 = 0; - s2 = j; - } else { - b2 = -j; - s2 = 0; - } - if (k >= 0) { - b5 = 0; - s5 = k; - s2 += k; - } else { - b2 -= k; - b5 = -k; - s5 = 0; - } - - if (roundingNone) { - ilim = ilim1 = -1; - i = 18; - ndigits = 0; - } - if (roundingSignificantFigures) { - if (ndigits <= 0) - ndigits = 1; - ilim = ilim1 = i = ndigits; - } - if (roundingDecimalPlaces) { - i = ndigits + k + 1; - ilim = i; - ilim1 = i - 1; - if (i <= 0) - i = 1; - } - - s = s0 = result; - - if (ilim >= 0 && ilim <= Quick_max) { - /* Try to get by with floating-point arithmetic. */ - - i = 0; - dval(&d2) = dval(&u); - k0 = k; - ilim0 = ilim; - ieps = 2; /* conservative */ - if (k > 0) { - ds = tens[k & 0xf]; - j = k >> 4; - if (j & Bletch) { - /* prevent overflows */ - j &= Bletch - 1; - dval(&u) /= bigtens[n_bigtens - 1]; - ieps++; - } - for (; j; j >>= 1, i++) { - if (j & 1) { - ieps++; - ds *= bigtens[i]; - } - } - dval(&u) /= ds; - } else if ((j1 = -k)) { - dval(&u) *= tens[j1 & 0xf]; - for (j = j1 >> 4; j; j >>= 1, i++) { - if (j & 1) { - ieps++; - dval(&u) *= bigtens[i]; - } - } - } - if (k_check && dval(&u) < 1. && ilim > 0) { - if (ilim1 <= 0) - goto fastFailed; - ilim = ilim1; - k--; - dval(&u) *= 10.; - ieps++; - } - dval(&eps) = (ieps * dval(&u)) + 7.; - word0(&eps) -= (P - 1) * Exp_msk1; - if (!ilim) { - S.clear(); - mhi.clear(); - dval(&u) -= 5.; - if (dval(&u) > dval(&eps)) - goto oneDigit; - if (dval(&u) < -dval(&eps)) - goto noDigits; - goto fastFailed; - } - if (leftright) { - /* Use Steele & White method of only - * generating digits needed. - */ - dval(&eps) = (0.5 / tens[ilim - 1]) - dval(&eps); - for (i = 0;;) { - L = (long int)dval(&u); - dval(&u) -= L; - *s++ = '0' + (int)L; - if (dval(&u) < dval(&eps)) - goto ret; - if (1. - dval(&u) < dval(&eps)) - goto bumpUp; - if (++i >= ilim) - break; - dval(&eps) *= 10.; - dval(&u) *= 10.; - } - } else { - /* Generate ilim digits, then fix them up. */ - dval(&eps) *= tens[ilim - 1]; - for (i = 1;; i++, dval(&u) *= 10.) { - L = (int32_t)(dval(&u)); - if (!(dval(&u) -= L)) - ilim = i; - *s++ = '0' + (int)L; - if (i == ilim) { - if (dval(&u) > 0.5 + dval(&eps)) - goto bumpUp; - if (dval(&u) < 0.5 - dval(&eps)) { - while (*--s == '0') { } - s++; - goto ret; - } - break; - } - } - } -fastFailed: - s = s0; - dval(&u) = dval(&d2); - k = k0; - ilim = ilim0; - } - - /* Do we have a "small" integer? */ - - if (be >= 0 && k <= Int_max) { - /* Yes. */ - ds = tens[k]; - if (ndigits < 0 && ilim <= 0) { - S.clear(); - mhi.clear(); - if (ilim < 0 || dval(&u) <= 5 * ds) - goto noDigits; - goto oneDigit; - } - for (i = 1;; i++, dval(&u) *= 10.) { - L = (int32_t)(dval(&u) / ds); - dval(&u) -= L * ds; - *s++ = '0' + (int)L; - if (!dval(&u)) { - break; - } - if (i == ilim) { - dval(&u) += dval(&u); - if (dval(&u) > ds || (dval(&u) == ds && (L & 1))) { -bumpUp: - while (*--s == '9') - if (s == s0) { - k++; - *s = '0'; - break; - } - ++*s++; - } - break; - } - } - goto ret; - } - - m2 = b2; - m5 = b5; - mhi.clear(); - mlo.clear(); - if (leftright) { - i = denorm ? be + (Bias + (P - 1) - 1 + 1) : 1 + P - bbits; - b2 += i; - s2 += i; - i2b(mhi, 1); - } - if (m2 > 0 && s2 > 0) { - i = m2 < s2 ? m2 : s2; - b2 -= i; - m2 -= i; - s2 -= i; - } - if (b5 > 0) { - if (leftright) { - if (m5 > 0) { - pow5mult(mhi, m5); - mult(b, mhi); - } - if ((j = b5 - m5)) - pow5mult(b, j); - } else - pow5mult(b, b5); - } - i2b(S, 1); - if (s5 > 0) - pow5mult(S, s5); - - /* Check for special case that d is a normalized power of 2. */ - - spec_case = 0; - if ((roundingNone || leftright) && (!word1(&u) && !(word0(&u) & Bndry_mask) && word0(&u) & (Exp_mask & ~Exp_msk1))) { - /* The special case */ - b2 += Log2P; - s2 += Log2P; - spec_case = 1; - } - - /* Arrange for convenient computation of quotients: - * shift left if necessary so divisor has 4 leading 0 bits. - * - * Perhaps we should just compute leading 28 bits of S once - * and for all and pass them and a shift to quorem, so it - * can do shifts and ors to compute the numerator for q. - */ - if ((i = ((s5 ? 32 - hi0bits(S.words()[S.size() - 1]) : 1) + s2) & 0x1f)) - i = 32 - i; - if (i > 4) { - i -= 4; - b2 += i; - m2 += i; - s2 += i; - } else if (i < 4) { - i += 28; - b2 += i; - m2 += i; - s2 += i; - } - if (b2 > 0) - lshift(b, b2); - if (s2 > 0) - lshift(S, s2); - if (k_check) { - if (cmp(b, S) < 0) { - k--; - multadd(b, 10, 0); /* we botched the k estimate */ - if (leftright) - multadd(mhi, 10, 0); - ilim = ilim1; - } - } - if (ilim <= 0 && roundingDecimalPlaces) { - if (ilim < 0) - goto noDigits; - multadd(S, 5, 0); - // For IEEE-754 unbiased rounding this check should be <=, such that 0.5 would flush to zero. - if (cmp(b, S) < 0) - goto noDigits; - goto oneDigit; - } - if (leftright) { - if (m2 > 0) - lshift(mhi, m2); - - /* Compute mlo -- check for special case - * that d is a normalized power of 2. - */ - - mlo = mhi; - if (spec_case) - lshift(mhi, Log2P); - - for (i = 1;;i++) { - dig = quorem(b, S) + '0'; - /* Do we yet have the shortest decimal string - * that will round to d? - */ - j = cmp(b, mlo); - diff(delta, S, mhi); - j1 = delta.sign ? 1 : cmp(b, delta); -#ifdef DTOA_ROUND_BIASED - if (j < 0 || !j) { -#else - // FIXME: ECMA-262 specifies that equidistant results round away from - // zero, which probably means we shouldn't be on the unbiased code path - // (the (word1(&u) & 1) clause is looking highly suspicious). I haven't - // yet understood this code well enough to make the call, but we should - // probably be enabling DTOA_ROUND_BIASED. I think the interesting corner - // case to understand is probably "Math.pow(0.5, 24).toString()". - // I believe this value is interesting because I think it is precisely - // representable in binary floating point, and its decimal representation - // has a single digit that Steele & White reduction can remove, with the - // value 5 (thus equidistant from the next numbers above and below). - // We produce the correct answer using either codepath, and I don't as - // yet understand why. :-) - if (!j1 && !(word1(&u) & 1)) { - if (dig == '9') - goto round9up; - if (j > 0) - dig++; - *s++ = dig; - goto ret; - } - if (j < 0 || (!j && !(word1(&u) & 1))) { -#endif - if ((b.words()[0] || b.size() > 1) && (j1 > 0)) { - lshift(b, 1); - j1 = cmp(b, S); - // For IEEE-754 round-to-even, this check should be (j1 > 0 || (!j1 && (dig & 1))), - // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should - // be rounded away from zero. - if (j1 >= 0) { - if (dig == '9') - goto round9up; - dig++; - } - } - *s++ = dig; - goto ret; - } - if (j1 > 0) { - if (dig == '9') { /* possible if i == 1 */ -round9up: - *s++ = '9'; - goto roundoff; - } - *s++ = dig + 1; - goto ret; - } - *s++ = dig; - if (i == ilim) - break; - multadd(b, 10, 0); - multadd(mlo, 10, 0); - multadd(mhi, 10, 0); - } - } else { - for (i = 1;; i++) { - *s++ = dig = quorem(b, S) + '0'; - if (!b.words()[0] && b.size() <= 1) - goto ret; - if (i >= ilim) - break; - multadd(b, 10, 0); - } - } - - /* Round off last digit */ - - lshift(b, 1); - j = cmp(b, S); - // For IEEE-754 round-to-even, this check should be (j > 0 || (!j && (dig & 1))), - // but ECMA-262 specifies that equidistant values (e.g. (.5).toFixed()) should - // be rounded away from zero. - if (j >= 0) { -roundoff: - while (*--s == '9') - if (s == s0) { - k++; - *s++ = '1'; - goto ret; - } - ++*s++; - } else { - while (*--s == '0') { } - s++; - } - goto ret; -noDigits: - exponentOut = 0; - precisionOut = 1; - result[0] = '0'; - result[1] = '\0'; - return; -oneDigit: - *s++ = '1'; - k++; - goto ret; -ret: - ASSERT(s > result); - *s = 0; - exponentOut = k; - precisionOut = s - result; -} - -void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& precision) -{ - // flags are roundingNone, leftright. - dtoa<true, false, false, true>(result, dd, 0, sign, exponent, precision); -} - -void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision) -{ - // flag is roundingSignificantFigures. - dtoa<false, true, false, false>(result, dd, ndigits, sign, exponent, precision); -} - -void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision) -{ - // flag is roundingDecimalPlaces. - dtoa<false, false, true, false>(result, dd, ndigits, sign, exponent, precision); -} - -static ALWAYS_INLINE void copyAsciiToUTF16(UChar* next, const char* src, unsigned size) -{ - for (unsigned i = 0; i < size; ++i) - *next++ = *src++; -} - -unsigned numberToString(double d, NumberToStringBuffer buffer) -{ - // Handle NaN and Infinity. - if (isnan(d) || isinf(d)) { - if (isnan(d)) { - copyAsciiToUTF16(buffer, "NaN", 3); - return 3; - } - if (d > 0) { - copyAsciiToUTF16(buffer, "Infinity", 8); - return 8; - } - copyAsciiToUTF16(buffer, "-Infinity", 9); - return 9; - } - - // Convert to decimal with rounding. - DecimalNumber number(d); - return number.exponent() >= -6 && number.exponent() < 21 - ? number.toStringDecimal(buffer, NumberToStringBufferLength) - : number.toStringExponential(buffer, NumberToStringBufferLength); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/dtoa.h b/JavaScriptCore/wtf/dtoa.h deleted file mode 100644 index 3924a1c..0000000 --- a/JavaScriptCore/wtf/dtoa.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2003, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_dtoa_h -#define WTF_dtoa_h - -#include <wtf/unicode/Unicode.h> - -namespace WTF { -class Mutex; - -extern WTF::Mutex* s_dtoaP5Mutex; - -// s00: input string. Must not be 0 and must be terminated by 0. -// se: *se will have the last consumed character position + 1. -double strtod(const char* s00, char** se); - -typedef char DtoaBuffer[80]; - -void dtoa(DtoaBuffer result, double dd, bool& sign, int& exponent, unsigned& precision); -void dtoaRoundSF(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision); -void dtoaRoundDP(DtoaBuffer result, double dd, int ndigits, bool& sign, int& exponent, unsigned& precision); - -// Size = 80 for sizeof(DtoaBuffer) + some sign bits, decimal point, 'e', exponent digits. -const unsigned NumberToStringBufferLength = 96; -typedef UChar NumberToStringBuffer[NumberToStringBufferLength]; -unsigned numberToString(double, NumberToStringBuffer); - -} // namespace WTF - -using WTF::NumberToStringBuffer; -using WTF::numberToString; - -#endif // WTF_dtoa_h diff --git a/JavaScriptCore/wtf/efl/MainThreadEfl.cpp b/JavaScriptCore/wtf/efl/MainThreadEfl.cpp deleted file mode 100644 index 8774d20..0000000 --- a/JavaScriptCore/wtf/efl/MainThreadEfl.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * Copyright (C) 2008 Diego Gonzalez - * Copyright (C) 2008 Kenneth Rohde Christiansen - * Copyright (C) 2009-2010 ProFUSION embedded systems - * Copyright (C) 2009-2010 Samsung Electronics - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include <Ecore.h> - -namespace WTF { - -void initializeMainThreadPlatform() -{ -} - -static Eina_Bool timeoutFired(void*) -{ - dispatchFunctionsFromMainThread(); - return ECORE_CALLBACK_CANCEL; -} - -void scheduleDispatchFunctionsOnMainThread() -{ - ecore_timer_add(0, timeoutFired, 0); -} - - -} diff --git a/JavaScriptCore/wtf/gobject/GOwnPtr.cpp b/JavaScriptCore/wtf/gobject/GOwnPtr.cpp deleted file mode 100644 index 8dcfb9e..0000000 --- a/JavaScriptCore/wtf/gobject/GOwnPtr.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2008 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "GOwnPtr.h" - -#if ENABLE(GLIB_SUPPORT) - -#include <gio/gio.h> -#include <glib.h> - -namespace WTF { - -template <> void freeOwnedGPtr<GError>(GError* ptr) -{ - if (ptr) - g_error_free(ptr); -} - -template <> void freeOwnedGPtr<GList>(GList* ptr) -{ - g_list_free(ptr); -} - -template <> void freeOwnedGPtr<GCond>(GCond* ptr) -{ - if (ptr) - g_cond_free(ptr); -} - -template <> void freeOwnedGPtr<GMutex>(GMutex* ptr) -{ - if (ptr) - g_mutex_free(ptr); -} - -template <> void freeOwnedGPtr<GPatternSpec>(GPatternSpec* ptr) -{ - if (ptr) - g_pattern_spec_free(ptr); -} - -template <> void freeOwnedGPtr<GDir>(GDir* ptr) -{ - if (ptr) - g_dir_close(ptr); -} - -template <> void freeOwnedGPtr<GFile>(GFile* ptr) -{ - if (ptr) - g_object_unref(ptr); -} -} // namespace WTF - -#endif // ENABLE(GLIB_SUPPORT) diff --git a/JavaScriptCore/wtf/gobject/GOwnPtr.h b/JavaScriptCore/wtf/gobject/GOwnPtr.h deleted file mode 100644 index cec3e43..0000000 --- a/JavaScriptCore/wtf/gobject/GOwnPtr.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2006, 2007 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora Ltd. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef GOwnPtr_h -#define GOwnPtr_h - -#if ENABLE(GLIB_SUPPORT) - -#include <algorithm> -#include <wtf/Assertions.h> -#include <wtf/Noncopyable.h> - -extern "C" void g_free(void*); - -namespace WTF { - -template <typename T> inline void freeOwnedGPtr(T* ptr); -template<> void freeOwnedGPtr<GError>(GError*); -template<> void freeOwnedGPtr<GList>(GList*); -template<> void freeOwnedGPtr<GCond>(GCond*); -template<> void freeOwnedGPtr<GMutex>(GMutex*); -template<> void freeOwnedGPtr<GPatternSpec>(GPatternSpec*); -template<> void freeOwnedGPtr<GDir>(GDir*); -template<> void freeOwnedGPtr<GFile>(GFile*); - -template <typename T> class GOwnPtr : public Noncopyable { -public: - explicit GOwnPtr(T* ptr = 0) : m_ptr(ptr) { } - ~GOwnPtr() { freeOwnedGPtr(m_ptr); } - - T* get() const { return m_ptr; } - T* release() - { - T* ptr = m_ptr; - m_ptr = 0; - return ptr; - } - - T*& outPtr() - { - ASSERT(!m_ptr); - return m_ptr; - } - - void set(T* ptr) - { - ASSERT(!ptr || m_ptr != ptr); - freeOwnedGPtr(m_ptr); - m_ptr = ptr; - } - - void clear() - { - T* ptr = m_ptr; - m_ptr = 0; - freeOwnedGPtr(ptr); - } - - T& operator*() const - { - ASSERT(m_ptr); - return *m_ptr; - } - - T* operator->() const - { - ASSERT(m_ptr); - return m_ptr; - } - - bool operator!() const { return !m_ptr; } - - // This conversion operator allows implicit conversion to bool but not to other integer types. - typedef T* GOwnPtr::*UnspecifiedBoolType; - operator UnspecifiedBoolType() const { return m_ptr ? &GOwnPtr::m_ptr : 0; } - - void swap(GOwnPtr& o) { std::swap(m_ptr, o.m_ptr); } - -private: - T* m_ptr; -}; - -template <typename T> inline void swap(GOwnPtr<T>& a, GOwnPtr<T>& b) -{ - a.swap(b); -} - -template <typename T, typename U> inline bool operator==(const GOwnPtr<T>& a, U* b) -{ - return a.get() == b; -} - -template <typename T, typename U> inline bool operator==(T* a, const GOwnPtr<U>& b) -{ - return a == b.get(); -} - -template <typename T, typename U> inline bool operator!=(const GOwnPtr<T>& a, U* b) -{ - return a.get() != b; -} - -template <typename T, typename U> inline bool operator!=(T* a, const GOwnPtr<U>& b) -{ - return a != b.get(); -} - -template <typename T> inline typename GOwnPtr<T>::PtrType getPtr(const GOwnPtr<T>& p) -{ - return p.get(); -} - -template <typename T> inline void freeOwnedGPtr(T* ptr) -{ - g_free(ptr); -} - -} // namespace WTF - -using WTF::GOwnPtr; - -#endif // ENABLE(GLIB_SUPPORT) - -#endif // GOwnPtr_h - diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp deleted file mode 100644 index 085684e..0000000 --- a/JavaScriptCore/wtf/gobject/GRefPtr.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2009 Martin Robinson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "config.h" -#include "GRefPtr.h" - -#if ENABLE(GLIB_SUPPORT) - -#include <glib.h> - -namespace WTF { - -template <> GHashTable* refPlatformPtr(GHashTable* ptr) -{ - if (ptr) - g_hash_table_ref(ptr); - return ptr; -} - -template <> void derefPlatformPtr(GHashTable* ptr) -{ - g_hash_table_unref(ptr); -} - -#if GLIB_CHECK_VERSION(2, 24, 0) -template <> GVariant* refPlatformPtr(GVariant* ptr) -{ - if (ptr) - g_variant_ref(ptr); - return ptr; -} - -template <> void derefPlatformPtr(GVariant* ptr) -{ - g_variant_unref(ptr); -} - -#else - -// We do this so that we can avoid including the glib.h header in GRefPtr.h. -typedef struct _GVariant { - bool fake; -} GVariant; - -template <> GVariant* refPlatformPtr(GVariant* ptr) -{ - return ptr; -} - -template <> void derefPlatformPtr(GVariant* ptr) -{ -} - -#endif - -template <> GSource* refPlatformPtr(GSource* ptr) -{ - if (ptr) - g_source_ref(ptr); - return ptr; -} - -template <> void derefPlatformPtr(GSource* ptr) -{ - if (ptr) - g_source_unref(ptr); -} - -} // namespace WTF - -#endif // ENABLE(GLIB_SUPPORT) diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h deleted file mode 100644 index 4efd9be..0000000 --- a/JavaScriptCore/wtf/gobject/GRefPtr.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2008 Collabora Ltd. - * Copyright (C) 2009 Martin Robinson - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_GRefPtr_h -#define WTF_GRefPtr_h - -#if ENABLE(GLIB_SUPPORT) - -#include "AlwaysInline.h" -#include "PlatformRefPtr.h" -#include <algorithm> - -extern "C" void g_object_unref(gpointer); -extern "C" gpointer g_object_ref_sink(gpointer); - -namespace WTF { - -template <> GHashTable* refPlatformPtr(GHashTable* ptr); -template <> void derefPlatformPtr(GHashTable* ptr); -template <> GVariant* refPlatformPtr(GVariant* ptr); -template <> void derefPlatformPtr(GVariant* ptr); -template <> GSource* refPlatformPtr(GSource* ptr); -template <> void derefPlatformPtr(GSource* ptr); - -template <typename T> inline T* refPlatformPtr(T* ptr) -{ - if (ptr) - g_object_ref_sink(ptr); - return ptr; -} - -template <typename T> inline void derefPlatformPtr(T* ptr) -{ - if (ptr) - g_object_unref(ptr); -} - -} // namespace WTF - -#endif // ENABLE(GLIB_SUPPORT) - -#endif // WTF_GRefPtr_h diff --git a/JavaScriptCore/wtf/gobject/GTypedefs.h b/JavaScriptCore/wtf/gobject/GTypedefs.h deleted file mode 100644 index 0b9a9ea..0000000 --- a/JavaScriptCore/wtf/gobject/GTypedefs.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (C) 2010 Igalia, S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#ifndef GtkTypedefs_h -#define GtkTypedefs_h - -/* Vanilla C code does not seem to be able to handle forward-declaration typedefs. */ -#ifdef __cplusplus - -typedef char gchar; -typedef double gdouble; -typedef float gfloat; -typedef int gint; -typedef gint gboolean; -typedef long glong; -typedef short gshort; -typedef unsigned char guchar; -typedef unsigned int guint; -typedef unsigned long gulong; -typedef unsigned short gushort; -typedef void* gpointer; - -typedef struct _GAsyncResult GAsyncResult; -typedef struct _GCancellable GCancellable; -typedef struct _GCharsetConverter GCharsetConverter; -typedef struct _GCond GCond; -typedef struct _GDir GDir; -typedef struct _GdkAtom* GdkAtom; -typedef struct _GdkCursor GdkCursor; -typedef struct _GdkDragContext GdkDragContext; -typedef struct _GdkEventConfigure GdkEventConfigure; -typedef struct _GdkEventExpose GdkEventExpose; -typedef struct _GdkPixbuf GdkPixbuf; -typedef struct _GError GError; -typedef struct _GFile GFile; -typedef struct _GHashTable GHashTable; -typedef struct _GInputStream GInputStream; -typedef struct _GList GList; -typedef struct _GMutex GMutex; -typedef struct _GOutputStream GOutputStream; -typedef struct _GPatternSpec GPatternSpec; -typedef struct _GSocketClient GSocketClient; -typedef struct _GSocketConnection GSocketConnection; -typedef struct _GSource GSource; -typedef struct _GVariant GVariant; -typedef union _GdkEvent GdkEvent; - -#if PLATFORM(CAIRO) -typedef struct _cairo_surface cairo_surface_t; -#endif - -#if PLATFORM(GTK) -typedef struct _GtkAction GtkAction; -typedef struct _GtkAdjustment GtkAdjustment; -typedef struct _GtkBorder GtkBorder; -typedef struct _GtkClipboard GtkClipboard; -typedef struct _GtkContainer GtkContainer; -typedef struct _GtkIconInfo GtkIconInfo; -typedef struct _GtkMenu GtkMenu; -typedef struct _GtkMenuItem GtkMenuItem; -typedef struct _GtkObject GtkObject; -typedef struct _GtkSelectionData GtkSelectionData; -typedef struct _GtkStyle GtkStyle; -typedef struct _GtkTargetList GtkTargetList; -typedef struct _GtkThemeParts GtkThemeParts; -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkWindow GtkWindow; - -#ifdef GTK_API_VERSION_2 -typedef struct _GdkRectangle GdkRectangle; -typedef struct _GdkDrawable GdkWindow; -#else -typedef struct _GdkWindow GdkWindow; -typedef struct _cairo_rectangle_int cairo_rectangle_int_t; -typedef cairo_rectangle_int_t GdkRectangle; -#endif - -#endif - -#endif -#endif /* GtkTypedefs_h */ diff --git a/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp b/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp deleted file mode 100644 index 7624247..0000000 --- a/JavaScriptCore/wtf/gtk/MainThreadGtk.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include <glib.h> - -namespace WTF { - -void initializeMainThreadPlatform() -{ -} - -static gboolean timeoutFired(gpointer) -{ - dispatchFunctionsFromMainThread(); - return FALSE; -} - -void scheduleDispatchFunctionsOnMainThread() -{ - g_timeout_add(0, timeoutFired, 0); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp b/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp deleted file mode 100644 index 863ee81..0000000 --- a/JavaScriptCore/wtf/gtk/ThreadingGtk.cpp +++ /dev/null @@ -1,248 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Threading.h" - -#if !USE(PTHREADS) - -#include "CurrentTime.h" -#include "HashMap.h" -#include "MainThread.h" -#include "RandomNumberSeed.h" -#include <wtf/StdLibExtras.h> - -#include <glib.h> -#include <limits.h> - -namespace WTF { - -typedef HashMap<ThreadIdentifier, GThread*> ThreadMap; - -static Mutex* atomicallyInitializedStaticMutex; - -static Mutex& threadMapMutex() -{ - DEFINE_STATIC_LOCAL(Mutex, mutex, ()); - return mutex; -} - -void initializeThreading() -{ - if (!g_thread_supported()) - g_thread_init(NULL); - ASSERT(g_thread_supported()); - - if (!atomicallyInitializedStaticMutex) { - atomicallyInitializedStaticMutex = new Mutex; - threadMapMutex(); - initializeRandomNumberGenerator(); - } -} - -void lockAtomicallyInitializedStaticMutex() -{ - ASSERT(atomicallyInitializedStaticMutex); - atomicallyInitializedStaticMutex->lock(); -} - -void unlockAtomicallyInitializedStaticMutex() -{ - atomicallyInitializedStaticMutex->unlock(); -} - -static ThreadMap& threadMap() -{ - DEFINE_STATIC_LOCAL(ThreadMap, map, ()); - return map; -} - -static ThreadIdentifier identifierByGthreadHandle(GThread*& thread) -{ - MutexLocker locker(threadMapMutex()); - - ThreadMap::iterator i = threadMap().begin(); - for (; i != threadMap().end(); ++i) { - if (i->second == thread) - return i->first; - } - - return 0; -} - -static ThreadIdentifier establishIdentifierForThread(GThread*& thread) -{ - ASSERT(!identifierByGthreadHandle(thread)); - - MutexLocker locker(threadMapMutex()); - - static ThreadIdentifier identifierCount = 1; - - threadMap().add(identifierCount, thread); - - return identifierCount++; -} - -static GThread* threadForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - - return threadMap().get(id); -} - -static void clearThreadForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - - ASSERT(threadMap().contains(id)); - - threadMap().remove(id); -} - -ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) -{ - GThread* thread; - if (!(thread = g_thread_create(entryPoint, data, TRUE, 0))) { - LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data); - return 0; - } - - ThreadIdentifier threadID = establishIdentifierForThread(thread); - return threadID; -} - -void initializeCurrentThreadInternal(const char*) -{ -} - -int waitForThreadCompletion(ThreadIdentifier threadID, void** result) -{ - ASSERT(threadID); - - GThread* thread = threadForIdentifier(threadID); - - void* joinResult = g_thread_join(thread); - if (result) - *result = joinResult; - - clearThreadForIdentifier(threadID); - return 0; -} - -void detachThread(ThreadIdentifier) -{ -} - -ThreadIdentifier currentThread() -{ - GThread* currentThread = g_thread_self(); - if (ThreadIdentifier id = identifierByGthreadHandle(currentThread)) - return id; - return establishIdentifierForThread(currentThread); -} - -void yield() -{ - g_thread_yield(); -} - -Mutex::Mutex() - : m_mutex(g_mutex_new()) -{ -} - -Mutex::~Mutex() -{ -} - -void Mutex::lock() -{ - g_mutex_lock(m_mutex.get()); -} - -bool Mutex::tryLock() -{ - return g_mutex_trylock(m_mutex.get()); -} - -void Mutex::unlock() -{ - g_mutex_unlock(m_mutex.get()); -} - -ThreadCondition::ThreadCondition() - : m_condition(g_cond_new()) -{ -} - -ThreadCondition::~ThreadCondition() -{ -} - -void ThreadCondition::wait(Mutex& mutex) -{ - g_cond_wait(m_condition.get(), mutex.impl().get()); -} - -bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) -{ - // Time is in the past - return right away. - if (absoluteTime < currentTime()) - return false; - - // Time is too far in the future for g_cond_timed_wait - wait forever. - if (absoluteTime > INT_MAX) { - wait(mutex); - return true; - } - - int timeSeconds = static_cast<int>(absoluteTime); - int timeMicroseconds = static_cast<int>((absoluteTime - timeSeconds) * 1000000.0); - - GTimeVal targetTime; - targetTime.tv_sec = timeSeconds; - targetTime.tv_usec = timeMicroseconds; - - return g_cond_timed_wait(m_condition.get(), mutex.impl().get(), &targetTime); -} - -void ThreadCondition::signal() -{ - g_cond_signal(m_condition.get()); -} - -void ThreadCondition::broadcast() -{ - g_cond_broadcast(m_condition.get()); -} - - -} - -#endif // !USE(PTHREADS) diff --git a/JavaScriptCore/wtf/haiku/MainThreadHaiku.cpp b/JavaScriptCore/wtf/haiku/MainThreadHaiku.cpp deleted file mode 100644 index 10c4248..0000000 --- a/JavaScriptCore/wtf/haiku/MainThreadHaiku.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2007 Kevin Ollivier - * Copyright (C) 2009 Maxime Simon - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include "NotImplemented.h" - -namespace WTF { - -void initializeMainThreadPlatform() -{ - notImplemented(); -} - -void scheduleDispatchFunctionsOnMainThread() -{ - notImplemented(); -} - -} // namespace WTF - diff --git a/JavaScriptCore/wtf/haiku/StringHaiku.cpp b/JavaScriptCore/wtf/haiku/StringHaiku.cpp deleted file mode 100644 index fdf4e72..0000000 --- a/JavaScriptCore/wtf/haiku/StringHaiku.cpp +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2007 Ryan Leavengood <leavengood@gmail.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PlatformString.h" - -#include <String.h> -#include <wtf/text/CString.h> - -namespace WTF { - -// String conversions -String::String(const BString& string) -{ - if (string.Length()) - m_impl = String::fromUTF8(string.String(), string.Length()).impl(); - else - m_impl = StringImpl::empty(); -} - -String::operator BString() const -{ - BString string; - string.SetTo(utf8().data()); - - return string; -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/mac/MainThreadMac.mm b/JavaScriptCore/wtf/mac/MainThreadMac.mm deleted file mode 100644 index 17363bc..0000000 --- a/JavaScriptCore/wtf/mac/MainThreadMac.mm +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#import "config.h" -#import "MainThread.h" - -#import <CoreFoundation/CoreFoundation.h> -#import <Foundation/NSThread.h> -#import <stdio.h> -#import <wtf/Assertions.h> -#import <wtf/Threading.h> - -@interface WTFMainThreadCaller : NSObject { -} -- (void)call; -@end - -@implementation WTFMainThreadCaller - -- (void)call -{ - WTF::dispatchFunctionsFromMainThread(); -} - -@end // implementation WTFMainThreadCaller - -namespace WTF { - -static WTFMainThreadCaller* staticMainThreadCaller; -static bool isTimerPosted; // This is only accessed on the 'main' thread. -static bool mainThreadEstablishedAsPthreadMain; -static pthread_t mainThreadPthread; -static NSThread* mainThreadNSThread; - -void initializeMainThreadPlatform() -{ -#if !defined(BUILDING_ON_TIGER) - ASSERT(!staticMainThreadCaller); - staticMainThreadCaller = [[WTFMainThreadCaller alloc] init]; - - mainThreadEstablishedAsPthreadMain = false; - mainThreadPthread = pthread_self(); - mainThreadNSThread = [[NSThread currentThread] retain]; -#else - ASSERT_NOT_REACHED(); -#endif -} - -void initializeMainThreadToProcessMainThreadPlatform() -{ - if (!pthread_main_np()) - NSLog(@"WebKit Threading Violation - initial use of WebKit from a secondary thread."); - - ASSERT(!staticMainThreadCaller); - staticMainThreadCaller = [[WTFMainThreadCaller alloc] init]; - - mainThreadEstablishedAsPthreadMain = true; - mainThreadPthread = 0; - mainThreadNSThread = nil; -} - -static void timerFired(CFRunLoopTimerRef timer, void*) -{ - CFRelease(timer); - isTimerPosted = false; - WTF::dispatchFunctionsFromMainThread(); -} - -static void postTimer() -{ - ASSERT(isMainThread()); - - if (isTimerPosted) - return; - - isTimerPosted = true; - CFRunLoopAddTimer(CFRunLoopGetCurrent(), CFRunLoopTimerCreate(0, 0, 0, 0, 0, timerFired, 0), kCFRunLoopCommonModes); -} - -void scheduleDispatchFunctionsOnMainThread() -{ - ASSERT(staticMainThreadCaller); - - if (isMainThread()) { - postTimer(); - return; - } - - if (mainThreadEstablishedAsPthreadMain) { - ASSERT(!mainThreadNSThread); - [staticMainThreadCaller performSelectorOnMainThread:@selector(call) withObject:nil waitUntilDone:NO]; - return; - } - -#if !defined(BUILDING_ON_TIGER) - ASSERT(mainThreadNSThread); - [staticMainThreadCaller performSelector:@selector(call) onThread:mainThreadNSThread withObject:nil waitUntilDone:NO]; -#else - ASSERT_NOT_REACHED(); -#endif -} - -bool isMainThread() -{ - if (mainThreadEstablishedAsPthreadMain) { - ASSERT(!mainThreadPthread); - return pthread_main_np(); - } - -#if !defined(BUILDING_ON_TIGER) - ASSERT(mainThreadPthread); - return pthread_equal(pthread_self(), mainThreadPthread); -#else - ASSERT_NOT_REACHED(); - return false; -#endif -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/qt/MainThreadQt.cpp b/JavaScriptCore/wtf/qt/MainThreadQt.cpp deleted file mode 100644 index 98b6a0c..0000000 --- a/JavaScriptCore/wtf/qt/MainThreadQt.cpp +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (C) 2007 Staikos Computing Services Inc. - * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include <QtCore/QObject> -#include <QtCore/QCoreApplication> -#include <QThread> - -namespace WTF { - -class MainThreadInvoker : public QObject { - Q_OBJECT -public: - MainThreadInvoker(); - -private Q_SLOTS: - void dispatch(); -}; - -MainThreadInvoker::MainThreadInvoker() -{ - moveToThread(QCoreApplication::instance()->thread()); -} - -void MainThreadInvoker::dispatch() -{ - dispatchFunctionsFromMainThread(); -} - -Q_GLOBAL_STATIC(MainThreadInvoker, webkit_main_thread_invoker) - -void initializeMainThreadPlatform() -{ -} - -void scheduleDispatchFunctionsOnMainThread() -{ - QMetaObject::invokeMethod(webkit_main_thread_invoker(), "dispatch", Qt::QueuedConnection); -} - -bool isMainThread() -{ - return QThread::currentThread() == QCoreApplication::instance()->thread(); -} - -} // namespace WTF - -#include "MainThreadQt.moc" diff --git a/JavaScriptCore/wtf/qt/StringQt.cpp b/JavaScriptCore/wtf/qt/StringQt.cpp deleted file mode 100644 index 16dd439..0000000 --- a/JavaScriptCore/wtf/qt/StringQt.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#include <wtf/StdLibExtras.h> -#include <wtf/text/WTFString.h> - -#include <QString> - -namespace WTF { - -// String conversions -String::String(const QString& qstr) -{ - if (qstr.isNull()) - return; - m_impl = StringImpl::create(reinterpret_cast_ptr<const UChar*>(qstr.constData()), qstr.length()); -} - -String::String(const QStringRef& ref) -{ - if (!ref.string()) - return; - m_impl = StringImpl::create(reinterpret_cast_ptr<const UChar*>(ref.unicode()), ref.length()); -} - -String::operator QString() const -{ - return QString(reinterpret_cast<const QChar*>(characters()), length()); -} - -QDataStream& operator<<(QDataStream& stream, const String& str) -{ - // could be faster - stream << QString(str); - return stream; -} - -QDataStream& operator>>(QDataStream& stream, String& str) -{ - // mabe not the fastest way, but really easy - QString tmp; - stream >> tmp; - str = tmp; - return stream; -} - -} - -// vim: ts=4 sw=4 et diff --git a/JavaScriptCore/wtf/qt/ThreadingQt.cpp b/JavaScriptCore/wtf/qt/ThreadingQt.cpp deleted file mode 100644 index 8041dea..0000000 --- a/JavaScriptCore/wtf/qt/ThreadingQt.cpp +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * Copyright (C) 2007 Justin Haygood (jhaygood@reaktix.com) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include "config.h" -#include "Threading.h" - -#if !ENABLE(SINGLE_THREADED) - -#include "CurrentTime.h" -#include "HashMap.h" -#include "MainThread.h" -#include "RandomNumberSeed.h" - -#include <QCoreApplication> -#include <QMutex> -#include <QThread> -#include <QWaitCondition> - -namespace WTF { - -class ThreadPrivate : public QThread { -public: - ThreadPrivate(ThreadFunction entryPoint, void* data); - void run(); - void* getReturnValue() { return m_returnValue; } -private: - void* m_data; - ThreadFunction m_entryPoint; - void* m_returnValue; -}; - -ThreadPrivate::ThreadPrivate(ThreadFunction entryPoint, void* data) - : m_data(data) - , m_entryPoint(entryPoint) - , m_returnValue(0) -{ -} - -void ThreadPrivate::run() -{ - m_returnValue = m_entryPoint(m_data); -} - -class ThreadMonitor : public QObject { - Q_OBJECT -public: - static ThreadMonitor * instance() - { - static ThreadMonitor *instance = new ThreadMonitor(); - return instance; - } - -public Q_SLOTS: - void threadFinished() - { - sender()->deleteLater(); - } -}; - -static Mutex* atomicallyInitializedStaticMutex; - -static Mutex& threadMapMutex() -{ - static Mutex mutex; - return mutex; -} - -static HashMap<ThreadIdentifier, QThread*>& threadMap() -{ - static HashMap<ThreadIdentifier, QThread*> map; - return map; -} - -static ThreadIdentifier identifierByQthreadHandle(QThread*& thread) -{ - MutexLocker locker(threadMapMutex()); - - HashMap<ThreadIdentifier, QThread*>::iterator i = threadMap().begin(); - for (; i != threadMap().end(); ++i) { - if (i->second == thread) - return i->first; - } - - return 0; -} - -static ThreadIdentifier establishIdentifierForThread(QThread*& thread) -{ - ASSERT(!identifierByQthreadHandle(thread)); - - MutexLocker locker(threadMapMutex()); - - static ThreadIdentifier identifierCount = 1; - - threadMap().add(identifierCount, thread); - - return identifierCount++; -} - -static void clearThreadForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - - ASSERT(threadMap().contains(id)); - - threadMap().remove(id); -} - -static QThread* threadForIdentifier(ThreadIdentifier id) -{ - MutexLocker locker(threadMapMutex()); - - return threadMap().get(id); -} - -void initializeThreading() -{ - if (!atomicallyInitializedStaticMutex) { - atomicallyInitializedStaticMutex = new Mutex; - threadMapMutex(); - initializeRandomNumberGenerator(); - } -} - -void lockAtomicallyInitializedStaticMutex() -{ - ASSERT(atomicallyInitializedStaticMutex); - atomicallyInitializedStaticMutex->lock(); -} - -void unlockAtomicallyInitializedStaticMutex() -{ - atomicallyInitializedStaticMutex->unlock(); -} - -ThreadIdentifier createThreadInternal(ThreadFunction entryPoint, void* data, const char*) -{ - ThreadPrivate* thread = new ThreadPrivate(entryPoint, data); - if (!thread) { - LOG_ERROR("Failed to create thread at entry point %p with data %p", entryPoint, data); - return 0; - } - - QObject::connect(thread, SIGNAL(finished()), ThreadMonitor::instance(), SLOT(threadFinished())); - - thread->start(); - - QThread* threadRef = static_cast<QThread*>(thread); - - return establishIdentifierForThread(threadRef); -} - -void initializeCurrentThreadInternal(const char*) -{ -} - -int waitForThreadCompletion(ThreadIdentifier threadID, void** result) -{ - ASSERT(threadID); - - QThread* thread = threadForIdentifier(threadID); - - bool res = thread->wait(); - - clearThreadForIdentifier(threadID); - if (result) - *result = static_cast<ThreadPrivate*>(thread)->getReturnValue(); - - return !res; -} - -void detachThread(ThreadIdentifier threadID) -{ - ASSERT(threadID); - clearThreadForIdentifier(threadID); -} - -ThreadIdentifier currentThread() -{ - QThread* currentThread = QThread::currentThread(); - if (ThreadIdentifier id = identifierByQthreadHandle(currentThread)) - return id; - return establishIdentifierForThread(currentThread); -} - -void yield() -{ - QThread::yieldCurrentThread(); -} - -Mutex::Mutex() - : m_mutex(new QMutex()) -{ -} - -Mutex::~Mutex() -{ - delete m_mutex; -} - -void Mutex::lock() -{ - m_mutex->lock(); -} - -bool Mutex::tryLock() -{ - return m_mutex->tryLock(); -} - -void Mutex::unlock() -{ - m_mutex->unlock(); -} - -ThreadCondition::ThreadCondition() - : m_condition(new QWaitCondition()) -{ -} - -ThreadCondition::~ThreadCondition() -{ - delete m_condition; -} - -void ThreadCondition::wait(Mutex& mutex) -{ - m_condition->wait(mutex.impl()); -} - -bool ThreadCondition::timedWait(Mutex& mutex, double absoluteTime) -{ - double currentTime = WTF::currentTime(); - - // Time is in the past - return immediately. - if (absoluteTime < currentTime) - return false; - - // Time is too far in the future (and would overflow unsigned long) - wait forever. - if (absoluteTime - currentTime > static_cast<double>(INT_MAX) / 1000.0) { - wait(mutex); - return true; - } - - double intervalMilliseconds = (absoluteTime - currentTime) * 1000.0; - return m_condition->wait(mutex.impl(), static_cast<unsigned long>(intervalMilliseconds)); -} - -void ThreadCondition::signal() -{ - m_condition->wakeOne(); -} - -void ThreadCondition::broadcast() -{ - m_condition->wakeAll(); -} - -} // namespace WebCore - -#include "ThreadingQt.moc" - -#endif diff --git a/JavaScriptCore/wtf/text/AtomicString.cpp b/JavaScriptCore/wtf/text/AtomicString.cpp deleted file mode 100644 index acbcd34..0000000 --- a/JavaScriptCore/wtf/text/AtomicString.cpp +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" - -#include "AtomicString.h" - -#include "StringHash.h" -#include <wtf/HashSet.h> -#include <wtf/Threading.h> -#include <wtf/WTFThreadData.h> -#include <wtf/unicode/UTF8.h> - -namespace WTF { - -using namespace Unicode; - -COMPILE_ASSERT(sizeof(AtomicString) == sizeof(String), atomic_string_and_string_must_be_same_size); - -class AtomicStringTable { -public: - static AtomicStringTable* create() - { - AtomicStringTable* table = new AtomicStringTable; - - WTFThreadData& data = wtfThreadData(); - data.m_atomicStringTable = table; - data.m_atomicStringTableDestructor = AtomicStringTable::destroy; - - return table; - } - - HashSet<StringImpl*>& table() - { - return m_table; - } - -private: - static void destroy(AtomicStringTable* table) - { - HashSet<StringImpl*>::iterator end = table->m_table.end(); - for (HashSet<StringImpl*>::iterator iter = table->m_table.begin(); iter != end; ++iter) - (*iter)->setIsAtomic(false); - delete table; - } - - HashSet<StringImpl*> m_table; -}; - -static inline HashSet<StringImpl*>& stringTable() -{ - // Once possible we should make this non-lazy (constructed in WTFThreadData's constructor). - AtomicStringTable* table = wtfThreadData().atomicStringTable(); - if (UNLIKELY(!table)) - table = AtomicStringTable::create(); - return table->table(); -} - -struct CStringTranslator { - static unsigned hash(const char* c) - { - return StringImpl::computeHash(c); - } - - static bool equal(StringImpl* r, const char* s) - { - int length = r->length(); - const UChar* d = r->characters(); - for (int i = 0; i != length; ++i) { - unsigned char c = s[i]; - if (d[i] != c) - return false; - } - return !s[length]; - } - - static void translate(StringImpl*& location, const char* const& c, unsigned hash) - { - location = StringImpl::create(c).leakRef(); - location->setHash(hash); - location->setIsAtomic(true); - } -}; - -bool operator==(const AtomicString& a, const char* b) -{ - StringImpl* impl = a.impl(); - if ((!impl || !impl->characters()) && !b) - return true; - if ((!impl || !impl->characters()) || !b) - return false; - return CStringTranslator::equal(impl, b); -} - -PassRefPtr<StringImpl> AtomicString::add(const char* c) -{ - if (!c) - return 0; - if (!*c) - return StringImpl::empty(); - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<const char*, CStringTranslator>(c); - if (!addResult.second) - return *addResult.first; - return adoptRef(*addResult.first); -} - -struct UCharBuffer { - const UChar* s; - unsigned length; -}; - -static inline bool equal(StringImpl* string, const UChar* characters, unsigned length) -{ - if (string->length() != length) - return false; - - // FIXME: perhaps we should have a more abstract macro that indicates when - // going 4 bytes at a time is unsafe -#if CPU(ARM) || CPU(SH4) || CPU(MIPS) - const UChar* stringCharacters = string->characters(); - for (unsigned i = 0; i != length; ++i) { - if (*stringCharacters++ != *characters++) - return false; - } - return true; -#else - /* Do it 4-bytes-at-a-time on architectures where it's safe */ - - const uint32_t* stringCharacters = reinterpret_cast<const uint32_t*>(string->characters()); - const uint32_t* bufferCharacters = reinterpret_cast<const uint32_t*>(characters); - - unsigned halfLength = length >> 1; - for (unsigned i = 0; i != halfLength; ++i) { - if (*stringCharacters++ != *bufferCharacters++) - return false; - } - - if (length & 1 && *reinterpret_cast<const uint16_t*>(stringCharacters) != *reinterpret_cast<const uint16_t*>(bufferCharacters)) - return false; - - return true; -#endif -} - -bool operator==(const AtomicString& string, const Vector<UChar>& vector) -{ - return string.impl() && equal(string.impl(), vector.data(), vector.size()); -} - -struct UCharBufferTranslator { - static unsigned hash(const UCharBuffer& buf) - { - return StringImpl::computeHash(buf.s, buf.length); - } - - static bool equal(StringImpl* const& str, const UCharBuffer& buf) - { - return WTF::equal(str, buf.s, buf.length); - } - - static void translate(StringImpl*& location, const UCharBuffer& buf, unsigned hash) - { - location = StringImpl::create(buf.s, buf.length).leakRef(); - location->setHash(hash); - location->setIsAtomic(true); - } -}; - -struct HashAndCharacters { - unsigned hash; - const UChar* characters; - unsigned length; -}; - -struct HashAndCharactersTranslator { - static unsigned hash(const HashAndCharacters& buffer) - { - ASSERT(buffer.hash == StringImpl::computeHash(buffer.characters, buffer.length)); - return buffer.hash; - } - - static bool equal(StringImpl* const& string, const HashAndCharacters& buffer) - { - return WTF::equal(string, buffer.characters, buffer.length); - } - - static void translate(StringImpl*& location, const HashAndCharacters& buffer, unsigned hash) - { - location = StringImpl::create(buffer.characters, buffer.length).leakRef(); - location->setHash(hash); - location->setIsAtomic(true); - } -}; - -struct HashAndUTF8Characters { - unsigned hash; - const char* characters; - unsigned length; - unsigned utf16Length; -}; - -struct HashAndUTF8CharactersTranslator { - static unsigned hash(const HashAndUTF8Characters& buffer) - { - return buffer.hash; - } - - static bool equal(StringImpl* const& string, const HashAndUTF8Characters& buffer) - { - return equalUTF16WithUTF8(string->characters(), string->characters() + string->length(), buffer.characters, buffer.characters + buffer.length); - } - - static void translate(StringImpl*& location, const HashAndUTF8Characters& buffer, unsigned hash) - { - UChar* target; - location = StringImpl::createUninitialized(buffer.utf16Length, target).releaseRef(); - - const char* source = buffer.characters; - if (convertUTF8ToUTF16(&source, source + buffer.length, &target, target + buffer.utf16Length) != conversionOK) - ASSERT_NOT_REACHED(); - - location->setHash(hash); - location->setIsAtomic(true); - } -}; - -PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length) -{ - if (!s) - return 0; - - if (!length) - return StringImpl::empty(); - - UCharBuffer buf = { s, length }; - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf); - - // If the string is newly-translated, then we need to adopt it. - // The boolean in the pair tells us if that is so. - return addResult.second ? adoptRef(*addResult.first) : *addResult.first; -} - -PassRefPtr<StringImpl> AtomicString::add(const UChar* s, unsigned length, unsigned existingHash) -{ - ASSERT(s); - ASSERT(existingHash); - - if (!length) - return StringImpl::empty(); - - HashAndCharacters buffer = { existingHash, s, length }; - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndCharacters, HashAndCharactersTranslator>(buffer); - if (!addResult.second) - return *addResult.first; - return adoptRef(*addResult.first); -} - -PassRefPtr<StringImpl> AtomicString::add(const UChar* s) -{ - if (!s) - return 0; - - int length = 0; - while (s[length] != UChar(0)) - length++; - - if (!length) - return StringImpl::empty(); - - UCharBuffer buf = {s, length}; - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<UCharBuffer, UCharBufferTranslator>(buf); - - // If the string is newly-translated, then we need to adopt it. - // The boolean in the pair tells us if that is so. - return addResult.second ? adoptRef(*addResult.first) : *addResult.first; -} - -PassRefPtr<StringImpl> AtomicString::addSlowCase(StringImpl* r) -{ - if (!r || r->isAtomic()) - return r; - - if (!r->length()) - return StringImpl::empty(); - - StringImpl* result = *stringTable().add(r).first; - if (result == r) - r->setIsAtomic(true); - return result; -} - -AtomicStringImpl* AtomicString::find(const UChar* s, unsigned length, unsigned existingHash) -{ - ASSERT(s); - ASSERT(existingHash); - - if (!length) - return static_cast<AtomicStringImpl*>(StringImpl::empty()); - - HashAndCharacters buffer = { existingHash, s, length }; - HashSet<StringImpl*>::iterator iterator = stringTable().find<HashAndCharacters, HashAndCharactersTranslator>(buffer); - if (iterator == stringTable().end()) - return 0; - return static_cast<AtomicStringImpl*>(*iterator); -} - -void AtomicString::remove(StringImpl* r) -{ - stringTable().remove(r); -} - -AtomicString AtomicString::lower() const -{ - // Note: This is a hot function in the Dromaeo benchmark. - StringImpl* impl = this->impl(); - if (UNLIKELY(!impl)) - return *this; - RefPtr<StringImpl> newImpl = impl->lower(); - if (LIKELY(newImpl == impl)) - return *this; - return AtomicString(newImpl); -} - -AtomicString AtomicString::fromUTF8(const char* characters, size_t length) -{ - if (!characters) - return AtomicString(); - - if (!length) - return emptyAtom; - - HashAndUTF8Characters buffer; - buffer.characters = characters; - buffer.length = length; - buffer.hash = calculateStringHashFromUTF8(characters, characters + length, buffer.utf16Length); - - if (!buffer.hash) - return AtomicString(); - - pair<HashSet<StringImpl*>::iterator, bool> addResult = stringTable().add<HashAndUTF8Characters, HashAndUTF8CharactersTranslator>(buffer); - - // If the string is newly-translated, then we need to adopt it. - // The boolean in the pair tells us if that is so. - AtomicString atomicString; - atomicString.m_string = addResult.second ? adoptRef(*addResult.first) : *addResult.first; - return atomicString; -} - -AtomicString AtomicString::fromUTF8(const char* characters) -{ - if (!characters) - return AtomicString(); - return fromUTF8(characters, strlen(characters)); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/text/AtomicString.h b/JavaScriptCore/wtf/text/AtomicString.h deleted file mode 100644 index ab5b366..0000000 --- a/JavaScriptCore/wtf/text/AtomicString.h +++ /dev/null @@ -1,185 +0,0 @@ -/* - * Copyright (C) 2004, 2005, 2006, 2008 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef AtomicString_h -#define AtomicString_h - -#include "AtomicStringImpl.h" -#include "WTFString.h" - -// Define 'NO_IMPLICIT_ATOMICSTRING' before including this header, -// to disallow (expensive) implicit String-->AtomicString conversions. -#ifdef NO_IMPLICIT_ATOMICSTRING -#define ATOMICSTRING_CONVERSION explicit -#else -#define ATOMICSTRING_CONVERSION -#endif - -namespace WTF { - -struct AtomicStringHash; - -class AtomicString { -public: - static void init(); - - AtomicString() { } - AtomicString(const char* s) : m_string(add(s)) { } - AtomicString(const UChar* s, unsigned length) : m_string(add(s, length)) { } - AtomicString(const UChar* s, unsigned length, unsigned existingHash) : m_string(add(s, length, existingHash)) { } - AtomicString(const UChar* s) : m_string(add(s)) { } - ATOMICSTRING_CONVERSION AtomicString(StringImpl* imp) : m_string(add(imp)) { } - AtomicString(AtomicStringImpl* imp) : m_string(imp) { } - ATOMICSTRING_CONVERSION AtomicString(const String& s) : m_string(add(s.impl())) { } - - // Hash table deleted values, which are only constructed and never copied or destroyed. - AtomicString(WTF::HashTableDeletedValueType) : m_string(WTF::HashTableDeletedValue) { } - bool isHashTableDeletedValue() const { return m_string.isHashTableDeletedValue(); } - - static AtomicStringImpl* find(const UChar* s, unsigned length, unsigned existingHash); - - operator const String&() const { return m_string; } - const String& string() const { return m_string; }; - - AtomicStringImpl* impl() const { return static_cast<AtomicStringImpl *>(m_string.impl()); } - - const UChar* characters() const { return m_string.characters(); } - unsigned length() const { return m_string.length(); } - - UChar operator[](unsigned int i) const { return m_string[i]; } - - bool contains(UChar c) const { return m_string.contains(c); } - bool contains(const char* s, bool caseSensitive = true) const - { return m_string.contains(s, caseSensitive); } - bool contains(const String& s, bool caseSensitive = true) const - { return m_string.contains(s, caseSensitive); } - - size_t find(UChar c, size_t start = 0) const { return m_string.find(c, start); } - size_t find(const char* s, size_t start = 0, bool caseSentitive = true) const - { return m_string.find(s, start, caseSentitive); } - size_t find(const String& s, size_t start = 0, bool caseSentitive = true) const - { return m_string.find(s, start, caseSentitive); } - - bool startsWith(const String& s, bool caseSensitive = true) const - { return m_string.startsWith(s, caseSensitive); } - bool endsWith(const String& s, bool caseSensitive = true) const - { return m_string.endsWith(s, caseSensitive); } - - AtomicString lower() const; - AtomicString upper() const { return AtomicString(impl()->upper()); } - - int toInt(bool* ok = 0) const { return m_string.toInt(ok); } - double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); } - float toFloat(bool* ok = 0) const { return m_string.toFloat(ok); } - bool percentage(int& p) const { return m_string.percentage(p); } - - bool isNull() const { return m_string.isNull(); } - bool isEmpty() const { return m_string.isEmpty(); } - - static void remove(StringImpl*); - -#if PLATFORM(CF) - AtomicString(CFStringRef s) : m_string(add(String(s).impl())) { } - CFStringRef createCFString() const { return m_string.createCFString(); } -#endif -#ifdef __OBJC__ - AtomicString(NSString* s) : m_string(add(String(s).impl())) { } - operator NSString*() const { return m_string; } -#endif -#if PLATFORM(QT) - AtomicString(const QString& s) : m_string(add(String(s).impl())) { } - operator QString() const { return m_string; } -#endif - - // AtomicString::fromUTF8 will return a null string if - // the input data contains invalid UTF-8 sequences. - static AtomicString fromUTF8(const char*, size_t); - static AtomicString fromUTF8(const char*); - -private: - String m_string; - - static PassRefPtr<StringImpl> add(const char*); - static PassRefPtr<StringImpl> add(const UChar*, unsigned length); - static PassRefPtr<StringImpl> add(const UChar*, unsigned length, unsigned existingHash); - static PassRefPtr<StringImpl> add(const UChar*); - ALWAYS_INLINE PassRefPtr<StringImpl> add(StringImpl* r) - { - if (!r || r->isAtomic()) - return r; - return addSlowCase(r); - } - static PassRefPtr<StringImpl> addSlowCase(StringImpl*); -}; - -inline bool operator==(const AtomicString& a, const AtomicString& b) { return a.impl() == b.impl(); } -bool operator==(const AtomicString& a, const char* b); -bool operator==(const AtomicString& a, const Vector<UChar>& b); -inline bool operator==(const AtomicString& a, const String& b) { return equal(a.impl(), b.impl()); } -inline bool operator==(const char* a, const AtomicString& b) { return b == a; } -inline bool operator==(const String& a, const AtomicString& b) { return equal(a.impl(), b.impl()); } -inline bool operator==(const Vector<UChar>& a, const AtomicString& b) { return b == a; } - -inline bool operator!=(const AtomicString& a, const AtomicString& b) { return a.impl() != b.impl(); } -inline bool operator!=(const AtomicString& a, const char *b) { return !(a == b); } -inline bool operator!=(const AtomicString& a, const String& b) { return !equal(a.impl(), b.impl()); } -inline bool operator!=(const AtomicString& a, const Vector<UChar>& b) { return !(a == b); } -inline bool operator!=(const char* a, const AtomicString& b) { return !(b == a); } -inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); } -inline bool operator!=(const Vector<UChar>& a, const AtomicString& b) { return !(a == b); } - -inline bool equalIgnoringCase(const AtomicString& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); } -inline bool equalIgnoringCase(const AtomicString& a, const char* b) { return equalIgnoringCase(a.impl(), b); } -inline bool equalIgnoringCase(const AtomicString& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } -inline bool equalIgnoringCase(const char* a, const AtomicString& b) { return equalIgnoringCase(a, b.impl()); } -inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); } - -// Define external global variables for the commonly used atomic strings. -// These are only usable from the main thread. -#ifndef ATOMICSTRING_HIDE_GLOBALS - extern const JS_EXPORTDATA AtomicString nullAtom; - extern const JS_EXPORTDATA AtomicString emptyAtom; - extern const JS_EXPORTDATA AtomicString textAtom; - extern const JS_EXPORTDATA AtomicString commentAtom; - extern const JS_EXPORTDATA AtomicString starAtom; - extern const JS_EXPORTDATA AtomicString xmlAtom; - extern const JS_EXPORTDATA AtomicString xmlnsAtom; -#endif - - // AtomicStringHash is the default hash for AtomicString - template<typename T> struct DefaultHash; - template<> struct DefaultHash<AtomicString> { - typedef AtomicStringHash Hash; - }; - -} // namespace WTF - -#ifndef ATOMICSTRING_HIDE_GLOBALS -using WTF::AtomicString; -using WTF::nullAtom; -using WTF::emptyAtom; -using WTF::textAtom; -using WTF::commentAtom; -using WTF::starAtom; -using WTF::xmlAtom; -using WTF::xmlnsAtom; -#endif - -#endif // AtomicString_h diff --git a/JavaScriptCore/wtf/text/AtomicStringHash.h b/JavaScriptCore/wtf/text/AtomicStringHash.h deleted file mode 100644 index f6e4ad1..0000000 --- a/JavaScriptCore/wtf/text/AtomicStringHash.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef AtomicStringHash_h -#define AtomicStringHash_h - -#include <wtf/text/AtomicString.h> -#include <wtf/HashTraits.h> - -namespace WTF { - - struct AtomicStringHash { - static unsigned hash(const AtomicString& key) - { - return key.impl()->existingHash(); - } - - static bool equal(const AtomicString& a, const AtomicString& b) - { - return a == b; - } - - static const bool safeToCompareToEmptyOrDeleted = false; - }; - - // AtomicStringHash is the default hash for AtomicString - template<> struct HashTraits<WTF::AtomicString> : GenericHashTraits<WTF::AtomicString> { - static const bool emptyValueIsZero = true; - static void constructDeletedValue(WTF::AtomicString& slot) { new (&slot) WTF::AtomicString(HashTableDeletedValue); } - static bool isDeletedValue(const WTF::AtomicString& slot) { return slot.isHashTableDeletedValue(); } - }; - -} - -using WTF::AtomicStringHash; - -#endif diff --git a/JavaScriptCore/wtf/text/AtomicStringImpl.h b/JavaScriptCore/wtf/text/AtomicStringImpl.h deleted file mode 100644 index 3f0c376..0000000 --- a/JavaScriptCore/wtf/text/AtomicStringImpl.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2006 Apple Computer, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef AtomicStringImpl_h -#define AtomicStringImpl_h - -#include "StringImpl.h" - -namespace WTF { - -class AtomicStringImpl : public StringImpl -{ -public: - AtomicStringImpl() : StringImpl(0) {} -}; - -} - -using WTF::AtomicStringImpl; - -#endif diff --git a/JavaScriptCore/wtf/text/CString.cpp b/JavaScriptCore/wtf/text/CString.cpp deleted file mode 100644 index 981d77a..0000000 --- a/JavaScriptCore/wtf/text/CString.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - - -#include "config.h" -#include "CString.h" - -using namespace std; - -namespace WTF { - -CString::CString(const char* str) -{ - if (!str) - return; - - init(str, strlen(str)); -} - -CString::CString(const char* str, size_t length) -{ - init(str, length); -} - -void CString::init(const char* str, size_t length) -{ - if (!str) - return; - - // We need to be sure we can add 1 to length without overflowing. - // Since the passed-in length is the length of an actual existing - // string, and we know the string doesn't occupy the entire address - // space, we can assert here and there's no need for a runtime check. - ASSERT(length < numeric_limits<size_t>::max()); - - m_buffer = CStringBuffer::create(length + 1); - memcpy(m_buffer->mutableData(), str, length); - m_buffer->mutableData()[length] = '\0'; -} - -char* CString::mutableData() -{ - copyBufferIfNeeded(); - if (!m_buffer) - return 0; - return m_buffer->mutableData(); -} - -CString CString::newUninitialized(size_t length, char*& characterBuffer) -{ - if (length >= numeric_limits<size_t>::max()) - CRASH(); - - CString result; - result.m_buffer = CStringBuffer::create(length + 1); - char* bytes = result.m_buffer->mutableData(); - bytes[length] = '\0'; - characterBuffer = bytes; - return result; -} - -void CString::copyBufferIfNeeded() -{ - if (!m_buffer || m_buffer->hasOneRef()) - return; - - RefPtr<CStringBuffer> buffer = m_buffer.release(); - size_t length = buffer->length(); - m_buffer = CStringBuffer::create(length); - memcpy(m_buffer->mutableData(), buffer->data(), length); -} - -bool operator==(const CString& a, const CString& b) -{ - if (a.isNull() != b.isNull()) - return false; - if (a.length() != b.length()) - return false; - return !strncmp(a.data(), b.data(), min(a.length(), b.length())); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/text/CString.h b/JavaScriptCore/wtf/text/CString.h deleted file mode 100644 index 343a7a5..0000000 --- a/JavaScriptCore/wtf/text/CString.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2003, 2006, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef CString_h -#define CString_h - -#include "PassRefPtr.h" -#include "RefCounted.h" -#include "Vector.h" - -namespace WTF { - -class CStringBuffer : public RefCounted<CStringBuffer> { -public: - const char* data() { return m_vector.data(); } - size_t length() { return m_vector.size(); } - -private: - friend class CString; - - static PassRefPtr<CStringBuffer> create(size_t length) { return adoptRef(new CStringBuffer(length)); } - CStringBuffer(size_t length) : m_vector(length) { } - char* mutableData() { return m_vector.data(); } - - Vector<char> m_vector; -}; - -// A container for a null-terminated char array supporting copy-on-write -// assignment. The contained char array may be null. -class CString { -public: - CString() { } - CString(const char*); - CString(const char*, size_t length); - CString(CStringBuffer* buffer) : m_buffer(buffer) { } - static CString newUninitialized(size_t length, char*& characterBuffer); - - const char* data() const - { - return m_buffer ? m_buffer->data() : 0; - } - char* mutableData(); - size_t length() const - { - return m_buffer ? m_buffer->length() - 1 : 0; - } - - bool isNull() const { return !m_buffer; } - - CStringBuffer* buffer() const { return m_buffer.get(); } - -private: - void copyBufferIfNeeded(); - void init(const char*, size_t length); - RefPtr<CStringBuffer> m_buffer; -}; - -bool operator==(const CString& a, const CString& b); -inline bool operator!=(const CString& a, const CString& b) { return !(a == b); } - -} // namespace WTF - -using WTF::CString; - -#endif // CString_h diff --git a/JavaScriptCore/wtf/text/StringBuffer.h b/JavaScriptCore/wtf/text/StringBuffer.h deleted file mode 100644 index a546bf3..0000000 --- a/JavaScriptCore/wtf/text/StringBuffer.h +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (C) 2008, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Inc. ("Apple") nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StringBuffer_h -#define StringBuffer_h - -#include <wtf/Assertions.h> -#include <wtf/Noncopyable.h> -#include <wtf/unicode/Unicode.h> -#include <limits> - -namespace WTF { - -class StringBuffer : public Noncopyable { -public: - explicit StringBuffer(unsigned length) - : m_length(length) - { - if (m_length > std::numeric_limits<unsigned>::max() / sizeof(UChar)) - CRASH(); - m_data = static_cast<UChar*>(fastMalloc(m_length * sizeof(UChar))); - } - - ~StringBuffer() - { - fastFree(m_data); - } - - void shrink(unsigned newLength) - { - ASSERT(newLength <= m_length); - m_length = newLength; - } - - void resize(unsigned newLength) - { - if (newLength > m_length) { - if (newLength > std::numeric_limits<unsigned>::max() / sizeof(UChar)) - CRASH(); - m_data = static_cast<UChar*>(fastRealloc(m_data, newLength * sizeof(UChar))); - } - m_length = newLength; - } - - unsigned length() const { return m_length; } - UChar* characters() { return m_data; } - - UChar& operator[](unsigned i) { ASSERT(i < m_length); return m_data[i]; } - - UChar* release() { UChar* data = m_data; m_data = 0; return data; } - -private: - unsigned m_length; - UChar* m_data; -}; - -} // namespace WTF - -using WTF::StringBuffer; - -#endif // StringBuffer_h diff --git a/JavaScriptCore/wtf/text/StringBuilder.cpp b/JavaScriptCore/wtf/text/StringBuilder.cpp deleted file mode 100644 index dfc9ff3..0000000 --- a/JavaScriptCore/wtf/text/StringBuilder.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "StringBuilder.h" - -#include "WTFString.h" - -namespace WTF { - -void StringBuilder::reifyString() -{ - // Check if the string already exists. - if (!m_string.isNull()) { - ASSERT(m_string.length() == m_length); - return; - } - - // Check for empty. - if (!m_length) { - m_string = StringImpl::empty(); - return; - } - - // Must be valid in the buffer, take a substring (unless string fills the buffer). - ASSERT(m_buffer && m_length <= m_buffer->length()); - m_string = (m_length == m_buffer->length()) - ? m_buffer.get() - : StringImpl::create(m_buffer, 0, m_length); -} - -void StringBuilder::resize(unsigned newSize) -{ - // Check newSize < m_length, hence m_length > 0. - ASSERT(newSize <= m_length); - if (newSize == m_length) - return; - ASSERT(m_length); - - // If there is a buffer, we only need to duplicate it if it has more than one ref. - if (m_buffer) { - if (!m_buffer->hasOneRef()) - allocateBuffer(m_buffer->characters(), m_buffer->length()); - m_length = newSize; - m_string = String(); - return; - } - - // Since m_length && !m_buffer, the string must be valid in m_string, and m_string.length() > 0. - ASSERT(!m_string.isEmpty()); - ASSERT(m_length == m_string.length()); - ASSERT(newSize < m_string.length()); - m_length = newSize; - m_string = StringImpl::create(m_string.impl(), 0, newSize); -} - -void StringBuilder::reserveCapacity(unsigned newCapacity) -{ - if (m_buffer) { - // If there is already a buffer, then grow if necessary. - if (newCapacity > m_buffer->length()) - allocateBuffer(m_buffer->characters(), newCapacity); - } else { - // Grow the string, if necessary. - if (newCapacity > m_length) - allocateBuffer(m_string.characters(), newCapacity); - } -} - -// Allocate a new buffer, copying in currentCharacters (these may come from either m_string -// or m_buffer, neither will be reassigned until the copy has completed). -void StringBuilder::allocateBuffer(const UChar* currentCharacters, unsigned requiredLength) -{ - // Copy the existing data into a new buffer, set result to point to the end of the existing data. - RefPtr<StringImpl> buffer = StringImpl::createUninitialized(requiredLength, m_bufferCharacters); - memcpy(m_bufferCharacters, currentCharacters, static_cast<size_t>(m_length) * sizeof(UChar)); // This can't overflow. - - // Update the builder state. - m_buffer = buffer.release(); - m_string = String(); -} - -// Make 'length' additional capacity be available in m_buffer, update m_string & m_length, -// return a pointer to the newly allocated storage. -UChar* StringBuilder::appendUninitialized(unsigned length) -{ - ASSERT(length); - - // Calcuate the new size of the builder after appending. - unsigned requiredLength = length + m_length; - if (requiredLength < length) - CRASH(); - - if (m_buffer) { - // If the buffer is valid it must be at least as long as the current builder contents! - ASSERT(m_buffer->length() >= m_length); - - // Check if the buffer already has sufficient capacity. - if (requiredLength <= m_buffer->length()) { - unsigned currentLength = m_length; - m_string = String(); - m_length = requiredLength; - return m_bufferCharacters + currentLength; - } - - // We need to realloc the buffer. - allocateBuffer(m_buffer->characters(), std::max(requiredLength, m_buffer->length() * 2)); - } else { - ASSERT(m_string.length() == m_length); - allocateBuffer(m_string.characters(), std::max(requiredLength, requiredLength * 2)); - } - - UChar* result = m_bufferCharacters + m_length; - m_length = requiredLength; - return result; -} - -void StringBuilder::append(const UChar* characters, unsigned length) -{ - if (!length) - return; - ASSERT(characters); - - memcpy(appendUninitialized(length), characters, static_cast<size_t>(length) * 2); -} - -void StringBuilder::append(const char* characters, unsigned length) -{ - if (!length) - return; - ASSERT(characters); - - UChar* dest = appendUninitialized(length); - const char* end = characters + length; - while (characters < end) - *(dest++) = *(const unsigned char*)(characters++); -} - -void StringBuilder::shrinkToFit() -{ - // If the buffer is at least 80% full, don't bother copying. Need to tune this heuristic! - if (m_buffer && m_buffer->length() > (m_length + (m_length >> 2))) { - UChar* result; - m_string = StringImpl::createUninitialized(m_length, result); - memcpy(result, m_buffer->characters(), static_cast<size_t>(m_length) * 2); // This can't overflow. - m_buffer = 0; - } -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/text/StringBuilder.h b/JavaScriptCore/wtf/text/StringBuilder.h deleted file mode 100644 index f10af64..0000000 --- a/JavaScriptCore/wtf/text/StringBuilder.h +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2009, 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StringBuilder_h -#define StringBuilder_h - -#include <wtf/Vector.h> -#include <wtf/text/WTFString.h> - -namespace WTF { - -class StringBuilder { -public: - StringBuilder() - : m_length(0) - { - } - - void append(const UChar*, unsigned); - void append(const char*, unsigned); - - void append(const String& string) - { - // If we're appending to an empty string, and there is not buffer - // (in case reserveCapacity has been called) then just retain the - // string. - if (!m_length && !m_buffer) { - m_string = string; - m_length = string.length(); - return; - } - append(string.characters(), string.length()); - } - - void append(const char* characters) - { - if (characters) - append(characters, strlen(characters)); - } - - void append(UChar c) - { - if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) - m_bufferCharacters[m_length++] = c; - else - append(&c, 1); - } - - void append(char c) - { - if (m_buffer && m_length < m_buffer->length() && m_string.isNull()) - m_bufferCharacters[m_length++] = (unsigned char)c; - else - append(&c, 1); - } - - String toString() - { - if (m_string.isNull()) { - shrinkToFit(); - reifyString(); - } - return m_string; - } - - String toStringPreserveCapacity() - { - if (m_string.isNull()) - reifyString(); - return m_string; - } - - unsigned length() const - { - return m_length; - } - - bool isEmpty() const { return !length(); } - - void reserveCapacity(unsigned newCapacity); - - void resize(unsigned newSize); - - void shrinkToFit(); - - UChar operator[](unsigned i) const - { - ASSERT(i < m_length); - if (!m_string.isNull()) - return m_string[i]; - ASSERT(m_buffer); - return m_buffer->characters()[i]; - } - - void clear() - { - m_length = 0; - m_string = String(); - m_buffer = 0; - } - -private: - void allocateBuffer(const UChar* currentCharacters, unsigned requiredLength); - UChar* appendUninitialized(unsigned length); - void reifyString(); - - unsigned m_length; - String m_string; - RefPtr<StringImpl> m_buffer; - UChar* m_bufferCharacters; -}; - -} // namespace WTF - -using WTF::StringBuilder; - -#endif // StringBuilder_h diff --git a/JavaScriptCore/wtf/text/StringConcatenate.h b/JavaScriptCore/wtf/text/StringConcatenate.h deleted file mode 100644 index 92a2d06..0000000 --- a/JavaScriptCore/wtf/text/StringConcatenate.h +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StringConcatenate_h -#define StringConcatenate_h - -#include <wtf/text/WTFString.h> - -namespace WTF { - -template<typename StringType> -class StringTypeAdapter { -}; - -template<> -class StringTypeAdapter<char> { -public: - StringTypeAdapter<char>(char buffer) - : m_buffer(buffer) - { - } - - unsigned length() { return 1; } - void writeTo(UChar* destination) { *destination = m_buffer; } - -private: - unsigned char m_buffer; -}; - -template<> -class StringTypeAdapter<UChar> { -public: - StringTypeAdapter<UChar>(UChar buffer) - : m_buffer(buffer) - { - } - - unsigned length() { return 1; } - void writeTo(UChar* destination) { *destination = m_buffer; } - -private: - UChar m_buffer; -}; - -template<> -class StringTypeAdapter<char*> { -public: - StringTypeAdapter<char*>(char* buffer) - : m_buffer(buffer) - , m_length(strlen(buffer)) - { - } - - unsigned length() { return m_length; } - - void writeTo(UChar* destination) - { - for (unsigned i = 0; i < m_length; ++i) { - unsigned char c = m_buffer[i]; - destination[i] = c; - } - } - -private: - const char* m_buffer; - unsigned m_length; -}; - -template<> -class StringTypeAdapter<const char*> { -public: - StringTypeAdapter<const char*>(const char* buffer) - : m_buffer(buffer) - , m_length(strlen(buffer)) - { - } - - unsigned length() { return m_length; } - - void writeTo(UChar* destination) - { - for (unsigned i = 0; i < m_length; ++i) { - unsigned char c = m_buffer[i]; - destination[i] = c; - } - } - -private: - const char* m_buffer; - unsigned m_length; -}; - -template<> -class StringTypeAdapter<Vector<char> > { -public: - StringTypeAdapter<Vector<char> >(const Vector<char>& buffer) - : m_buffer(buffer) - { - } - - size_t length() { return m_buffer.size(); } - - void writeTo(UChar* destination) - { - for (size_t i = 0; i < m_buffer.size(); ++i) { - unsigned char c = m_buffer[i]; - destination[i] = c; - } - } - -private: - const Vector<char>& m_buffer; -}; - -template<> -class StringTypeAdapter<String> { -public: - StringTypeAdapter<String>(const String& string) - : m_buffer(string) - { - } - - unsigned length() { return m_buffer.length(); } - - void writeTo(UChar* destination) - { - const UChar* data = m_buffer.characters(); - unsigned length = m_buffer.length(); - for (unsigned i = 0; i < length; ++i) - destination[i] = data[i]; - } - -private: - const String& m_buffer; -}; - -inline void sumWithOverflow(unsigned& total, unsigned addend, bool& overflow) -{ - unsigned oldTotal = total; - total = oldTotal + addend; - if (total < oldTotal) - overflow = true; -} - -template<typename StringType1, typename StringType2> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - - UChar* buffer = 0; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - StringTypeAdapter<StringType6> adapter6(string6); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - sumWithOverflow(length, adapter6.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - result += adapter5.length(); - adapter6.writeTo(result); - - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - StringTypeAdapter<StringType6> adapter6(string6); - StringTypeAdapter<StringType7> adapter7(string7); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - sumWithOverflow(length, adapter6.length(), overflow); - sumWithOverflow(length, adapter7.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - result += adapter5.length(); - adapter6.writeTo(result); - result += adapter6.length(); - adapter7.writeTo(result); - - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> -PassRefPtr<StringImpl> tryMakeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) -{ - StringTypeAdapter<StringType1> adapter1(string1); - StringTypeAdapter<StringType2> adapter2(string2); - StringTypeAdapter<StringType3> adapter3(string3); - StringTypeAdapter<StringType4> adapter4(string4); - StringTypeAdapter<StringType5> adapter5(string5); - StringTypeAdapter<StringType6> adapter6(string6); - StringTypeAdapter<StringType7> adapter7(string7); - StringTypeAdapter<StringType8> adapter8(string8); - - UChar* buffer; - bool overflow = false; - unsigned length = adapter1.length(); - sumWithOverflow(length, adapter2.length(), overflow); - sumWithOverflow(length, adapter3.length(), overflow); - sumWithOverflow(length, adapter4.length(), overflow); - sumWithOverflow(length, adapter5.length(), overflow); - sumWithOverflow(length, adapter6.length(), overflow); - sumWithOverflow(length, adapter7.length(), overflow); - sumWithOverflow(length, adapter8.length(), overflow); - if (overflow) - return 0; - PassRefPtr<StringImpl> resultImpl = StringImpl::tryCreateUninitialized(length, buffer); - if (!resultImpl) - return 0; - - UChar* result = buffer; - adapter1.writeTo(result); - result += adapter1.length(); - adapter2.writeTo(result); - result += adapter2.length(); - adapter3.writeTo(result); - result += adapter3.length(); - adapter4.writeTo(result); - result += adapter4.length(); - adapter5.writeTo(result); - result += adapter5.length(); - adapter6.writeTo(result); - result += adapter6.length(); - adapter7.writeTo(result); - result += adapter7.length(); - adapter8.writeTo(result); - - return resultImpl; -} - -// Convenience only. -template<typename StringType1> -String makeString(StringType1 string1) -{ - return String(string1); -} - -template<typename StringType1, typename StringType2> -String makeString(StringType1 string1, StringType2 string2) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3> -String makeString(StringType1 string1, StringType2 string2, StringType3 string3) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4> -String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5> -String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6> -String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7> -String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -template<typename StringType1, typename StringType2, typename StringType3, typename StringType4, typename StringType5, typename StringType6, typename StringType7, typename StringType8> -String makeString(StringType1 string1, StringType2 string2, StringType3 string3, StringType4 string4, StringType5 string5, StringType6 string6, StringType7 string7, StringType8 string8) -{ - PassRefPtr<StringImpl> resultImpl = tryMakeString(string1, string2, string3, string4, string5, string6, string7, string8); - if (!resultImpl) - CRASH(); - return resultImpl; -} - -} // namespace WTF - -using WTF::makeString; - -#endif diff --git a/JavaScriptCore/wtf/text/StringHash.h b/JavaScriptCore/wtf/text/StringHash.h deleted file mode 100644 index d7aabdb..0000000 --- a/JavaScriptCore/wtf/text/StringHash.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved - * Copyright (C) Research In Motion Limited 2009. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef StringHash_h -#define StringHash_h - -#include "AtomicString.h" -#include "WTFString.h" -#include <wtf/Forward.h> -#include <wtf/HashTraits.h> -#include <wtf/StringHasher.h> -#include <wtf/unicode/Unicode.h> - -namespace WTF { - - // The hash() functions on StringHash and CaseFoldingHash do not support - // null strings. get(), contains(), and add() on HashMap<String,..., StringHash> - // cause a null-pointer dereference when passed null strings. - - // FIXME: We should really figure out a way to put the computeHash function that's - // currently a member function of StringImpl into this file so we can be a little - // closer to having all the nearly-identical hash functions in one place. - - struct StringHash { - static unsigned hash(StringImpl* key) { return key->hash(); } - static bool equal(const StringImpl* a, const StringImpl* b) - { - if (a == b) - return true; - if (!a || !b) - return false; - - unsigned aLength = a->length(); - unsigned bLength = b->length(); - if (aLength != bLength) - return false; - - // FIXME: perhaps we should have a more abstract macro that indicates when - // going 4 bytes at a time is unsafe -#if CPU(ARM) || CPU(SH4) || CPU(MIPS) - const UChar* aChars = a->characters(); - const UChar* bChars = b->characters(); - for (unsigned i = 0; i != aLength; ++i) { - if (*aChars++ != *bChars++) - return false; - } - return true; -#else - /* Do it 4-bytes-at-a-time on architectures where it's safe */ - const uint32_t* aChars = reinterpret_cast<const uint32_t*>(a->characters()); - const uint32_t* bChars = reinterpret_cast<const uint32_t*>(b->characters()); - - unsigned halfLength = aLength >> 1; - for (unsigned i = 0; i != halfLength; ++i) - if (*aChars++ != *bChars++) - return false; - - if (aLength & 1 && *reinterpret_cast<const uint16_t*>(aChars) != *reinterpret_cast<const uint16_t*>(bChars)) - return false; - - return true; -#endif - } - - static unsigned hash(const RefPtr<StringImpl>& key) { return key->hash(); } - static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b) - { - return equal(a.get(), b.get()); - } - - static unsigned hash(const String& key) { return key.impl()->hash(); } - static bool equal(const String& a, const String& b) - { - return equal(a.impl(), b.impl()); - } - - static const bool safeToCompareToEmptyOrDeleted = false; - }; - - class CaseFoldingHash { - public: - template<typename T> static inline UChar foldCase(T ch) - { - return WTF::Unicode::foldCase(ch); - } - - static unsigned hash(const UChar* data, unsigned length) - { - return StringHasher::createHash<UChar, foldCase<UChar> >(data, length); - } - - static unsigned hash(StringImpl* str) - { - return hash(str->characters(), str->length()); - } - - static unsigned hash(const char* data, unsigned length) - { - return StringHasher::createHash<char, foldCase<char> >(data, length); - } - - static bool equal(const StringImpl* a, const StringImpl* b) - { - if (a == b) - return true; - if (!a || !b) - return false; - unsigned length = a->length(); - if (length != b->length()) - return false; - return WTF::Unicode::umemcasecmp(a->characters(), b->characters(), length) == 0; - } - - static unsigned hash(const RefPtr<StringImpl>& key) - { - return hash(key.get()); - } - - static bool equal(const RefPtr<StringImpl>& a, const RefPtr<StringImpl>& b) - { - return equal(a.get(), b.get()); - } - - static unsigned hash(const String& key) - { - return hash(key.impl()); - } - static unsigned hash(const AtomicString& key) - { - return hash(key.impl()); - } - static bool equal(const String& a, const String& b) - { - return equal(a.impl(), b.impl()); - } - static bool equal(const AtomicString& a, const AtomicString& b) - { - return (a == b) || equal(a.impl(), b.impl()); - } - - static const bool safeToCompareToEmptyOrDeleted = false; - }; - - // This hash can be used in cases where the key is a hash of a string, but we don't - // want to store the string. It's not really specific to string hashing, but all our - // current uses of it are for strings. - struct AlreadyHashed : IntHash<unsigned> { - static unsigned hash(unsigned key) { return key; } - - // To use a hash value as a key for a hash table, we need to eliminate the - // "deleted" value, which is negative one. That could be done by changing - // the string hash function to never generate negative one, but this works - // and is still relatively efficient. - static unsigned avoidDeletedValue(unsigned hash) - { - ASSERT(hash); - unsigned newHash = hash | (!(hash + 1) << 31); - ASSERT(newHash); - ASSERT(newHash != 0xFFFFFFFF); - return newHash; - } - }; - - template<> struct HashTraits<String> : GenericHashTraits<String> { - static const bool emptyValueIsZero = true; - static void constructDeletedValue(String& slot) { new (&slot) String(HashTableDeletedValue); } - static bool isDeletedValue(const String& slot) { return slot.isHashTableDeletedValue(); } - }; - -} - -using WTF::StringHash; -using WTF::CaseFoldingHash; -using WTF::AlreadyHashed; - -#endif diff --git a/JavaScriptCore/wtf/text/StringImpl.cpp b/JavaScriptCore/wtf/text/StringImpl.cpp deleted file mode 100644 index c83ec42..0000000 --- a/JavaScriptCore/wtf/text/StringImpl.cpp +++ /dev/null @@ -1,1073 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * (C) 1999 Antti Koivisto (koivisto@kde.org) - * (C) 2001 Dirk Mueller ( mueller@kde.org ) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "StringImpl.h" - -#include "AtomicString.h" -#include "StringBuffer.h" -#include "StringHash.h" -#include <wtf/StdLibExtras.h> -#include <wtf/WTFThreadData.h> - -using namespace std; - -namespace WTF { - -using namespace Unicode; - -static const unsigned minLengthToShare = 20; - -COMPILE_ASSERT(sizeof(StringImpl) == 2 * sizeof(int) + 3 * sizeof(void*), StringImpl_should_stay_small); - -StringImpl::~StringImpl() -{ - ASSERT(!isStatic()); - - if (isAtomic()) - AtomicString::remove(this); -#if USE(JSC) - if (isIdentifier()) { - if (!wtfThreadData().currentIdentifierTable()->remove(this)) - CRASH(); - } -#endif - - BufferOwnership ownership = bufferOwnership(); - if (ownership != BufferInternal) { - if (ownership == BufferOwned) { - ASSERT(!m_sharedBuffer); - ASSERT(m_data); - fastFree(const_cast<UChar*>(m_data)); - } else if (ownership == BufferSubstring) { - ASSERT(m_substringBuffer); - m_substringBuffer->deref(); - } else { - ASSERT(ownership == BufferShared); - ASSERT(m_sharedBuffer); - m_sharedBuffer->deref(); - } - } -} - -PassRefPtr<StringImpl> StringImpl::createUninitialized(unsigned length, UChar*& data) -{ - if (!length) { - data = 0; - return empty(); - } - - // Allocate a single buffer large enough to contain the StringImpl - // struct as well as the data which it contains. This removes one - // heap allocation from this call. - if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) - CRASH(); - size_t size = sizeof(StringImpl) + length * sizeof(UChar); - StringImpl* string = static_cast<StringImpl*>(fastMalloc(size)); - - data = reinterpret_cast<UChar*>(string + 1); - return adoptRef(new (string) StringImpl(length)); -} - -PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length) -{ - if (!characters || !length) - return empty(); - - UChar* data; - RefPtr<StringImpl> string = createUninitialized(length, data); - memcpy(data, characters, length * sizeof(UChar)); - return string.release(); -} - -PassRefPtr<StringImpl> StringImpl::create(const char* characters, unsigned length) -{ - if (!characters || !length) - return empty(); - - UChar* data; - RefPtr<StringImpl> string = createUninitialized(length, data); - for (unsigned i = 0; i != length; ++i) { - unsigned char c = characters[i]; - data[i] = c; - } - return string.release(); -} - -PassRefPtr<StringImpl> StringImpl::create(const char* string) -{ - if (!string) - return empty(); - size_t length = strlen(string); - if (length > numeric_limits<unsigned>::max()) - CRASH(); - return create(string, length); -} - -PassRefPtr<StringImpl> StringImpl::create(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) -{ - ASSERT(characters); - ASSERT(minLengthToShare && length >= minLengthToShare); - return adoptRef(new StringImpl(characters, length, sharedBuffer)); -} - -SharedUChar* StringImpl::sharedBuffer() -{ - if (m_length < minLengthToShare) - return 0; - // All static strings are smaller that the minimim length to share. - ASSERT(!isStatic()); - - BufferOwnership ownership = bufferOwnership(); - - if (ownership == BufferInternal) - return 0; - if (ownership == BufferSubstring) - return m_substringBuffer->sharedBuffer(); - if (ownership == BufferOwned) { - ASSERT(!m_sharedBuffer); - m_sharedBuffer = SharedUChar::create(new SharableUChar(m_data)).leakRef(); - m_refCountAndFlags = (m_refCountAndFlags & ~s_refCountMaskBufferOwnership) | BufferShared; - } - - ASSERT(bufferOwnership() == BufferShared); - ASSERT(m_sharedBuffer); - return m_sharedBuffer; -} - -bool StringImpl::containsOnlyWhitespace() -{ - // FIXME: The definition of whitespace here includes a number of characters - // that are not whitespace from the point of view of RenderText; I wonder if - // that's a problem in practice. - for (unsigned i = 0; i < m_length; i++) - if (!isASCIISpace(m_data[i])) - return false; - return true; -} - -PassRefPtr<StringImpl> StringImpl::substring(unsigned start, unsigned length) -{ - if (start >= m_length) - return empty(); - unsigned maxLength = m_length - start; - if (length >= maxLength) { - if (!start) - return this; - length = maxLength; - } - return create(m_data + start, length); -} - -UChar32 StringImpl::characterStartingAt(unsigned i) -{ - if (U16_IS_SINGLE(m_data[i])) - return m_data[i]; - if (i + 1 < m_length && U16_IS_LEAD(m_data[i]) && U16_IS_TRAIL(m_data[i + 1])) - return U16_GET_SUPPLEMENTARY(m_data[i], m_data[i + 1]); - return 0; -} - -PassRefPtr<StringImpl> StringImpl::lower() -{ - // Note: This is a hot function in the Dromaeo benchmark, specifically the - // no-op code path up through the first 'return' statement. - - // First scan the string for uppercase and non-ASCII characters: - UChar ored = 0; - bool noUpper = true; - const UChar *end = m_data + m_length; - for (const UChar* chp = m_data; chp != end; chp++) { - if (UNLIKELY(isASCIIUpper(*chp))) - noUpper = false; - ored |= *chp; - } - - // Nothing to do if the string is all ASCII with no uppercase. - if (noUpper && !(ored & ~0x7F)) - return this; - - if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) - CRASH(); - int32_t length = m_length; - - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); - - if (!(ored & ~0x7F)) { - // Do a faster loop for the case where all the characters are ASCII. - for (int i = 0; i < length; i++) { - UChar c = m_data[i]; - data[i] = toASCIILower(c); - } - return newImpl; - } - - // Do a slower implementation for cases that include non-ASCII characters. - bool error; - int32_t realLength = Unicode::toLower(data, length, m_data, m_length, &error); - if (!error && realLength == length) - return newImpl; - newImpl = createUninitialized(realLength, data); - Unicode::toLower(data, realLength, m_data, m_length, &error); - if (error) - return this; - return newImpl; -} - -PassRefPtr<StringImpl> StringImpl::upper() -{ - // This function could be optimized for no-op cases the way lower() is, - // but in empirical testing, few actual calls to upper() are no-ops, so - // it wouldn't be worth the extra time for pre-scanning. - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); - - if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) - CRASH(); - int32_t length = m_length; - - // Do a faster loop for the case where all the characters are ASCII. - UChar ored = 0; - for (int i = 0; i < length; i++) { - UChar c = m_data[i]; - ored |= c; - data[i] = toASCIIUpper(c); - } - if (!(ored & ~0x7F)) - return newImpl.release(); - - // Do a slower implementation for cases that include non-ASCII characters. - bool error; - int32_t realLength = Unicode::toUpper(data, length, m_data, m_length, &error); - if (!error && realLength == length) - return newImpl; - newImpl = createUninitialized(realLength, data); - Unicode::toUpper(data, realLength, m_data, m_length, &error); - if (error) - return this; - return newImpl.release(); -} - -PassRefPtr<StringImpl> StringImpl::secure(UChar character, LastCharacterBehavior behavior) -{ - if (!m_length) - return this; - - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); - unsigned lastCharacterIndex = m_length - 1; - for (unsigned i = 0; i < lastCharacterIndex; ++i) - data[i] = character; - data[lastCharacterIndex] = (behavior == ObscureLastCharacter) ? character : m_data[lastCharacterIndex]; - return newImpl.release(); -} - -PassRefPtr<StringImpl> StringImpl::foldCase() -{ - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); - - if (m_length > static_cast<unsigned>(numeric_limits<int32_t>::max())) - CRASH(); - int32_t length = m_length; - - // Do a faster loop for the case where all the characters are ASCII. - UChar ored = 0; - for (int32_t i = 0; i < length; i++) { - UChar c = m_data[i]; - ored |= c; - data[i] = toASCIILower(c); - } - if (!(ored & ~0x7F)) - return newImpl.release(); - - // Do a slower implementation for cases that include non-ASCII characters. - bool error; - int32_t realLength = Unicode::foldCase(data, length, m_data, m_length, &error); - if (!error && realLength == length) - return newImpl.release(); - newImpl = createUninitialized(realLength, data); - Unicode::foldCase(data, realLength, m_data, m_length, &error); - if (error) - return this; - return newImpl.release(); -} - -PassRefPtr<StringImpl> StringImpl::stripWhiteSpace() -{ - if (!m_length) - return empty(); - - unsigned start = 0; - unsigned end = m_length - 1; - - // skip white space from start - while (start <= end && isSpaceOrNewline(m_data[start])) - start++; - - // only white space - if (start > end) - return empty(); - - // skip white space from end - while (end && isSpaceOrNewline(m_data[end])) - end--; - - if (!start && end == m_length - 1) - return this; - return create(m_data + start, end + 1 - start); -} - -PassRefPtr<StringImpl> StringImpl::removeCharacters(CharacterMatchFunctionPtr findMatch) -{ - const UChar* from = m_data; - const UChar* fromend = from + m_length; - - // Assume the common case will not remove any characters - while (from != fromend && !findMatch(*from)) - from++; - if (from == fromend) - return this; - - StringBuffer data(m_length); - UChar* to = data.characters(); - unsigned outc = from - m_data; - - if (outc) - memcpy(to, m_data, outc * sizeof(UChar)); - - while (true) { - while (from != fromend && findMatch(*from)) - from++; - while (from != fromend && !findMatch(*from)) - to[outc++] = *from++; - if (from == fromend) - break; - } - - data.shrink(outc); - - return adopt(data); -} - -PassRefPtr<StringImpl> StringImpl::simplifyWhiteSpace() -{ - StringBuffer data(m_length); - - const UChar* from = m_data; - const UChar* fromend = from + m_length; - int outc = 0; - bool changedToSpace = false; - - UChar* to = data.characters(); - - while (true) { - while (from != fromend && isSpaceOrNewline(*from)) { - if (*from != ' ') - changedToSpace = true; - from++; - } - while (from != fromend && !isSpaceOrNewline(*from)) - to[outc++] = *from++; - if (from != fromend) - to[outc++] = ' '; - else - break; - } - - if (outc > 0 && to[outc - 1] == ' ') - outc--; - - if (static_cast<unsigned>(outc) == m_length && !changedToSpace) - return this; - - data.shrink(outc); - - return adopt(data); -} - -int StringImpl::toIntStrict(bool* ok, int base) -{ - return charactersToIntStrict(m_data, m_length, ok, base); -} - -unsigned StringImpl::toUIntStrict(bool* ok, int base) -{ - return charactersToUIntStrict(m_data, m_length, ok, base); -} - -int64_t StringImpl::toInt64Strict(bool* ok, int base) -{ - return charactersToInt64Strict(m_data, m_length, ok, base); -} - -uint64_t StringImpl::toUInt64Strict(bool* ok, int base) -{ - return charactersToUInt64Strict(m_data, m_length, ok, base); -} - -intptr_t StringImpl::toIntPtrStrict(bool* ok, int base) -{ - return charactersToIntPtrStrict(m_data, m_length, ok, base); -} - -int StringImpl::toInt(bool* ok) -{ - return charactersToInt(m_data, m_length, ok); -} - -unsigned StringImpl::toUInt(bool* ok) -{ - return charactersToUInt(m_data, m_length, ok); -} - -int64_t StringImpl::toInt64(bool* ok) -{ - return charactersToInt64(m_data, m_length, ok); -} - -uint64_t StringImpl::toUInt64(bool* ok) -{ - return charactersToUInt64(m_data, m_length, ok); -} - -intptr_t StringImpl::toIntPtr(bool* ok) -{ - return charactersToIntPtr(m_data, m_length, ok); -} - -double StringImpl::toDouble(bool* ok) -{ - return charactersToDouble(m_data, m_length, ok); -} - -float StringImpl::toFloat(bool* ok) -{ - return charactersToFloat(m_data, m_length, ok); -} - -static bool equal(const UChar* a, const char* b, int length) -{ - ASSERT(length >= 0); - while (length--) { - unsigned char bc = *b++; - if (*a++ != bc) - return false; - } - return true; -} - -bool equalIgnoringCase(const UChar* a, const char* b, unsigned length) -{ - while (length--) { - unsigned char bc = *b++; - if (foldCase(*a++) != foldCase(bc)) - return false; - } - return true; -} - -static inline bool equalIgnoringCase(const UChar* a, const UChar* b, int length) -{ - ASSERT(length >= 0); - return umemcasecmp(a, b, length) == 0; -} - -int codePointCompare(const StringImpl* s1, const StringImpl* s2) -{ - const unsigned l1 = s1 ? s1->length() : 0; - const unsigned l2 = s2 ? s2->length() : 0; - const unsigned lmin = l1 < l2 ? l1 : l2; - const UChar* c1 = s1 ? s1->characters() : 0; - const UChar* c2 = s2 ? s2->characters() : 0; - unsigned pos = 0; - while (pos < lmin && *c1 == *c2) { - c1++; - c2++; - pos++; - } - - if (pos < lmin) - return (c1[0] > c2[0]) ? 1 : -1; - - if (l1 == l2) - return 0; - - return (l1 > l2) ? 1 : -1; -} - -size_t StringImpl::find(UChar c, unsigned start) -{ - return WTF::find(m_data, m_length, c, start); -} - -size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start) -{ - return WTF::find(m_data, m_length, matchFunction, start); -} - -size_t StringImpl::find(const char* matchString, unsigned index) -{ - // Check for null or empty string to match against - if (!matchString) - return notFound; - size_t matchStringLength = strlen(matchString); - if (matchStringLength > numeric_limits<unsigned>::max()) - CRASH(); - unsigned matchLength = matchStringLength; - if (!matchLength) - return min(index, length()); - - // Optimization 1: fast case for strings of length 1. - if (matchLength == 1) - return WTF::find(characters(), length(), *(const unsigned char*)matchString, index); - - // Check index & matchLength are in range. - if (index > length()) - return notFound; - unsigned searchLength = length() - index; - if (matchLength > searchLength) - return notFound; - // delta is the number of additional times to test; delta == 0 means test only once. - unsigned delta = searchLength - matchLength; - - const UChar* searchCharacters = characters() + index; - const unsigned char* matchCharacters = (const unsigned char*)matchString; - - // Optimization 2: keep a running hash of the strings, - // only call memcmp if the hashes match. - unsigned searchHash = 0; - unsigned matchHash = 0; - for (unsigned i = 0; i < matchLength; ++i) { - searchHash += searchCharacters[i]; - matchHash += matchCharacters[i]; - } - - unsigned i = 0; - // keep looping until we match - while (searchHash != matchHash || !equal(searchCharacters + i, matchString, matchLength)) { - if (i == delta) - return notFound; - searchHash += searchCharacters[i + matchLength]; - searchHash -= searchCharacters[i]; - ++i; - } - return index + i; -} - -size_t StringImpl::findIgnoringCase(const char* matchString, unsigned index) -{ - // Check for null or empty string to match against - if (!matchString) - return notFound; - size_t matchStringLength = strlen(matchString); - if (matchStringLength > numeric_limits<unsigned>::max()) - CRASH(); - unsigned matchLength = matchStringLength; - if (!matchLength) - return min(index, length()); - - // Check index & matchLength are in range. - if (index > length()) - return notFound; - unsigned searchLength = length() - index; - if (matchLength > searchLength) - return notFound; - // delta is the number of additional times to test; delta == 0 means test only once. - unsigned delta = searchLength - matchLength; - - const UChar* searchCharacters = characters() + index; - - unsigned i = 0; - // keep looping until we match - while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) { - if (i == delta) - return notFound; - ++i; - } - return index + i; -} - -size_t StringImpl::find(StringImpl* matchString, unsigned index) -{ - // Check for null or empty string to match against - if (!matchString) - return notFound; - unsigned matchLength = matchString->length(); - if (!matchLength) - return min(index, length()); - - // Optimization 1: fast case for strings of length 1. - if (matchLength == 1) - return WTF::find(characters(), length(), matchString->characters()[0], index); - - // Check index & matchLength are in range. - if (index > length()) - return notFound; - unsigned searchLength = length() - index; - if (matchLength > searchLength) - return notFound; - // delta is the number of additional times to test; delta == 0 means test only once. - unsigned delta = searchLength - matchLength; - - const UChar* searchCharacters = characters() + index; - const UChar* matchCharacters = matchString->characters(); - - // Optimization 2: keep a running hash of the strings, - // only call memcmp if the hashes match. - unsigned searchHash = 0; - unsigned matchHash = 0; - for (unsigned i = 0; i < matchLength; ++i) { - searchHash += searchCharacters[i]; - matchHash += matchCharacters[i]; - } - - unsigned i = 0; - // keep looping until we match - while (searchHash != matchHash || memcmp(searchCharacters + i, matchCharacters, matchLength * sizeof(UChar))) { - if (i == delta) - return notFound; - searchHash += searchCharacters[i + matchLength]; - searchHash -= searchCharacters[i]; - ++i; - } - return index + i; -} - -size_t StringImpl::findIgnoringCase(StringImpl* matchString, unsigned index) -{ - // Check for null or empty string to match against - if (!matchString) - return notFound; - unsigned matchLength = matchString->length(); - if (!matchLength) - return min(index, length()); - - // Check index & matchLength are in range. - if (index > length()) - return notFound; - unsigned searchLength = length() - index; - if (matchLength > searchLength) - return notFound; - // delta is the number of additional times to test; delta == 0 means test only once. - unsigned delta = searchLength - matchLength; - - const UChar* searchCharacters = characters() + index; - const UChar* matchCharacters = matchString->characters(); - - unsigned i = 0; - // keep looping until we match - while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { - if (i == delta) - return notFound; - ++i; - } - return index + i; -} - -size_t StringImpl::reverseFind(UChar c, unsigned index) -{ - return WTF::reverseFind(m_data, m_length, c, index); -} - -size_t StringImpl::reverseFind(StringImpl* matchString, unsigned index) -{ - // Check for null or empty string to match against - if (!matchString) - return notFound; - unsigned matchLength = matchString->length(); - if (!matchLength) - return min(index, length()); - - // Optimization 1: fast case for strings of length 1. - if (matchLength == 1) - return WTF::reverseFind(characters(), length(), matchString->characters()[0], index); - - // Check index & matchLength are in range. - if (matchLength > length()) - return notFound; - // delta is the number of additional times to test; delta == 0 means test only once. - unsigned delta = min(index, length() - matchLength); - - const UChar *searchCharacters = characters(); - const UChar *matchCharacters = matchString->characters(); - - // Optimization 2: keep a running hash of the strings, - // only call memcmp if the hashes match. - unsigned searchHash = 0; - unsigned matchHash = 0; - for (unsigned i = 0; i < matchLength; ++i) { - searchHash += searchCharacters[delta + i]; - matchHash += matchCharacters[i]; - } - - // keep looping until we match - while (searchHash != matchHash || memcmp(searchCharacters + delta, matchCharacters, matchLength * sizeof(UChar))) { - if (!delta) - return notFound; - delta--; - searchHash -= searchCharacters[delta + matchLength]; - searchHash += searchCharacters[delta]; - } - return delta; -} - -size_t StringImpl::reverseFindIgnoringCase(StringImpl* matchString, unsigned index) -{ - // Check for null or empty string to match against - if (!matchString) - return notFound; - unsigned matchLength = matchString->length(); - if (!matchLength) - return min(index, length()); - - // Check index & matchLength are in range. - if (matchLength > length()) - return notFound; - // delta is the number of additional times to test; delta == 0 means test only once. - unsigned delta = min(index, length() - matchLength); - - const UChar *searchCharacters = characters(); - const UChar *matchCharacters = matchString->characters(); - - // keep looping until we match - while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) { - if (!delta) - return notFound; - delta--; - } - return delta; -} - -bool StringImpl::endsWith(StringImpl* m_data, bool caseSensitive) -{ - ASSERT(m_data); - if (m_length >= m_data->m_length) { - unsigned start = m_length - m_data->m_length; - return (caseSensitive ? find(m_data, start) : findIgnoringCase(m_data, start)) == start; - } - return false; -} - -PassRefPtr<StringImpl> StringImpl::replace(UChar oldC, UChar newC) -{ - if (oldC == newC) - return this; - unsigned i; - for (i = 0; i != m_length; ++i) - if (m_data[i] == oldC) - break; - if (i == m_length) - return this; - - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(m_length, data); - - for (i = 0; i != m_length; ++i) { - UChar ch = m_data[i]; - if (ch == oldC) - ch = newC; - data[i] = ch; - } - return newImpl.release(); -} - -PassRefPtr<StringImpl> StringImpl::replace(unsigned position, unsigned lengthToReplace, StringImpl* str) -{ - position = min(position, length()); - lengthToReplace = min(lengthToReplace, length() - position); - unsigned lengthToInsert = str ? str->length() : 0; - if (!lengthToReplace && !lengthToInsert) - return this; - UChar* data; - - if ((length() - lengthToReplace) >= (numeric_limits<unsigned>::max() - lengthToInsert)) - CRASH(); - - RefPtr<StringImpl> newImpl = - createUninitialized(length() - lengthToReplace + lengthToInsert, data); - memcpy(data, characters(), position * sizeof(UChar)); - if (str) - memcpy(data + position, str->characters(), lengthToInsert * sizeof(UChar)); - memcpy(data + position + lengthToInsert, characters() + position + lengthToReplace, - (length() - position - lengthToReplace) * sizeof(UChar)); - return newImpl.release(); -} - -PassRefPtr<StringImpl> StringImpl::replace(UChar pattern, StringImpl* replacement) -{ - if (!replacement) - return this; - - unsigned repStrLength = replacement->length(); - size_t srcSegmentStart = 0; - unsigned matchCount = 0; - - // Count the matches - while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) { - ++matchCount; - ++srcSegmentStart; - } - - // If we have 0 matches, we don't have to do any more work - if (!matchCount) - return this; - - if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength) - CRASH(); - - unsigned replaceSize = matchCount * repStrLength; - unsigned newSize = m_length - matchCount; - if (newSize >= (numeric_limits<unsigned>::max() - replaceSize)) - CRASH(); - - newSize += replaceSize; - - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); - - // Construct the new data - size_t srcSegmentEnd; - unsigned srcSegmentLength; - srcSegmentStart = 0; - unsigned dstOffset = 0; - - while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) { - srcSegmentLength = srcSegmentEnd - srcSegmentStart; - memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); - dstOffset += srcSegmentLength; - memcpy(data + dstOffset, replacement->m_data, repStrLength * sizeof(UChar)); - dstOffset += repStrLength; - srcSegmentStart = srcSegmentEnd + 1; - } - - srcSegmentLength = m_length - srcSegmentStart; - memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); - - ASSERT(dstOffset + srcSegmentLength == newImpl->length()); - - return newImpl.release(); -} - -PassRefPtr<StringImpl> StringImpl::replace(StringImpl* pattern, StringImpl* replacement) -{ - if (!pattern || !replacement) - return this; - - unsigned patternLength = pattern->length(); - if (!patternLength) - return this; - - unsigned repStrLength = replacement->length(); - size_t srcSegmentStart = 0; - unsigned matchCount = 0; - - // Count the matches - while ((srcSegmentStart = find(pattern, srcSegmentStart)) != notFound) { - ++matchCount; - srcSegmentStart += patternLength; - } - - // If we have 0 matches, we don't have to do any more work - if (!matchCount) - return this; - - unsigned newSize = m_length - matchCount * patternLength; - if (repStrLength && matchCount > numeric_limits<unsigned>::max() / repStrLength) - CRASH(); - - if (newSize > (numeric_limits<unsigned>::max() - matchCount * repStrLength)) - CRASH(); - - newSize += matchCount * repStrLength; - - UChar* data; - RefPtr<StringImpl> newImpl = createUninitialized(newSize, data); - - // Construct the new data - size_t srcSegmentEnd; - unsigned srcSegmentLength; - srcSegmentStart = 0; - unsigned dstOffset = 0; - - while ((srcSegmentEnd = find(pattern, srcSegmentStart)) != notFound) { - srcSegmentLength = srcSegmentEnd - srcSegmentStart; - memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); - dstOffset += srcSegmentLength; - memcpy(data + dstOffset, replacement->m_data, repStrLength * sizeof(UChar)); - dstOffset += repStrLength; - srcSegmentStart = srcSegmentEnd + patternLength; - } - - srcSegmentLength = m_length - srcSegmentStart; - memcpy(data + dstOffset, m_data + srcSegmentStart, srcSegmentLength * sizeof(UChar)); - - ASSERT(dstOffset + srcSegmentLength == newImpl->length()); - - return newImpl.release(); -} - -bool equal(const StringImpl* a, const StringImpl* b) -{ - return StringHash::equal(a, b); -} - -bool equal(const StringImpl* a, const char* b) -{ - if (!a) - return !b; - if (!b) - return !a; - - unsigned length = a->length(); - const UChar* as = a->characters(); - for (unsigned i = 0; i != length; ++i) { - unsigned char bc = b[i]; - if (!bc) - return false; - if (as[i] != bc) - return false; - } - - return !b[length]; -} - -bool equalIgnoringCase(StringImpl* a, StringImpl* b) -{ - return CaseFoldingHash::equal(a, b); -} - -bool equalIgnoringCase(StringImpl* a, const char* b) -{ - if (!a) - return !b; - if (!b) - return !a; - - unsigned length = a->length(); - const UChar* as = a->characters(); - - // Do a faster loop for the case where all the characters are ASCII. - UChar ored = 0; - bool equal = true; - for (unsigned i = 0; i != length; ++i) { - char bc = b[i]; - if (!bc) - return false; - UChar ac = as[i]; - ored |= ac; - equal = equal && (toASCIILower(ac) == toASCIILower(bc)); - } - - // Do a slower implementation for cases that include non-ASCII characters. - if (ored & ~0x7F) { - equal = true; - for (unsigned i = 0; i != length; ++i) { - unsigned char bc = b[i]; - equal = equal && (foldCase(as[i]) == foldCase(bc)); - } - } - - return equal && !b[length]; -} - -bool equalIgnoringNullity(StringImpl* a, StringImpl* b) -{ - if (StringHash::equal(a, b)) - return true; - if (!a && b && !b->length()) - return true; - if (!b && a && !a->length()) - return true; - - return false; -} - -WTF::Unicode::Direction StringImpl::defaultWritingDirection() -{ - for (unsigned i = 0; i < m_length; ++i) { - WTF::Unicode::Direction charDirection = WTF::Unicode::direction(m_data[i]); - if (charDirection == WTF::Unicode::LeftToRight) - return WTF::Unicode::LeftToRight; - if (charDirection == WTF::Unicode::RightToLeft || charDirection == WTF::Unicode::RightToLeftArabic) - return WTF::Unicode::RightToLeft; - } - return WTF::Unicode::LeftToRight; -} - -// This is a hot function because it's used when parsing HTML. -PassRefPtr<StringImpl> StringImpl::createStrippingNullCharactersSlowCase(const UChar* characters, unsigned length) -{ - StringBuffer strippedCopy(length); - unsigned strippedLength = 0; - for (unsigned i = 0; i < length; i++) { - if (int c = characters[i]) - strippedCopy[strippedLength++] = c; - } - ASSERT(strippedLength < length); // Only take the slow case when stripping. - strippedCopy.shrink(strippedLength); - return adopt(strippedCopy); -} - -PassRefPtr<StringImpl> StringImpl::adopt(StringBuffer& buffer) -{ - unsigned length = buffer.length(); - if (length == 0) - return empty(); - return adoptRef(new StringImpl(buffer.release(), length)); -} - -PassRefPtr<StringImpl> StringImpl::createWithTerminatingNullCharacter(const StringImpl& string) -{ - // Use createUninitialized instead of 'new StringImpl' so that the string and its buffer - // get allocated in a single memory block. - UChar* data; - unsigned length = string.m_length; - if (length >= numeric_limits<unsigned>::max()) - CRASH(); - RefPtr<StringImpl> terminatedString = createUninitialized(length + 1, data); - memcpy(data, string.m_data, length * sizeof(UChar)); - data[length] = 0; - terminatedString->m_length--; - terminatedString->m_hash = string.m_hash; - terminatedString->m_refCountAndFlags |= s_refCountFlagHasTerminatingNullCharacter; - return terminatedString.release(); -} - -PassRefPtr<StringImpl> StringImpl::threadsafeCopy() const -{ - return create(m_data, m_length); -} - -PassRefPtr<StringImpl> StringImpl::crossThreadString() -{ - if (SharedUChar* sharedBuffer = this->sharedBuffer()) - return adoptRef(new StringImpl(m_data, m_length, sharedBuffer->crossThreadCopy())); - - // If no shared buffer is available, create a copy. - return threadsafeCopy(); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/text/StringImpl.h b/JavaScriptCore/wtf/text/StringImpl.h deleted file mode 100644 index dc1dbb2..0000000 --- a/JavaScriptCore/wtf/text/StringImpl.h +++ /dev/null @@ -1,408 +0,0 @@ -/* - * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2009 Google Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef StringImpl_h -#define StringImpl_h - -#include <limits.h> -#include <wtf/ASCIICType.h> -#include <wtf/CrossThreadRefCounted.h> -#include <wtf/Forward.h> -#include <wtf/OwnFastMallocPtr.h> -#include <wtf/StdLibExtras.h> -#include <wtf/StringHasher.h> -#include <wtf/Vector.h> -#include <wtf/text/StringImplBase.h> -#include <wtf/unicode/Unicode.h> - -#if PLATFORM(CF) -typedef const struct __CFString * CFStringRef; -#endif - -#ifdef __OBJC__ -@class NSString; -#endif - -// FIXME: This is a temporary layering violation while we move string code to WTF. -// Landing the file moves in one patch, will follow on with patches to change the namespaces. -namespace JSC { -struct IdentifierCStringTranslator; -struct IdentifierUCharBufferTranslator; -} - -namespace WTF { - -struct CStringTranslator; -struct HashAndCharactersTranslator; -struct HashAndUTF8CharactersTranslator; -struct UCharBufferTranslator; - -enum TextCaseSensitivity { TextCaseSensitive, TextCaseInsensitive }; - -typedef OwnFastMallocPtr<const UChar> SharableUChar; -typedef CrossThreadRefCounted<SharableUChar> SharedUChar; -typedef bool (*CharacterMatchFunctionPtr)(UChar); - -class StringImpl : public StringImplBase { - friend struct JSC::IdentifierCStringTranslator; - friend struct JSC::IdentifierUCharBufferTranslator; - friend struct WTF::CStringTranslator; - friend struct WTF::HashAndCharactersTranslator; - friend struct WTF::HashAndUTF8CharactersTranslator; - friend struct WTF::UCharBufferTranslator; - friend class AtomicStringImpl; -private: - // Used to construct static strings, which have an special refCount that can never hit zero. - // This means that the static string will never be destroyed, which is important because - // static strings will be shared across threads & ref-counted in a non-threadsafe manner. - StringImpl(const UChar* characters, unsigned length, StaticStringConstructType) - : StringImplBase(length, ConstructStaticString) - , m_data(characters) - , m_buffer(0) - , m_hash(0) - { - // Ensure that the hash is computed so that AtomicStringHash can call existingHash() - // with impunity. The empty string is special because it is never entered into - // AtomicString's HashKey, but still needs to compare correctly. - hash(); - } - - // Create a normal string with internal storage (BufferInternal) - StringImpl(unsigned length) - : StringImplBase(length, BufferInternal) - , m_data(reinterpret_cast<const UChar*>(this + 1)) - , m_buffer(0) - , m_hash(0) - { - ASSERT(m_data); - ASSERT(m_length); - } - - // Create a StringImpl adopting ownership of the provided buffer (BufferOwned) - StringImpl(const UChar* characters, unsigned length) - : StringImplBase(length, BufferOwned) - , m_data(characters) - , m_buffer(0) - , m_hash(0) - { - ASSERT(m_data); - ASSERT(m_length); - } - - // Used to create new strings that are a substring of an existing StringImpl (BufferSubstring) - StringImpl(const UChar* characters, unsigned length, PassRefPtr<StringImpl> base) - : StringImplBase(length, BufferSubstring) - , m_data(characters) - , m_substringBuffer(base.leakRef()) - , m_hash(0) - { - ASSERT(m_data); - ASSERT(m_length); - ASSERT(m_substringBuffer->bufferOwnership() != BufferSubstring); - } - - // Used to construct new strings sharing an existing SharedUChar (BufferShared) - StringImpl(const UChar* characters, unsigned length, PassRefPtr<SharedUChar> sharedBuffer) - : StringImplBase(length, BufferShared) - , m_data(characters) - , m_sharedBuffer(sharedBuffer.leakRef()) - , m_hash(0) - { - ASSERT(m_data); - ASSERT(m_length); - } - - // For use only by AtomicString's XXXTranslator helpers. - void setHash(unsigned hash) - { - ASSERT(!isStatic()); - ASSERT(!m_hash); - ASSERT(hash == computeHash(m_data, m_length)); - m_hash = hash; - } - -public: - ~StringImpl(); - - static PassRefPtr<StringImpl> create(const UChar*, unsigned length); - static PassRefPtr<StringImpl> create(const char*, unsigned length); - static PassRefPtr<StringImpl> create(const char*); - static PassRefPtr<StringImpl> create(const UChar*, unsigned length, PassRefPtr<SharedUChar> sharedBuffer); - static ALWAYS_INLINE PassRefPtr<StringImpl> create(PassRefPtr<StringImpl> rep, unsigned offset, unsigned length) - { - ASSERT(rep); - ASSERT(length <= rep->length()); - - if (!length) - return empty(); - - StringImpl* ownerRep = (rep->bufferOwnership() == BufferSubstring) ? rep->m_substringBuffer : rep.get(); - return adoptRef(new StringImpl(rep->m_data + offset, length, ownerRep)); - } - - static PassRefPtr<StringImpl> createUninitialized(unsigned length, UChar*& data); - static ALWAYS_INLINE PassRefPtr<StringImpl> tryCreateUninitialized(unsigned length, UChar*& output) - { - if (!length) { - output = 0; - return empty(); - } - - if (length > ((std::numeric_limits<unsigned>::max() - sizeof(StringImpl)) / sizeof(UChar))) { - output = 0; - return 0; - } - StringImpl* resultImpl; - if (!tryFastMalloc(sizeof(UChar) * length + sizeof(StringImpl)).getValue(resultImpl)) { - output = 0; - return 0; - } - output = reinterpret_cast<UChar*>(resultImpl + 1); - return adoptRef(new(resultImpl) StringImpl(length)); - } - - static unsigned dataOffset() { return OBJECT_OFFSETOF(StringImpl, m_data); } - static PassRefPtr<StringImpl> createWithTerminatingNullCharacter(const StringImpl&); - static PassRefPtr<StringImpl> createStrippingNullCharacters(const UChar*, unsigned length); - - template<size_t inlineCapacity> - static PassRefPtr<StringImpl> adopt(Vector<UChar, inlineCapacity>& vector) - { - if (size_t size = vector.size()) { - ASSERT(vector.data()); - if (size > std::numeric_limits<unsigned>::max()) - CRASH(); - return adoptRef(new StringImpl(vector.releaseBuffer(), size)); - } - return empty(); - } - static PassRefPtr<StringImpl> adopt(StringBuffer&); - - SharedUChar* sharedBuffer(); - const UChar* characters() const { return m_data; } - - size_t cost() - { - // For substrings, return the cost of the base string. - if (bufferOwnership() == BufferSubstring) - return m_substringBuffer->cost(); - - if (m_refCountAndFlags & s_refCountFlagShouldReportedCost) { - m_refCountAndFlags &= ~s_refCountFlagShouldReportedCost; - return m_length; - } - return 0; - } - - bool isIdentifier() const { return m_refCountAndFlags & s_refCountFlagIsIdentifier; } - void setIsIdentifier(bool isIdentifier) - { - ASSERT(!isStatic()); - if (isIdentifier) - m_refCountAndFlags |= s_refCountFlagIsIdentifier; - else - m_refCountAndFlags &= ~s_refCountFlagIsIdentifier; - } - - bool hasTerminatingNullCharacter() const { return m_refCountAndFlags & s_refCountFlagHasTerminatingNullCharacter; } - - bool isAtomic() const { return m_refCountAndFlags & s_refCountFlagIsAtomic; } - void setIsAtomic(bool isIdentifier) - { - ASSERT(!isStatic()); - if (isIdentifier) - m_refCountAndFlags |= s_refCountFlagIsAtomic; - else - m_refCountAndFlags &= ~s_refCountFlagIsAtomic; - } - - unsigned hash() const { if (!m_hash) m_hash = computeHash(m_data, m_length); return m_hash; } - unsigned existingHash() const { ASSERT(m_hash); return m_hash; } - static unsigned computeHash(const UChar* data, unsigned length) { return WTF::StringHasher::createHash<UChar>(data, length); } - static unsigned computeHash(const char* data, unsigned length) { return WTF::StringHasher::createHash<char>(data, length); } - static unsigned computeHash(const char* data) { return WTF::StringHasher::createHash<char>(data); } - - ALWAYS_INLINE void deref() { m_refCountAndFlags -= s_refCountIncrement; if (!(m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic))) delete this; } - ALWAYS_INLINE bool hasOneRef() const { return (m_refCountAndFlags & (s_refCountMask | s_refCountFlagStatic)) == s_refCountIncrement; } - - static StringImpl* empty(); - - static void copyChars(UChar* destination, const UChar* source, unsigned numCharacters) - { - if (numCharacters <= s_copyCharsInlineCutOff) { - for (unsigned i = 0; i < numCharacters; ++i) - destination[i] = source[i]; - } else - memcpy(destination, source, numCharacters * sizeof(UChar)); - } - - // Returns a StringImpl suitable for use on another thread. - PassRefPtr<StringImpl> crossThreadString(); - // Makes a deep copy. Helpful only if you need to use a String on another thread - // (use crossThreadString if the method call doesn't need to be threadsafe). - // Since StringImpl objects are immutable, there's no other reason to make a copy. - PassRefPtr<StringImpl> threadsafeCopy() const; - - PassRefPtr<StringImpl> substring(unsigned pos, unsigned len = UINT_MAX); - - UChar operator[](unsigned i) { ASSERT(i < m_length); return m_data[i]; } - UChar32 characterStartingAt(unsigned); - - bool containsOnlyWhitespace(); - - int toIntStrict(bool* ok = 0, int base = 10); - unsigned toUIntStrict(bool* ok = 0, int base = 10); - int64_t toInt64Strict(bool* ok = 0, int base = 10); - uint64_t toUInt64Strict(bool* ok = 0, int base = 10); - intptr_t toIntPtrStrict(bool* ok = 0, int base = 10); - - int toInt(bool* ok = 0); // ignores trailing garbage - unsigned toUInt(bool* ok = 0); // ignores trailing garbage - int64_t toInt64(bool* ok = 0); // ignores trailing garbage - uint64_t toUInt64(bool* ok = 0); // ignores trailing garbage - intptr_t toIntPtr(bool* ok = 0); // ignores trailing garbage - - double toDouble(bool* ok = 0); - float toFloat(bool* ok = 0); - - PassRefPtr<StringImpl> lower(); - PassRefPtr<StringImpl> upper(); - - enum LastCharacterBehavior { ObscureLastCharacter, DisplayLastCharacter }; - - PassRefPtr<StringImpl> secure(UChar, LastCharacterBehavior = ObscureLastCharacter); - PassRefPtr<StringImpl> foldCase(); - - PassRefPtr<StringImpl> stripWhiteSpace(); - PassRefPtr<StringImpl> simplifyWhiteSpace(); - - PassRefPtr<StringImpl> removeCharacters(CharacterMatchFunctionPtr); - - size_t find(UChar, unsigned index = 0); - size_t find(CharacterMatchFunctionPtr, unsigned index = 0); - size_t find(const char*, unsigned index = 0); - size_t find(StringImpl*, unsigned index = 0); - size_t findIgnoringCase(const char*, unsigned index = 0); - size_t findIgnoringCase(StringImpl*, unsigned index = 0); - - size_t reverseFind(UChar, unsigned index = UINT_MAX); - size_t reverseFind(StringImpl*, unsigned index = UINT_MAX); - size_t reverseFindIgnoringCase(StringImpl*, unsigned index = UINT_MAX); - - bool startsWith(StringImpl* str, bool caseSensitive = true) { return (caseSensitive ? reverseFind(str, 0) : reverseFindIgnoringCase(str, 0)) == 0; } - bool endsWith(StringImpl*, bool caseSensitive = true); - - PassRefPtr<StringImpl> replace(UChar, UChar); - PassRefPtr<StringImpl> replace(UChar, StringImpl*); - PassRefPtr<StringImpl> replace(StringImpl*, StringImpl*); - PassRefPtr<StringImpl> replace(unsigned index, unsigned len, StringImpl*); - - WTF::Unicode::Direction defaultWritingDirection(); - -#if PLATFORM(CF) - CFStringRef createCFString(); -#endif -#ifdef __OBJC__ - operator NSString*(); -#endif - -private: - // This number must be at least 2 to avoid sharing empty, null as well as 1 character strings from SmallStrings. - static const unsigned s_copyCharsInlineCutOff = 20; - - static PassRefPtr<StringImpl> createStrippingNullCharactersSlowCase(const UChar*, unsigned length); - - BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_refCountAndFlags & s_refCountMaskBufferOwnership); } - bool isStatic() const { return m_refCountAndFlags & s_refCountFlagStatic; } - const UChar* m_data; - union { - void* m_buffer; - StringImpl* m_substringBuffer; - SharedUChar* m_sharedBuffer; - }; - mutable unsigned m_hash; -}; - -bool equal(const StringImpl*, const StringImpl*); -bool equal(const StringImpl*, const char*); -inline bool equal(const char* a, StringImpl* b) { return equal(b, a); } - -bool equalIgnoringCase(StringImpl*, StringImpl*); -bool equalIgnoringCase(StringImpl*, const char*); -inline bool equalIgnoringCase(const char* a, StringImpl* b) { return equalIgnoringCase(b, a); } -bool equalIgnoringCase(const UChar* a, const char* b, unsigned length); -inline bool equalIgnoringCase(const char* a, const UChar* b, unsigned length) { return equalIgnoringCase(b, a, length); } - -bool equalIgnoringNullity(StringImpl*, StringImpl*); - -int codePointCompare(const StringImpl*, const StringImpl*); - -static inline bool isSpaceOrNewline(UChar c) -{ - // Use isASCIISpace() for basic Latin-1. - // This will include newlines, which aren't included in Unicode DirWS. - return c <= 0x7F ? WTF::isASCIISpace(c) : WTF::Unicode::direction(c) == WTF::Unicode::WhiteSpaceNeutral; -} - -// This is a hot function because it's used when parsing HTML. -inline PassRefPtr<StringImpl> StringImpl::createStrippingNullCharacters(const UChar* characters, unsigned length) -{ - ASSERT(characters); - ASSERT(length); - - // Optimize for the case where there are no Null characters by quickly - // searching for nulls, and then using StringImpl::create, which will - // memcpy the whole buffer. This is faster than assigning character by - // character during the loop. - - // Fast case. - int foundNull = 0; - for (unsigned i = 0; !foundNull && i < length; i++) { - int c = characters[i]; // more efficient than using UChar here (at least on Intel Mac OS) - foundNull |= !c; - } - if (!foundNull) - return StringImpl::create(characters, length); - - return StringImpl::createStrippingNullCharactersSlowCase(characters, length); -} - -struct StringHash; - -// StringHash is the default hash for StringImpl* and RefPtr<StringImpl> -template<typename T> struct DefaultHash; -template<> struct DefaultHash<StringImpl*> { - typedef StringHash Hash; -}; -template<> struct DefaultHash<RefPtr<StringImpl> > { - typedef StringHash Hash; -}; - -} - -using WTF::StringImpl; -using WTF::equal; -using WTF::TextCaseSensitivity; -using WTF::TextCaseSensitive; -using WTF::TextCaseInsensitive; - -#endif diff --git a/JavaScriptCore/wtf/text/StringImplBase.h b/JavaScriptCore/wtf/text/StringImplBase.h deleted file mode 100644 index 6567672..0000000 --- a/JavaScriptCore/wtf/text/StringImplBase.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef StringImplBase_h -#define StringImplBase_h - -#include <wtf/Noncopyable.h> -#include <wtf/unicode/Unicode.h> - -namespace WTF { - -class StringImplBase : public Noncopyable { -public: - bool isStringImpl() { return (m_refCountAndFlags & s_refCountInvalidForStringImpl) != s_refCountInvalidForStringImpl; } - unsigned length() const { return m_length; } - void ref() { m_refCountAndFlags += s_refCountIncrement; } - -protected: - enum BufferOwnership { - BufferInternal, - BufferOwned, - BufferSubstring, - BufferShared, - }; - - using Noncopyable::operator new; - void* operator new(size_t, void* inPlace) { ASSERT(inPlace); return inPlace; } - - // For SmallStringStorage, which allocates an array and uses an in-place new. - StringImplBase() { } - - StringImplBase(unsigned length, BufferOwnership ownership) - : m_refCountAndFlags(s_refCountIncrement | s_refCountFlagShouldReportedCost | ownership) - , m_length(length) - { - ASSERT(isStringImpl()); - } - - enum StaticStringConstructType { ConstructStaticString }; - StringImplBase(unsigned length, StaticStringConstructType) - : m_refCountAndFlags(s_refCountFlagStatic | s_refCountFlagIsIdentifier | BufferOwned) - , m_length(length) - { - ASSERT(isStringImpl()); - } - - // This constructor is not used when creating StringImpl objects, - // and sets the flags into a state marking the object as such. - enum NonStringImplConstructType { ConstructNonStringImpl }; - StringImplBase(NonStringImplConstructType) - : m_refCountAndFlags(s_refCountIncrement | s_refCountInvalidForStringImpl) - , m_length(0) - { - ASSERT(!isStringImpl()); - } - - // The bottom 7 bits hold flags, the top 25 bits hold the ref count. - // When dereferencing StringImpls we check for the ref count AND the - // static bit both being zero - static strings are never deleted. - static const unsigned s_refCountMask = 0xFFFFFF80; - static const unsigned s_refCountIncrement = 0x80; - static const unsigned s_refCountFlagStatic = 0x40; - static const unsigned s_refCountFlagHasTerminatingNullCharacter = 0x20; - static const unsigned s_refCountFlagIsAtomic = 0x10; - static const unsigned s_refCountFlagShouldReportedCost = 0x8; - static const unsigned s_refCountFlagIsIdentifier = 0x4; - static const unsigned s_refCountMaskBufferOwnership = 0x3; - // An invalid permutation of flags (static & shouldReportedCost - static strings do not - // set shouldReportedCost in the constructor, and this bit is only ever cleared, not set). - // Used by "ConstructNonStringImpl" constructor, above. - static const unsigned s_refCountInvalidForStringImpl = s_refCountFlagStatic | s_refCountFlagShouldReportedCost; - - unsigned m_refCountAndFlags; - unsigned m_length; -}; - -} // namespace WTF - -using WTF::StringImplBase; - -#endif diff --git a/JavaScriptCore/wtf/text/StringStatics.cpp b/JavaScriptCore/wtf/text/StringStatics.cpp deleted file mode 100644 index 5654044..0000000 --- a/JavaScriptCore/wtf/text/StringStatics.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2010 Apple Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" - -#ifdef SKIP_STATIC_CONSTRUCTORS_ON_GCC -#define ATOMICSTRING_HIDE_GLOBALS 1 -#endif - -#include "AtomicString.h" -#include "StaticConstructors.h" -#include "StringImpl.h" - -namespace WTF { - -StringImpl* StringImpl::empty() -{ - // FIXME: This works around a bug in our port of PCRE, that a regular expression - // run on the empty string may still perform a read from the first element, and - // as such we need this to be a valid pointer. No code should ever be reading - // from a zero length string, so this should be able to be a non-null pointer - // into the zero-page. - // Replace this with 'reinterpret_cast<UChar*>(static_cast<intptr_t>(1))' once - // PCRE goes away. - static UChar emptyUCharData = 0; - DEFINE_STATIC_LOCAL(StringImpl, emptyString, (&emptyUCharData, 0, ConstructStaticString)); - return &emptyString; -} - -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, nullAtom) -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, emptyAtom, "") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, textAtom, "#text") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, commentAtom, "#comment") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, starAtom, "*") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlAtom, "xml") -JS_EXPORTDATA DEFINE_GLOBAL(AtomicString, xmlnsAtom, "xmlns") - -void AtomicString::init() -{ - static bool initialized; - if (!initialized) { - // Initialization is not thread safe, so this function must be called from the main thread first. - ASSERT(isMainThread()); - - // Use placement new to initialize the globals. - new ((void*)&nullAtom) AtomicString; - new ((void*)&emptyAtom) AtomicString(""); - new ((void*)&textAtom) AtomicString("#text"); - new ((void*)&commentAtom) AtomicString("#comment"); - new ((void*)&starAtom) AtomicString("*"); - new ((void*)&xmlAtom) AtomicString("xml"); - new ((void*)&xmlnsAtom) AtomicString("xmlns"); - - initialized = true; - } -} - -} diff --git a/JavaScriptCore/wtf/text/TextPosition.h b/JavaScriptCore/wtf/text/TextPosition.h deleted file mode 100644 index 63dc594..0000000 --- a/JavaScriptCore/wtf/text/TextPosition.h +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright (C) 2010, Google Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TextPosition_h -#define TextPosition_h - -#include <wtf/Assertions.h> - -namespace WTF { - -/* - * Text Position - * - * TextPosition structure specifies coordinates within an text resource. It is used mostly - * for saving script source position. - * - * Later TextPosition0 and TextPosition1 and both number types can be merged together quite easily. - * - * 0-based and 1-based - * - * Line and column numbers could be interpreted as zero-based or 1-based. Since - * both practices coexist in WebKit source base, 'int' type should be replaced with - * a dedicated wrapper types, so that compiler helped us with this ambiguity. - * - * Here we introduce 2 types of numbers: ZeroBasedNumber and OneBasedNumber and - * 2 corresponding types of TextPosition structure. While only one type ought to be enough, - * this is done to keep transition to the new types as transparent as possible: - * e.g. in areas where 0-based integers are used, TextPosition0 should be introduced. This - * way all changes will remain trackable. - * - * Later both number types can be merged in one type quite easily. - * - * For type safety and for the future type merge it is important that all operations in API - * that accept or return integer have a name explicitly defining base of integer. For this reason - * int-receiving constructors are hidden from API. - */ - -template<typename NUMBER> -class TextPosition { -public: - TextPosition(NUMBER line, NUMBER column) - : m_line(line) - , m_column(column) - { - } - TextPosition() {} - - // A 'minimum' value of position, used as a default value. - static TextPosition<NUMBER> minimumPosition() { return TextPosition<NUMBER>(NUMBER::base(), NUMBER::base()); } - - // A value with line value less than a minimum; used as an impossible position. - static TextPosition<NUMBER> belowRangePosition() { return TextPosition<NUMBER>(NUMBER::belowBase(), NUMBER::base()); } - - NUMBER m_line; - NUMBER m_column; -}; - -class OneBasedNumber; - -// An int wrapper that always reminds you that the number should be 0-based -class ZeroBasedNumber { -public: - static ZeroBasedNumber fromZeroBasedInt(int zeroBasedInt) { return ZeroBasedNumber(zeroBasedInt); } - - ZeroBasedNumber() {} - - int zeroBasedInt() const { return m_value; } - - OneBasedNumber convertToOneBased() const; - - static ZeroBasedNumber base() { return 0; } - static ZeroBasedNumber belowBase() { return -1; } - -private: - ZeroBasedNumber(int value) : m_value(value) {} - int m_value; -}; - -// An int wrapper that always reminds you that the number should be 1-based -class OneBasedNumber { -public: - static OneBasedNumber fromOneBasedInt(int oneBasedInt) { return OneBasedNumber(oneBasedInt); } - OneBasedNumber() {} - - int oneBasedInt() const { return m_value; } - int convertAsZeroBasedInt() const { return m_value - 1; } - ZeroBasedNumber convertToZeroBased() const { return ZeroBasedNumber::fromZeroBasedInt(m_value - 1); } - - static OneBasedNumber base() { return 1; } - static OneBasedNumber belowBase() { return 0; } - -private: - OneBasedNumber(int value) : m_value(value) {} - int m_value; -}; - -typedef TextPosition<ZeroBasedNumber> TextPosition0; -typedef TextPosition<OneBasedNumber> TextPosition1; - -inline TextPosition0 toZeroBasedTextPosition(const TextPosition1& position) -{ - return TextPosition0(position.m_line.convertToZeroBased(), position.m_column.convertToZeroBased()); -} - -inline TextPosition1 toOneBasedTextPosition(const TextPosition0& position) -{ - return TextPosition1(position.m_line.convertToOneBased(), position.m_column.convertToOneBased()); -} - -inline OneBasedNumber ZeroBasedNumber::convertToOneBased() const -{ - return OneBasedNumber::fromOneBasedInt(m_value + 1); -} - -} - -using WTF::TextPosition0; -using WTF::TextPosition1; - -#endif // TextPosition_h diff --git a/JavaScriptCore/wtf/text/WTFString.cpp b/JavaScriptCore/wtf/text/WTFString.cpp deleted file mode 100644 index 6bb74f6..0000000 --- a/JavaScriptCore/wtf/text/WTFString.cpp +++ /dev/null @@ -1,1003 +0,0 @@ -/* - * (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "WTFString.h" - -#include <stdarg.h> -#include <wtf/ASCIICType.h> -#include <wtf/text/CString.h> -#include <wtf/StringExtras.h> -#include <wtf/Vector.h> -#include <wtf/dtoa.h> -#include <wtf/unicode/UTF8.h> -#include <wtf/unicode/Unicode.h> - -using namespace std; - -namespace WTF { - -using namespace Unicode; -using namespace std; - -// Construct a string with UTF-16 data. -String::String(const UChar* characters, unsigned length) - : m_impl(characters ? StringImpl::create(characters, length) : 0) -{ -} - -// Construct a string with UTF-16 data, from a null-terminated source. -String::String(const UChar* str) -{ - if (!str) - return; - - size_t len = 0; - while (str[len] != UChar(0)) - len++; - - if (len > numeric_limits<unsigned>::max()) - CRASH(); - - m_impl = StringImpl::create(str, len); -} - -// Construct a string with latin1 data. -String::String(const char* characters, unsigned length) - : m_impl(characters ? StringImpl::create(characters, length) : 0) -{ -} - -// Construct a string with latin1 data, from a null-terminated source. -String::String(const char* characters) - : m_impl(characters ? StringImpl::create(characters) : 0) -{ -} - -void String::append(const String& str) -{ - if (str.isEmpty()) - return; - - // FIXME: This is extremely inefficient. So much so that we might want to take this - // out of String's API. We can make it better by optimizing the case where exactly - // one String is pointing at this StringImpl, but even then it's going to require a - // call to fastMalloc every single time. - if (str.m_impl) { - if (m_impl) { - UChar* data; - if (str.length() > numeric_limits<unsigned>::max() - m_impl->length()) - CRASH(); - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + str.length(), data); - memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar)); - memcpy(data + m_impl->length(), str.characters(), str.length() * sizeof(UChar)); - m_impl = newImpl.release(); - } else - m_impl = str.m_impl; - } -} - -void String::append(char c) -{ - // FIXME: This is extremely inefficient. So much so that we might want to take this - // out of String's API. We can make it better by optimizing the case where exactly - // one String is pointing at this StringImpl, but even then it's going to require a - // call to fastMalloc every single time. - if (m_impl) { - UChar* data; - if (m_impl->length() >= numeric_limits<unsigned>::max()) - CRASH(); - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + 1, data); - memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar)); - data[m_impl->length()] = c; - m_impl = newImpl.release(); - } else - m_impl = StringImpl::create(&c, 1); -} - -void String::append(UChar c) -{ - // FIXME: This is extremely inefficient. So much so that we might want to take this - // out of String's API. We can make it better by optimizing the case where exactly - // one String is pointing at this StringImpl, but even then it's going to require a - // call to fastMalloc every single time. - if (m_impl) { - UChar* data; - if (m_impl->length() >= numeric_limits<unsigned>::max()) - CRASH(); - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(m_impl->length() + 1, data); - memcpy(data, m_impl->characters(), m_impl->length() * sizeof(UChar)); - data[m_impl->length()] = c; - m_impl = newImpl.release(); - } else - m_impl = StringImpl::create(&c, 1); -} - -String operator+(const String& a, const String& b) -{ - if (a.isEmpty()) - return b; - if (b.isEmpty()) - return a; - String c = a; - c += b; - return c; -} - -String operator+(const String& s, const char* cs) -{ - return s + String(cs); -} - -String operator+(const char* cs, const String& s) -{ - return String(cs) + s; -} - -int codePointCompare(const String& a, const String& b) -{ - return codePointCompare(a.impl(), b.impl()); -} - -void String::insert(const String& str, unsigned pos) -{ - if (str.isEmpty()) { - if (str.isNull()) - return; - if (isNull()) - m_impl = str.impl(); - return; - } - insert(str.characters(), str.length(), pos); -} - -void String::append(const UChar* charactersToAppend, unsigned lengthToAppend) -{ - if (!m_impl) { - if (!charactersToAppend) - return; - m_impl = StringImpl::create(charactersToAppend, lengthToAppend); - return; - } - - if (!lengthToAppend) - return; - - ASSERT(charactersToAppend); - UChar* data; - if (lengthToAppend > numeric_limits<unsigned>::max() - length()) - CRASH(); - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data); - memcpy(data, characters(), length() * sizeof(UChar)); - memcpy(data + length(), charactersToAppend, lengthToAppend * sizeof(UChar)); - m_impl = newImpl.release(); -} - -void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position) -{ - if (position >= length()) { - append(charactersToInsert, lengthToInsert); - return; - } - - ASSERT(m_impl); - - if (!lengthToInsert) - return; - - ASSERT(charactersToInsert); - UChar* data; - if (lengthToInsert > numeric_limits<unsigned>::max() - length()) - CRASH(); - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToInsert, data); - memcpy(data, characters(), position * sizeof(UChar)); - memcpy(data + position, charactersToInsert, lengthToInsert * sizeof(UChar)); - memcpy(data + position + lengthToInsert, characters() + position, (length() - position) * sizeof(UChar)); - m_impl = newImpl.release(); -} - -UChar32 String::characterStartingAt(unsigned i) const -{ - if (!m_impl || i >= m_impl->length()) - return 0; - return m_impl->characterStartingAt(i); -} - -void String::truncate(unsigned position) -{ - if (position >= length()) - return; - UChar* data; - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(position, data); - memcpy(data, characters(), position * sizeof(UChar)); - m_impl = newImpl.release(); -} - -void String::remove(unsigned position, int lengthToRemove) -{ - if (lengthToRemove <= 0) - return; - if (position >= length()) - return; - if (static_cast<unsigned>(lengthToRemove) > length() - position) - lengthToRemove = length() - position; - UChar* data; - RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() - lengthToRemove, data); - memcpy(data, characters(), position * sizeof(UChar)); - memcpy(data + position, characters() + position + lengthToRemove, - (length() - lengthToRemove - position) * sizeof(UChar)); - m_impl = newImpl.release(); -} - -String String::substring(unsigned pos, unsigned len) const -{ - if (!m_impl) - return String(); - return m_impl->substring(pos, len); -} - -String String::substringSharingImpl(unsigned offset, unsigned length) const -{ - // FIXME: We used to check against a limit of Heap::minExtraCost / sizeof(UChar). - - unsigned stringLength = this->length(); - offset = min(offset, stringLength); - length = min(length, stringLength - offset); - - if (!offset && length == stringLength) - return *this; - return String(StringImpl::create(m_impl, offset, length)); -} - -String String::lower() const -{ - if (!m_impl) - return String(); - return m_impl->lower(); -} - -String String::upper() const -{ - if (!m_impl) - return String(); - return m_impl->upper(); -} - -String String::stripWhiteSpace() const -{ - if (!m_impl) - return String(); - return m_impl->stripWhiteSpace(); -} - -String String::simplifyWhiteSpace() const -{ - if (!m_impl) - return String(); - return m_impl->simplifyWhiteSpace(); -} - -String String::removeCharacters(CharacterMatchFunctionPtr findMatch) const -{ - if (!m_impl) - return String(); - return m_impl->removeCharacters(findMatch); -} - -String String::foldCase() const -{ - if (!m_impl) - return String(); - return m_impl->foldCase(); -} - -bool String::percentage(int& result) const -{ - if (!m_impl || !m_impl->length()) - return false; - - if ((*m_impl)[m_impl->length() - 1] != '%') - return false; - - result = charactersToIntStrict(m_impl->characters(), m_impl->length() - 1); - return true; -} - -const UChar* String::charactersWithNullTermination() -{ - if (!m_impl) - return 0; - if (m_impl->hasTerminatingNullCharacter()) - return m_impl->characters(); - m_impl = StringImpl::createWithTerminatingNullCharacter(*m_impl); - return m_impl->characters(); -} - -String String::format(const char *format, ...) -{ -#if PLATFORM(QT) - // Use QString::vsprintf to avoid the locale dependent formatting of vsnprintf. - // https://bugs.webkit.org/show_bug.cgi?id=18994 - va_list args; - va_start(args, format); - - QString buffer; - buffer.vsprintf(format, args); - - va_end(args); - - QByteArray ba = buffer.toUtf8(); - return StringImpl::create(ba.constData(), ba.length()); - -#elif OS(WINCE) - va_list args; - va_start(args, format); - - Vector<char, 256> buffer; - - int bufferSize = 256; - buffer.resize(bufferSize); - for (;;) { - int written = vsnprintf(buffer.data(), bufferSize, format, args); - va_end(args); - - if (written == 0) - return String(""); - if (written > 0) - return StringImpl::create(buffer.data(), written); - - bufferSize <<= 1; - buffer.resize(bufferSize); - va_start(args, format); - } - -#else - va_list args; - va_start(args, format); - - Vector<char, 256> buffer; - - // Do the format once to get the length. -#if COMPILER(MSVC) - int result = _vscprintf(format, args); -#else - char ch; - int result = vsnprintf(&ch, 1, format, args); - // We need to call va_end() and then va_start() again here, as the - // contents of args is undefined after the call to vsnprintf - // according to http://man.cx/snprintf(3) - // - // Not calling va_end/va_start here happens to work on lots of - // systems, but fails e.g. on 64bit Linux. - va_end(args); - va_start(args, format); -#endif - - if (result == 0) - return String(""); - if (result < 0) - return String(); - unsigned len = result; - buffer.grow(len + 1); - - // Now do the formatting again, guaranteed to fit. - vsnprintf(buffer.data(), buffer.size(), format, args); - - va_end(args); - - return StringImpl::create(buffer.data(), len); -#endif -} - -String String::number(short n) -{ - return String::format("%hd", n); -} - -String String::number(unsigned short n) -{ - return String::format("%hu", n); -} - -String String::number(int n) -{ - return String::format("%d", n); -} - -String String::number(unsigned n) -{ - return String::format("%u", n); -} - -String String::number(long n) -{ - return String::format("%ld", n); -} - -String String::number(unsigned long n) -{ - return String::format("%lu", n); -} - -String String::number(long long n) -{ -#if OS(WINDOWS) && !PLATFORM(QT) - return String::format("%I64i", n); -#else - return String::format("%lli", n); -#endif -} - -String String::number(unsigned long long n) -{ -#if OS(WINDOWS) && !PLATFORM(QT) - return String::format("%I64u", n); -#else - return String::format("%llu", n); -#endif -} - -String String::number(double n) -{ - return String::format("%.6lg", n); -} - -int String::toIntStrict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toIntStrict(ok, base); -} - -unsigned String::toUIntStrict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUIntStrict(ok, base); -} - -int64_t String::toInt64Strict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toInt64Strict(ok, base); -} - -uint64_t String::toUInt64Strict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUInt64Strict(ok, base); -} - -intptr_t String::toIntPtrStrict(bool* ok, int base) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toIntPtrStrict(ok, base); -} - - -int String::toInt(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toInt(ok); -} - -unsigned String::toUInt(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUInt(ok); -} - -int64_t String::toInt64(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toInt64(ok); -} - -uint64_t String::toUInt64(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toUInt64(ok); -} - -intptr_t String::toIntPtr(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0; - } - return m_impl->toIntPtr(ok); -} - -double String::toDouble(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0.0; - } - return m_impl->toDouble(ok); -} - -float String::toFloat(bool* ok) const -{ - if (!m_impl) { - if (ok) - *ok = false; - return 0.0f; - } - return m_impl->toFloat(ok); -} - -String String::threadsafeCopy() const -{ - if (!m_impl) - return String(); - return m_impl->threadsafeCopy(); -} - -String String::crossThreadString() const -{ - if (!m_impl) - return String(); - return m_impl->crossThreadString(); -} - -void String::split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const -{ - result.clear(); - - unsigned startPos = 0; - size_t endPos; - while ((endPos = find(separator, startPos)) != notFound) { - if (allowEmptyEntries || startPos != endPos) - result.append(substring(startPos, endPos - startPos)); - startPos = endPos + separator.length(); - } - if (allowEmptyEntries || startPos != length()) - result.append(substring(startPos)); -} - -void String::split(const String& separator, Vector<String>& result) const -{ - return split(separator, false, result); -} - -void String::split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const -{ - result.clear(); - - unsigned startPos = 0; - size_t endPos; - while ((endPos = find(separator, startPos)) != notFound) { - if (allowEmptyEntries || startPos != endPos) - result.append(substring(startPos, endPos - startPos)); - startPos = endPos + 1; - } - if (allowEmptyEntries || startPos != length()) - result.append(substring(startPos)); -} - -void String::split(UChar separator, Vector<String>& result) const -{ - return split(String(&separator, 1), false, result); -} - -CString String::ascii() const -{ - // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are - // preserved, characters outside of this range are converted to '?'. - - unsigned length = this->length(); - const UChar* characters = this->characters(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - characterBuffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch; - } - - return result; -} - -CString String::latin1() const -{ - // Basic Latin1 (ISO) encoding - Unicode characters 0..255 are - // preserved, characters outside of this range are converted to '?'. - - unsigned length = this->length(); - const UChar* characters = this->characters(); - - char* characterBuffer; - CString result = CString::newUninitialized(length, characterBuffer); - - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - characterBuffer[i] = ch > 0xff ? '?' : ch; - } - - return result; -} - -// Helper to write a three-byte UTF-8 code point to the buffer, caller must check room is available. -static inline void putUTF8Triple(char*& buffer, UChar ch) -{ - ASSERT(ch >= 0x0800); - *buffer++ = static_cast<char>(((ch >> 12) & 0x0F) | 0xE0); - *buffer++ = static_cast<char>(((ch >> 6) & 0x3F) | 0x80); - *buffer++ = static_cast<char>((ch & 0x3F) | 0x80); -} - -CString String::utf8(bool strict) const -{ - unsigned length = this->length(); - const UChar* characters = this->characters(); - - // Allocate a buffer big enough to hold all the characters - // (an individual UTF-16 UChar can only expand to 3 UTF-8 bytes). - // Optimization ideas, if we find this function is hot: - // * We could speculatively create a CStringBuffer to contain 'length' - // characters, and resize if necessary (i.e. if the buffer contains - // non-ascii characters). (Alternatively, scan the buffer first for - // ascii characters, so we know this will be sufficient). - // * We could allocate a CStringBuffer with an appropriate size to - // have a good chance of being able to write the string into the - // buffer without reallocing (say, 1.5 x length). - if (length > numeric_limits<unsigned>::max() / 3) - return CString(); - Vector<char, 1024> bufferVector(length * 3); - - char* buffer = bufferVector.data(); - ConversionResult result = convertUTF16ToUTF8(&characters, characters + length, &buffer, buffer + bufferVector.size(), strict); - ASSERT(result != targetExhausted); // (length * 3) should be sufficient for any conversion - - // Only produced from strict conversion. - if (result == sourceIllegal) - return CString(); - - // Check for an unconverted high surrogate. - if (result == sourceExhausted) { - if (strict) - return CString(); - // This should be one unpaired high surrogate. Treat it the same - // was as an unpaired high surrogate would have been handled in - // the middle of a string with non-strict conversion - which is - // to say, simply encode it to UTF-8. - ASSERT((characters + 1) == (this->characters() + length)); - ASSERT((*characters >= 0xD800) && (*characters <= 0xDBFF)); - // There should be room left, since one UChar hasn't been converted. - ASSERT((buffer + 3) <= (buffer + bufferVector.size())); - putUTF8Triple(buffer, *characters); - } - - return CString(bufferVector.data(), buffer - bufferVector.data()); -} - -String String::fromUTF8(const char* stringStart, size_t length) -{ - if (length > numeric_limits<unsigned>::max()) - CRASH(); - - if (!stringStart) - return String(); - - // We'll use a StringImpl as a buffer; if the source string only contains ascii this should be - // the right length, if there are any multi-byte sequences this buffer will be too large. - UChar* buffer; - String stringBuffer(StringImpl::createUninitialized(length, buffer)); - UChar* bufferEnd = buffer + length; - - // Try converting into the buffer. - const char* stringCurrent = stringStart; - if (convertUTF8ToUTF16(&stringCurrent, stringStart + length, &buffer, bufferEnd) != conversionOK) - return String(); - - // stringBuffer is full (the input must have been all ascii) so just return it! - if (buffer == bufferEnd) - return stringBuffer; - - // stringBuffer served its purpose as a buffer, copy the contents out into a new string. - unsigned utf16Length = buffer - stringBuffer.characters(); - ASSERT(utf16Length < length); - return String(stringBuffer.characters(), utf16Length); -} - -String String::fromUTF8(const char* string) -{ - if (!string) - return String(); - return fromUTF8(string, strlen(string)); -} - -String String::fromUTF8WithLatin1Fallback(const char* string, size_t size) -{ - String utf8 = fromUTF8(string, size); - if (!utf8) - return String(string, size); - return utf8; -} - -// String Operations - -static bool isCharacterAllowedInBase(UChar c, int base) -{ - if (c > 0x7F) - return false; - if (isASCIIDigit(c)) - return c - '0' < base; - if (isASCIIAlpha(c)) { - if (base > 36) - base = 36; - return (c >= 'a' && c < 'a' + base - 10) - || (c >= 'A' && c < 'A' + base - 10); - } - return false; -} - -template <typename IntegralType> -static inline IntegralType toIntegralType(const UChar* data, size_t length, bool* ok, int base) -{ - static const IntegralType integralMax = numeric_limits<IntegralType>::max(); - static const bool isSigned = numeric_limits<IntegralType>::is_signed; - const IntegralType maxMultiplier = integralMax / base; - - IntegralType value = 0; - bool isOk = false; - bool isNegative = false; - - if (!data) - goto bye; - - // skip leading whitespace - while (length && isSpaceOrNewline(*data)) { - length--; - data++; - } - - if (isSigned && length && *data == '-') { - length--; - data++; - isNegative = true; - } else if (length && *data == '+') { - length--; - data++; - } - - if (!length || !isCharacterAllowedInBase(*data, base)) - goto bye; - - while (length && isCharacterAllowedInBase(*data, base)) { - length--; - IntegralType digitValue; - UChar c = *data; - if (isASCIIDigit(c)) - digitValue = c - '0'; - else if (c >= 'a') - digitValue = c - 'a' + 10; - else - digitValue = c - 'A' + 10; - - if (value > maxMultiplier || (value == maxMultiplier && digitValue > (integralMax % base) + isNegative)) - goto bye; - - value = base * value + digitValue; - data++; - } - -#if COMPILER(MSVC) -#pragma warning(push, 0) -#pragma warning(disable:4146) -#endif - - if (isNegative) - value = -value; - -#if COMPILER(MSVC) -#pragma warning(pop) -#endif - - // skip trailing space - while (length && isSpaceOrNewline(*data)) { - length--; - data++; - } - - if (!length) - isOk = true; -bye: - if (ok) - *ok = isOk; - return isOk ? value : 0; -} - -static unsigned lengthOfCharactersAsInteger(const UChar* data, size_t length) -{ - size_t i = 0; - - // Allow leading spaces. - for (; i != length; ++i) { - if (!isSpaceOrNewline(data[i])) - break; - } - - // Allow sign. - if (i != length && (data[i] == '+' || data[i] == '-')) - ++i; - - // Allow digits. - for (; i != length; ++i) { - if (!isASCIIDigit(data[i])) - break; - } - - return i; -} - -int charactersToIntStrict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<int>(data, length, ok, base); -} - -unsigned charactersToUIntStrict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<unsigned>(data, length, ok, base); -} - -int64_t charactersToInt64Strict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<int64_t>(data, length, ok, base); -} - -uint64_t charactersToUInt64Strict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<uint64_t>(data, length, ok, base); -} - -intptr_t charactersToIntPtrStrict(const UChar* data, size_t length, bool* ok, int base) -{ - return toIntegralType<intptr_t>(data, length, ok, base); -} - -int charactersToInt(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<int>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -unsigned charactersToUInt(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<unsigned>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -int64_t charactersToInt64(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<int64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -uint64_t charactersToUInt64(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<uint64_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -intptr_t charactersToIntPtr(const UChar* data, size_t length, bool* ok) -{ - return toIntegralType<intptr_t>(data, lengthOfCharactersAsInteger(data, length), ok, 10); -} - -double charactersToDouble(const UChar* data, size_t length, bool* ok) -{ - if (!length) { - if (ok) - *ok = false; - return 0.0; - } - - Vector<char, 256> bytes(length + 1); - for (unsigned i = 0; i < length; ++i) - bytes[i] = data[i] < 0x7F ? data[i] : '?'; - bytes[length] = '\0'; - char* end; - double val = WTF::strtod(bytes.data(), &end); - if (ok) - *ok = (end == 0 || *end == '\0'); - return val; -} - -float charactersToFloat(const UChar* data, size_t length, bool* ok) -{ - // FIXME: This will return ok even when the string fits into a double but not a float. - return static_cast<float>(charactersToDouble(data, length, ok)); -} - -} // namespace WTF - -#ifndef NDEBUG -// For use in the debugger -String* string(const char*); -Vector<char> asciiDebug(StringImpl* impl); -Vector<char> asciiDebug(String& string); - -String* string(const char* s) -{ - // leaks memory! - return new String(s); -} - -Vector<char> asciiDebug(StringImpl* impl) -{ - if (!impl) - return asciiDebug(String("[null]").impl()); - - Vector<char> buffer; - unsigned length = impl->length(); - const UChar* characters = impl->characters(); - - buffer.resize(length + 1); - for (unsigned i = 0; i < length; ++i) { - UChar ch = characters[i]; - buffer[i] = ch && (ch < 0x20 || ch > 0x7f) ? '?' : ch; - } - buffer[length] = '\0'; - - return buffer; -} - -Vector<char> asciiDebug(String& string) -{ - return asciiDebug(string.impl()); -} - -#endif diff --git a/JavaScriptCore/wtf/text/WTFString.h b/JavaScriptCore/wtf/text/WTFString.h deleted file mode 100644 index 4d853d2..0000000 --- a/JavaScriptCore/wtf/text/WTFString.h +++ /dev/null @@ -1,502 +0,0 @@ -/* - * (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTFString_h -#define WTFString_h - -// This file would be called String.h, but that conflicts with <string.h> -// on systems without case-sensitive file systems. - -#include "StringImpl.h" - -#ifdef __OBJC__ -#include <objc/objc.h> -#endif - -#if PLATFORM(CF) -typedef const struct __CFString * CFStringRef; -#endif - -#if PLATFORM(QT) -QT_BEGIN_NAMESPACE -class QString; -QT_END_NAMESPACE -#include <QDataStream> -#endif - -#if PLATFORM(WX) -class wxString; -#endif - -#if PLATFORM(HAIKU) -class BString; -#endif - -#if PLATFORM(BREWMP) -// AECHAR is defined in AEEStdDef.h, but don't include it here to avoid conflicts. -#ifndef _AECHAR_DEFINED -typedef uint16 AECHAR; -#define _AECHAR_DEFINED -#endif -#endif - -namespace WTF { - -class CString; -struct StringHash; - -// Declarations of string operations - -bool charactersAreAllASCII(const UChar*, size_t); -int charactersToIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); -unsigned charactersToUIntStrict(const UChar*, size_t, bool* ok = 0, int base = 10); -int64_t charactersToInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); -uint64_t charactersToUInt64Strict(const UChar*, size_t, bool* ok = 0, int base = 10); -intptr_t charactersToIntPtrStrict(const UChar*, size_t, bool* ok = 0, int base = 10); - -int charactersToInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -unsigned charactersToUInt(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -int64_t charactersToInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -uint64_t charactersToUInt64(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage -intptr_t charactersToIntPtr(const UChar*, size_t, bool* ok = 0); // ignores trailing garbage - -double charactersToDouble(const UChar*, size_t, bool* ok = 0); -float charactersToFloat(const UChar*, size_t, bool* ok = 0); - -template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters(const UChar*, size_t); - -class String { -public: - // Construct a null string, distinguishable from an empty string. - String() { } - - // Construct a string with UTF-16 data. - String(const UChar* characters, unsigned length); - - // Construct a string with UTF-16 data, from a null-terminated source. - String(const UChar*); - - // Construct a string with latin1 data. - String(const char* characters, unsigned length); - - // Construct a string with latin1 data, from a null-terminated source. - String(const char* characters); - - // Construct a string referencing an existing StringImpl. - String(StringImpl* impl) : m_impl(impl) { } - String(PassRefPtr<StringImpl> impl) : m_impl(impl) { } - String(RefPtr<StringImpl> impl) : m_impl(impl) { } - - // Inline the destructor. - ALWAYS_INLINE ~String() { } - - void swap(String& o) { m_impl.swap(o.m_impl); } - - static String adopt(StringBuffer& buffer) { return StringImpl::adopt(buffer); } - template<size_t inlineCapacity> - static String adopt(Vector<UChar, inlineCapacity>& vector) { return StringImpl::adopt(vector); } - - bool isNull() const { return !m_impl; } - bool isEmpty() const { return !m_impl || !m_impl->length(); } - - StringImpl* impl() const { return m_impl.get(); } - - unsigned length() const - { - if (!m_impl) - return 0; - return m_impl->length(); - } - - const UChar* characters() const - { - if (!m_impl) - return 0; - return m_impl->characters(); - } - - CString ascii() const; - CString latin1() const; - CString utf8(bool strict = false) const; - - UChar operator[](unsigned index) const - { - if (!m_impl || index >= m_impl->length()) - return 0; - return m_impl->characters()[index]; - } - - static String number(short); - static String number(unsigned short); - static String number(int); - static String number(unsigned); - static String number(long); - static String number(unsigned long); - static String number(long long); - static String number(unsigned long long); - static String number(double); - - // Find a single character or string, also with match function & latin1 forms. - size_t find(UChar c, unsigned start = 0) const - { return m_impl ? m_impl->find(c, start) : notFound; } - size_t find(const String& str, unsigned start = 0) const - { return m_impl ? m_impl->find(str.impl(), start) : notFound; } - size_t find(CharacterMatchFunctionPtr matchFunction, unsigned start = 0) const - { return m_impl ? m_impl->find(matchFunction, start) : notFound; } - size_t find(const char* str, unsigned start = 0) const - { return m_impl ? m_impl->find(str, start) : notFound; } - - // Find the last instance of a single character or string. - size_t reverseFind(UChar c, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFind(c, start) : notFound; } - size_t reverseFind(const String& str, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFind(str.impl(), start) : notFound; } - - // Case insensitive string matching. - size_t findIgnoringCase(const char* str, unsigned start = 0) const - { return m_impl ? m_impl->findIgnoringCase(str, start) : notFound; } - size_t findIgnoringCase(const String& str, unsigned start = 0) const - { return m_impl ? m_impl->findIgnoringCase(str.impl(), start) : notFound; } - size_t reverseFindIgnoringCase(const String& str, unsigned start = UINT_MAX) const - { return m_impl ? m_impl->reverseFindIgnoringCase(str.impl(), start) : notFound; } - - // Wrappers for find & reverseFind adding dynamic sensitivity check. - size_t find(const char* str, unsigned start, bool caseSensitive) const - { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } - size_t find(const String& str, unsigned start, bool caseSensitive) const - { return caseSensitive ? find(str, start) : findIgnoringCase(str, start); } - size_t reverseFind(const String& str, unsigned start, bool caseSensitive) const - { return caseSensitive ? reverseFind(str, start) : reverseFindIgnoringCase(str, start); } - - const UChar* charactersWithNullTermination(); - - UChar32 characterStartingAt(unsigned) const; // Ditto. - - bool contains(UChar c) const { return find(c) != notFound; } - bool contains(const char* str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; } - bool contains(const String& str, bool caseSensitive = true) const { return find(str, 0, caseSensitive) != notFound; } - - bool startsWith(const String& s, bool caseSensitive = true) const - { return m_impl ? m_impl->startsWith(s.impl(), caseSensitive) : s.isEmpty(); } - bool endsWith(const String& s, bool caseSensitive = true) const - { return m_impl ? m_impl->endsWith(s.impl(), caseSensitive) : s.isEmpty(); } - - void append(const String&); - void append(char); - void append(UChar); - void append(const UChar*, unsigned length); - void insert(const String&, unsigned pos); - void insert(const UChar*, unsigned length, unsigned pos); - - String& replace(UChar a, UChar b) { if (m_impl) m_impl = m_impl->replace(a, b); return *this; } - String& replace(UChar a, const String& b) { if (m_impl) m_impl = m_impl->replace(a, b.impl()); return *this; } - String& replace(const String& a, const String& b) { if (m_impl) m_impl = m_impl->replace(a.impl(), b.impl()); return *this; } - String& replace(unsigned index, unsigned len, const String& b) { if (m_impl) m_impl = m_impl->replace(index, len, b.impl()); return *this; } - - void makeLower() { if (m_impl) m_impl = m_impl->lower(); } - void makeUpper() { if (m_impl) m_impl = m_impl->upper(); } - void makeSecure(UChar aChar) { if (m_impl) m_impl = m_impl->secure(aChar); } - - void truncate(unsigned len); - void remove(unsigned pos, int len = 1); - - String substring(unsigned pos, unsigned len = UINT_MAX) const; - String substringSharingImpl(unsigned pos, unsigned len = UINT_MAX) const; - String left(unsigned len) const { return substring(0, len); } - String right(unsigned len) const { return substring(length() - len, len); } - - // Returns a lowercase/uppercase version of the string - String lower() const; - String upper() const; - - String stripWhiteSpace() const; - String simplifyWhiteSpace() const; - - String removeCharacters(CharacterMatchFunctionPtr) const; - template<bool isSpecialCharacter(UChar)> bool isAllSpecialCharacters() const; - - // Return the string with case folded for case insensitive comparison. - String foldCase() const; - -#if !PLATFORM(QT) - static String format(const char *, ...) WTF_ATTRIBUTE_PRINTF(1, 2); -#else - static String format(const char *, ...); -#endif - - // Returns an uninitialized string. The characters needs to be written - // into the buffer returned in data before the returned string is used. - // Failure to do this will have unpredictable results. - static String createUninitialized(unsigned length, UChar*& data) { return StringImpl::createUninitialized(length, data); } - - void split(const String& separator, Vector<String>& result) const; - void split(const String& separator, bool allowEmptyEntries, Vector<String>& result) const; - void split(UChar separator, Vector<String>& result) const; - void split(UChar separator, bool allowEmptyEntries, Vector<String>& result) const; - - int toIntStrict(bool* ok = 0, int base = 10) const; - unsigned toUIntStrict(bool* ok = 0, int base = 10) const; - int64_t toInt64Strict(bool* ok = 0, int base = 10) const; - uint64_t toUInt64Strict(bool* ok = 0, int base = 10) const; - intptr_t toIntPtrStrict(bool* ok = 0, int base = 10) const; - - int toInt(bool* ok = 0) const; - unsigned toUInt(bool* ok = 0) const; - int64_t toInt64(bool* ok = 0) const; - uint64_t toUInt64(bool* ok = 0) const; - intptr_t toIntPtr(bool* ok = 0) const; - double toDouble(bool* ok = 0) const; - float toFloat(bool* ok = 0) const; - - bool percentage(int& percentage) const; - - // Returns a StringImpl suitable for use on another thread. - String crossThreadString() const; - // Makes a deep copy. Helpful only if you need to use a String on another thread - // (use crossThreadString if the method call doesn't need to be threadsafe). - // Since the underlying StringImpl objects are immutable, there's no other reason - // to ever prefer copy() over plain old assignment. - String threadsafeCopy() const; - - // Prevent Strings from being implicitly convertable to bool as it will be ambiguous on any platform that - // allows implicit conversion to another pointer type (e.g., Mac allows implicit conversion to NSString*). - typedef struct ImplicitConversionFromWTFStringToBoolDisallowedA* (String::*UnspecifiedBoolTypeA); - typedef struct ImplicitConversionFromWTFStringToBoolDisallowedB* (String::*UnspecifiedBoolTypeB); - operator UnspecifiedBoolTypeA() const; - operator UnspecifiedBoolTypeB() const; - -#if PLATFORM(CF) - String(CFStringRef); - CFStringRef createCFString() const; -#endif - -#ifdef __OBJC__ - String(NSString*); - - // This conversion maps NULL to "", which loses the meaning of NULL, but we - // need this mapping because AppKit crashes when passed nil NSStrings. - operator NSString*() const { if (!m_impl) return @""; return *m_impl; } -#endif - -#if PLATFORM(QT) - String(const QString&); - String(const QStringRef&); - operator QString() const; -#endif - -#if PLATFORM(WX) - String(const wxString&); - operator wxString() const; -#endif - -#if PLATFORM(HAIKU) - String(const BString&); - operator BString() const; -#endif - -#if PLATFORM(BREWMP) - String(const AECHAR*); -#endif - - // String::fromUTF8 will return a null string if - // the input data contains invalid UTF-8 sequences. - static String fromUTF8(const char*, size_t); - static String fromUTF8(const char*); - - // Tries to convert the passed in string to UTF-8, but will fall back to Latin-1 if the string is not valid UTF-8. - static String fromUTF8WithLatin1Fallback(const char*, size_t); - - // Determines the writing direction using the Unicode Bidi Algorithm rules P2 and P3. - WTF::Unicode::Direction defaultWritingDirection() const { return m_impl ? m_impl->defaultWritingDirection() : WTF::Unicode::LeftToRight; } - - bool containsOnlyASCII() const { return charactersAreAllASCII(characters(), length()); } - - // Hash table deleted values, which are only constructed and never copied or destroyed. - String(WTF::HashTableDeletedValueType) : m_impl(WTF::HashTableDeletedValue) { } - bool isHashTableDeletedValue() const { return m_impl.isHashTableDeletedValue(); } - -private: - RefPtr<StringImpl> m_impl; -}; - -#if PLATFORM(QT) -QDataStream& operator<<(QDataStream& stream, const String& str); -QDataStream& operator>>(QDataStream& stream, String& str); -#endif - -String operator+(const String&, const String&); -String operator+(const String&, const char*); -String operator+(const char*, const String&); - -inline String& operator+=(String& a, const String& b) { a.append(b); return a; } - -inline bool operator==(const String& a, const String& b) { return equal(a.impl(), b.impl()); } -inline bool operator==(const String& a, const char* b) { return equal(a.impl(), b); } -inline bool operator==(const char* a, const String& b) { return equal(a, b.impl()); } - -inline bool operator!=(const String& a, const String& b) { return !equal(a.impl(), b.impl()); } -inline bool operator!=(const String& a, const char* b) { return !equal(a.impl(), b); } -inline bool operator!=(const char* a, const String& b) { return !equal(a, b.impl()); } - -inline bool equalIgnoringCase(const String& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } -inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), b); } -inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(a, b.impl()); } - -inline bool equalPossiblyIgnoringCase(const String& a, const String& b, bool ignoreCase) -{ - return ignoreCase ? equalIgnoringCase(a, b) : (a == b); -} - -inline bool equalIgnoringNullity(const String& a, const String& b) { return equalIgnoringNullity(a.impl(), b.impl()); } - -inline bool operator!(const String& str) { return str.isNull(); } - -inline void swap(String& a, String& b) { a.swap(b); } - -// Definitions of string operations - -#ifdef __OBJC__ -// This is for situations in WebKit where the long standing behavior has been -// "nil if empty", so we try to maintain longstanding behavior for the sake of -// entrenched clients -inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ? nil : (NSString*)str; } -#endif - -inline bool charactersAreAllASCII(const UChar* characters, size_t length) -{ - UChar ored = 0; - for (size_t i = 0; i < length; ++i) - ored |= characters[i]; - return !(ored & 0xFF80); -} - -int codePointCompare(const String&, const String&); - -inline size_t find(const UChar* characters, unsigned length, UChar matchCharacter, unsigned index = 0) -{ - while (index < length) { - if (characters[index] == matchCharacter) - return index; - ++index; - } - return notFound; -} - -inline size_t find(const UChar* characters, unsigned length, CharacterMatchFunctionPtr matchFunction, unsigned index = 0) -{ - while (index < length) { - if (matchFunction(characters[index])) - return index; - ++index; - } - return notFound; -} - -inline size_t reverseFind(const UChar* characters, unsigned length, UChar matchCharacter, unsigned index = UINT_MAX) -{ - if (!length) - return notFound; - if (index >= length) - index = length - 1; - while (characters[index] != matchCharacter) { - if (!index--) - return notFound; - } - return index; -} - -inline void append(Vector<UChar>& vector, const String& string) -{ - vector.append(string.characters(), string.length()); -} - -inline void appendNumber(Vector<UChar>& vector, unsigned char number) -{ - int numberLength = number > 99 ? 3 : (number > 9 ? 2 : 1); - size_t vectorSize = vector.size(); - vector.grow(vectorSize + numberLength); - - switch (numberLength) { - case 3: - vector[vectorSize + 2] = number % 10 + '0'; - number /= 10; - - case 2: - vector[vectorSize + 1] = number % 10 + '0'; - number /= 10; - - case 1: - vector[vectorSize] = number % 10 + '0'; - } -} - -template<bool isSpecialCharacter(UChar)> inline bool isAllSpecialCharacters(const UChar* characters, size_t length) -{ - for (size_t i = 0; i < length; ++i) { - if (!isSpecialCharacter(characters[i])) - return false; - } - return true; -} - -template<bool isSpecialCharacter(UChar)> inline bool String::isAllSpecialCharacters() const -{ - return WTF::isAllSpecialCharacters<isSpecialCharacter>(characters(), length()); -} - -// StringHash is the default hash for String -template<typename T> struct DefaultHash; -template<> struct DefaultHash<String> { - typedef StringHash Hash; -}; - -template <> struct VectorTraits<String> : SimpleClassVectorTraits -{ - static const bool canInitializeWithMemset = true; -}; - -} - -using WTF::CString; -using WTF::String; -using WTF::append; -using WTF::appendNumber; -using WTF::charactersAreAllASCII; -using WTF::charactersToIntStrict; -using WTF::charactersToUIntStrict; -using WTF::charactersToInt64Strict; -using WTF::charactersToUInt64Strict; -using WTF::charactersToIntPtrStrict; -using WTF::charactersToInt; -using WTF::charactersToUInt; -using WTF::charactersToInt64; -using WTF::charactersToUInt64; -using WTF::charactersToIntPtr; -using WTF::charactersToDouble; -using WTF::charactersToFloat; -using WTF::equal; -using WTF::equalIgnoringCase; -using WTF::find; -using WTF::isAllSpecialCharacters; -using WTF::isSpaceOrNewline; -using WTF::reverseFind; - -#endif diff --git a/JavaScriptCore/wtf/unicode/Collator.h b/JavaScriptCore/wtf/unicode/Collator.h deleted file mode 100644 index fe6a809..0000000 --- a/JavaScriptCore/wtf/unicode/Collator.h +++ /dev/null @@ -1,67 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_Collator_h -#define WTF_Collator_h - -#include <wtf/Noncopyable.h> -#include <wtf/PassOwnPtr.h> -#include <wtf/unicode/Unicode.h> - -#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION -struct UCollator; -#endif - -namespace WTF { - - class Collator : public Noncopyable { - public: - enum Result { Equal = 0, Greater = 1, Less = -1 }; - - Collator(const char* locale); // Parsing is lenient; e.g. language identifiers (such as "en-US") are accepted, too. - ~Collator(); - void setOrderLowerFirst(bool); - - static PassOwnPtr<Collator> userDefault(); - - Result collate(const ::UChar*, size_t, const ::UChar*, size_t) const; - - private: -#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION - void createCollator() const; - void releaseCollator(); - mutable UCollator* m_collator; -#endif - char* m_locale; - bool m_lowerFirst; - }; -} - -using WTF::Collator; - -#endif diff --git a/JavaScriptCore/wtf/unicode/CollatorDefault.cpp b/JavaScriptCore/wtf/unicode/CollatorDefault.cpp deleted file mode 100644 index 4e05432..0000000 --- a/JavaScriptCore/wtf/unicode/CollatorDefault.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Collator.h" - -#if !USE(ICU_UNICODE) || UCONFIG_NO_COLLATION - -namespace WTF { - -Collator::Collator(const char*) -{ -} - -Collator::~Collator() -{ -} - -void Collator::setOrderLowerFirst(bool) -{ -} - -PassOwnPtr<Collator> Collator::userDefault() -{ - return new Collator(0); -} - -// A default implementation for platforms that lack Unicode-aware collation. -Collator::Result Collator::collate(const UChar* lhs, size_t lhsLength, const UChar* rhs, size_t rhsLength) const -{ - int lmin = lhsLength < rhsLength ? lhsLength : rhsLength; - int l = 0; - while (l < lmin && *lhs == *rhs) { - lhs++; - rhs++; - l++; - } - - if (l < lmin) - return (*lhs > *rhs) ? Greater : Less; - - if (lhsLength == rhsLength) - return Equal; - - return (lhsLength > rhsLength) ? Greater : Less; -} - -} - -#endif diff --git a/JavaScriptCore/wtf/unicode/UTF8.cpp b/JavaScriptCore/wtf/unicode/UTF8.cpp deleted file mode 100644 index dc24ed5..0000000 --- a/JavaScriptCore/wtf/unicode/UTF8.cpp +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "UTF8.h" -#include <wtf/StringHasher.h> - -#include "ASCIICType.h" - -namespace WTF { -namespace Unicode { - -// FIXME: Use definition from CharacterNames.h. -static const UChar replacementCharacter = 0xFFFD; - -inline int inlineUTF8SequenceLengthNonASCII(char b0) -{ - if ((b0 & 0xC0) != 0xC0) - return 0; - if ((b0 & 0xE0) == 0xC0) - return 2; - if ((b0 & 0xF0) == 0xE0) - return 3; - if ((b0 & 0xF8) == 0xF0) - return 4; - return 0; -} - -inline int inlineUTF8SequenceLength(char b0) -{ - return isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0); -} - -int UTF8SequenceLength(char b0) -{ - return isASCII(b0) ? 1 : inlineUTF8SequenceLengthNonASCII(b0); -} - -int decodeUTF8Sequence(const char* sequence) -{ - // Handle 0-byte sequences (never valid). - const unsigned char b0 = sequence[0]; - const int length = inlineUTF8SequenceLength(b0); - if (length == 0) - return -1; - - // Handle 1-byte sequences (plain ASCII). - const unsigned char b1 = sequence[1]; - if (length == 1) { - if (b1) - return -1; - return b0; - } - - // Handle 2-byte sequences. - if ((b1 & 0xC0) != 0x80) - return -1; - const unsigned char b2 = sequence[2]; - if (length == 2) { - if (b2) - return -1; - const int c = ((b0 & 0x1F) << 6) | (b1 & 0x3F); - if (c < 0x80) - return -1; - return c; - } - - // Handle 3-byte sequences. - if ((b2 & 0xC0) != 0x80) - return -1; - const unsigned char b3 = sequence[3]; - if (length == 3) { - if (b3) - return -1; - const int c = ((b0 & 0xF) << 12) | ((b1 & 0x3F) << 6) | (b2 & 0x3F); - if (c < 0x800) - return -1; - // UTF-16 surrogates should never appear in UTF-8 data. - if (c >= 0xD800 && c <= 0xDFFF) - return -1; - return c; - } - - // Handle 4-byte sequences. - if ((b3 & 0xC0) != 0x80) - return -1; - const unsigned char b4 = sequence[4]; - if (length == 4) { - if (b4) - return -1; - const int c = ((b0 & 0x7) << 18) | ((b1 & 0x3F) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F); - if (c < 0x10000 || c > 0x10FFFF) - return -1; - return c; - } - - return -1; -} - -// Once the bits are split out into bytes of UTF-8, this is a mask OR-ed -// into the first byte, depending on how many bytes follow. There are -// as many entries in this table as there are UTF-8 sequence types. -// (I.e., one byte sequence, two byte... etc.). Remember that sequencs -// for *legal* UTF-8 will be 4 or fewer bytes total. -static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; - -ConversionResult convertUTF16ToUTF8( - const UChar** sourceStart, const UChar* sourceEnd, - char** targetStart, char* targetEnd, bool strict) -{ - ConversionResult result = conversionOK; - const UChar* source = *sourceStart; - char* target = *targetStart; - while (source < sourceEnd) { - UChar32 ch; - unsigned short bytesToWrite = 0; - const UChar32 byteMask = 0xBF; - const UChar32 byteMark = 0x80; - const UChar* oldSource = source; // In case we have to back up because of target overflow. - ch = static_cast<unsigned short>(*source++); - // If we have a surrogate pair, convert to UChar32 first. - if (ch >= 0xD800 && ch <= 0xDBFF) { - // If the 16 bits following the high surrogate are in the source buffer... - if (source < sourceEnd) { - UChar32 ch2 = static_cast<unsigned short>(*source); - // If it's a low surrogate, convert to UChar32. - if (ch2 >= 0xDC00 && ch2 <= 0xDFFF) { - ch = ((ch - 0xD800) << 10) + (ch2 - 0xDC00) + 0x0010000; - ++source; - } else if (strict) { // it's an unpaired high surrogate - --source; // return to the illegal value itself - result = sourceIllegal; - break; - } - } else { // We don't have the 16 bits following the high surrogate. - --source; // return to the high surrogate - result = sourceExhausted; - break; - } - } else if (strict) { - // UTF-16 surrogate values are illegal in UTF-32 - if (ch >= 0xDC00 && ch <= 0xDFFF) { - --source; // return to the illegal value itself - result = sourceIllegal; - break; - } - } - // Figure out how many bytes the result will require - if (ch < (UChar32)0x80) { - bytesToWrite = 1; - } else if (ch < (UChar32)0x800) { - bytesToWrite = 2; - } else if (ch < (UChar32)0x10000) { - bytesToWrite = 3; - } else if (ch < (UChar32)0x110000) { - bytesToWrite = 4; - } else { - bytesToWrite = 3; - ch = replacementCharacter; - } - - target += bytesToWrite; - if (target > targetEnd) { - source = oldSource; // Back up source pointer! - target -= bytesToWrite; - result = targetExhausted; - break; - } - switch (bytesToWrite) { // note: everything falls through. - case 4: *--target = (char)((ch | byteMark) & byteMask); ch >>= 6; - case 3: *--target = (char)((ch | byteMark) & byteMask); ch >>= 6; - case 2: *--target = (char)((ch | byteMark) & byteMask); ch >>= 6; - case 1: *--target = (char)(ch | firstByteMark[bytesToWrite]); - } - target += bytesToWrite; - } - *sourceStart = source; - *targetStart = target; - return result; -} - -// This must be called with the length pre-determined by the first byte. -// If presented with a length > 4, this returns false. The Unicode -// definition of UTF-8 goes up to 4-byte sequences. -static bool isLegalUTF8(const unsigned char* source, int length) -{ - unsigned char a; - const unsigned char* srcptr = source + length; - switch (length) { - default: return false; - // Everything else falls through when "true"... - case 4: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 3: if ((a = (*--srcptr)) < 0x80 || a > 0xBF) return false; - case 2: if ((a = (*--srcptr)) > 0xBF) return false; - - switch (*source) { - // no fall-through in this inner switch - case 0xE0: if (a < 0xA0) return false; break; - case 0xED: if (a > 0x9F) return false; break; - case 0xF0: if (a < 0x90) return false; break; - case 0xF4: if (a > 0x8F) return false; break; - default: if (a < 0x80) return false; - } - - case 1: if (*source >= 0x80 && *source < 0xC2) return false; - } - if (*source > 0xF4) - return false; - return true; -} - -// Magic values subtracted from a buffer value during UTF8 conversion. -// This table contains as many values as there might be trailing bytes -// in a UTF-8 sequence. -static const UChar32 offsetsFromUTF8[6] = { 0x00000000UL, 0x00003080UL, 0x000E2080UL, - 0x03C82080UL, 0xFA082080UL, 0x82082080UL }; - -static inline UChar32 readUTF8Sequence(const char*& sequence, unsigned length) -{ - UChar32 character = 0; - - // The cases all fall through. - switch (length) { - case 6: character += static_cast<unsigned char>(*sequence++); character <<= 6; - case 5: character += static_cast<unsigned char>(*sequence++); character <<= 6; - case 4: character += static_cast<unsigned char>(*sequence++); character <<= 6; - case 3: character += static_cast<unsigned char>(*sequence++); character <<= 6; - case 2: character += static_cast<unsigned char>(*sequence++); character <<= 6; - case 1: character += static_cast<unsigned char>(*sequence++); - } - - return character - offsetsFromUTF8[length - 1]; -} - -ConversionResult convertUTF8ToUTF16( - const char** sourceStart, const char* sourceEnd, - UChar** targetStart, UChar* targetEnd, bool strict) -{ - ConversionResult result = conversionOK; - const char* source = *sourceStart; - UChar* target = *targetStart; - while (source < sourceEnd) { - int utf8SequenceLength = inlineUTF8SequenceLength(*source); - if (sourceEnd - source < utf8SequenceLength) { - result = sourceExhausted; - break; - } - // Do this check whether lenient or strict - if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(source), utf8SequenceLength)) { - result = sourceIllegal; - break; - } - - UChar32 character = readUTF8Sequence(source, utf8SequenceLength); - - if (target >= targetEnd) { - source -= utf8SequenceLength; // Back up source pointer! - result = targetExhausted; - break; - } - - if (U_IS_BMP(character)) { - // UTF-16 surrogate values are illegal in UTF-32 - if (U_IS_SURROGATE(character)) { - if (strict) { - source -= utf8SequenceLength; // return to the illegal value itself - result = sourceIllegal; - break; - } else - *target++ = replacementCharacter; - } else - *target++ = character; // normal case - } else if (U_IS_SUPPLEMENTARY(character)) { - // target is a character in range 0xFFFF - 0x10FFFF - if (target + 1 >= targetEnd) { - source -= utf8SequenceLength; // Back up source pointer! - result = targetExhausted; - break; - } - *target++ = U16_LEAD(character); - *target++ = U16_TRAIL(character); - } else { - if (strict) { - source -= utf8SequenceLength; // return to the start - result = sourceIllegal; - break; // Bail out; shouldn't continue - } else - *target++ = replacementCharacter; - } - } - *sourceStart = source; - *targetStart = target; - return result; -} - -unsigned calculateStringHashFromUTF8(const char* data, const char* dataEnd, unsigned& utf16Length) -{ - if (!data) - return 0; - - WTF::StringHasher stringHasher; - utf16Length = 0; - - while (data < dataEnd) { - if (isASCII(*data)) { - stringHasher.addCharacter(*data++); - utf16Length++; - continue; - } - - int utf8SequenceLength = inlineUTF8SequenceLengthNonASCII(*data); - - if (dataEnd - data < utf8SequenceLength) - return false; - - if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(data), utf8SequenceLength)) - return 0; - - UChar32 character = readUTF8Sequence(data, utf8SequenceLength); - ASSERT(!isASCII(character)); - - if (U_IS_BMP(character)) { - // UTF-16 surrogate values are illegal in UTF-32 - if (U_IS_SURROGATE(character)) - return 0; - stringHasher.addCharacter(static_cast<UChar>(character)); // normal case - utf16Length++; - } else if (U_IS_SUPPLEMENTARY(character)) { - stringHasher.addCharacters(static_cast<UChar>(U16_LEAD(character)), - static_cast<UChar>(U16_TRAIL(character))); - utf16Length += 2; - } else - return 0; - } - - return stringHasher.hash(); -} - -bool equalUTF16WithUTF8(const UChar* a, const UChar* aEnd, const char* b, const char* bEnd) -{ - while (b < bEnd) { - if (isASCII(*b)) { - if (*a++ != *b++) - return false; - continue; - } - - int utf8SequenceLength = inlineUTF8SequenceLengthNonASCII(*b); - - if (bEnd - b < utf8SequenceLength) - return false; - - if (!isLegalUTF8(reinterpret_cast<const unsigned char*>(b), utf8SequenceLength)) - return 0; - - UChar32 character = readUTF8Sequence(b, utf8SequenceLength); - ASSERT(!isASCII(character)); - - if (U_IS_BMP(character)) { - // UTF-16 surrogate values are illegal in UTF-32 - if (U_IS_SURROGATE(character)) - return false; - if (*a++ != character) - return false; - } else if (U_IS_SUPPLEMENTARY(character)) { - if (*a++ != U16_LEAD(character)) - return false; - if (*a++ != U16_TRAIL(character)) - return false; - } else - return false; - } - - return a == aEnd; -} - -} // namespace Unicode -} // namespace WTF diff --git a/JavaScriptCore/wtf/unicode/UTF8.h b/JavaScriptCore/wtf/unicode/UTF8.h deleted file mode 100644 index 1f4baca..0000000 --- a/JavaScriptCore/wtf/unicode/UTF8.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WTF_UTF8_h -#define WTF_UTF8_h - -#include "Unicode.h" - -namespace WTF { -namespace Unicode { - - // Given a first byte, gives the length of the UTF-8 sequence it begins. - // Returns 0 for bytes that are not legal starts of UTF-8 sequences. - // Only allows sequences of up to 4 bytes, since that works for all Unicode characters (U-00000000 to U-0010FFFF). - int UTF8SequenceLength(char); - - // Takes a null-terminated C-style string with a UTF-8 sequence in it and converts it to a character. - // Only allows Unicode characters (U-00000000 to U-0010FFFF). - // Returns -1 if the sequence is not valid (including presence of extra bytes). - int decodeUTF8Sequence(const char*); - - typedef enum { - conversionOK, // conversion successful - sourceExhausted, // partial character in source, but hit end - targetExhausted, // insuff. room in target for conversion - sourceIllegal // source sequence is illegal/malformed - } ConversionResult; - - // These conversion functions take a "strict" argument. When this - // flag is set to strict, both irregular sequences and isolated surrogates - // will cause an error. When the flag is set to lenient, both irregular - // sequences and isolated surrogates are converted. - // - // Whether the flag is strict or lenient, all illegal sequences will cause - // an error return. This includes sequences such as: <F4 90 80 80>, <C0 80>, - // or <A0> in UTF-8, and values above 0x10FFFF in UTF-32. Conformant code - // must check for illegal sequences. - // - // When the flag is set to lenient, characters over 0x10FFFF are converted - // to the replacement character; otherwise (when the flag is set to strict) - // they constitute an error. - - ConversionResult convertUTF8ToUTF16( - const char** sourceStart, const char* sourceEnd, - UChar** targetStart, UChar* targetEnd, bool strict = true); - - ConversionResult convertUTF16ToUTF8( - const UChar** sourceStart, const UChar* sourceEnd, - char** targetStart, char* targetEnd, bool strict = true); - - unsigned calculateStringHashFromUTF8(const char* data, const char* dataEnd, unsigned& utf16Length); - - bool equalUTF16WithUTF8(const UChar* a, const UChar* aEnd, const char* b, const char* bEnd); - -} // namespace Unicode -} // namespace WTF - -#endif // WTF_UTF8_h diff --git a/JavaScriptCore/wtf/unicode/Unicode.h b/JavaScriptCore/wtf/unicode/Unicode.h deleted file mode 100644 index 50524b1..0000000 --- a/JavaScriptCore/wtf/unicode/Unicode.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006, 2008, 2009 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_UNICODE_H -#define WTF_UNICODE_H - -#include <wtf/Assertions.h> - -#if USE(QT4_UNICODE) -#include "qt4/UnicodeQt4.h" -#elif USE(ICU_UNICODE) -#include <wtf/unicode/icu/UnicodeIcu.h> -#elif USE(GLIB_UNICODE) -#include <wtf/unicode/glib/UnicodeGLib.h> -#elif USE(WINCE_UNICODE) -#include <wtf/unicode/wince/UnicodeWinCE.h> -#elif USE(BREWMP_UNICODE) -#include <wtf/unicode/brew/UnicodeBrew.h> -#else -#error "Unknown Unicode implementation" -#endif - -COMPILE_ASSERT(sizeof(UChar) == 2, UCharIsTwoBytes); - -#endif // WTF_UNICODE_H diff --git a/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h b/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h deleted file mode 100644 index 8959912..0000000 --- a/JavaScriptCore/wtf/unicode/UnicodeMacrosFromICU.h +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 1999-2004, International Business Machines Corporation and others. All Rights Reserved. - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2007 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2008 Jürg Billeter <j@bitron.ch> - * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef UnicodeMacrosFromICU_h -#define UnicodeMacrosFromICU_h - -// some defines from ICU - -#define U_IS_BMP(c) ((UChar32)(c)<=0xffff) -#define U16_IS_LEAD(c) (((c)&0xfffffc00)==0xd800) -#define U16_IS_TRAIL(c) (((c)&0xfffffc00)==0xdc00) -#define U16_SURROGATE_OFFSET ((0xd800<<10UL)+0xdc00-0x10000) -#define U16_GET_SUPPLEMENTARY(lead, trail) \ - (((UChar32)(lead)<<10UL)+(UChar32)(trail)-U16_SURROGATE_OFFSET) - -#define U16_LEAD(supplementary) (UChar)(((supplementary)>>10)+0xd7c0) -#define U16_TRAIL(supplementary) (UChar)(((supplementary)&0x3ff)|0xdc00) -#define U16_LENGTH(c) ((uint32_t)(c) <= 0xffff ? 1 : 2) - -#define U_IS_SUPPLEMENTARY(c) ((UChar32)((c)-0x10000)<=0xfffff) -#define U_IS_SURROGATE(c) (((c)&0xfffff800)==0xd800) -#define U16_IS_SINGLE(c) !U_IS_SURROGATE(c) -#define U16_IS_SURROGATE(c) U_IS_SURROGATE(c) -#define U16_IS_SURROGATE_LEAD(c) (((c)&0x400)==0) - -#define U16_GET(s, start, i, length, c) { \ - (c)=(s)[i]; \ - if(U16_IS_SURROGATE(c)) { \ - uint16_t __c2; \ - if(U16_IS_SURROGATE_LEAD(c)) { \ - if((i)+1<(length) && U16_IS_TRAIL(__c2=(s)[(i)+1])) { \ - (c)=U16_GET_SUPPLEMENTARY((c), __c2); \ - } \ - } else { \ - if((i)-1>=(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ - (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ - } \ - } \ - } \ -} - -#define U16_PREV(s, start, i, c) { \ - (c)=(s)[--(i)]; \ - if(U16_IS_TRAIL(c)) { \ - uint16_t __c2; \ - if((i)>(start) && U16_IS_LEAD(__c2=(s)[(i)-1])) { \ - --(i); \ - (c)=U16_GET_SUPPLEMENTARY(__c2, (c)); \ - } \ - } \ -} - -#define U16_BACK_1(s, start, i) { \ - if(U16_IS_TRAIL((s)[--(i)]) && (i)>(start) && U16_IS_LEAD((s)[(i)-1])) { \ - --(i); \ - } \ -} - -#define U16_NEXT(s, i, length, c) { \ - (c)=(s)[(i)++]; \ - if(U16_IS_LEAD(c)) { \ - uint16_t __c2; \ - if((i)<(length) && U16_IS_TRAIL(__c2=(s)[(i)])) { \ - ++(i); \ - (c)=U16_GET_SUPPLEMENTARY((c), __c2); \ - } \ - } \ -} - -#define U16_FWD_1(s, i, length) { \ - if(U16_IS_LEAD((s)[(i)++]) && (i)<(length) && U16_IS_TRAIL((s)[i])) { \ - ++(i); \ - } \ -} - -#define U_MASK(x) ((uint32_t)1<<(x)) - -#endif diff --git a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp deleted file mode 100644 index 8367f17..0000000 --- a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * Copyright (C) 2010 Company 100, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "UnicodeBrew.h" - -#include <wchar.h> -#include <wctype.h> - -namespace WTF { -namespace Unicode { - -UChar toLower(UChar c) -{ - return towlower(c); -} - -UChar toUpper(UChar c) -{ - return towupper(c); -} - -UChar foldCase(UChar c) -{ - return towlower(c); -} - -bool isPrintableChar(UChar c) -{ - return !!iswprint(c); -} - -bool isUpper(UChar c) -{ - return !!iswupper(c); -} - -bool isLower(UChar c) -{ - return !!iswlower(c); -} - -bool isDigit(UChar c) -{ - return !!iswdigit(c); -} - -bool isPunct(UChar c) -{ - return !!iswpunct(c); -} - -bool isAlphanumeric(UChar c) -{ - return !!iswalnum(c); -} - -int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) -{ - const UChar* sourceIterator = source; - const UChar* sourceEnd = source + sourceLength; - UChar* resultIterator = result; - UChar* resultEnd = result + resultLength; - - if (sourceLength <= resultLength) { - while (sourceIterator < sourceEnd) - *resultIterator++ = towlower(*sourceIterator++); - } else { - while (resultIterator < resultEnd) - *resultIterator++ = towlower(*sourceIterator++); - } - - int remainingCharacters = sourceIterator < sourceEnd ? sourceEnd - sourceIterator : 0; - *isError = !!remainingCharacters; - if (resultIterator < resultEnd) - *resultIterator = 0; - - return (resultIterator - result) + remainingCharacters; -} - -int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) -{ - const UChar* sourceIterator = source; - const UChar* sourceEnd = source + sourceLength; - UChar* resultIterator = result; - UChar* resultEnd = result + resultLength; - - if (sourceLength <= resultLength) { - while (sourceIterator < sourceEnd) - *resultIterator++ = towupper(*sourceIterator++); - } else { - while (resultIterator < resultEnd) - *resultIterator++ = towupper(*sourceIterator++); - } - - int remainingCharacters = sourceIterator < sourceEnd ? sourceEnd - sourceIterator : 0; - *isError = !!remainingCharacters; - if (resultIterator < resultEnd) - *resultIterator = 0; - - return (resultIterator - result) + remainingCharacters; -} - -int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) -{ - *isError = false; - if (resultLength < sourceLength) { - *isError = true; - return sourceLength; - } - for (int i = 0; i < sourceLength; ++i) - result[i] = foldCase(source[i]); - return sourceLength; -} - -UChar toTitleCase(UChar c) -{ - return towupper(c); -} - -Direction direction(UChar32 c) -{ - return static_cast<Direction>(ICU::direction(c)); -} - -CharCategory category(unsigned int c) -{ - return static_cast<CharCategory>(TO_MASK((int8_t) ICU::category(c))); -} - -DecompositionType decompositionType(UChar32 c) -{ - return static_cast<DecompositionType>(ICU::decompositionType(c)); -} - -unsigned char combiningClass(UChar32 c) -{ - return ICU::combiningClass(c); -} - -UChar mirroredChar(UChar32 c) -{ - return ICU::mirroredChar(c); -} - -int digitValue(UChar c) -{ - return ICU::digitValue(c); -} - -bool isSpace(UChar c) -{ - return !!iswspace(c); -} - -bool isLetter(UChar c) -{ - return !!iswalpha(c); -} - -} // namespace Unicode -} // namespace WTF diff --git a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h b/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h deleted file mode 100644 index 1d7576f..0000000 --- a/JavaScriptCore/wtf/unicode/brew/UnicodeBrew.h +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2007 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * Copyright (C) 2010 Company 100, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef UnicodeBrew_h -#define UnicodeBrew_h - -#include "UnicodeFromICU.h" -#include "UnicodeMacrosFromICU.h" - -namespace WTF { -namespace Unicode { - -enum Direction { - LeftToRight = ICU::U_LEFT_TO_RIGHT, - RightToLeft = ICU::U_RIGHT_TO_LEFT, - EuropeanNumber = ICU::U_EUROPEAN_NUMBER, - EuropeanNumberSeparator = ICU::U_EUROPEAN_NUMBER_SEPARATOR, - EuropeanNumberTerminator = ICU::U_EUROPEAN_NUMBER_TERMINATOR, - ArabicNumber = ICU::U_ARABIC_NUMBER, - CommonNumberSeparator = ICU::U_COMMON_NUMBER_SEPARATOR, - BlockSeparator = ICU::U_BLOCK_SEPARATOR, - SegmentSeparator = ICU::U_SEGMENT_SEPARATOR, - WhiteSpaceNeutral = ICU::U_WHITE_SPACE_NEUTRAL, - OtherNeutral = ICU::U_OTHER_NEUTRAL, - LeftToRightEmbedding = ICU::U_LEFT_TO_RIGHT_EMBEDDING, - LeftToRightOverride = ICU::U_LEFT_TO_RIGHT_OVERRIDE, - RightToLeftArabic = ICU::U_RIGHT_TO_LEFT_ARABIC, - RightToLeftEmbedding = ICU::U_RIGHT_TO_LEFT_EMBEDDING, - RightToLeftOverride = ICU::U_RIGHT_TO_LEFT_OVERRIDE, - PopDirectionalFormat = ICU::U_POP_DIRECTIONAL_FORMAT, - NonSpacingMark = ICU::U_DIR_NON_SPACING_MARK, - BoundaryNeutral = ICU::U_BOUNDARY_NEUTRAL -}; - -enum DecompositionType { - DecompositionNone = ICU::U_DT_NONE, - DecompositionCanonical = ICU::U_DT_CANONICAL, - DecompositionCompat = ICU::U_DT_COMPAT, - DecompositionCircle = ICU::U_DT_CIRCLE, - DecompositionFinal = ICU::U_DT_FINAL, - DecompositionFont = ICU::U_DT_FONT, - DecompositionFraction = ICU::U_DT_FRACTION, - DecompositionInitial = ICU::U_DT_INITIAL, - DecompositionIsolated = ICU::U_DT_ISOLATED, - DecompositionMedial = ICU::U_DT_MEDIAL, - DecompositionNarrow = ICU::U_DT_NARROW, - DecompositionNoBreak = ICU::U_DT_NOBREAK, - DecompositionSmall = ICU::U_DT_SMALL, - DecompositionSquare = ICU::U_DT_SQUARE, - DecompositionSub = ICU::U_DT_SUB, - DecompositionSuper = ICU::U_DT_SUPER, - DecompositionVertical = ICU::U_DT_VERTICAL, - DecompositionWide = ICU::U_DT_WIDE, -}; - -enum CharCategory { - NoCategory = 0, - Other_NotAssigned = TO_MASK(ICU::U_GENERAL_OTHER_TYPES), - Letter_Uppercase = TO_MASK(ICU::U_UPPERCASE_LETTER), - Letter_Lowercase = TO_MASK(ICU::U_LOWERCASE_LETTER), - Letter_Titlecase = TO_MASK(ICU::U_TITLECASE_LETTER), - Letter_Modifier = TO_MASK(ICU::U_MODIFIER_LETTER), - Letter_Other = TO_MASK(ICU::U_OTHER_LETTER), - - Mark_NonSpacing = TO_MASK(ICU::U_NON_SPACING_MARK), - Mark_Enclosing = TO_MASK(ICU::U_ENCLOSING_MARK), - Mark_SpacingCombining = TO_MASK(ICU::U_COMBINING_SPACING_MARK), - - Number_DecimalDigit = TO_MASK(ICU::U_DECIMAL_DIGIT_NUMBER), - Number_Letter = TO_MASK(ICU::U_LETTER_NUMBER), - Number_Other = TO_MASK(ICU::U_OTHER_NUMBER), - - Separator_Space = TO_MASK(ICU::U_SPACE_SEPARATOR), - Separator_Line = TO_MASK(ICU::U_LINE_SEPARATOR), - Separator_Paragraph = TO_MASK(ICU::U_PARAGRAPH_SEPARATOR), - - Other_Control = TO_MASK(ICU::U_CONTROL_CHAR), - Other_Format = TO_MASK(ICU::U_FORMAT_CHAR), - Other_PrivateUse = TO_MASK(ICU::U_PRIVATE_USE_CHAR), - Other_Surrogate = TO_MASK(ICU::U_SURROGATE), - - Punctuation_Dash = TO_MASK(ICU::U_DASH_PUNCTUATION), - Punctuation_Open = TO_MASK(ICU::U_START_PUNCTUATION), - Punctuation_Close = TO_MASK(ICU::U_END_PUNCTUATION), - Punctuation_Connector = TO_MASK(ICU::U_CONNECTOR_PUNCTUATION), - Punctuation_Other = TO_MASK(ICU::U_OTHER_PUNCTUATION), - - Symbol_Math = TO_MASK(ICU::U_MATH_SYMBOL), - Symbol_Currency = TO_MASK(ICU::U_CURRENCY_SYMBOL), - Symbol_Modifier = TO_MASK(ICU::U_MODIFIER_SYMBOL), - Symbol_Other = TO_MASK(ICU::U_OTHER_SYMBOL), - - Punctuation_InitialQuote = TO_MASK(ICU::U_INITIAL_PUNCTUATION), - Punctuation_FinalQuote = TO_MASK(ICU::U_FINAL_PUNCTUATION) -}; - -UChar foldCase(UChar); - -int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); - -int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); - -UChar toUpper(UChar); -UChar toLower(UChar); - -bool isUpper(UChar); - -int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); - -UChar toTitleCase(UChar); - -inline bool isArabicChar(UChar32 c) -{ - return c >= 0x0600 && c <= 0x06FF; -} - -bool isAlphanumeric(UChar); - -CharCategory category(unsigned int); - -inline bool isSeparatorSpace(UChar c) -{ - return category(c) == Separator_Space; -} - -bool isPrintableChar(UChar); - -bool isDigit(UChar); - -bool isPunct(UChar); - -inline bool hasLineBreakingPropertyComplexContext(UChar32) -{ - // FIXME: implement! - return false; -} - -inline bool hasLineBreakingPropertyComplexContextOrIdeographic(UChar32 c) -{ - // FIXME - return false; -} - -UChar mirroredChar(UChar32); - -Direction direction(UChar32); - -bool isLower(UChar); - -int digitValue(UChar); - -unsigned char combiningClass(UChar32); - -DecompositionType decompositionType(UChar32); - -inline int umemcasecmp(const UChar* a, const UChar* b, int len) -{ - for (int i = 0; i < len; ++i) { - UChar c1 = foldCase(a[i]); - UChar c2 = foldCase(b[i]); - if (c1 != c2) - return c1 - c2; - } - return 0; -} - -bool isSpace(UChar); -bool isLetter(UChar); - -} // namespace Unicode -} // namespace WTF - -#endif diff --git a/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp b/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp deleted file mode 100644 index a01c3ee..0000000 --- a/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (C) 2008 Jürg Billeter <j@bitron.ch> - * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com> - * Copyright (C) 2010 Igalia S.L. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#include "config.h" -#include "UnicodeGLib.h" - -#include <wtf/Vector.h> -#include <wtf/unicode/UTF8.h> - -#define UTF8_IS_SURROGATE(character) (character >= 0x10000 && character <= 0x10FFFF) - -namespace WTF { -namespace Unicode { - -UChar32 foldCase(UChar32 ch) -{ - GOwnPtr<GError> gerror; - - GOwnPtr<char> utf8char; - utf8char.set(g_ucs4_to_utf8(reinterpret_cast<gunichar*>(&ch), 1, 0, 0, &gerror.outPtr())); - if (gerror) - return ch; - - GOwnPtr<char> utf8caseFolded; - utf8caseFolded.set(g_utf8_casefold(utf8char.get(), -1)); - - GOwnPtr<gunichar> ucs4Result; - ucs4Result.set(g_utf8_to_ucs4_fast(utf8caseFolded.get(), -1, 0)); - - return *ucs4Result; -} - -static int getUTF16LengthFromUTF8(const gchar* utf8String, int length) -{ - int utf16Length = 0; - const gchar* inputString = utf8String; - - while ((utf8String + length - inputString > 0) && *inputString) { - gunichar character = g_utf8_get_char(inputString); - - utf16Length += UTF8_IS_SURROGATE(character) ? 2 : 1; - inputString = g_utf8_next_char(inputString); - } - - return utf16Length; -} - -typedef gchar* (*UTF8CaseFunction)(const gchar*, gssize length); - -static int convertCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error, UTF8CaseFunction caseFunction) -{ - *error = false; - - // Allocate a buffer big enough to hold all the characters. - Vector<char> buffer(srcLength * 3); - char* utf8Target = buffer.data(); - const UChar* utf16Source = src; - ConversionResult conversionResult = convertUTF16ToUTF8(&utf16Source, utf16Source + srcLength, &utf8Target, utf8Target + buffer.size(), true); - if (conversionResult != conversionOK) { - *error = true; - return -1; - } - buffer.shrink(utf8Target - buffer.data()); - - GOwnPtr<char> utf8Result(caseFunction(buffer.data(), buffer.size())); - long utf8ResultLength = strlen(utf8Result.get()); - - // Calculate the destination buffer size. - int realLength = getUTF16LengthFromUTF8(utf8Result.get(), utf8ResultLength); - if (realLength > resultLength) { - *error = true; - return realLength; - } - - // Convert the result to UTF-16. - UChar* utf16Target = result; - const char* utf8Source = utf8Result.get(); - conversionResult = convertUTF8ToUTF16(&utf8Source, utf8Source + utf8ResultLength, &utf16Target, utf16Target + resultLength, true); - long utf16ResultLength = utf16Target - result; - if (conversionResult != conversionOK) - *error = true; - - return utf16ResultLength <= 0 ? -1 : utf16ResultLength; -} -int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - return convertCase(result, resultLength, src, srcLength, error, g_utf8_casefold); -} - -int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - return convertCase(result, resultLength, src, srcLength, error, g_utf8_strdown); -} - -int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - return convertCase(result, resultLength, src, srcLength, error, g_utf8_strup); -} - -Direction direction(UChar32 c) -{ - PangoBidiType type = pango_bidi_type_for_unichar(c); - switch (type) { - case PANGO_BIDI_TYPE_L: - return LeftToRight; - case PANGO_BIDI_TYPE_R: - return RightToLeft; - case PANGO_BIDI_TYPE_AL: - return RightToLeftArabic; - case PANGO_BIDI_TYPE_LRE: - return LeftToRightEmbedding; - case PANGO_BIDI_TYPE_RLE: - return RightToLeftEmbedding; - case PANGO_BIDI_TYPE_LRO: - return LeftToRightOverride; - case PANGO_BIDI_TYPE_RLO: - return RightToLeftOverride; - case PANGO_BIDI_TYPE_PDF: - return PopDirectionalFormat; - case PANGO_BIDI_TYPE_EN: - return EuropeanNumber; - case PANGO_BIDI_TYPE_AN: - return ArabicNumber; - case PANGO_BIDI_TYPE_ES: - return EuropeanNumberSeparator; - case PANGO_BIDI_TYPE_ET: - return EuropeanNumberTerminator; - case PANGO_BIDI_TYPE_CS: - return CommonNumberSeparator; - case PANGO_BIDI_TYPE_NSM: - return NonSpacingMark; - case PANGO_BIDI_TYPE_BN: - return BoundaryNeutral; - case PANGO_BIDI_TYPE_B: - return BlockSeparator; - case PANGO_BIDI_TYPE_S: - return SegmentSeparator; - case PANGO_BIDI_TYPE_WS: - return WhiteSpaceNeutral; - default: - return OtherNeutral; - } -} - -int umemcasecmp(const UChar* a, const UChar* b, int len) -{ - GOwnPtr<char> utf8a; - GOwnPtr<char> utf8b; - - utf8a.set(g_utf16_to_utf8(a, len, 0, 0, 0)); - utf8b.set(g_utf16_to_utf8(b, len, 0, 0, 0)); - - GOwnPtr<char> foldedA; - GOwnPtr<char> foldedB; - - foldedA.set(g_utf8_casefold(utf8a.get(), -1)); - foldedB.set(g_utf8_casefold(utf8b.get(), -1)); - - // FIXME: umemcasecmp needs to mimic u_memcasecmp of icu - // from the ICU docs: - // "Compare two strings case-insensitively using full case folding. - // his is equivalent to u_strcmp(u_strFoldCase(s1, n, options), u_strFoldCase(s2, n, options))." - // - // So it looks like we don't need the full g_utf8_collate here, - // but really a bitwise comparison of casefolded unicode chars (not utf-8 bytes). - // As there is no direct equivalent to this icu function in GLib, for now - // we'll use g_utf8_collate(): - - return g_utf8_collate(foldedA.get(), foldedB.get()); -} - -} -} diff --git a/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h b/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h deleted file mode 100644 index 46b00ea..0000000 --- a/JavaScriptCore/wtf/unicode/glib/UnicodeGLib.h +++ /dev/null @@ -1,243 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2007 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2008 Jürg Billeter <j@bitron.ch> - * Copyright (C) 2008 Dominik Röttsches <dominik.roettsches@access-company.com> - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef UnicodeGLib_h -#define UnicodeGLib_h - -#include "UnicodeMacrosFromICU.h" -#include "GOwnPtr.h" - -#include <glib.h> -#include <pango/pango.h> -#include <stdint.h> -#include <stdlib.h> -#include <string.h> - -typedef uint16_t UChar; -typedef int32_t UChar32; - -namespace WTF { -namespace Unicode { - -enum Direction { - LeftToRight, - RightToLeft, - EuropeanNumber, - EuropeanNumberSeparator, - EuropeanNumberTerminator, - ArabicNumber, - CommonNumberSeparator, - BlockSeparator, - SegmentSeparator, - WhiteSpaceNeutral, - OtherNeutral, - LeftToRightEmbedding, - LeftToRightOverride, - RightToLeftArabic, - RightToLeftEmbedding, - RightToLeftOverride, - PopDirectionalFormat, - NonSpacingMark, - BoundaryNeutral -}; - -enum DecompositionType { - DecompositionNone, - DecompositionCanonical, - DecompositionCompat, - DecompositionCircle, - DecompositionFinal, - DecompositionFont, - DecompositionFraction, - DecompositionInitial, - DecompositionIsolated, - DecompositionMedial, - DecompositionNarrow, - DecompositionNoBreak, - DecompositionSmall, - DecompositionSquare, - DecompositionSub, - DecompositionSuper, - DecompositionVertical, - DecompositionWide, -}; - -enum CharCategory { - NoCategory = 0, - Other_NotAssigned = U_MASK(G_UNICODE_UNASSIGNED), - Letter_Uppercase = U_MASK(G_UNICODE_UPPERCASE_LETTER), - Letter_Lowercase = U_MASK(G_UNICODE_LOWERCASE_LETTER), - Letter_Titlecase = U_MASK(G_UNICODE_TITLECASE_LETTER), - Letter_Modifier = U_MASK(G_UNICODE_MODIFIER_LETTER), - Letter_Other = U_MASK(G_UNICODE_OTHER_LETTER), - - Mark_NonSpacing = U_MASK(G_UNICODE_NON_SPACING_MARK), - Mark_Enclosing = U_MASK(G_UNICODE_ENCLOSING_MARK), - Mark_SpacingCombining = U_MASK(G_UNICODE_COMBINING_MARK), - - Number_DecimalDigit = U_MASK(G_UNICODE_DECIMAL_NUMBER), - Number_Letter = U_MASK(G_UNICODE_LETTER_NUMBER), - Number_Other = U_MASK(G_UNICODE_OTHER_NUMBER), - - Separator_Space = U_MASK(G_UNICODE_SPACE_SEPARATOR), - Separator_Line = U_MASK(G_UNICODE_LINE_SEPARATOR), - Separator_Paragraph = U_MASK(G_UNICODE_PARAGRAPH_SEPARATOR), - - Other_Control = U_MASK(G_UNICODE_CONTROL), - Other_Format = U_MASK(G_UNICODE_FORMAT), - Other_PrivateUse = U_MASK(G_UNICODE_PRIVATE_USE), - Other_Surrogate = U_MASK(G_UNICODE_SURROGATE), - - Punctuation_Dash = U_MASK(G_UNICODE_DASH_PUNCTUATION), - Punctuation_Open = U_MASK(G_UNICODE_OPEN_PUNCTUATION), - Punctuation_Close = U_MASK(G_UNICODE_CLOSE_PUNCTUATION), - Punctuation_Connector = U_MASK(G_UNICODE_CONNECT_PUNCTUATION), - Punctuation_Other = U_MASK(G_UNICODE_OTHER_PUNCTUATION), - - Symbol_Math = U_MASK(G_UNICODE_MATH_SYMBOL), - Symbol_Currency = U_MASK(G_UNICODE_CURRENCY_SYMBOL), - Symbol_Modifier = U_MASK(G_UNICODE_MODIFIER_SYMBOL), - Symbol_Other = U_MASK(G_UNICODE_OTHER_SYMBOL), - - Punctuation_InitialQuote = U_MASK(G_UNICODE_INITIAL_PUNCTUATION), - Punctuation_FinalQuote = U_MASK(G_UNICODE_FINAL_PUNCTUATION) -}; - -UChar32 foldCase(UChar32); - -int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error); - -int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error); - -inline UChar32 toLower(UChar32 c) -{ - return g_unichar_tolower(c); -} - -inline UChar32 toUpper(UChar32 c) -{ - return g_unichar_toupper(c); -} - -int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error); - -inline UChar32 toTitleCase(UChar32 c) -{ - return g_unichar_totitle(c); -} - -inline bool isArabicChar(UChar32 c) -{ - return c >= 0x0600 && c <= 0x06FF; -} - -inline bool isAlphanumeric(UChar32 c) -{ - return g_unichar_isalnum(c); -} - -inline bool isFormatChar(UChar32 c) -{ - return g_unichar_type(c) == G_UNICODE_FORMAT; -} - -inline bool isSeparatorSpace(UChar32 c) -{ - return g_unichar_type(c) == G_UNICODE_SPACE_SEPARATOR; -} - -inline bool isPrintableChar(UChar32 c) -{ - return g_unichar_isprint(c); -} - -inline bool isDigit(UChar32 c) -{ - return g_unichar_isdigit(c); -} - -inline bool isPunct(UChar32 c) -{ - return g_unichar_ispunct(c); -} - -inline bool hasLineBreakingPropertyComplexContext(UChar32 c) -{ - // FIXME - return false; -} - -inline bool hasLineBreakingPropertyComplexContextOrIdeographic(UChar32 c) -{ - // FIXME - return false; -} - -inline UChar32 mirroredChar(UChar32 c) -{ - gunichar mirror = 0; - g_unichar_get_mirror_char(c, &mirror); - return mirror; -} - -inline CharCategory category(UChar32 c) -{ - if (c > 0xffff) - return NoCategory; - - return (CharCategory) U_MASK(g_unichar_type(c)); -} - -Direction direction(UChar32); - -inline bool isLower(UChar32 c) -{ - return g_unichar_islower(c); -} - -inline int digitValue(UChar32 c) -{ - return g_unichar_digit_value(c); -} - -inline uint8_t combiningClass(UChar32 c) -{ - // FIXME - // return g_unichar_combining_class(c); - return 0; -} - -inline DecompositionType decompositionType(UChar32 c) -{ - // FIXME - return DecompositionNone; -} - -int umemcasecmp(const UChar*, const UChar*, int len); - -} -} - -#endif - diff --git a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp b/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp deleted file mode 100644 index 805b114..0000000 --- a/JavaScriptCore/wtf/unicode/icu/CollatorICU.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2008 Apple Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "Collator.h" - -#if USE(ICU_UNICODE) && !UCONFIG_NO_COLLATION - -#include "Assertions.h" -#include "Threading.h" -#include <unicode/ucol.h> -#include <string.h> - -#if OS(DARWIN) -#include "RetainPtr.h" -#include <CoreFoundation/CoreFoundation.h> -#endif - -namespace WTF { - -static UCollator* cachedCollator; -static Mutex& cachedCollatorMutex() -{ - AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); - return mutex; -} - -Collator::Collator(const char* locale) - : m_collator(0) - , m_locale(locale ? strdup(locale) : 0) - , m_lowerFirst(false) -{ -} - -PassOwnPtr<Collator> Collator::userDefault() -{ -#if OS(DARWIN) && PLATFORM(CF) - // Mac OS X doesn't set UNIX locale to match user-selected one, so ICU default doesn't work. -#if !defined(BUILDING_ON_TIGER) && !defined(BUILDING_ON_LEOPARD) && !OS(IOS) - RetainPtr<CFLocaleRef> currentLocale(AdoptCF, CFLocaleCopyCurrent()); - CFStringRef collationOrder = (CFStringRef)CFLocaleGetValue(currentLocale.get(), kCFLocaleCollatorIdentifier); -#else - RetainPtr<CFStringRef> collationOrderRetainer(AdoptCF, (CFStringRef)CFPreferencesCopyValue(CFSTR("AppleCollationOrder"), kCFPreferencesAnyApplication, kCFPreferencesCurrentUser, kCFPreferencesAnyHost)); - CFStringRef collationOrder = collationOrderRetainer.get(); -#endif - char buf[256]; - if (!collationOrder) - return adoptPtr(new Collator("")); - CFStringGetCString(collationOrder, buf, sizeof(buf), kCFStringEncodingASCII); - return adoptPtr(new Collator(buf)); -#else - return adoptPtr(new Collator(0)); -#endif -} - -Collator::~Collator() -{ - releaseCollator(); - free(m_locale); -} - -void Collator::setOrderLowerFirst(bool lowerFirst) -{ - m_lowerFirst = lowerFirst; -} - -Collator::Result Collator::collate(const UChar* lhs, size_t lhsLength, const UChar* rhs, size_t rhsLength) const -{ - if (!m_collator) - createCollator(); - - return static_cast<Result>(ucol_strcoll(m_collator, lhs, lhsLength, rhs, rhsLength)); -} - -void Collator::createCollator() const -{ - ASSERT(!m_collator); - UErrorCode status = U_ZERO_ERROR; - - { - Locker<Mutex> lock(cachedCollatorMutex()); - if (cachedCollator) { - const char* cachedCollatorLocale = ucol_getLocaleByType(cachedCollator, ULOC_REQUESTED_LOCALE, &status); - ASSERT(U_SUCCESS(status)); - ASSERT(cachedCollatorLocale); - - UColAttributeValue cachedCollatorLowerFirst = ucol_getAttribute(cachedCollator, UCOL_CASE_FIRST, &status); - ASSERT(U_SUCCESS(status)); - - // FIXME: default locale is never matched, because ucol_getLocaleByType returns the actual one used, not 0. - if (m_locale && 0 == strcmp(cachedCollatorLocale, m_locale) - && ((UCOL_LOWER_FIRST == cachedCollatorLowerFirst && m_lowerFirst) || (UCOL_UPPER_FIRST == cachedCollatorLowerFirst && !m_lowerFirst))) { - m_collator = cachedCollator; - cachedCollator = 0; - return; - } - } - } - - m_collator = ucol_open(m_locale, &status); - if (U_FAILURE(status)) { - status = U_ZERO_ERROR; - m_collator = ucol_open("", &status); // Fallback to Unicode Collation Algorithm. - } - ASSERT(U_SUCCESS(status)); - - ucol_setAttribute(m_collator, UCOL_CASE_FIRST, m_lowerFirst ? UCOL_LOWER_FIRST : UCOL_UPPER_FIRST, &status); - ASSERT(U_SUCCESS(status)); -} - -void Collator::releaseCollator() -{ - { - Locker<Mutex> lock(cachedCollatorMutex()); - if (cachedCollator) - ucol_close(cachedCollator); - cachedCollator = m_collator; - m_collator = 0; - } -} - -} - -#endif diff --git a/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h b/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h deleted file mode 100644 index a2a5c0a..0000000 --- a/JavaScriptCore/wtf/unicode/icu/UnicodeIcu.h +++ /dev/null @@ -1,235 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_UNICODE_ICU_H -#define WTF_UNICODE_ICU_H - -#include <stdlib.h> -#include <unicode/uchar.h> -#include <unicode/ustring.h> -#include <unicode/utf16.h> - -namespace WTF { -namespace Unicode { - -enum Direction { - LeftToRight = U_LEFT_TO_RIGHT, - RightToLeft = U_RIGHT_TO_LEFT, - EuropeanNumber = U_EUROPEAN_NUMBER, - EuropeanNumberSeparator = U_EUROPEAN_NUMBER_SEPARATOR, - EuropeanNumberTerminator = U_EUROPEAN_NUMBER_TERMINATOR, - ArabicNumber = U_ARABIC_NUMBER, - CommonNumberSeparator = U_COMMON_NUMBER_SEPARATOR, - BlockSeparator = U_BLOCK_SEPARATOR, - SegmentSeparator = U_SEGMENT_SEPARATOR, - WhiteSpaceNeutral = U_WHITE_SPACE_NEUTRAL, - OtherNeutral = U_OTHER_NEUTRAL, - LeftToRightEmbedding = U_LEFT_TO_RIGHT_EMBEDDING, - LeftToRightOverride = U_LEFT_TO_RIGHT_OVERRIDE, - RightToLeftArabic = U_RIGHT_TO_LEFT_ARABIC, - RightToLeftEmbedding = U_RIGHT_TO_LEFT_EMBEDDING, - RightToLeftOverride = U_RIGHT_TO_LEFT_OVERRIDE, - PopDirectionalFormat = U_POP_DIRECTIONAL_FORMAT, - NonSpacingMark = U_DIR_NON_SPACING_MARK, - BoundaryNeutral = U_BOUNDARY_NEUTRAL -}; - -enum DecompositionType { - DecompositionNone = U_DT_NONE, - DecompositionCanonical = U_DT_CANONICAL, - DecompositionCompat = U_DT_COMPAT, - DecompositionCircle = U_DT_CIRCLE, - DecompositionFinal = U_DT_FINAL, - DecompositionFont = U_DT_FONT, - DecompositionFraction = U_DT_FRACTION, - DecompositionInitial = U_DT_INITIAL, - DecompositionIsolated = U_DT_ISOLATED, - DecompositionMedial = U_DT_MEDIAL, - DecompositionNarrow = U_DT_NARROW, - DecompositionNoBreak = U_DT_NOBREAK, - DecompositionSmall = U_DT_SMALL, - DecompositionSquare = U_DT_SQUARE, - DecompositionSub = U_DT_SUB, - DecompositionSuper = U_DT_SUPER, - DecompositionVertical = U_DT_VERTICAL, - DecompositionWide = U_DT_WIDE, -}; - -enum CharCategory { - NoCategory = 0, - Other_NotAssigned = U_MASK(U_GENERAL_OTHER_TYPES), - Letter_Uppercase = U_MASK(U_UPPERCASE_LETTER), - Letter_Lowercase = U_MASK(U_LOWERCASE_LETTER), - Letter_Titlecase = U_MASK(U_TITLECASE_LETTER), - Letter_Modifier = U_MASK(U_MODIFIER_LETTER), - Letter_Other = U_MASK(U_OTHER_LETTER), - - Mark_NonSpacing = U_MASK(U_NON_SPACING_MARK), - Mark_Enclosing = U_MASK(U_ENCLOSING_MARK), - Mark_SpacingCombining = U_MASK(U_COMBINING_SPACING_MARK), - - Number_DecimalDigit = U_MASK(U_DECIMAL_DIGIT_NUMBER), - Number_Letter = U_MASK(U_LETTER_NUMBER), - Number_Other = U_MASK(U_OTHER_NUMBER), - - Separator_Space = U_MASK(U_SPACE_SEPARATOR), - Separator_Line = U_MASK(U_LINE_SEPARATOR), - Separator_Paragraph = U_MASK(U_PARAGRAPH_SEPARATOR), - - Other_Control = U_MASK(U_CONTROL_CHAR), - Other_Format = U_MASK(U_FORMAT_CHAR), - Other_PrivateUse = U_MASK(U_PRIVATE_USE_CHAR), - Other_Surrogate = U_MASK(U_SURROGATE), - - Punctuation_Dash = U_MASK(U_DASH_PUNCTUATION), - Punctuation_Open = U_MASK(U_START_PUNCTUATION), - Punctuation_Close = U_MASK(U_END_PUNCTUATION), - Punctuation_Connector = U_MASK(U_CONNECTOR_PUNCTUATION), - Punctuation_Other = U_MASK(U_OTHER_PUNCTUATION), - - Symbol_Math = U_MASK(U_MATH_SYMBOL), - Symbol_Currency = U_MASK(U_CURRENCY_SYMBOL), - Symbol_Modifier = U_MASK(U_MODIFIER_SYMBOL), - Symbol_Other = U_MASK(U_OTHER_SYMBOL), - - Punctuation_InitialQuote = U_MASK(U_INITIAL_PUNCTUATION), - Punctuation_FinalQuote = U_MASK(U_FINAL_PUNCTUATION) -}; - -inline UChar32 foldCase(UChar32 c) -{ - return u_foldCase(c, U_FOLD_CASE_DEFAULT); -} - -inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - UErrorCode status = U_ZERO_ERROR; - int realLength = u_strFoldCase(result, resultLength, src, srcLength, U_FOLD_CASE_DEFAULT, &status); - *error = !U_SUCCESS(status); - return realLength; -} - -inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - UErrorCode status = U_ZERO_ERROR; - int realLength = u_strToLower(result, resultLength, src, srcLength, "", &status); - *error = !!U_FAILURE(status); - return realLength; -} - -inline UChar32 toLower(UChar32 c) -{ - return u_tolower(c); -} - -inline UChar32 toUpper(UChar32 c) -{ - return u_toupper(c); -} - -inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - UErrorCode status = U_ZERO_ERROR; - int realLength = u_strToUpper(result, resultLength, src, srcLength, "", &status); - *error = !!U_FAILURE(status); - return realLength; -} - -inline UChar32 toTitleCase(UChar32 c) -{ - return u_totitle(c); -} - -inline bool isArabicChar(UChar32 c) -{ - return ublock_getCode(c) == UBLOCK_ARABIC; -} - -inline bool isAlphanumeric(UChar32 c) -{ - return u_isalnum(c); -} - -inline bool isSeparatorSpace(UChar32 c) -{ - return u_charType(c) == U_SPACE_SEPARATOR; -} - -inline bool isPrintableChar(UChar32 c) -{ - return !!u_isprint(c); -} - -inline bool isPunct(UChar32 c) -{ - return !!u_ispunct(c); -} - -inline bool hasLineBreakingPropertyComplexContext(UChar32 c) -{ - return u_getIntPropertyValue(c, UCHAR_LINE_BREAK) == U_LB_COMPLEX_CONTEXT; -} - -inline bool hasLineBreakingPropertyComplexContextOrIdeographic(UChar32 c) -{ - int32_t prop = u_getIntPropertyValue(c, UCHAR_LINE_BREAK); - return prop == U_LB_COMPLEX_CONTEXT || prop == U_LB_IDEOGRAPHIC; -} - -inline UChar32 mirroredChar(UChar32 c) -{ - return u_charMirror(c); -} - -inline CharCategory category(UChar32 c) -{ - return static_cast<CharCategory>(U_GET_GC_MASK(c)); -} - -inline Direction direction(UChar32 c) -{ - return static_cast<Direction>(u_charDirection(c)); -} - -inline bool isLower(UChar32 c) -{ - return !!u_islower(c); -} - -inline uint8_t combiningClass(UChar32 c) -{ - return u_getCombiningClass(c); -} - -inline DecompositionType decompositionType(UChar32 c) -{ - return static_cast<DecompositionType>(u_getIntPropertyValue(c, UCHAR_DECOMPOSITION_TYPE)); -} - -inline int umemcasecmp(const UChar* a, const UChar* b, int len) -{ - return u_memcasecmp(a, b, len, U_FOLD_CASE_DEFAULT); -} - -} } - -#endif // WTF_UNICODE_ICU_H diff --git a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h b/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h deleted file mode 100644 index eaa7a07..0000000 --- a/JavaScriptCore/wtf/unicode/qt4/UnicodeQt4.h +++ /dev/null @@ -1,375 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_UNICODE_QT4_H -#define WTF_UNICODE_QT4_H - -#include "UnicodeMacrosFromICU.h" - -#include <QChar> -#include <QString> - -#include <config.h> - -#include <stdint.h> -#if USE(QT_ICU_TEXT_BREAKING) -#include <unicode/ubrk.h> -#endif - -QT_BEGIN_NAMESPACE -namespace QUnicodeTables { - struct Properties { - ushort category : 8; - ushort line_break_class : 8; - ushort direction : 8; - ushort combiningClass :8; - ushort joining : 2; - signed short digitValue : 6; /* 5 needed */ - ushort unicodeVersion : 4; - ushort lowerCaseSpecial : 1; - ushort upperCaseSpecial : 1; - ushort titleCaseSpecial : 1; - ushort caseFoldSpecial : 1; /* currently unused */ - signed short mirrorDiff : 16; - signed short lowerCaseDiff : 16; - signed short upperCaseDiff : 16; - signed short titleCaseDiff : 16; - signed short caseFoldDiff : 16; - }; - Q_CORE_EXPORT const Properties * QT_FASTCALL properties(uint ucs4); - Q_CORE_EXPORT const Properties * QT_FASTCALL properties(ushort ucs2); -} -QT_END_NAMESPACE - -// ugly hack to make UChar compatible with JSChar in API/JSStringRef.h -#if defined(Q_OS_WIN) || COMPILER(WINSCW) || (COMPILER(RVCT) && !OS(LINUX)) -typedef wchar_t UChar; -#else -typedef uint16_t UChar; -#endif - -#if !USE(QT_ICU_TEXT_BREAKING) -typedef uint32_t UChar32; -#endif - -namespace WTF { -namespace Unicode { - -enum Direction { - LeftToRight = QChar::DirL, - RightToLeft = QChar::DirR, - EuropeanNumber = QChar::DirEN, - EuropeanNumberSeparator = QChar::DirES, - EuropeanNumberTerminator = QChar::DirET, - ArabicNumber = QChar::DirAN, - CommonNumberSeparator = QChar::DirCS, - BlockSeparator = QChar::DirB, - SegmentSeparator = QChar::DirS, - WhiteSpaceNeutral = QChar::DirWS, - OtherNeutral = QChar::DirON, - LeftToRightEmbedding = QChar::DirLRE, - LeftToRightOverride = QChar::DirLRO, - RightToLeftArabic = QChar::DirAL, - RightToLeftEmbedding = QChar::DirRLE, - RightToLeftOverride = QChar::DirRLO, - PopDirectionalFormat = QChar::DirPDF, - NonSpacingMark = QChar::DirNSM, - BoundaryNeutral = QChar::DirBN -}; - -enum DecompositionType { - DecompositionNone = QChar::NoDecomposition, - DecompositionCanonical = QChar::Canonical, - DecompositionCompat = QChar::Compat, - DecompositionCircle = QChar::Circle, - DecompositionFinal = QChar::Final, - DecompositionFont = QChar::Font, - DecompositionFraction = QChar::Fraction, - DecompositionInitial = QChar::Initial, - DecompositionIsolated = QChar::Isolated, - DecompositionMedial = QChar::Medial, - DecompositionNarrow = QChar::Narrow, - DecompositionNoBreak = QChar::NoBreak, - DecompositionSmall = QChar::Small, - DecompositionSquare = QChar::Square, - DecompositionSub = QChar::Sub, - DecompositionSuper = QChar::Super, - DecompositionVertical = QChar::Vertical, - DecompositionWide = QChar::Wide -}; - -enum CharCategory { - NoCategory = 0, - Mark_NonSpacing = U_MASK(QChar::Mark_NonSpacing), - Mark_SpacingCombining = U_MASK(QChar::Mark_SpacingCombining), - Mark_Enclosing = U_MASK(QChar::Mark_Enclosing), - Number_DecimalDigit = U_MASK(QChar::Number_DecimalDigit), - Number_Letter = U_MASK(QChar::Number_Letter), - Number_Other = U_MASK(QChar::Number_Other), - Separator_Space = U_MASK(QChar::Separator_Space), - Separator_Line = U_MASK(QChar::Separator_Line), - Separator_Paragraph = U_MASK(QChar::Separator_Paragraph), - Other_Control = U_MASK(QChar::Other_Control), - Other_Format = U_MASK(QChar::Other_Format), - Other_Surrogate = U_MASK(QChar::Other_Surrogate), - Other_PrivateUse = U_MASK(QChar::Other_PrivateUse), - Other_NotAssigned = U_MASK(QChar::Other_NotAssigned), - Letter_Uppercase = U_MASK(QChar::Letter_Uppercase), - Letter_Lowercase = U_MASK(QChar::Letter_Lowercase), - Letter_Titlecase = U_MASK(QChar::Letter_Titlecase), - Letter_Modifier = U_MASK(QChar::Letter_Modifier), - Letter_Other = U_MASK(QChar::Letter_Other), - Punctuation_Connector = U_MASK(QChar::Punctuation_Connector), - Punctuation_Dash = U_MASK(QChar::Punctuation_Dash), - Punctuation_Open = U_MASK(QChar::Punctuation_Open), - Punctuation_Close = U_MASK(QChar::Punctuation_Close), - Punctuation_InitialQuote = U_MASK(QChar::Punctuation_InitialQuote), - Punctuation_FinalQuote = U_MASK(QChar::Punctuation_FinalQuote), - Punctuation_Other = U_MASK(QChar::Punctuation_Other), - Symbol_Math = U_MASK(QChar::Symbol_Math), - Symbol_Currency = U_MASK(QChar::Symbol_Currency), - Symbol_Modifier = U_MASK(QChar::Symbol_Modifier), - Symbol_Other = U_MASK(QChar::Symbol_Other) -}; - - -// FIXME: handle surrogates correctly in all methods - -inline UChar32 toLower(UChar32 ch) -{ - return QChar::toLower(uint32_t(ch)); -} - -inline int toLower(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - const UChar *e = src + srcLength; - const UChar *s = src; - UChar *r = result; - uint rindex = 0; - - // this avoids one out of bounds check in the loop - if (s < e && QChar(*s).isLowSurrogate()) { - if (r) - r[rindex] = *s++; - ++rindex; - } - - int needed = 0; - while (s < e && (rindex < uint(resultLength) || !r)) { - uint c = *s; - if (QChar(c).isLowSurrogate() && QChar(*(s - 1)).isHighSurrogate()) - c = QChar::surrogateToUcs4(*(s - 1), c); - const QUnicodeTables::Properties *prop = QUnicodeTables::properties(c); - if (prop->lowerCaseSpecial) { - QString qstring; - if (c < 0x10000) { - qstring += QChar(c); - } else { - qstring += QChar(*(s-1)); - qstring += QChar(*s); - } - qstring = qstring.toLower(); - for (int i = 0; i < qstring.length(); ++i) { - if (rindex >= uint(resultLength)) { - needed += qstring.length() - i; - break; - } - if (r) - r[rindex] = qstring.at(i).unicode(); - ++rindex; - } - } else { - if (r) - r[rindex] = *s + prop->lowerCaseDiff; - ++rindex; - } - ++s; - } - if (s < e) - needed += e - s; - *error = (needed != 0); - if (rindex < uint(resultLength)) - r[rindex] = 0; - return rindex + needed; -} - -inline UChar32 toUpper(UChar32 c) -{ - return QChar::toUpper(uint32_t(c)); -} - -inline int toUpper(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - const UChar *e = src + srcLength; - const UChar *s = src; - UChar *r = result; - int rindex = 0; - - // this avoids one out of bounds check in the loop - if (s < e && QChar(*s).isLowSurrogate()) { - if (r) - r[rindex] = *s++; - ++rindex; - } - - int needed = 0; - while (s < e && (rindex < resultLength || !r)) { - uint c = *s; - if (QChar(c).isLowSurrogate() && QChar(*(s - 1)).isHighSurrogate()) - c = QChar::surrogateToUcs4(*(s - 1), c); - const QUnicodeTables::Properties *prop = QUnicodeTables::properties(c); - if (prop->upperCaseSpecial) { - QString qstring; - if (c < 0x10000) { - qstring += QChar(c); - } else { - qstring += QChar(*(s-1)); - qstring += QChar(*s); - } - qstring = qstring.toUpper(); - for (int i = 0; i < qstring.length(); ++i) { - if (rindex >= resultLength) { - needed += qstring.length() - i; - break; - } - if (r) - r[rindex] = qstring.at(i).unicode(); - ++rindex; - } - } else { - if (r) - r[rindex] = *s + prop->upperCaseDiff; - ++rindex; - } - ++s; - } - if (s < e) - needed += e - s; - *error = (needed != 0); - if (rindex < resultLength) - r[rindex] = 0; - return rindex + needed; -} - -inline int toTitleCase(UChar32 c) -{ - return QChar::toTitleCase(uint32_t(c)); -} - -inline UChar32 foldCase(UChar32 c) -{ - return QChar::toCaseFolded(uint32_t(c)); -} - -inline int foldCase(UChar* result, int resultLength, const UChar* src, int srcLength, bool* error) -{ - // FIXME: handle special casing. Easiest with some low level API in Qt - *error = false; - if (resultLength < srcLength) { - *error = true; - return srcLength; - } - for (int i = 0; i < srcLength; ++i) - result[i] = QChar::toCaseFolded(ushort(src[i])); - return srcLength; -} - -inline bool isArabicChar(UChar32 c) -{ - return c >= 0x0600 && c <= 0x06FF; -} - -inline bool isPrintableChar(UChar32 c) -{ - const uint test = U_MASK(QChar::Other_Control) | - U_MASK(QChar::Other_NotAssigned); - return !(U_MASK(QChar::category(uint32_t(c))) & test); -} - -inline bool isSeparatorSpace(UChar32 c) -{ - return QChar::category(uint32_t(c)) == QChar::Separator_Space; -} - -inline bool isPunct(UChar32 c) -{ - const uint test = U_MASK(QChar::Punctuation_Connector) | - U_MASK(QChar::Punctuation_Dash) | - U_MASK(QChar::Punctuation_Open) | - U_MASK(QChar::Punctuation_Close) | - U_MASK(QChar::Punctuation_InitialQuote) | - U_MASK(QChar::Punctuation_FinalQuote) | - U_MASK(QChar::Punctuation_Other); - return U_MASK(QChar::category(uint32_t(c))) & test; -} - -inline bool isLower(UChar32 c) -{ - return QChar::category(uint32_t(c)) == QChar::Letter_Lowercase; -} - -inline bool hasLineBreakingPropertyComplexContext(UChar32) -{ - // FIXME: Implement this to return whether the character has line breaking property SA (Complex Context). - return false; -} - -inline UChar32 mirroredChar(UChar32 c) -{ - return QChar::mirroredChar(uint32_t(c)); -} - -inline uint8_t combiningClass(UChar32 c) -{ - return QChar::combiningClass(uint32_t(c)); -} - -inline DecompositionType decompositionType(UChar32 c) -{ - return (DecompositionType)QChar::decompositionTag(c); -} - -inline int umemcasecmp(const UChar* a, const UChar* b, int len) -{ - // handle surrogates correctly - for (int i = 0; i < len; ++i) { - uint c1 = QChar::toCaseFolded(ushort(a[i])); - uint c2 = QChar::toCaseFolded(ushort(b[i])); - if (c1 != c2) - return c1 - c2; - } - return 0; -} - -inline Direction direction(UChar32 c) -{ - return (Direction)QChar::direction(uint32_t(c)); -} - -inline CharCategory category(UChar32 c) -{ - return (CharCategory) U_MASK(QChar::category(uint32_t(c))); -} - -} } - -#endif // WTF_UNICODE_QT4_H diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp deleted file mode 100644 index 96dac7d..0000000 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "UnicodeWinCE.h" - -#include <wchar.h> - -namespace WTF { -namespace Unicode { - -UChar toLower(UChar c) -{ - return towlower(c); -} - -UChar toUpper(UChar c) -{ - return towupper(c); -} - -UChar foldCase(UChar c) -{ - return towlower(c); -} - -bool isPrintableChar(UChar c) -{ - return !!iswprint(c); -} - -bool isSpace(UChar c) -{ - return !!iswspace(c); -} - -bool isLetter(UChar c) -{ - return !!iswalpha(c); -} - -bool isUpper(UChar c) -{ - return !!iswupper(c); -} - -bool isLower(UChar c) -{ - return !!iswlower(c); -} - -bool isDigit(UChar c) -{ - return !!iswdigit(c); -} - -bool isPunct(UChar c) -{ - return !!iswpunct(c); -} - -bool isAlphanumeric(UChar c) -{ - return !!iswalnum(c); -} - -int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) -{ - const UChar* sourceIterator = source; - const UChar* sourceEnd = source + sourceLength; - UChar* resultIterator = result; - UChar* resultEnd = result + resultLength; - - int remainingCharacters = 0; - if (sourceLength <= resultLength) - while (sourceIterator < sourceEnd) - *resultIterator++ = towlower(*sourceIterator++); - else - while (resultIterator < resultEnd) - *resultIterator++ = towlower(*sourceIterator++); - - if (sourceIterator < sourceEnd) - remainingCharacters += sourceEnd - sourceIterator; - *isError = !!remainingCharacters; - if (resultIterator < resultEnd) - *resultIterator = 0; - - return (resultIterator - result) + remainingCharacters; -} - -int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) -{ - const UChar* sourceIterator = source; - const UChar* sourceEnd = source + sourceLength; - UChar* resultIterator = result; - UChar* resultEnd = result + resultLength; - - int remainingCharacters = 0; - if (sourceLength <= resultLength) - while (sourceIterator < sourceEnd) - *resultIterator++ = towupper(*sourceIterator++); - else - while (resultIterator < resultEnd) - *resultIterator++ = towupper(*sourceIterator++); - - if (sourceIterator < sourceEnd) - remainingCharacters += sourceEnd - sourceIterator; - *isError = !!remainingCharacters; - if (resultIterator < resultEnd) - *resultIterator = 0; - - return (resultIterator - result) + remainingCharacters; -} - -int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError) -{ - *isError = false; - if (resultLength < sourceLength) { - *isError = true; - return sourceLength; - } - for (int i = 0; i < sourceLength; ++i) - result[i] = foldCase(source[i]); - return sourceLength; -} - -UChar toTitleCase(UChar c) -{ - return towupper(c); -} - -Direction direction(UChar32 c) -{ - return static_cast<Direction>(UnicodeCE::direction(c)); -} - -CharCategory category(unsigned int c) -{ - return static_cast<CharCategory>(TO_MASK((__int8) UnicodeCE::category(c))); -} - -DecompositionType decompositionType(UChar32 c) -{ - return static_cast<DecompositionType>(UnicodeCE::decompositionType(c)); -} - -unsigned char combiningClass(UChar32 c) -{ - return UnicodeCE::combiningClass(c); -} - -UChar mirroredChar(UChar32 c) -{ - return UnicodeCE::mirroredChar(c); -} - -int digitValue(UChar c) -{ - return UnicodeCE::digitValue(c); -} - -} // namespace Unicode -} // namespace WTF diff --git a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h b/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h deleted file mode 100644 index 2688aa9..0000000 --- a/JavaScriptCore/wtf/unicode/wince/UnicodeWinCE.h +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Copyright (C) 2006 George Staikos <staikos@kde.org> - * Copyright (C) 2006 Alexey Proskuryakov <ap@nypop.com> - * Copyright (C) 2007 Apple Computer, Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_UnicodeWinCE_h -#define WTF_UnicodeWinCE_h - -#include "UnicodeMacrosFromICU.h" - -#include "ce_unicode.h" - -#define TO_MASK(x) (1 << (x)) - -namespace WTF { -namespace Unicode { - -enum Direction { - LeftToRight = UnicodeCE::U_LEFT_TO_RIGHT, - RightToLeft = UnicodeCE::U_RIGHT_TO_LEFT, - EuropeanNumber = UnicodeCE::U_EUROPEAN_NUMBER, - EuropeanNumberSeparator = UnicodeCE::U_EUROPEAN_NUMBER_SEPARATOR, - EuropeanNumberTerminator = UnicodeCE::U_EUROPEAN_NUMBER_TERMINATOR, - ArabicNumber = UnicodeCE::U_ARABIC_NUMBER, - CommonNumberSeparator = UnicodeCE::U_COMMON_NUMBER_SEPARATOR, - BlockSeparator = UnicodeCE::U_BLOCK_SEPARATOR, - SegmentSeparator = UnicodeCE::U_SEGMENT_SEPARATOR, - WhiteSpaceNeutral = UnicodeCE::U_WHITE_SPACE_NEUTRAL, - OtherNeutral = UnicodeCE::U_OTHER_NEUTRAL, - LeftToRightEmbedding = UnicodeCE::U_LEFT_TO_RIGHT_EMBEDDING, - LeftToRightOverride = UnicodeCE::U_LEFT_TO_RIGHT_OVERRIDE, - RightToLeftArabic = UnicodeCE::U_RIGHT_TO_LEFT_ARABIC, - RightToLeftEmbedding = UnicodeCE::U_RIGHT_TO_LEFT_EMBEDDING, - RightToLeftOverride = UnicodeCE::U_RIGHT_TO_LEFT_OVERRIDE, - PopDirectionalFormat = UnicodeCE::U_POP_DIRECTIONAL_FORMAT, - NonSpacingMark = UnicodeCE::U_DIR_NON_SPACING_MARK, - BoundaryNeutral = UnicodeCE::U_BOUNDARY_NEUTRAL -}; - -enum DecompositionType { - DecompositionNone = UnicodeCE::U_DT_NONE, - DecompositionCanonical = UnicodeCE::U_DT_CANONICAL, - DecompositionCompat = UnicodeCE::U_DT_COMPAT, - DecompositionCircle = UnicodeCE::U_DT_CIRCLE, - DecompositionFinal = UnicodeCE::U_DT_FINAL, - DecompositionFont = UnicodeCE::U_DT_FONT, - DecompositionFraction = UnicodeCE::U_DT_FRACTION, - DecompositionInitial = UnicodeCE::U_DT_INITIAL, - DecompositionIsolated = UnicodeCE::U_DT_ISOLATED, - DecompositionMedial = UnicodeCE::U_DT_MEDIAL, - DecompositionNarrow = UnicodeCE::U_DT_NARROW, - DecompositionNoBreak = UnicodeCE::U_DT_NOBREAK, - DecompositionSmall = UnicodeCE::U_DT_SMALL, - DecompositionSquare = UnicodeCE::U_DT_SQUARE, - DecompositionSub = UnicodeCE::U_DT_SUB, - DecompositionSuper = UnicodeCE::U_DT_SUPER, - DecompositionVertical = UnicodeCE::U_DT_VERTICAL, - DecompositionWide = UnicodeCE::U_DT_WIDE -}; - -enum CharCategory { - NoCategory = 0, - Other_NotAssigned = TO_MASK(UnicodeCE::U_GENERAL_OTHER_TYPES), - Letter_Uppercase = TO_MASK(UnicodeCE::U_UPPERCASE_LETTER), - Letter_Lowercase = TO_MASK(UnicodeCE::U_LOWERCASE_LETTER), - Letter_Titlecase = TO_MASK(UnicodeCE::U_TITLECASE_LETTER), - Letter_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_LETTER), - Letter_Other = TO_MASK(UnicodeCE::U_OTHER_LETTER), - - Mark_NonSpacing = TO_MASK(UnicodeCE::U_NON_SPACING_MARK), - Mark_Enclosing = TO_MASK(UnicodeCE::U_ENCLOSING_MARK), - Mark_SpacingCombining = TO_MASK(UnicodeCE::U_COMBINING_SPACING_MARK), - - Number_DecimalDigit = TO_MASK(UnicodeCE::U_DECIMAL_DIGIT_NUMBER), - Number_Letter = TO_MASK(UnicodeCE::U_LETTER_NUMBER), - Number_Other = TO_MASK(UnicodeCE::U_OTHER_NUMBER), - - Separator_Space = TO_MASK(UnicodeCE::U_SPACE_SEPARATOR), - Separator_Line = TO_MASK(UnicodeCE::U_LINE_SEPARATOR), - Separator_Paragraph = TO_MASK(UnicodeCE::U_PARAGRAPH_SEPARATOR), - - Other_Control = TO_MASK(UnicodeCE::U_CONTROL_CHAR), - Other_Format = TO_MASK(UnicodeCE::U_FORMAT_CHAR), - Other_PrivateUse = TO_MASK(UnicodeCE::U_PRIVATE_USE_CHAR), - Other_Surrogate = TO_MASK(UnicodeCE::U_SURROGATE), - - Punctuation_Dash = TO_MASK(UnicodeCE::U_DASH_PUNCTUATION), - Punctuation_Open = TO_MASK(UnicodeCE::U_START_PUNCTUATION), - Punctuation_Close = TO_MASK(UnicodeCE::U_END_PUNCTUATION), - Punctuation_Connector = TO_MASK(UnicodeCE::U_CONNECTOR_PUNCTUATION), - Punctuation_Other = TO_MASK(UnicodeCE::U_OTHER_PUNCTUATION), - - Symbol_Math = TO_MASK(UnicodeCE::U_MATH_SYMBOL), - Symbol_Currency = TO_MASK(UnicodeCE::U_CURRENCY_SYMBOL), - Symbol_Modifier = TO_MASK(UnicodeCE::U_MODIFIER_SYMBOL), - Symbol_Other = TO_MASK(UnicodeCE::U_OTHER_SYMBOL), - - Punctuation_InitialQuote = TO_MASK(UnicodeCE::U_INITIAL_PUNCTUATION), - Punctuation_FinalQuote = TO_MASK(UnicodeCE::U_FINAL_PUNCTUATION) -}; - -CharCategory category(unsigned int); - -bool isSpace(UChar); -bool isLetter(UChar); -bool isPrintableChar(UChar); -bool isUpper(UChar); -bool isLower(UChar); -bool isPunct(UChar); -bool isDigit(UChar); -bool isAlphanumeric(UChar); -inline bool isSeparatorSpace(UChar c) { return category(c) == Separator_Space; } -inline bool isHighSurrogate(UChar c) { return (c & 0xfc00) == 0xd800; } -inline bool isLowSurrogate(UChar c) { return (c & 0xfc00) == 0xdc00; } - -UChar toLower(UChar); -UChar toUpper(UChar); -UChar foldCase(UChar); -UChar toTitleCase(UChar); -int toLower(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); -int toUpper(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); -int foldCase(UChar* result, int resultLength, const UChar* source, int sourceLength, bool* isError); - -int digitValue(UChar); - -UChar mirroredChar(UChar32); -unsigned char combiningClass(UChar32); -DecompositionType decompositionType(UChar32); -Direction direction(UChar32); -inline bool isArabicChar(UChar32 c) -{ - return c >= 0x0600 && c <= 0x06FF; -} - -inline bool hasLineBreakingPropertyComplexContext(UChar32) -{ - return false; // FIXME: implement! -} - -inline int umemcasecmp(const UChar* a, const UChar* b, int len) -{ - for (int i = 0; i < len; ++i) { - UChar c1 = foldCase(a[i]); - UChar c2 = foldCase(b[i]); - if (c1 != c2) - return c1 - c2; - } - return 0; -} - -inline UChar32 surrogateToUcs4(UChar high, UChar low) -{ - return (UChar32(high) << 10) + low - 0x35fdc00; -} - -} // namespace Unicode -} // namespace WTF - -#endif // WTF_UnicodeWinCE_h diff --git a/JavaScriptCore/wtf/url/api/ParsedURL.cpp b/JavaScriptCore/wtf/url/api/ParsedURL.cpp deleted file mode 100644 index abe0061..0000000 --- a/JavaScriptCore/wtf/url/api/ParsedURL.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "ParsedURL.h" - -#include "URLComponent.h" -#include "URLParser.h" - -namespace WTF { - -ParsedURL::ParsedURL(const URLString& spec) - : m_spec(spec) -{ - // FIXME: Handle non-standard URLs. - if (spec.string().isEmpty()) - return; - URLParser<UChar>::parseStandardURL(spec.string().characters(), spec.string().length(), m_segments); -} - -String ParsedURL::scheme() const -{ - return segment(m_segments.scheme); -} - -String ParsedURL::username() const -{ - return segment(m_segments.username); -} - -String ParsedURL::password() const -{ - return segment(m_segments.password); -} - -String ParsedURL::host() const -{ - return segment(m_segments.host); -} - -String ParsedURL::port() const -{ - return segment(m_segments.port); -} - -String ParsedURL::path() const -{ - return segment(m_segments.path); -} - -String ParsedURL::query() const -{ - return segment(m_segments.query); -} - -String ParsedURL::fragment() const -{ - return segment(m_segments.fragment); -} - -String ParsedURL::segment(const URLComponent& component) const -{ - if (!component.isValid()) - return String(); - return m_spec.string().substring(component.begin(), component.length()); -} - -} diff --git a/JavaScriptCore/wtf/url/api/ParsedURL.h b/JavaScriptCore/wtf/url/api/ParsedURL.h deleted file mode 100644 index ebc19b7..0000000 --- a/JavaScriptCore/wtf/url/api/ParsedURL.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef ParsedURL_h -#define ParsedURL_h - -#include "URLSegments.h" -#include "URLString.h" - -namespace WTF { - -class URLComponent; - -class ParsedURL { -public: - explicit ParsedURL(const URLString&); - - // FIXME: Add a method for parsing non-canonicalized URLs. - - String scheme() const; - String username() const; - String password() const; - String host() const; - String port() const; - String path() const; - String query() const; - String fragment() const; - - URLString spec() { return m_spec; } - -private: - inline String segment(const URLComponent&) const; - - URLString m_spec; - URLSegments m_segments; -}; - -} - -#endif diff --git a/JavaScriptCore/wtf/url/api/URLString.h b/JavaScriptCore/wtf/url/api/URLString.h deleted file mode 100644 index 7395d49..0000000 --- a/JavaScriptCore/wtf/url/api/URLString.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2010 Google, Inc. All Rights Reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef URLString_h -#define URLString_h - -#include "WTFString.h" - -namespace WTF { - -// URLString represents a string that's a canonicalized URL. -class URLString { -public: - URLString() { } - - const String& string() const { return m_string;} - -private: - friend class ParsedURL; - - // URLString can only be constructed by a ParsedURL. - explicit URLString(const String& string) - : m_string(string) - { - } - - String m_string; -}; - -} - -#endif - diff --git a/JavaScriptCore/wtf/url/src/RawURLBuffer.h b/JavaScriptCore/wtf/url/src/RawURLBuffer.h deleted file mode 100644 index 9bb2e8e..0000000 --- a/JavaScriptCore/wtf/url/src/RawURLBuffer.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef RawURLBuffer_h -#define RawURLBuffer_h - -#include "URLBuffer.h" -#include <stdlib.h> - -namespace WTF { - -// Simple implementation of the URLBuffer using new[]. This class -// also supports a static buffer so if it is allocated on the stack, most -// URLs can be canonicalized with no heap allocations. -template<typename CHAR, int inlineCapacity = 1024> -class RawURLBuffer : public URLBuffer<CHAR> { -public: - RawURLBuffer() : URLBuffer<CHAR>() - { - this->m_buffer = m_inlineBuffer; - this->m_capacity = inlineCapacity; - } - - virtual ~RawURLBuffer() - { - if (this->m_buffer != m_inlineBuffer) - delete[] this->m_buffer; - } - - virtual void resize(int size) - { - CHAR* newBuffer = new CHAR[size]; - memcpy(newBuffer, this->m_buffer, sizeof(CHAR) * (this->m_length < size ? this->m_length : size)); - if (this->m_buffer != m_inlineBuffer) - delete[] this->m_buffer; - this->m_buffer = newBuffer; - this->m_capacity = size; - } - -protected: - CHAR m_inlineBuffer[inlineCapacity]; -}; - -} // namespace WTF - -#endif // RawURLBuffer_h diff --git a/JavaScriptCore/wtf/url/src/URLBuffer.h b/JavaScriptCore/wtf/url/src/URLBuffer.h deleted file mode 100644 index e07402e..0000000 --- a/JavaScriptCore/wtf/url/src/URLBuffer.h +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef URLBuffer_h -#define URLBuffer_h - -namespace WTF { - -// Base class for the canonicalizer output, this maintains a buffer and -// supports simple resizing and append operations on it. -// -// It is VERY IMPORTANT that no virtual function calls be made on the common -// code path. We only have two virtual function calls, the destructor and a -// resize function that is called when the existing buffer is not big enough. -// The derived class is then in charge of setting up our buffer which we will -// manage. -template<typename CHAR> -class URLBuffer { -public: - URLBuffer() : m_buffer(0), m_capacity(0), m_length(0) { } - virtual ~URLBuffer() { } - - // Implemented to resize the buffer. This function should update the buffer - // pointer to point to the new buffer, and any old data up to |m_length| in - // the buffer must be copied over. - // - // The new size must be larger than m_capacity. - virtual void resize(int) = 0; - - inline char at(int offset) const { return m_buffer[offset]; } - inline void set(int offset, CHAR ch) - { - // FIXME: Add ASSERT(offset < length()); - m_buffer[offset] = ch; - } - - // Returns the current capacity of the buffer. The length() is the number of - // characters that have been declared to be written, but the capacity() is - // the number that can be written without reallocation. If the caller must - // write many characters at once, it can make sure there is enough capacity, - // write the data, then use setLength() to declare the new length(). - int capacity() const { return m_capacity; } - int length() const { return m_length; } - - // The output will NOT be 0-terminated. Call length() to get the length. - const CHAR* data() const { return m_buffer; } - CHAR* data() { return m_buffer; } - - // Shortens the URL to the new length. Used for "backing up" when processing - // relative paths. This can also be used if an external function writes a lot - // of data to the buffer (when using the "Raw" version below) beyond the end, - // to declare the new length. - void setLength(int length) - { - // FIXME: Add ASSERT(length < capacity()); - m_length = length; - } - - // This is the most performance critical function, since it is called for - // every character. - void append(CHAR ch) - { - // In VC2005, putting this common case first speeds up execution - // dramatically because this branch is predicted as taken. - if (m_length < m_capacity) { - m_buffer[m_length] = ch; - ++m_length; - return; - } - - if (!grow(1)) - return; - - m_buffer[m_length] = ch; - ++m_length; - } - - void append(const CHAR* str, int strLength) - { - if (m_length + strLength > m_capacity) { - if (!grow(m_length + strLength - m_capacity)) - return; - } - for (int i = 0; i < strLength; i++) - m_buffer[m_length + i] = str[i]; - m_length += strLength; - } - -protected: - // Returns true if the buffer could be resized, false on OOM. - bool grow(int minimumAdditionalCapacity) - { - static const int minimumCapacity = 16; - int newCapacity = m_capacity ? m_capacity : minimumCapacity; - do { - if (newCapacity >= (1 << 30)) // Prevent overflow below. - return false; - newCapacity *= 2; - } while (newCapacity < m_capacity + minimumAdditionalCapacity); - resize(newCapacity); - return true; - } - - CHAR* m_buffer; - int m_capacity; - int m_length; // Used characters in the buffer. -}; - -} // namespace WTF - -#endif // URLBuffer_h diff --git a/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp b/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp deleted file mode 100644 index ee2014e..0000000 --- a/JavaScriptCore/wtf/url/src/URLCharacterTypes.cpp +++ /dev/null @@ -1,173 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "config.h" -#include "URLCharacterTypes.h" - -namespace WTF { - -const unsigned char URLCharacterTypes::characterTypeTable[0x100] = { - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x00 - 0x0f - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x10 - 0x1f - InvalidCharacter, // 0x20 ' ' (escape spaces in queries) - QueryCharacter | UserInfoCharacter, // 0x21 ! - InvalidCharacter, // 0x22 " - InvalidCharacter, // 0x23 # (invalid in query since it marks the ref) - QueryCharacter | UserInfoCharacter, // 0x24 $ - QueryCharacter | UserInfoCharacter, // 0x25 % - QueryCharacter | UserInfoCharacter, // 0x26 & - QueryCharacter | UserInfoCharacter, // 0x27 ' - QueryCharacter | UserInfoCharacter, // 0x28 ( - QueryCharacter | UserInfoCharacter, // 0x29 ) - QueryCharacter | UserInfoCharacter, // 0x2a * - QueryCharacter | UserInfoCharacter, // 0x2b + - QueryCharacter | UserInfoCharacter, // 0x2c , - QueryCharacter | UserInfoCharacter, // 0x2d - - QueryCharacter | UserInfoCharacter | IPv4Character, // 0x2e . - QueryCharacter, // 0x2f / - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x30 0 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x31 1 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x32 2 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x33 3 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x34 4 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x35 5 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x36 6 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter | OctalCharacter, // 0x37 7 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x38 8 - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter | DecimalCharacter, // 0x39 9 - QueryCharacter, // 0x3a : - QueryCharacter, // 0x3b ; - InvalidCharacter, // 0x3c < - QueryCharacter, // 0x3d = - InvalidCharacter, // 0x3e > - QueryCharacter, // 0x3f ? - QueryCharacter, // 0x40 @ - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x41 A - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x42 B - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x43 C - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x44 D - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x45 E - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x46 F - QueryCharacter | UserInfoCharacter, // 0x47 G - QueryCharacter | UserInfoCharacter, // 0x48 H - QueryCharacter | UserInfoCharacter, // 0x49 I - QueryCharacter | UserInfoCharacter, // 0x4a J - QueryCharacter | UserInfoCharacter, // 0x4b K - QueryCharacter | UserInfoCharacter, // 0x4c L - QueryCharacter | UserInfoCharacter, // 0x4d M - QueryCharacter | UserInfoCharacter, // 0x4e N - QueryCharacter | UserInfoCharacter, // 0x4f O - QueryCharacter | UserInfoCharacter, // 0x50 P - QueryCharacter | UserInfoCharacter, // 0x51 Q - QueryCharacter | UserInfoCharacter, // 0x52 R - QueryCharacter | UserInfoCharacter, // 0x53 S - QueryCharacter | UserInfoCharacter, // 0x54 T - QueryCharacter | UserInfoCharacter, // 0x55 U - QueryCharacter | UserInfoCharacter, // 0x56 V - QueryCharacter | UserInfoCharacter, // 0x57 W - QueryCharacter | UserInfoCharacter | IPv4Character, // 0x58 X - QueryCharacter | UserInfoCharacter, // 0x59 Y - QueryCharacter | UserInfoCharacter, // 0x5a Z - QueryCharacter, // 0x5b [ - QueryCharacter, // 0x5c '\' - QueryCharacter, // 0x5d ] - QueryCharacter, // 0x5e ^ - QueryCharacter | UserInfoCharacter, // 0x5f _ - QueryCharacter, // 0x60 ` - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x61 a - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x62 b - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x63 c - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x64 d - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x65 e - QueryCharacter | UserInfoCharacter | IPv4Character | HexCharacter, // 0x66 f - QueryCharacter | UserInfoCharacter, // 0x67 g - QueryCharacter | UserInfoCharacter, // 0x68 h - QueryCharacter | UserInfoCharacter, // 0x69 i - QueryCharacter | UserInfoCharacter, // 0x6a j - QueryCharacter | UserInfoCharacter, // 0x6b k - QueryCharacter | UserInfoCharacter, // 0x6c l - QueryCharacter | UserInfoCharacter, // 0x6d m - QueryCharacter | UserInfoCharacter, // 0x6e n - QueryCharacter | UserInfoCharacter, // 0x6f o - QueryCharacter | UserInfoCharacter, // 0x70 p - QueryCharacter | UserInfoCharacter, // 0x71 q - QueryCharacter | UserInfoCharacter, // 0x72 r - QueryCharacter | UserInfoCharacter, // 0x73 s - QueryCharacter | UserInfoCharacter, // 0x74 t - QueryCharacter | UserInfoCharacter, // 0x75 u - QueryCharacter | UserInfoCharacter, // 0x76 v - QueryCharacter | UserInfoCharacter, // 0x77 w - QueryCharacter | UserInfoCharacter | IPv4Character, // 0x78 x - QueryCharacter | UserInfoCharacter, // 0x79 y - QueryCharacter | UserInfoCharacter, // 0x7a z - QueryCharacter, // 0x7b { - QueryCharacter, // 0x7c | - QueryCharacter, // 0x7d } - QueryCharacter | UserInfoCharacter, // 0x7e ~ - InvalidCharacter, // 0x7f - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x80 - 0x8f - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0x90 - 0x9f - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xa0 - 0xaf - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xb0 - 0xbf - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xc0 - 0xcf - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xd0 - 0xdf - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xe0 - 0xef - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, - InvalidCharacter, InvalidCharacter, InvalidCharacter, InvalidCharacter, // 0xf0 - 0xff -}; - -} diff --git a/JavaScriptCore/wtf/url/src/URLCharacterTypes.h b/JavaScriptCore/wtf/url/src/URLCharacterTypes.h deleted file mode 100644 index 194f6b0..0000000 --- a/JavaScriptCore/wtf/url/src/URLCharacterTypes.h +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef URLCharacterTypes_h -#define URLCharacterTypes_h - -namespace WTF { - -class URLCharacterTypes { -public: - static inline bool isQueryChar(unsigned char c) { return isCharOfType(c, QueryCharacter); } - static inline bool isIPv4Char(unsigned char c) { return isCharOfType(c, IPv4Character); } - static inline bool isHexChar(unsigned char c) { return isCharOfType(c, HexCharacter); } - -private: - enum CharTypes { - InvalidCharacter = 0, - QueryCharacter = 1 << 0, - UserInfoCharacter = 1 << 1, - IPv4Character = 1 << 2, - HexCharacter = 1 << 3, - DecimalCharacter = 1 << 4, - OctalCharacter = 1 << 5, - }; - - static const unsigned char characterTypeTable[0x100]; - - static inline bool isCharOfType(unsigned char c, CharTypes type) - { - return !!(characterTypeTable[c] & type); - } -}; - -} - -#endif diff --git a/JavaScriptCore/wtf/url/src/URLComponent.h b/JavaScriptCore/wtf/url/src/URLComponent.h deleted file mode 100644 index 1b7976e..0000000 --- a/JavaScriptCore/wtf/url/src/URLComponent.h +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef URLComponent_h -#define URLComponent_h - -namespace WTF { - -// Represents a substring for URL parsing. -class URLComponent { -public: - URLComponent() : m_begin(0), m_length(-1) { } - URLComponent(int begin, int length) : m_begin(begin), m_length(length) { } - - // Helper that returns a component created with the given begin and ending - // points. The ending point is non-inclusive. - static inline URLComponent fromRange(int begin, int end) - { - return URLComponent(begin, end - begin); - } - - // Returns true if this component is valid, meaning the length is given. Even - // valid components may be empty to record the fact that they exist. - bool isValid() const { return m_length != -1; } - - bool isNonEmpty() const { return m_length > 0; } - bool isEmptyOrInvalid() const { return m_length <= 0; } - - void reset() - { - m_begin = 0; - m_length = -1; - } - - bool operator==(const URLComponent& other) const { return m_begin == other.m_begin && m_length == other.m_length; } - - int begin() const { return m_begin; } - void setBegin(int begin) { m_begin = begin; } - - int length() const { return m_length; } - void setLength(int length) { m_length = length; } - - int end() const { return m_begin + m_length; } - -private: - int m_begin; // Byte offset in the string of this component. - int m_length; // Will be -1 if the component is unspecified. -}; - -} // namespace WTF - -#endif // URLComponent_h diff --git a/JavaScriptCore/wtf/url/src/URLEscape.cpp b/JavaScriptCore/wtf/url/src/URLEscape.cpp deleted file mode 100644 index 2987343..0000000 --- a/JavaScriptCore/wtf/url/src/URLEscape.cpp +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#include "config.h" -#include "URLEscape.h" - -namespace WTF { - -const char hexCharacterTable[16] = { - '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', -}; - -} diff --git a/JavaScriptCore/wtf/url/src/URLEscape.h b/JavaScriptCore/wtf/url/src/URLEscape.h deleted file mode 100644 index cc2b77f..0000000 --- a/JavaScriptCore/wtf/url/src/URLEscape.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -#ifndef URLEscape_h -#define URLEscape_h - -#include "URLBuffer.h" - -namespace WTF { - -extern const char hexCharacterTable[16]; - -template<typename InChar, typename OutChar> -inline void appendURLEscapedCharacter(InChar ch, URLBuffer<OutChar>& buffer) -{ - buffer.append('%'); - buffer.append(hexCharacterTable[ch >> 4]); - buffer.append(hexCharacterTable[ch & 0xf]); -} - -} - -#endif diff --git a/JavaScriptCore/wtf/url/src/URLParser.h b/JavaScriptCore/wtf/url/src/URLParser.h deleted file mode 100644 index 4d5ca51..0000000 --- a/JavaScriptCore/wtf/url/src/URLParser.h +++ /dev/null @@ -1,575 +0,0 @@ -/* Based on nsURLParsers.cc from Mozilla - * ------------------------------------- - * Copyright (C) 1998 Netscape Communications Corporation. - * - * Other contributors: - * Darin Fisher (original author) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Alternatively, the contents of this file may be used under the terms - * of either the Mozilla Public License Version 1.1, found at - * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public - * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html - * (the "GPL"), in which case the provisions of the MPL or the GPL are - * applicable instead of those above. If you wish to allow use of your - * version of this file only under the terms of one of those two - * licenses (the MPL or the GPL) and not to allow others to use your - * version of this file under the LGPL, indicate your decision by - * deletingthe provisions above and replace them with the notice and - * other provisions required by the MPL or the GPL, as the case may be. - * If you do not delete the provisions above, a recipient may use your - * version of this file under any of the LGPL, the MPL or the GPL. - */ - -#ifndef URLParser_h -#define URLParser_h - -#include "URLComponent.h" -#include "URLSegments.h" - -namespace WTF { - -template<typename CHAR> -class URLParser { -public: - enum SpecialPort { - UnspecifiedPort = -1, - InvalidPort = -2, - }; - - // This handles everything that may be an authority terminator, including - // backslash. For special backslash handling see parseAfterScheme. - static bool isPossibleAuthorityTerminator(CHAR ch) - { - return isURLSlash(ch) || ch == '?' || ch == '#' || ch == ';'; - } - - // Given an already-identified auth section, breaks it into its constituent - // parts. The port number will be parsed and the resulting integer will be - // filled into the given *port variable, or -1 if there is no port number - // or it is invalid. - static void parseAuthority(const CHAR* spec, const URLComponent& auth, URLComponent& username, URLComponent& password, URLComponent& host, URLComponent& port) - { - // FIXME: add ASSERT(auth.isValid()); // We should always get an authority. - if (!auth.length()) { - username.reset(); - password.reset(); - host.reset(); - port.reset(); - return; - } - - // Search backwards for @, which is the separator between the user info - // and the server info. RFC 3986 forbids @ from occuring in auth, but - // someone might include it in a password unescaped. - int i = auth.begin() + auth.length() - 1; - while (i > auth.begin() && spec[i] != '@') - --i; - - if (spec[i] == '@') { - // Found user info: <user-info>@<server-info> - parseUserInfo(spec, URLComponent(auth.begin(), i - auth.begin()), username, password); - parseServerInfo(spec, URLComponent::fromRange(i + 1, auth.begin() + auth.length()), host, port); - } else { - // No user info, everything is server info. - username.reset(); - password.reset(); - parseServerInfo(spec, auth, host, port); - } - } - - static bool extractScheme(const CHAR* spec, int specLength, URLComponent& scheme) - { - // Skip leading whitespace and control characters. - int begin = 0; - while (begin < specLength && shouldTrimFromURL(spec[begin])) - begin++; - if (begin == specLength) - return false; // Input is empty or all whitespace. - - // Find the first colon character. - for (int i = begin; i < specLength; i++) { - if (spec[i] == ':') { - scheme = URLComponent::fromRange(begin, i); - return true; - } - } - return false; // No colon found: no scheme - } - - // Fills in all members of the URLSegments structure (except for the - // scheme) for standard URLs. - // - // |spec| is the full spec being parsed, of length |specLength|. - // |afterScheme| is the character immediately following the scheme (after - // the colon) where we'll begin parsing. - static void parseAfterScheme(const CHAR* spec, int specLength, int afterScheme, URLSegments& parsed) - { - int numberOfSlashes = consecutiveSlashes(spec, afterScheme, specLength); - int afterSlashes = afterScheme + numberOfSlashes; - - // First split into two main parts, the authority (username, password, - // host, and port) and the full path (path, query, and reference). - URLComponent authority; - URLComponent fullPath; - - // Found "//<some data>", looks like an authority section. Treat - // everything from there to the next slash (or end of spec) to be the - // authority. Note that we ignore the number of slashes and treat it as - // the authority. - int authEnd = nextAuthorityTerminator(spec, afterSlashes, specLength); - authority = URLComponent(afterSlashes, authEnd - afterSlashes); - - if (authEnd == specLength) // No beginning of path found. - fullPath = URLComponent(); - else // Everything starting from the slash to the end is the path. - fullPath = URLComponent(authEnd, specLength - authEnd); - - // Now parse those two sub-parts. - parseAuthority(spec, authority, parsed.username, parsed.password, parsed.host, parsed.port); - parsePath(spec, fullPath, parsed.path, parsed.query, parsed.fragment); - } - - // The main parsing function for standard URLs. Standard URLs have a scheme, - // host, path, etc. - static void parseStandardURL(const CHAR* spec, int specLength, URLSegments& parsed) - { - // FIXME: add ASSERT(specLength >= 0); - - // Strip leading & trailing spaces and control characters. - int begin = 0; - trimURL(spec, begin, specLength); - - int afterScheme; - if (extractScheme(spec, specLength, parsed.scheme)) - afterScheme = parsed.scheme.end() + 1; // Skip past the colon. - else { - // Say there's no scheme when there is a colon. We could also say - // that everything is the scheme. Both would produce an invalid - // URL, but this way seems less wrong in more cases. - parsed.scheme.reset(); - afterScheme = begin; - } - parseAfterScheme(spec, specLength, afterScheme, parsed); - } - - static void parsePath(const CHAR* spec, const URLComponent& path, URLComponent& filepath, URLComponent& query, URLComponent& fragment) - { - // path = [/]<segment1>/<segment2>/<...>/<segmentN>;<param>?<query>#<fragment> - - // Special case when there is no path. - if (!path.isValid()) { - filepath.reset(); - query.reset(); - fragment.reset(); - return; - } - // FIXME: add ASSERT(path.length() > 0); // We should never have 0 length paths. - - // Search for first occurrence of either ? or #. - int pathEnd = path.begin() + path.length(); - - int querySeparator = -1; // Index of the '?' - int refSeparator = -1; // Index of the '#' - for (int i = path.begin(); i < pathEnd; i++) { - switch (spec[i]) { - case '?': - if (querySeparator < 0) - querySeparator = i; - break; - case '#': - refSeparator = i; - i = pathEnd; // Break out of the loop. - break; - default: - break; - } - } - - // Markers pointing to the character after each of these corresponding - // components. The code below works from the end back to the beginning, - // and will update these indices as it finds components that exist. - int fileEnd, queryEnd; - - // Fragment: from the # to the end of the path. - if (refSeparator >= 0) { - fileEnd = refSeparator; - queryEnd = refSeparator; - fragment = URLComponent::fromRange(refSeparator + 1, pathEnd); - } else { - fileEnd = pathEnd; - queryEnd = pathEnd; - fragment.reset(); - } - - // Query fragment: everything from the ? to the next boundary (either - // the end of the path or the fragment fragment). - if (querySeparator >= 0) { - fileEnd = querySeparator; - query = URLComponent::fromRange(querySeparator + 1, queryEnd); - } else - query.reset(); - - // File path: treat an empty file path as no file path. - if (fileEnd != path.begin()) - filepath = URLComponent::fromRange(path.begin(), fileEnd); - else - filepath.reset(); - } - - // Initializes a path URL which is merely a scheme followed by a path. - // Examples include "about:foo" and "javascript:alert('bar');" - static void parsePathURL(const CHAR* spec, int specLength, URLSegments& parsed) - { - // Get the non-path and non-scheme parts of the URL out of the way, we - // never use them. - parsed.username.reset(); - parsed.password.reset(); - parsed.host.reset(); - parsed.port.reset(); - parsed.query.reset(); - parsed.fragment.reset(); - - // Strip leading & trailing spaces and control characters. - // FIXME: Perhaps this is unnecessary? - int begin = 0; - trimURL(spec, begin, specLength); - - // Handle empty specs or ones that contain only whitespace or control - // chars. - if (begin == specLength) { - parsed.scheme.reset(); - parsed.path.reset(); - return; - } - - // Extract the scheme, with the path being everything following. We also - // handle the case where there is no scheme. - if (extractScheme(&spec[begin], specLength - begin, parsed.scheme)) { - // Offset the results since we gave extractScheme a substring. - parsed.scheme.setBegin(parsed.scheme.begin() + begin); - - // For compatibility with the standard URL parser, we treat no path - // as -1, rather than having a length of 0 (we normally wouldn't - // care so much for these non-standard URLs). - if (parsed.scheme.end() == specLength - 1) - parsed.path.reset(); - else - parsed.path = URLComponent::fromRange(parsed.scheme.end() + 1, specLength); - } else { - // No scheme found, just path. - parsed.scheme.reset(); - parsed.path = URLComponent::fromRange(begin, specLength); - } - } - - static void parseMailtoURL(const CHAR* spec, int specLength, URLSegments& parsed) - { - // FIXME: add ASSERT(specLength >= 0); - - // Get the non-path and non-scheme parts of the URL out of the way, we - // never use them. - parsed.username.reset(); - parsed.password.reset(); - parsed.host.reset(); - parsed.port.reset(); - parsed.fragment.reset(); - parsed.query.reset(); // May use this; reset for convenience. - - // Strip leading & trailing spaces and control characters. - int begin = 0; - trimURL(spec, begin, specLength); - - // Handle empty specs or ones that contain only whitespace or control - // chars. - if (begin == specLength) { - parsed.scheme.reset(); - parsed.path.reset(); - return; - } - - int pathBegin = -1; - int pathEnd = -1; - - // Extract the scheme, with the path being everything following. We also - // handle the case where there is no scheme. - if (extractScheme(&spec[begin], specLength - begin, parsed.scheme)) { - // Offset the results since we gave extractScheme a substring. - parsed.scheme.setBegin(parsed.scheme.begin() + begin); - - if (parsed.scheme.end() != specLength - 1) { - pathBegin = parsed.scheme.end() + 1; - pathEnd = specLength; - } - } else { - // No scheme found, just path. - parsed.scheme.reset(); - pathBegin = begin; - pathEnd = specLength; - } - - // Split [pathBegin, pathEnd) into a path + query. - for (int i = pathBegin; i < pathEnd; ++i) { - if (spec[i] == '?') { - parsed.query = URLComponent::fromRange(i + 1, pathEnd); - pathEnd = i; - break; - } - } - - // For compatibility with the standard URL parser, treat no path as - // -1, rather than having a length of 0 - if (pathBegin == pathEnd) - parsed.path.reset(); - else - parsed.path = URLComponent::fromRange(pathBegin, pathEnd); - } - - static int parsePort(const CHAR* spec, const URLComponent& component) - { - // Easy success case when there is no port. - const int maxDigits = 5; - if (component.isEmptyOrInvalid()) - return UnspecifiedPort; - - URLComponent nonZeroDigits(component.end(), 0); - for (int i = 0; i < component.length(); ++i) { - if (spec[component.begin() + i] != '0') { - nonZeroDigits = URLComponent::fromRange(component.begin() + i, component.end()); - break; - } - } - if (!nonZeroDigits.length()) - return 0; // All digits were 0. - - if (nonZeroDigits.length() > maxDigits) - return InvalidPort; - - int port = 0; - for (int i = 0; i < nonZeroDigits.length(); ++i) { - CHAR ch = spec[nonZeroDigits.begin() + i]; - if (!isPortDigit(ch)) - return InvalidPort; - port *= 10; - port += static_cast<char>(ch) - '0'; - } - if (port > 65535) - return InvalidPort; - return port; - } - - static void extractFileName(const CHAR* spec, const URLComponent& path, URLComponent& fileName) - { - // Handle empty paths: they have no file names. - if (path.isEmptyOrInvalid()) { - fileName.reset(); - return; - } - - // Search backwards for a parameter, which is a normally unused field - // in a URL delimited by a semicolon. We parse the parameter as part of - // the path, but here, we don't want to count it. The last semicolon is - // the parameter. - int fileEnd = path.end(); - for (int i = path.end() - 1; i > path.begin(); --i) { - if (spec[i] == ';') { - fileEnd = i; - break; - } - } - - // Now search backwards from the filename end to the previous slash - // to find the beginning of the filename. - for (int i = fileEnd - 1; i >= path.begin(); --i) { - if (isURLSlash(spec[i])) { - // File name is everything following this character to the end - fileName = URLComponent::fromRange(i + 1, fileEnd); - return; - } - } - - // No slash found, this means the input was degenerate (generally paths - // will start with a slash). Let's call everything the file name. - fileName = URLComponent::fromRange(path.begin(), fileEnd); - } - - static bool extractQueryKeyValue(const CHAR* spec, URLComponent& query, URLComponent& key, URLComponent& value) - { - if (query.isEmptyOrInvalid()) - return false; - - int start = query.begin(); - int current = start; - int end = query.end(); - - // We assume the beginning of the input is the beginning of the "key" - // and we skip to the end of it. - key.setBegin(current); - while (current < end && spec[current] != '&' && spec[current] != '=') - ++current; - key.setLength(current - key.begin()); - - // Skip the separator after the key (if any). - if (current < end && spec[current] == '=') - ++current; - - // Find the value part. - value.setBegin(current); - while (current < end && spec[current] != '&') - ++current; - value.setLength(current - value.begin()); - - // Finally skip the next separator if any - if (current < end && spec[current] == '&') - ++current; - - // Save the new query - query = URLComponent::fromRange(current, end); - return true; - } - -// FIXME: This should be protected or private. -public: - // We treat slashes and backslashes the same for IE compatibility. - static inline bool isURLSlash(CHAR ch) - { - return ch == '/' || ch == '\\'; - } - - // Returns true if we should trim this character from the URL because it is - // a space or a control character. - static inline bool shouldTrimFromURL(CHAR ch) - { - return ch <= ' '; - } - - // Given an already-initialized begin index and end index (the index after - // the last CHAR in spec), this shrinks the range to eliminate - // "should-be-trimmed" characters. - static inline void trimURL(const CHAR* spec, int& begin, int& end) - { - // Strip leading whitespace and control characters. - while (begin < end && shouldTrimFromURL(spec[begin])) - ++begin; - - // Strip trailing whitespace and control characters. We need the >i - // test for when the input string is all blanks; we don't want to back - // past the input. - while (end > begin && shouldTrimFromURL(spec[end - 1])) - --end; - } - - // Counts the number of consecutive slashes starting at the given offset - // in the given string of the given length. - static inline int consecutiveSlashes(const CHAR *string, int beginOffset, int stringLength) - { - int count = 0; - while (beginOffset + count < stringLength && isURLSlash(string[beginOffset + count])) - ++count; - return count; - } - -private: - // URLParser cannot be constructed. - URLParser(); - - // Returns true if the given character is a valid digit to use in a port. - static inline bool isPortDigit(CHAR ch) - { - return ch >= '0' && ch <= '9'; - } - - // Returns the offset of the next authority terminator in the input starting - // from startOffset. If no terminator is found, the return value will be equal - // to specLength. - static int nextAuthorityTerminator(const CHAR* spec, int startOffset, int specLength) - { - for (int i = startOffset; i < specLength; i++) { - if (isPossibleAuthorityTerminator(spec[i])) - return i; - } - return specLength; // Not found. - } - - static void parseUserInfo(const CHAR* spec, const URLComponent& user, URLComponent& username, URLComponent& password) - { - // Find the first colon in the user section, which separates the - // username and password. - int colonOffset = 0; - while (colonOffset < user.length() && spec[user.begin() + colonOffset] != ':') - ++colonOffset; - - if (colonOffset < user.length()) { - // Found separator: <username>:<password> - username = URLComponent(user.begin(), colonOffset); - password = URLComponent::fromRange(user.begin() + colonOffset + 1, user.begin() + user.length()); - } else { - // No separator, treat everything as the username - username = user; - password = URLComponent(); - } - } - - static void parseServerInfo(const CHAR* spec, const URLComponent& serverInfo, URLComponent& host, URLComponent& port) - { - if (!serverInfo.length()) { - // No server info, host name is empty. - host.reset(); - port.reset(); - return; - } - - // If the host starts with a left-bracket, assume the entire host is an - // IPv6 literal. Otherwise, assume none of the host is an IPv6 literal. - // This assumption will be overridden if we find a right-bracket. - // - // Our IPv6 address canonicalization code requires both brackets to - // exist, but the ability to locate an incomplete address can still be - // useful. - int ipv6Terminator = spec[serverInfo.begin()] == '[' ? serverInfo.end() : -1; - int colon = -1; - - // Find the last right-bracket, and the last colon. - for (int i = serverInfo.begin(); i < serverInfo.end(); i++) { - switch (spec[i]) { - case ']': - ipv6Terminator = i; - break; - case ':': - colon = i; - break; - default: - break; - } - } - - if (colon > ipv6Terminator) { - // Found a port number: <hostname>:<port> - host = URLComponent::fromRange(serverInfo.begin(), colon); - if (!host.length()) - host.reset(); - port = URLComponent::fromRange(colon + 1, serverInfo.end()); - } else { - // No port: <hostname> - host = serverInfo; - port.reset(); - } - } -}; - -} // namespace WTF - -#endif // URLParser_h diff --git a/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h b/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h deleted file mode 100644 index 7740200..0000000 --- a/JavaScriptCore/wtf/url/src/URLQueryCanonicalizer.h +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2010, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -#ifndef URLQueryCanonicalizer_h -#define URLQueryCanonicalizer_h - -#include "RawURLBuffer.h" -#include "URLBuffer.h" -#include "URLCharacterTypes.h" -#include "URLComponent.h" -#include "URLEscape.h" - -namespace WTF { - -template<typename InChar, typename OutChar, void convertCharset(const InChar*, int length, URLBuffer<char>&)> -class URLQueryCanonicalizer { -public: - static void canonicalize(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer, URLComponent& resultQuery) - { - if (query.length() < 0) { - resultQuery = URLComponent(); - return; - } - - buffer->append('?'); - resultQuery.setBegin(buffer->length()); - convertToQueryEncoding(spec, query, buffer); - resultQuery.setLength(buffer->length() - resultQuery.begin()); - } - -private: - static bool isAllASCII(const InChar* spec, const URLComponent& query) - { - int end = query.end(); - for (int i = query.begin(); i < end; ++i) { - if (static_cast<unsigned>(spec[i]) >= 0x80) - return false; - } - return true; - } - -#ifndef NDEBUG - static bool isRaw8Bit(const InChar* source, int length) - { - for (int i = source; i < length; ++i) { - if (source[i] & 0xFF != source[i]) - return false; - } - return true; - } -#endif - - static void appendRaw8BitQueryString(const InChar* source, int length, URLBuffer<OutChar>* buffer) - { - ASSERT(isRaw8Bit(source, length)); - for (int i = 0; i < length; ++i) { - if (!URLCharacterTypes::isQueryChar(source[i])) - appendURLEscapedCharacter(static_cast<unsigned char>(source[i]), buffer); - else - buffer->append(static_cast<char>(source[i])); - } - } - - static void convertToQueryEncoding(const InChar* spec, const URLComponent& query, URLBuffer<OutChar>& buffer) - { - if (isAllASCII(spec, query)) { - appendRaw8BitQueryString(&spec[query.begin()], query.length(), buffer); - return; - } - - RawURLBuffer<char, 1024> convertedQuery; - convertCharset(spec, query, convertedQuery); - appendRaw8BitQueryString(convertedQuery.data(), convertedQuery.length(), buffer); - } -}; - -} - -#endif - - diff --git a/JavaScriptCore/wtf/url/src/URLSegments.cpp b/JavaScriptCore/wtf/url/src/URLSegments.cpp deleted file mode 100644 index bb9542f..0000000 --- a/JavaScriptCore/wtf/url/src/URLSegments.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* Based on nsURLParsers.cc from Mozilla - * ------------------------------------- - * Copyright (C) 1998 Netscape Communications Corporation. - * - * Other contributors: - * Darin Fisher (original author) - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * Alternatively, the contents of this file may be used under the terms - * of either the Mozilla Public License Version 1.1, found at - * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public - * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html - * (the "GPL"), in which case the provisions of the MPL or the GPL are - * applicable instead of those above. If you wish to allow use of your - * version of this file only under the terms of one of those two - * licenses (the MPL or the GPL) and not to allow others to use your - * version of this file under the LGPL, indicate your decision by - * deletingthe provisions above and replace them with the notice and - * other provisions required by the MPL or the GPL, as the case may be. - * If you do not delete the provisions above, a recipient may use your - * version of this file under any of the LGPL, the MPL or the GPL. - */ - -#include "config.h" -#include "URLSegments.h" - -namespace WTF { - -int URLSegments::length() const -{ - if (fragment.isValid()) - return fragment.end(); - return charactersBefore(Fragment, false); -} - -int URLSegments::charactersBefore(ComponentType type, bool includeDelimiter) const -{ - if (type == Scheme) - return scheme.begin(); - - int current = 0; - if (scheme.isValid()) - current = scheme.end() + 1; // Advance over the ':' at the end of the scheme. - - if (username.isValid()) { - if (type <= Username) - return username.begin(); - current = username.end() + 1; // Advance over the '@' or ':' at the end. - } - - if (password.isValid()) { - if (type <= Password) - return password.begin(); - current = password.end() + 1; // Advance over the '@' at the end. - } - - if (host.isValid()) { - if (type <= Host) - return host.begin(); - current = host.end(); - } - - if (port.isValid()) { - if (type < Port || (type == Port && includeDelimiter)) - return port.begin() - 1; // Back over delimiter. - if (type == Port) - return port.begin(); // Don't want delimiter counted. - current = port.end(); - } - - if (path.isValid()) { - if (type <= Path) - return path.begin(); - current = path.end(); - } - - if (query.isValid()) { - if (type < Query || (type == Query && includeDelimiter)) - return query.begin() - 1; // Back over delimiter. - if (type == Query) - return query.begin(); // Don't want delimiter counted. - current = query.end(); - } - - if (fragment.isValid()) { - if (type == Fragment && !includeDelimiter) - return fragment.begin(); // Back over delimiter. - - // When there is a fragment and we get here, the component we wanted was before - // this and not found, so we always know the beginning of the fragment is right. - return fragment.begin() - 1; // Don't want delimiter counted. - } - - return current; -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/url/src/URLSegments.h b/JavaScriptCore/wtf/url/src/URLSegments.h deleted file mode 100644 index 436c7fe..0000000 --- a/JavaScriptCore/wtf/url/src/URLSegments.h +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2007, Google Inc. All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are -// met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -#ifndef URLSegments_h -#define URLSegments_h - -#include "URLComponent.h" - -namespace WTF { - -// A structure that holds the identified parts of an input URL. This structure -// does NOT store the URL itself. The caller will have to store the URL text -// and its corresponding Parsed structure separately. -class URLSegments { -public: - // Identifies different components. - enum ComponentType { - Scheme, - Username, - Password, - Host, - Port, - Path, - Query, - Fragment, - }; - - URLSegments() { } - - // Returns the length of the URL (the end of the last component). - // - // Note that for some invalid, non-canonical URLs, this may not be the length - // of the string. For example "http://": the parsed structure will only - // contain an entry for the four-character scheme, and it doesn't know about - // the "://". For all other last-components, it will return the real length. - int length() const; - - // Returns the number of characters before the given component if it exists, - // or where the component would be if it did exist. This will return the - // string length if the component would be appended to the end. - // - // Note that this can get a little funny for the port, query, and fragment - // components which have a delimiter that is not counted as part of the - // component. The |includeDelimiter| flag controls if you want this counted - // as part of the component or not when the component exists. - // - // This example shows the difference between the two flags for two of these - // delimited components that is present (the port and query) and one that - // isn't (the reference). The components that this flag affects are marked - // with a *. - // 0 1 2 - // 012345678901234567890 - // Example input: http://foo:80/?query - // include_delim=true, ...=false ("<-" indicates different) - // Scheme: 0 0 - // Username: 5 5 - // Password: 5 5 - // Host: 7 7 - // *Port: 10 11 <- - // Path: 13 13 - // *Query: 14 15 <- - // *Fragment: 20 20 - // - int charactersBefore(ComponentType, bool includeDelimiter) const; - - // Each component excludes the related delimiters and has a length of -1 - // if that component is absent but 0 if the component exists but is empty. - URLComponent scheme; - URLComponent username; - URLComponent password; - URLComponent host; - URLComponent port; - URLComponent path; - URLComponent query; - URLComponent fragment; -}; - -} // namespace WTF - -#endif // URLSegments_h diff --git a/JavaScriptCore/wtf/url/wtfurl.gyp b/JavaScriptCore/wtf/url/wtfurl.gyp deleted file mode 100644 index f254ae4..0000000 --- a/JavaScriptCore/wtf/url/wtfurl.gyp +++ /dev/null @@ -1,58 +0,0 @@ -# Copyright (C) 2009 Google Inc. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -{ - 'variables': { - 'chromium_code': 1, - }, - 'targets': [ - { - 'target_name': 'wtfurl', - 'type': '<(library)', - 'msvs_guid': 'EF5E94AB-B646-4E5B-A058-52EF07B8351C', - 'dependencies': [ - ], - 'sources': [ - 'src/URLComponent.h', - 'src/URLSegments.cpp', - 'src/URLSegments.h', - ], - 'direct_dependent_settings': { - 'include_dirs': [ - 'src', - ], - }, - }, - ], -} - -# Local Variables: -# tab-width:2 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=2 shiftwidth=2: diff --git a/JavaScriptCore/wtf/win/MainThreadWin.cpp b/JavaScriptCore/wtf/win/MainThreadWin.cpp deleted file mode 100644 index ee3a273..0000000 --- a/JavaScriptCore/wtf/win/MainThreadWin.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright (C) 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2009 Torch Mobile Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include "Assertions.h" -#include "Threading.h" -#if !OS(WINCE) -#include <windows.h> -#endif - -namespace WTF { - -static HWND threadingWindowHandle; -static UINT threadingFiredMessage; -const LPCWSTR kThreadingWindowClassName = L"ThreadingWindowClass"; - -LRESULT CALLBACK ThreadingWindowWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) -{ - if (message == threadingFiredMessage) - dispatchFunctionsFromMainThread(); - else - return DefWindowProc(hWnd, message, wParam, lParam); - return 0; -} - -void initializeMainThreadPlatform() -{ - if (threadingWindowHandle) - return; - - HWND hWndParent = 0; -#if OS(WINCE) - WNDCLASS wcex; - memset(&wcex, 0, sizeof(WNDCLASS)); -#else - WNDCLASSEX wcex; - memset(&wcex, 0, sizeof(WNDCLASSEX)); - wcex.cbSize = sizeof(WNDCLASSEX); -#endif - wcex.lpfnWndProc = ThreadingWindowWndProc; - wcex.lpszClassName = kThreadingWindowClassName; -#if OS(WINCE) - RegisterClass(&wcex); -#else - RegisterClassEx(&wcex); - hWndParent = HWND_MESSAGE; -#endif - - threadingWindowHandle = CreateWindow(kThreadingWindowClassName, 0, 0, - CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, hWndParent, 0, 0, 0); - threadingFiredMessage = RegisterWindowMessage(L"com.apple.WebKit.MainThreadFired"); - - initializeCurrentThreadInternal("Main Thread"); -} - -void scheduleDispatchFunctionsOnMainThread() -{ - ASSERT(threadingWindowHandle); - PostMessage(threadingWindowHandle, threadingFiredMessage, 0, 0); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/win/OwnPtrWin.cpp b/JavaScriptCore/wtf/win/OwnPtrWin.cpp deleted file mode 100644 index 67a32ff..0000000 --- a/JavaScriptCore/wtf/win/OwnPtrWin.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (C) 2007 Apple Inc. All rights reserved. - * Copyright (C) 2008, 2009 Torch Mobile, Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "OwnPtr.h" - -#include <windows.h> - -namespace WTF { - -void deleteOwnedPtr(HBITMAP ptr) -{ - if (ptr) - DeleteObject(ptr); -} - -void deleteOwnedPtr(HBRUSH ptr) -{ - if (ptr) - DeleteObject(ptr); -} - -void deleteOwnedPtr(HDC ptr) -{ - if (ptr) - DeleteDC(ptr); -} - -void deleteOwnedPtr(HFONT ptr) -{ - if (ptr) - DeleteObject(ptr); -} - -void deleteOwnedPtr(HPALETTE ptr) -{ - if (ptr) - DeleteObject(ptr); -} - -void deleteOwnedPtr(HPEN ptr) -{ - if (ptr) - DeleteObject(ptr); -} - -void deleteOwnedPtr(HRGN ptr) -{ - if (ptr) - DeleteObject(ptr); -} - -} diff --git a/JavaScriptCore/wtf/wince/FastMallocWinCE.h b/JavaScriptCore/wtf/wince/FastMallocWinCE.h deleted file mode 100644 index d91a5f2..0000000 --- a/JavaScriptCore/wtf/wince/FastMallocWinCE.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved. - * Copyright (C) 2007-2009 Torch Mobile, Inc. All rights reserved - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - * - */ - -#ifndef WTF_FastMallocWinCE_h -#define WTF_FastMallocWinCE_h - -#include <new.h> - -#ifdef __cplusplus -#include <new> -#include "MemoryManager.h" -extern "C" { -#endif - -void* fastMalloc(size_t n); -void* fastCalloc(size_t n_elements, size_t element_size); -void fastFree(void* p); -void* fastRealloc(void* p, size_t n); -void* fastZeroedMalloc(size_t n); -// These functions return 0 if an allocation fails. -void* tryFastMalloc(size_t n); -void* tryFastZeroedMalloc(size_t n); -void* tryFastCalloc(size_t n_elements, size_t element_size); -void* tryFastRealloc(void* p, size_t n); -char* fastStrDup(const char*); - -#ifndef NDEBUG -void fastMallocForbid(); -void fastMallocAllow(); -#endif - -#if !defined(USE_SYSTEM_MALLOC) || !USE_SYSTEM_MALLOC - -#define malloc(n) fastMalloc(n) -#define calloc(n_elements, element_size) fastCalloc(n_elements, element_size) -#define realloc(p, n) fastRealloc(p, n) -#define free(p) fastFree(p) -#define strdup(p) fastStrDup(p) - -#else - -#define strdup(p) _strdup(p) - -#endif - -#ifdef __cplusplus -} -#endif - -#ifdef __cplusplus -#if !defined(USE_SYSTEM_MALLOC) || !USE_SYSTEM_MALLOC -static inline void* __cdecl operator new(size_t s) { return fastMalloc(s); } -static inline void __cdecl operator delete(void* p) { fastFree(p); } -static inline void* __cdecl operator new[](size_t s) { return fastMalloc(s); } -static inline void __cdecl operator delete[](void* p) { fastFree(p); } -static inline void* operator new(size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); } -static inline void operator delete(void* p, const std::nothrow_t&) throw() { fastFree(p); } -static inline void* operator new[](size_t s, const std::nothrow_t&) throw() { return fastMalloc(s); } -static inline void operator delete[](void* p, const std::nothrow_t&) throw() { fastFree(p); } -#endif - -namespace WTF { - // This defines a type which holds an unsigned integer and is the same - // size as the minimally aligned memory allocation. - typedef unsigned long long AllocAlignmentInteger; - - namespace Internal { - enum AllocType { // Start with an unusual number instead of zero, because zero is common. - AllocTypeMalloc = 0x375d6750, // Encompasses fastMalloc, fastZeroedMalloc, fastCalloc, fastRealloc. - AllocTypeClassNew, // Encompasses class operator new from FastAllocBase. - AllocTypeClassNewArray, // Encompasses class operator new[] from FastAllocBase. - AllocTypeFastNew, // Encompasses fastNew. - AllocTypeFastNewArray, // Encompasses fastNewArray. - AllocTypeNew, // Encompasses global operator new. - AllocTypeNewArray // Encompasses global operator new[]. - }; - } - - -#if ENABLE(FAST_MALLOC_MATCH_VALIDATION) - - // Malloc validation is a scheme whereby a tag is attached to an - // allocation which identifies how it was originally allocated. - // This allows us to verify that the freeing operation matches the - // allocation operation. If memory is allocated with operator new[] - // but freed with free or delete, this system would detect that. - // In the implementation here, the tag is an integer prepended to - // the allocation memory which is assigned one of the AllocType - // enumeration values. An alternative implementation of this - // scheme could store the tag somewhere else or ignore it. - // Users of FastMalloc don't need to know or care how this tagging - // is implemented. - - namespace Internal { - - // Return the AllocType tag associated with the allocated block p. - inline AllocType fastMallocMatchValidationType(const void* p) - { - const AllocAlignmentInteger* type = static_cast<const AllocAlignmentInteger*>(p) - 1; - return static_cast<AllocType>(*type); - } - - // Return the address of the AllocType tag associated with the allocated block p. - inline AllocAlignmentInteger* fastMallocMatchValidationValue(void* p) - { - return reinterpret_cast<AllocAlignmentInteger*>(static_cast<char*>(p) - sizeof(AllocAlignmentInteger)); - } - - // Set the AllocType tag to be associaged with the allocated block p. - inline void setFastMallocMatchValidationType(void* p, AllocType allocType) - { - AllocAlignmentInteger* type = static_cast<AllocAlignmentInteger*>(p) - 1; - *type = static_cast<AllocAlignmentInteger>(allocType); - } - - // Handle a detected alloc/free mismatch. By default this calls CRASH(). - void fastMallocMatchFailed(void* p); - - } // namespace Internal - - // This is a higher level function which is used by FastMalloc-using code. - inline void fastMallocMatchValidateMalloc(void* p, Internal::AllocType allocType) - { - if (!p) - return; - - Internal::setFastMallocMatchValidationType(p, allocType); - } - - // This is a higher level function which is used by FastMalloc-using code. - inline void fastMallocMatchValidateFree(void* p, Internal::AllocType allocType) - { - if (!p) - return; - - if (Internal::fastMallocMatchValidationType(p) != allocType) - Internal::fastMallocMatchFailed(p); - Internal::setFastMallocMatchValidationType(p, Internal::AllocTypeMalloc); // Set it to this so that fastFree thinks it's OK. - } - -#else - - inline void fastMallocMatchValidateMalloc(void*, Internal::AllocType) - { - } - - inline void fastMallocMatchValidateFree(void*, Internal::AllocType) - { - } - -#endif - -} // namespace WTF - -#endif - -#endif // WTF_FastMallocWinCE_h diff --git a/JavaScriptCore/wtf/wince/MemoryManager.cpp b/JavaScriptCore/wtf/wince/MemoryManager.cpp deleted file mode 100644 index 81d4f80..0000000 --- a/JavaScriptCore/wtf/wince/MemoryManager.cpp +++ /dev/null @@ -1,171 +0,0 @@ -/* - * Copyright (C) 2008-2009 Torch Mobile Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#include "config.h" -#include "MemoryManager.h" - -#undef malloc -#undef calloc -#undef realloc -#undef free -#undef strdup -#undef _strdup -#undef VirtualAlloc -#undef VirtualFree - -#include <malloc.h> -#include <windows.h> - -namespace WTF { - -MemoryManager* memoryManager() -{ - static MemoryManager mm; - return &mm; -} - -MemoryManager::MemoryManager() -: m_allocationCanFail(false) -{ -} - -MemoryManager::~MemoryManager() -{ -} - -HBITMAP MemoryManager::createCompatibleBitmap(HDC hdc, int width, int height) -{ - return ::CreateCompatibleBitmap(hdc, width, height); -} - -HBITMAP MemoryManager::createDIBSection(const BITMAPINFO* pbmi, void** ppvBits) -{ - return ::CreateDIBSection(0, pbmi, DIB_RGB_COLORS, ppvBits, 0, 0); -} - -void* MemoryManager::m_malloc(size_t size) -{ - return malloc(size); -} - -void* MemoryManager::m_calloc(size_t num, size_t size) -{ - return calloc(num, size); -} - -void* MemoryManager::m_realloc(void* p, size_t size) -{ - return realloc(p, size); -} - -void MemoryManager::m_free(void* p) -{ - return free(p); -} - -bool MemoryManager::resizeMemory(void*, size_t) -{ - return false; -} - -void* MemoryManager::allocate64kBlock() -{ - return VirtualAlloc(0, 65536, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); -} - -void MemoryManager::free64kBlock(void* p) -{ - VirtualFree(p, 65536, MEM_RELEASE); -} - -bool MemoryManager::onIdle(DWORD& timeLimitMs) -{ - return false; -} - -LPVOID MemoryManager::virtualAlloc(LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect) -{ - return ::VirtualAlloc(lpAddress, dwSize, flAllocationType, flProtect); -} - -BOOL MemoryManager::virtualFree(LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType) -{ - return ::VirtualFree(lpAddress, dwSize, dwFreeType); -} - - -#if defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC - -void *fastMalloc(size_t n) { return malloc(n); } -void *fastCalloc(size_t n_elements, size_t element_size) { return calloc(n_elements, element_size); } -void fastFree(void* p) { return free(p); } -void *fastRealloc(void* p, size_t n) { return realloc(p, n); } - -#else - -void *fastMalloc(size_t n) { return MemoryManager::m_malloc(n); } -void *fastCalloc(size_t n_elements, size_t element_size) { return MemoryManager::m_calloc(n_elements, element_size); } -void fastFree(void* p) { return MemoryManager::m_free(p); } -void *fastRealloc(void* p, size_t n) { return MemoryManager::m_realloc(p, n); } - -#endif - -#ifndef NDEBUG -void fastMallocForbid() {} -void fastMallocAllow() {} -#endif - -void* fastZeroedMalloc(size_t n) -{ - void* p = fastMalloc(n); - if (p) - memset(p, 0, n); - return p; -} - -TryMallocReturnValue tryFastMalloc(size_t n) -{ - MemoryAllocationCanFail canFail; - return fastMalloc(n); -} - -TryMallocReturnValue tryFastZeroedMalloc(size_t n) -{ - MemoryAllocationCanFail canFail; - return fastZeroedMalloc(n); -} - -TryMallocReturnValue tryFastCalloc(size_t n_elements, size_t element_size) -{ - MemoryAllocationCanFail canFail; - return fastCalloc(n_elements, element_size); -} - -TryMallocReturnValue tryFastRealloc(void* p, size_t n) -{ - MemoryAllocationCanFail canFail; - return fastRealloc(p, n); -} - -char* fastStrDup(const char* str) -{ - return _strdup(str); -} - -}
\ No newline at end of file diff --git a/JavaScriptCore/wtf/wince/MemoryManager.h b/JavaScriptCore/wtf/wince/MemoryManager.h deleted file mode 100644 index f405612..0000000 --- a/JavaScriptCore/wtf/wince/MemoryManager.h +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2008-2009 Torch Mobile Inc. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public License - * along with this library; see the file COPYING.LIB. If not, write to - * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, - * Boston, MA 02110-1301, USA. - */ - -#pragma once - -#include <winbase.h> - -typedef struct HBITMAP__* HBITMAP; -typedef struct HDC__* HDC; -typedef void *HANDLE; -typedef struct tagBITMAPINFO BITMAPINFO; - -namespace WTF { - - class MemoryManager { - public: - MemoryManager(); - ~MemoryManager(); - - bool allocationCanFail() const { return m_allocationCanFail; } - void setAllocationCanFail(bool c) { m_allocationCanFail = c; } - - static HBITMAP createCompatibleBitmap(HDC hdc, int width, int height); - static HBITMAP createDIBSection(const BITMAPINFO* pbmi, void** ppvBits); - static void* m_malloc(size_t size); - static void* m_calloc(size_t num, size_t size); - static void* m_realloc(void* p, size_t size); - static void m_free(void*); - static bool resizeMemory(void* p, size_t newSize); - static void* allocate64kBlock(); - static void free64kBlock(void*); - static bool onIdle(DWORD& timeLimitMs); - static LPVOID virtualAlloc(LPVOID lpAddress, DWORD dwSize, DWORD flAllocationType, DWORD flProtect); - static BOOL virtualFree(LPVOID lpAddress, DWORD dwSize, DWORD dwFreeType); - - private: - friend MemoryManager* memoryManager(); - - bool m_allocationCanFail; - }; - - MemoryManager* memoryManager(); - - class MemoryAllocationCanFail { - public: - MemoryAllocationCanFail() : m_old(memoryManager()->allocationCanFail()) { memoryManager()->setAllocationCanFail(true); } - ~MemoryAllocationCanFail() { memoryManager()->setAllocationCanFail(m_old); } - private: - bool m_old; - }; - - class MemoryAllocationCannotFail { - public: - MemoryAllocationCannotFail() : m_old(memoryManager()->allocationCanFail()) { memoryManager()->setAllocationCanFail(false); } - ~MemoryAllocationCannotFail() { memoryManager()->setAllocationCanFail(m_old); } - private: - bool m_old; - }; -} - -using WTF::MemoryManager; -using WTF::memoryManager; -using WTF::MemoryAllocationCanFail; -using WTF::MemoryAllocationCannotFail; diff --git a/JavaScriptCore/wtf/wince/mt19937ar.c b/JavaScriptCore/wtf/wince/mt19937ar.c deleted file mode 100644 index 4715958..0000000 --- a/JavaScriptCore/wtf/wince/mt19937ar.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - A C-program for MT19937, with initialization improved 2002/1/26. - Coded by Takuji Nishimura and Makoto Matsumoto. - - Before using, initialize the state by using init_genrand(seed) - or init_by_array(init_key, key_length). - - Copyright (C) 1997 - 2002, Makoto Matsumoto and Takuji Nishimura, - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - - 1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. The names of its contributors may not be used to endorse or promote - products derived from this software without specific prior written - permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - - Any feedback is very welcome. - http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html - email: m-mat @ math.sci.hiroshima-u.ac.jp (remove space) -*/ - -#include <stdio.h> - -/* Period parameters */ -#define N 624 -#define M 397 -#define MATRIX_A 0x9908b0dfUL /* constant vector a */ -#define UPPER_MASK 0x80000000UL /* most significant w-r bits */ -#define LOWER_MASK 0x7fffffffUL /* least significant r bits */ - -static unsigned long mt[N]; /* the array for the state vector */ -static int mti=N+1; /* mti==N+1 means mt[N] is not initialized */ - -/* initializes mt[N] with a seed */ -void init_genrand(unsigned long s) -{ - mt[0]= s & 0xffffffffUL; - for (mti=1; mti<N; mti++) { - mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); - /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */ - /* In the previous versions, MSBs of the seed affect */ - /* only MSBs of the array mt[]. */ - /* 2002/01/09 modified by Makoto Matsumoto */ - mt[mti] &= 0xffffffffUL; - /* for >32 bit machines */ - } -} - -/* initialize by an array with array-length */ -/* init_key is the array for initializing keys */ -/* key_length is its length */ -/* slight change for C++, 2004/2/26 */ -void init_by_array(unsigned long init_key[],int key_length) -{ - int i, j, k; - init_genrand(19650218UL); - i=1; j=0; - k = (N>key_length ? N : key_length); - for (; k; k--) { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) - + init_key[j] + j; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ - i++; j++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - if (j>=key_length) j=0; - } - for (k=N-1; k; k--) { - mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - - i; /* non linear */ - mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */ - i++; - if (i>=N) { mt[0] = mt[N-1]; i=1; } - } - - mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ -} - -/* generates a random number on [0,0xffffffff]-interval */ -unsigned long genrand_int32(void) -{ - unsigned long y; - static unsigned long mag01[2]={0x0UL, MATRIX_A}; - /* mag01[x] = x * MATRIX_A for x=0,1 */ - - if (mti >= N) { /* generate N words at one time */ - int kk; - - if (mti == N+1) /* if init_genrand() has not been called, */ - init_genrand(5489UL); /* a default initial seed is used */ - - for (kk=0;kk<N-M;kk++) { - y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); - mt[kk] = mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1UL]; - } - for (;kk<N-1;kk++) { - y = (mt[kk]&UPPER_MASK)|(mt[kk+1]&LOWER_MASK); - mt[kk] = mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1UL]; - } - y = (mt[N-1]&UPPER_MASK)|(mt[0]&LOWER_MASK); - mt[N-1] = mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1UL]; - - mti = 0; - } - - y = mt[mti++]; - - /* Tempering */ - y ^= (y >> 11); - y ^= (y << 7) & 0x9d2c5680UL; - y ^= (y << 15) & 0xefc60000UL; - y ^= (y >> 18); - - return y; -} - -/* generates a random number on [0,0x7fffffff]-interval */ -long genrand_int31(void) -{ - return (long)(genrand_int32()>>1); -} - -/* generates a random number on [0,1]-real-interval */ -double genrand_real1(void) -{ - return genrand_int32()*(1.0/4294967295.0); - /* divided by 2^32-1 */ -} - -/* generates a random number on [0,1)-real-interval */ -double genrand_real2(void) -{ - return genrand_int32()*(1.0/4294967296.0); - /* divided by 2^32 */ -} - -/* generates a random number on (0,1)-real-interval */ -double genrand_real3(void) -{ - return (((double)genrand_int32()) + 0.5)*(1.0/4294967296.0); - /* divided by 2^32 */ -} - -/* generates a random number on [0,1) with 53-bit resolution*/ -double genrand_res53(void) -{ - unsigned long a=genrand_int32()>>5, b=genrand_int32()>>6; - return(a*67108864.0+b)*(1.0/9007199254740992.0); -} diff --git a/JavaScriptCore/wtf/wtf.pri b/JavaScriptCore/wtf/wtf.pri deleted file mode 100644 index c5617ce..0000000 --- a/JavaScriptCore/wtf/wtf.pri +++ /dev/null @@ -1,50 +0,0 @@ -# wtf - qmake build info - -SOURCES += \ - wtf/Assertions.cpp \ - wtf/ByteArray.cpp \ - wtf/CurrentTime.cpp \ - wtf/DateMath.cpp \ - wtf/dtoa.cpp \ - wtf/DecimalNumber.cpp \ - wtf/FastMalloc.cpp \ - wtf/gobject/GOwnPtr.cpp \ - wtf/gobject/GRefPtr.cpp \ - wtf/HashTable.cpp \ - wtf/MD5.cpp \ - wtf/MainThread.cpp \ - wtf/qt/MainThreadQt.cpp \ - wtf/qt/StringQt.cpp \ - wtf/qt/ThreadingQt.cpp \ - wtf/PageAllocationAligned.cpp \ - wtf/PageBlock.cpp \ - wtf/RandomNumber.cpp \ - wtf/RefCountedLeakCounter.cpp \ - wtf/StackBounds.cpp \ - wtf/ThreadingNone.cpp \ - wtf/Threading.cpp \ - wtf/TypeTraits.cpp \ - wtf/WTFThreadData.cpp \ - wtf/text/AtomicString.cpp \ - wtf/text/CString.cpp \ - wtf/text/StringBuilder.cpp \ - wtf/text/StringImpl.cpp \ - wtf/text/StringStatics.cpp \ - wtf/text/WTFString.cpp \ - wtf/unicode/CollatorDefault.cpp \ - wtf/unicode/icu/CollatorICU.cpp \ - wtf/unicode/UTF8.cpp - -contains(DEFINES, USE_GSTREAMER=1) { - DEFINES += ENABLE_GLIB_SUPPORT=1 - PKGCONFIG += glib-2.0 gio-2.0 - CONFIG += link_pkgconfig -} - -!contains(DEFINES, USE_SYSTEM_MALLOC) { - SOURCES += wtf/TCSystemAlloc.cpp -} - -unix:!symbian: SOURCES += wtf/OSAllocatorPosix.cpp -symbian: SOURCES += wtf/OSAllocatorSymbian.cpp -win*|wince*: SOURCES += wtf/OSAllocatorWin.cpp diff --git a/JavaScriptCore/wtf/wx/MainThreadWx.cpp b/JavaScriptCore/wtf/wx/MainThreadWx.cpp deleted file mode 100644 index e1d15c9..0000000 --- a/JavaScriptCore/wtf/wx/MainThreadWx.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (C) 2007 Kevin Ollivier - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of - * its contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "MainThread.h" - -#include <wx/defs.h> -#include <wx/app.h> -#include <wx/event.h> - -const wxEventType wxEVT_CALL_AFTER = wxNewEventType(); - -class wxCallAfter : public wxEvtHandler -{ -public: - wxCallAfter() - : wxEvtHandler() - { - wxTheApp->Connect(-1, -1, wxEVT_CALL_AFTER, wxCommandEventHandler(wxCallAfter::OnCallback)); - wxCommandEvent event(wxEVT_CALL_AFTER); - wxPostEvent(wxTheApp, event); - } - - void OnCallback(wxCommandEvent& event) - { - WTF::dispatchFunctionsFromMainThread(); - } -}; - -namespace WTF { - -void initializeMainThreadPlatform() -{ -} - -void scheduleDispatchFunctionsOnMainThread() -{ - wxCallAfter(); -} - -} // namespace WTF diff --git a/JavaScriptCore/wtf/wx/StringWx.cpp b/JavaScriptCore/wtf/wx/StringWx.cpp deleted file mode 100644 index 59d500b..0000000 --- a/JavaScriptCore/wtf/wx/StringWx.cpp +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (C) 2007 Vaclav Slavik, Kevin Ollivier <kevino@theolliviers.com> - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY - * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "config.h" -#include "PlatformString.h" - -#include <unicode/ustring.h> -#include <wtf/text/CString.h> -#include <wx/defs.h> -#include <wx/string.h> - -namespace WTF { - -String::String(const wxString& wxstr) -{ -#if !wxUSE_UNICODE - #error "This code only works in Unicode build of wxWidgets" -#endif - -#if SIZEOF_WCHAR_T == sizeof(UChar) - - m_impl = StringImpl::create(wxstr.wc_str(), wxstr.length()); - -#else // SIZEOF_WCHAR_T == 4 - - // NB: we can't simply use wxstr.mb_str(wxMBConvUTF16()) here because - // the number of characters in UTF-16 encoding of the string may differ - // from the number of UTF-32 values and we can't get the length from - // returned buffer: - -#if defined(wxUSE_UNICODE_UTF8) && wxUSE_UNICODE_UTF8 - // in wx3's UTF8 mode, wc_str() returns a buffer, not raw pointer - wxWCharBuffer wideString(wxstr.wc_str()); -#else - const wxChar *wideString = wxstr.wc_str(); -#endif - size_t wideLength = wxstr.length(); - - UChar* data; - wxMBConvUTF16 conv; - unsigned utf16Length = conv.FromWChar(0, 0, wideString, wideLength); - m_impl = StringImpl::createUninitialized(utf16Length, data) - conv.FromWChar(data, utf16Length, wideString, wideLength); - -#endif // SIZEOF_WCHAR_T == 4 -} - -String::operator wxString() const -{ - return wxString(utf8().data(), wxConvUTF8); -} - -} // namespace WTF |