Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: src/runtime.cc

Issue 435003: Patch for allowing several V8 instances in process:... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.h ('k') | src/scanner.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2006-2009 the V8 project authors. All rights reserved. 1 // Copyright 2006-2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
85 RUNTIME_ASSERT(obj->IsNumber()); \ 85 RUNTIME_ASSERT(obj->IsNumber()); \
86 double name = (obj)->Number(); 86 double name = (obj)->Number();
87 87
88 // Call the specified converter on the object *comand store the result in 88 // Call the specified converter on the object *comand store the result in
89 // a variable of the specified type with the given name. If the 89 // a variable of the specified type with the given name. If the
90 // object is not a Number call IllegalOperation and return. 90 // object is not a Number call IllegalOperation and return.
91 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ 91 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \
92 RUNTIME_ASSERT(obj->IsNumber()); \ 92 RUNTIME_ASSERT(obj->IsNumber()); \
93 type name = NumberTo##Type(obj); 93 type name = NumberTo##Type(obj);
94 94
95 // Non-reentrant string buffer for efficient general use in this file.
96 static StaticResource<StringInputBuffer> runtime_string_input_buffer;
97
98
99 static Object* DeepCopyBoilerplate(JSObject* boilerplate) { 95 static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
100 StackLimitCheck check; 96 StackLimitCheck check;
101 if (check.HasOverflowed()) return Top::StackOverflow(); 97 if (check.HasOverflowed()) return Top::StackOverflow();
102 98
103 Object* result = Heap::CopyJSObject(boilerplate); 99 Object* result = Heap::CopyJSObject(boilerplate);
104 if (result->IsFailure()) return result; 100 if (result->IsFailure()) return result;
105 JSObject* copy = JSObject::cast(result); 101 JSObject* copy = JSObject::cast(result);
106 102
107 // Deep copy local properties. 103 // Deep copy local properties.
108 if (copy->HasFastProperties()) { 104 if (copy->HasFastProperties()) {
(...skipping 1794 matching lines...) Expand 10 before | Expand all | Expand 10 after
1903 return biased_good_suffix_shift_[index]; 1899 return biased_good_suffix_shift_[index];
1904 } 1900 }
1905 private: 1901 private:
1906 int suffixes_[kBMMaxShift + 1]; 1902 int suffixes_[kBMMaxShift + 1];
1907 int good_suffix_shift_[kBMMaxShift + 1]; 1903 int good_suffix_shift_[kBMMaxShift + 1];
1908 int* biased_suffixes_; 1904 int* biased_suffixes_;
1909 int* biased_good_suffix_shift_; 1905 int* biased_good_suffix_shift_;
1910 DISALLOW_COPY_AND_ASSIGN(BMGoodSuffixBuffers); 1906 DISALLOW_COPY_AND_ASSIGN(BMGoodSuffixBuffers);
1911 }; 1907 };
1912 1908
1913 // buffers reused by BoyerMoore 1909 class RuntimeData {
1914 static int bad_char_occurrence[kBMAlphabetSize]; 1910 public:
1915 static BMGoodSuffixBuffers bmgs_buffers; 1911 // Non-reentrant string buffer for efficient general use in this file.
1912 StaticResource<StringInputBuffer> runtime_string_input_buffer_;
1913 // buffers reused by BoyerMoore
1914 int bad_char_occurrence_[kBMAlphabetSize];
1915 BMGoodSuffixBuffers bmgs_buffers_;
1916 StringInputBuffer buf1_;
1917 StringInputBuffer buf2_;
1918
1919 unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_;
1920 unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_;
1921
1922 // Arrays for the individual characters of the two Smis. Smis are
1923 // 31 bit integers and 10 decimal digits are therefore enough.
1924 int x_elms_[10];
1925 int y_elms_[10];
1926
1927 StringInputBuffer bufx_;
1928 StringInputBuffer bufy_;
1929
1930 RuntimeData() {}
1931 DISALLOW_COPY_AND_ASSIGN(RuntimeData);
1932 };
1916 1933
1917 // Compute the bad-char table for Boyer-Moore in the static buffer. 1934 // Compute the bad-char table for Boyer-Moore in the static buffer.
1918 template <typename pchar> 1935 template <typename pchar>
1919 static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern, 1936 static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern,
1920 int start) { 1937 int start) {
1921 // Run forwards to populate bad_char_table, so that *last* instance 1938 // Run forwards to populate bad_char_table, so that *last* instance
1922 // of character equivalence class is the one registered. 1939 // of character equivalence class is the one registered.
1923 // Notice: Doesn't include the last character. 1940 // Notice: Doesn't include the last character.
1924 int table_size = (sizeof(pchar) == 1) ? String::kMaxAsciiCharCode + 1 1941 int table_size = (sizeof(pchar) == 1) ? String::kMaxAsciiCharCode + 1
1925 : kBMAlphabetSize; 1942 : kBMAlphabetSize;
1943 int* const bad_char_occurrence = v8_context()->runtime_data_->
1944 bad_char_occurrence_;
1945
1926 if (start == 0) { // All patterns less than kBMMaxShift in length. 1946 if (start == 0) { // All patterns less than kBMMaxShift in length.
1927 memset(bad_char_occurrence, -1, table_size * sizeof(*bad_char_occurrence)); 1947 memset(bad_char_occurrence, -1, table_size * sizeof(*bad_char_occurrence));
1928 } else { 1948 } else {
1929 for (int i = 0; i < table_size; i++) { 1949 for (int i = 0; i < table_size; i++) {
1930 bad_char_occurrence[i] = start - 1; 1950 bad_char_occurrence[i] = start - 1;
1931 } 1951 }
1932 } 1952 }
1933 for (int i = start; i < pattern.length() - 1; i++) { 1953 for (int i = start; i < pattern.length() - 1; i++) {
1934 pchar c = pattern[i]; 1954 pchar c = pattern[i];
1935 int bucket = (sizeof(pchar) ==1) ? c : c % kBMAlphabetSize; 1955 int bucket = (sizeof(pchar) ==1) ? c : c % kBMAlphabetSize;
1936 bad_char_occurrence[bucket] = i; 1956 bad_char_occurrence[bucket] = i;
1937 } 1957 }
1938 } 1958 }
1939 1959
1940 template <typename pchar> 1960 template <typename pchar>
1941 static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern, 1961 static void BoyerMoorePopulateGoodSuffixTable(Vector<const pchar> pattern,
1942 int start) { 1962 int start) {
1943 int m = pattern.length(); 1963 int m = pattern.length();
1944 int len = m - start; 1964 int len = m - start;
1945 // Compute Good Suffix tables. 1965 // Compute Good Suffix tables.
1966 BMGoodSuffixBuffers& bmgs_buffers =
1967 v8_context()->runtime_data_->bmgs_buffers_;
1946 bmgs_buffers.init(m); 1968 bmgs_buffers.init(m);
1947 1969
1948 bmgs_buffers.shift(m-1) = 1; 1970 bmgs_buffers.shift(m-1) = 1;
1949 bmgs_buffers.suffix(m) = m + 1; 1971 bmgs_buffers.suffix(m) = m + 1;
1950 pchar last_char = pattern[m - 1]; 1972 pchar last_char = pattern[m - 1];
1951 int suffix = m + 1; 1973 int suffix = m + 1;
1952 for (int i = m; i > start;) { 1974 for (int i = m; i > start;) {
1953 for (pchar c = pattern[i - 1]; suffix <= m && c != pattern[suffix - 1];) { 1975 for (pchar c = pattern[i - 1]; suffix <= m && c != pattern[suffix - 1];) {
1954 if (bmgs_buffers.shift(suffix) == len) { 1976 if (bmgs_buffers.shift(suffix) == len) {
1955 bmgs_buffers.shift(suffix) = suffix - i; 1977 bmgs_buffers.shift(suffix) = suffix - i;
(...skipping 25 matching lines...) Expand all
1981 bmgs_buffers.shift(i) = suffix - start; 2003 bmgs_buffers.shift(i) = suffix - start;
1982 } 2004 }
1983 if (i == suffix) { 2005 if (i == suffix) {
1984 suffix = bmgs_buffers.suffix(suffix); 2006 suffix = bmgs_buffers.suffix(suffix);
1985 } 2007 }
1986 } 2008 }
1987 } 2009 }
1988 } 2010 }
1989 2011
1990 template <typename schar, typename pchar> 2012 template <typename schar, typename pchar>
1991 static inline int CharOccurrence(int char_code) { 2013 static inline int CharOccurrence(int char_code, RuntimeData* data) {
1992 if (sizeof(schar) == 1) { 2014 if (sizeof(schar) == 1) {
1993 return bad_char_occurrence[char_code]; 2015 return data->bad_char_occurrence_[char_code];
1994 } 2016 }
1995 if (sizeof(pchar) == 1) { 2017 if (sizeof(pchar) == 1) {
1996 if (char_code > String::kMaxAsciiCharCode) { 2018 if (char_code > String::kMaxAsciiCharCode) {
1997 return -1; 2019 return -1;
1998 } 2020 }
1999 return bad_char_occurrence[char_code]; 2021 return data->bad_char_occurrence_[char_code];
2000 } 2022 }
2001 return bad_char_occurrence[char_code % kBMAlphabetSize]; 2023 return data->bad_char_occurrence_[char_code % kBMAlphabetSize];
2002 } 2024 }
2003 2025
2004 // Restricted simplified Boyer-Moore string matching. 2026 // Restricted simplified Boyer-Moore string matching.
2005 // Uses only the bad-shift table of Boyer-Moore and only uses it 2027 // Uses only the bad-shift table of Boyer-Moore and only uses it
2006 // for the character compared to the last character of the needle. 2028 // for the character compared to the last character of the needle.
2007 template <typename schar, typename pchar> 2029 template <typename schar, typename pchar>
2008 static int BoyerMooreHorspool(Vector<const schar> subject, 2030 static int BoyerMooreHorspool(Vector<const schar> subject,
2009 Vector<const pchar> pattern, 2031 Vector<const pchar> pattern,
2010 int start_index, 2032 int start_index,
2011 bool* complete) { 2033 bool* complete) {
2012 int n = subject.length(); 2034 int n = subject.length();
2013 int m = pattern.length(); 2035 int m = pattern.length();
2014 // Only preprocess at most kBMMaxShift last characters of pattern. 2036 // Only preprocess at most kBMMaxShift last characters of pattern.
2015 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift; 2037 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
2016 2038
2017 BoyerMoorePopulateBadCharTable(pattern, start); 2039 BoyerMoorePopulateBadCharTable(pattern, start);
2018 2040
2041 RuntimeData* const data = v8_context()->runtime_data_;
2019 int badness = -m; // How bad we are doing without a good-suffix table. 2042 int badness = -m; // How bad we are doing without a good-suffix table.
2020 int idx; // No matches found prior to this index. 2043 int idx; // No matches found prior to this index.
2021 pchar last_char = pattern[m - 1]; 2044 pchar last_char = pattern[m - 1];
2022 int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char); 2045 int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char, data);
2023 // Perform search 2046 // Perform search
2024 for (idx = start_index; idx <= n - m;) { 2047 for (idx = start_index; idx <= n - m;) {
2025 int j = m - 1; 2048 int j = m - 1;
2026 int c; 2049 int c;
2027 while (last_char != (c = subject[idx + j])) { 2050 while (last_char != (c = subject[idx + j])) {
2028 int bc_occ = CharOccurrence<schar, pchar>(c); 2051 int bc_occ = CharOccurrence<schar, pchar>(c, data);
2029 int shift = j - bc_occ; 2052 int shift = j - bc_occ;
2030 idx += shift; 2053 idx += shift;
2031 badness += 1 - shift; // at most zero, so badness cannot increase. 2054 badness += 1 - shift; // at most zero, so badness cannot increase.
2032 if (idx > n - m) { 2055 if (idx > n - m) {
2033 *complete = true; 2056 *complete = true;
2034 return -1; 2057 return -1;
2035 } 2058 }
2036 } 2059 }
2037 j--; 2060 j--;
2038 while (j >= 0 && pattern[j] == (subject[idx + j])) j--; 2061 while (j >= 0 && pattern[j] == (subject[idx + j])) j--;
(...skipping 23 matching lines...) Expand all
2062 Vector<const pchar> pattern, 2085 Vector<const pchar> pattern,
2063 int idx) { 2086 int idx) {
2064 int n = subject.length(); 2087 int n = subject.length();
2065 int m = pattern.length(); 2088 int m = pattern.length();
2066 // Only preprocess at most kBMMaxShift last characters of pattern. 2089 // Only preprocess at most kBMMaxShift last characters of pattern.
2067 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift; 2090 int start = m < kBMMaxShift ? 0 : m - kBMMaxShift;
2068 2091
2069 // Build the Good Suffix table and continue searching. 2092 // Build the Good Suffix table and continue searching.
2070 BoyerMoorePopulateGoodSuffixTable(pattern, start); 2093 BoyerMoorePopulateGoodSuffixTable(pattern, start);
2071 pchar last_char = pattern[m - 1]; 2094 pchar last_char = pattern[m - 1];
2095 RuntimeData* runtime_data = v8_context()->runtime_data_;
2096 BMGoodSuffixBuffers& bmgs_buffers = runtime_data->bmgs_buffers_;
2072 // Continue search from i. 2097 // Continue search from i.
2073 while (idx <= n - m) { 2098 while (idx <= n - m) {
2074 int j = m - 1; 2099 int j = m - 1;
2075 schar c; 2100 schar c;
2076 while (last_char != (c = subject[idx + j])) { 2101 while (last_char != (c = subject[idx + j])) {
2077 int shift = j - CharOccurrence<schar, pchar>(c); 2102 int shift = j - CharOccurrence<schar, pchar>(c, runtime_data);
2078 idx += shift; 2103 idx += shift;
2079 if (idx > n - m) { 2104 if (idx > n - m) {
2080 return -1; 2105 return -1;
2081 } 2106 }
2082 } 2107 }
2083 while (j >= 0 && pattern[j] == (c = subject[idx + j])) j--; 2108 while (j >= 0 && pattern[j] == (c = subject[idx + j])) j--;
2084 if (j < 0) { 2109 if (j < 0) {
2085 return idx; 2110 return idx;
2086 } else if (j < start) { 2111 } else if (j < start) {
2087 // we have matched more than our tables allow us to be smart about. 2112 // we have matched more than our tables allow us to be smart about.
2088 // Fall back on BMH shift. 2113 // Fall back on BMH shift.
2089 idx += m - 1 - CharOccurrence<schar, pchar>(last_char); 2114 idx += m - 1 - CharOccurrence<schar, pchar>(last_char, runtime_data);
2090 } else { 2115 } else {
2091 int gs_shift = bmgs_buffers.shift(j + 1); // Good suffix shift. 2116 int gs_shift = bmgs_buffers.shift(j + 1); // Good suffix shift.
2092 int bc_occ = CharOccurrence<schar, pchar>(c); 2117 int bc_occ = CharOccurrence<schar, pchar>(c, runtime_data);
2093 int shift = j - bc_occ; // Bad-char shift. 2118 int shift = j - bc_occ; // Bad-char shift.
2094 if (gs_shift > shift) { 2119 if (gs_shift > shift) {
2095 shift = gs_shift; 2120 shift = gs_shift;
2096 } 2121 }
2097 idx += shift; 2122 idx += shift;
2098 } 2123 }
2099 } 2124 }
2100 2125
2101 return -1; 2126 return -1;
2102 } 2127 }
(...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after
2352 2377
2353 // No need to flatten if we are going to find the answer on the first 2378 // No need to flatten if we are going to find the answer on the first
2354 // character. At this point we know there is at least one character 2379 // character. At this point we know there is at least one character
2355 // in each string, due to the trivial case handling above. 2380 // in each string, due to the trivial case handling above.
2356 int d = str1->Get(0) - str2->Get(0); 2381 int d = str1->Get(0) - str2->Get(0);
2357 if (d != 0) return Smi::FromInt(d); 2382 if (d != 0) return Smi::FromInt(d);
2358 2383
2359 str1->TryFlattenIfNotFlat(); 2384 str1->TryFlattenIfNotFlat();
2360 str2->TryFlattenIfNotFlat(); 2385 str2->TryFlattenIfNotFlat();
2361 2386
2362 static StringInputBuffer buf1; 2387 RuntimeData* data = v8_context()->runtime_data_;
2363 static StringInputBuffer buf2; 2388 StringInputBuffer& buf1 = data->buf1_;
2389 StringInputBuffer& buf2 = data->buf2_;
2364 2390
2365 buf1.Reset(str1); 2391 buf1.Reset(str1);
2366 buf2.Reset(str2); 2392 buf2.Reset(str2);
2367 2393
2368 for (int i = 0; i < end; i++) { 2394 for (int i = 0; i < end; i++) {
2369 uint16_t char1 = buf1.GetNext(); 2395 uint16_t char1 = buf1.GetNext();
2370 uint16_t char2 = buf2.GetNext(); 2396 uint16_t char2 = buf2.GetNext();
2371 if (char1 != char2) return Smi::FromInt(char1 - char2); 2397 if (char1 != char2) return Smi::FromInt(char1 - char2);
2372 } 2398 }
2373 2399
(...skipping 893 matching lines...) Expand 10 before | Expand all | Expand 10 after
3267 const char hex_chars[] = "0123456789ABCDEF"; 3293 const char hex_chars[] = "0123456789ABCDEF";
3268 NoHandleAllocation ha; 3294 NoHandleAllocation ha;
3269 ASSERT(args.length() == 1); 3295 ASSERT(args.length() == 1);
3270 CONVERT_CHECKED(String, source, args[0]); 3296 CONVERT_CHECKED(String, source, args[0]);
3271 3297
3272 source->TryFlattenIfNotFlat(); 3298 source->TryFlattenIfNotFlat();
3273 3299
3274 int escaped_length = 0; 3300 int escaped_length = 0;
3275 int length = source->length(); 3301 int length = source->length();
3276 { 3302 {
3277 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); 3303 Access<StringInputBuffer> buffer(
3304 &v8_context()->runtime_data_->runtime_string_input_buffer_);
3278 buffer->Reset(source); 3305 buffer->Reset(source);
3279 while (buffer->has_more()) { 3306 while (buffer->has_more()) {
3280 uint16_t character = buffer->GetNext(); 3307 uint16_t character = buffer->GetNext();
3281 if (character >= 256) { 3308 if (character >= 256) {
3282 escaped_length += 6; 3309 escaped_length += 6;
3283 } else if (IsNotEscaped(character)) { 3310 } else if (IsNotEscaped(character)) {
3284 escaped_length++; 3311 escaped_length++;
3285 } else { 3312 } else {
3286 escaped_length += 3; 3313 escaped_length += 3;
3287 } 3314 }
3288 // We don't allow strings that are longer than a maximal length. 3315 // We don't allow strings that are longer than a maximal length.
3289 if (escaped_length > String::kMaxLength) { 3316 if (escaped_length > String::kMaxLength) {
3290 Top::context()->mark_out_of_memory(); 3317 Top::context()->mark_out_of_memory();
3291 return Failure::OutOfMemoryException(); 3318 return Failure::OutOfMemoryException();
3292 } 3319 }
3293 } 3320 }
3294 } 3321 }
3295 // No length change implies no change. Return original string if no change. 3322 // No length change implies no change. Return original string if no change.
3296 if (escaped_length == length) { 3323 if (escaped_length == length) {
3297 return source; 3324 return source;
3298 } 3325 }
3299 Object* o = Heap::AllocateRawAsciiString(escaped_length); 3326 Object* o = Heap::AllocateRawAsciiString(escaped_length);
3300 if (o->IsFailure()) return o; 3327 if (o->IsFailure()) return o;
3301 String* destination = String::cast(o); 3328 String* destination = String::cast(o);
3302 int dest_position = 0; 3329 int dest_position = 0;
3303 3330
3304 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); 3331 Access<StringInputBuffer> buffer(
3332 &v8_context()->runtime_data_->runtime_string_input_buffer_);
3305 buffer->Rewind(); 3333 buffer->Rewind();
3306 while (buffer->has_more()) { 3334 while (buffer->has_more()) {
3307 uint16_t chr = buffer->GetNext(); 3335 uint16_t chr = buffer->GetNext();
3308 if (chr >= 256) { 3336 if (chr >= 256) {
3309 destination->Set(dest_position, '%'); 3337 destination->Set(dest_position, '%');
3310 destination->Set(dest_position+1, 'u'); 3338 destination->Set(dest_position+1, 'u');
3311 destination->Set(dest_position+2, hex_chars[chr >> 12]); 3339 destination->Set(dest_position+2, hex_chars[chr >> 12]);
3312 destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]); 3340 destination->Set(dest_position+3, hex_chars[(chr >> 8) & 0xf]);
3313 destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]); 3341 destination->Set(dest_position+4, hex_chars[(chr >> 4) & 0xf]);
3314 destination->Set(dest_position+5, hex_chars[chr & 0xf]); 3342 destination->Set(dest_position+5, hex_chars[chr & 0xf]);
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
3420 3448
3421 CONVERT_CHECKED(String, s, args[0]); 3449 CONVERT_CHECKED(String, s, args[0]);
3422 CONVERT_SMI_CHECKED(radix, args[1]); 3450 CONVERT_SMI_CHECKED(radix, args[1]);
3423 3451
3424 s->TryFlattenIfNotFlat(); 3452 s->TryFlattenIfNotFlat();
3425 3453
3426 int len = s->length(); 3454 int len = s->length();
3427 int i; 3455 int i;
3428 3456
3429 // Skip leading white space. 3457 // Skip leading white space.
3430 for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ; 3458 unibrow::Predicate<unibrow::WhiteSpace, 128>& kIsWhiteSpace =
3459 v8_context()->scanner_data_.kIsWhiteSpace_;
3460 for (i = 0; i < len && kIsWhiteSpace.get(s->Get(i)); i++) ;
3431 if (i == len) return Heap::nan_value(); 3461 if (i == len) return Heap::nan_value();
3432 3462
3433 // Compute the sign (default to +). 3463 // Compute the sign (default to +).
3434 int sign = 1; 3464 int sign = 1;
3435 if (s->Get(i) == '-') { 3465 if (s->Get(i) == '-') {
3436 sign = -1; 3466 sign = -1;
3437 i++; 3467 i++;
3438 } else if (s->Get(i) == '+') { 3468 } else if (s->Get(i) == '+') {
3439 i++; 3469 i++;
3440 } 3470 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
3475 CONVERT_CHECKED(String, str, args[0]); 3505 CONVERT_CHECKED(String, str, args[0]);
3476 3506
3477 // ECMA-262 section 15.1.2.3, empty string is NaN 3507 // ECMA-262 section 15.1.2.3, empty string is NaN
3478 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value()); 3508 double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value());
3479 3509
3480 // Create a number object from the value. 3510 // Create a number object from the value.
3481 return Heap::NumberFromDouble(value); 3511 return Heap::NumberFromDouble(value);
3482 } 3512 }
3483 3513
3484 3514
3485 static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping;
3486 static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping;
3487 3515
3488 3516
3489 template <class Converter> 3517 template <class Converter>
3490 static Object* ConvertCaseHelper(String* s, 3518 static Object* ConvertCaseHelper(String* s,
3491 int length, 3519 int length,
3492 int input_string_length, 3520 int input_string_length,
3493 unibrow::Mapping<Converter, 128>* mapping) { 3521 unibrow::Mapping<Converter, 128>* mapping) {
3494 // We try this twice, once with the assumption that the result is no longer 3522 // We try this twice, once with the assumption that the result is no longer
3495 // than the input and, if that assumption breaks, again with the exact 3523 // than the input and, if that assumption breaks, again with the exact
3496 // length. This may not be pretty, but it is nicer than what was here before 3524 // length. This may not be pretty, but it is nicer than what was here before
3497 // and I hereby claim my vaffel-is. 3525 // and I hereby claim my vaffel-is.
3498 // 3526 //
3499 // Allocate the resulting string. 3527 // Allocate the resulting string.
3500 // 3528 //
3501 // NOTE: This assumes that the upper/lower case of an ascii 3529 // NOTE: This assumes that the upper/lower case of an ascii
3502 // character is also ascii. This is currently the case, but it 3530 // character is also ascii. This is currently the case, but it
3503 // might break in the future if we implement more context and locale 3531 // might break in the future if we implement more context and locale
3504 // dependent upper/lower conversions. 3532 // dependent upper/lower conversions.
3505 Object* o = s->IsAsciiRepresentation() 3533 Object* o = s->IsAsciiRepresentation()
3506 ? Heap::AllocateRawAsciiString(length) 3534 ? Heap::AllocateRawAsciiString(length)
3507 : Heap::AllocateRawTwoByteString(length); 3535 : Heap::AllocateRawTwoByteString(length);
3508 if (o->IsFailure()) return o; 3536 if (o->IsFailure()) return o;
3509 String* result = String::cast(o); 3537 String* result = String::cast(o);
3510 bool has_changed_character = false; 3538 bool has_changed_character = false;
3511 3539
3512 // Convert all characters to upper case, assuming that they will fit 3540 // Convert all characters to upper case, assuming that they will fit
3513 // in the buffer 3541 // in the buffer
3514 Access<StringInputBuffer> buffer(&runtime_string_input_buffer); 3542 Access<StringInputBuffer> buffer(&v8_context()->runtime_data_->
3543 runtime_string_input_buffer_);
3515 buffer->Reset(s); 3544 buffer->Reset(s);
3516 unibrow::uchar chars[Converter::kMaxWidth]; 3545 unibrow::uchar chars[Converter::kMaxWidth];
3517 // We can assume that the string is not empty 3546 // We can assume that the string is not empty
3518 uc32 current = buffer->GetNext(); 3547 uc32 current = buffer->GetNext();
3519 for (int i = 0; i < length;) { 3548 for (int i = 0; i < length;) {
3520 bool has_next = buffer->has_more(); 3549 bool has_next = buffer->has_more();
3521 uc32 next = has_next ? buffer->GetNext() : 0; 3550 uc32 next = has_next ? buffer->GetNext() : 0;
3522 int char_length = mapping->get(current, next, chars); 3551 int char_length = mapping->get(current, next, chars);
3523 if (char_length == 0) { 3552 if (char_length == 0) {
3524 // The case conversion of this character is the character itself. 3553 // The case conversion of this character is the character itself.
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
3601 Object* answer = ConvertCaseHelper(s, length, length, mapping); 3630 Object* answer = ConvertCaseHelper(s, length, length, mapping);
3602 if (answer->IsSmi()) { 3631 if (answer->IsSmi()) {
3603 // Retry with correct length. 3632 // Retry with correct length.
3604 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping); 3633 answer = ConvertCaseHelper(s, Smi::cast(answer)->value(), length, mapping);
3605 } 3634 }
3606 return answer; // This may be a failure. 3635 return answer; // This may be a failure.
3607 } 3636 }
3608 3637
3609 3638
3610 static Object* Runtime_StringToLowerCase(Arguments args) { 3639 static Object* Runtime_StringToLowerCase(Arguments args) {
3611 return ConvertCase<unibrow::ToLowercase>(args, &to_lower_mapping); 3640 return ConvertCase<unibrow::ToLowercase>(
3641 args,
3642 &v8_context()->runtime_data_->to_lower_mapping_);
3612 } 3643 }
3613 3644
3614 3645
3615 static Object* Runtime_StringToUpperCase(Arguments args) { 3646 static Object* Runtime_StringToUpperCase(Arguments args) {
3616 return ConvertCase<unibrow::ToUppercase>(args, &to_upper_mapping); 3647 return ConvertCase<unibrow::ToUppercase>(
3648 args,
3649 &v8_context()->runtime_data_->to_upper_mapping_);
3617 } 3650 }
3618 3651
3619 static inline bool IsTrimWhiteSpace(unibrow::uchar c) { 3652 static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
3620 return unibrow::WhiteSpace::Is(c) || c == 0x200b; 3653 return unibrow::WhiteSpace::Is(c) || c == 0x200b;
3621 } 3654 }
3622 3655
3623 static Object* Runtime_StringTrim(Arguments args) { 3656 static Object* Runtime_StringTrim(Arguments args) {
3624 NoHandleAllocation ha; 3657 NoHandleAllocation ha;
3625 ASSERT(args.length() == 3); 3658 ASSERT(args.length() == 3);
3626 3659
(...skipping 15 matching lines...) Expand all
3642 if (trimRight) { 3675 if (trimRight) {
3643 while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) { 3676 while (right > left && IsTrimWhiteSpace(s->Get(right - 1))) {
3644 right--; 3677 right--;
3645 } 3678 }
3646 } 3679 }
3647 return s->SubString(left, right); 3680 return s->SubString(left, right);
3648 } 3681 }
3649 3682
3650 bool Runtime::IsUpperCaseChar(uint16_t ch) { 3683 bool Runtime::IsUpperCaseChar(uint16_t ch) {
3651 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth]; 3684 unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
3652 int char_length = to_upper_mapping.get(ch, 0, chars); 3685 int char_length = v8_context()->runtime_data_->
3686 to_upper_mapping_.get(ch, 0, chars);
3653 return char_length == 0; 3687 return char_length == 0;
3654 } 3688 }
3655 3689
3656 3690
3657 static Object* Runtime_NumberToString(Arguments args) { 3691 static Object* Runtime_NumberToString(Arguments args) {
3658 NoHandleAllocation ha; 3692 NoHandleAllocation ha;
3659 ASSERT(args.length() == 1); 3693 ASSERT(args.length() == 1);
3660 3694
3661 Object* number = args[0]; 3695 Object* number = args[0];
3662 RUNTIME_ASSERT(number->IsNumber()); 3696 RUNTIME_ASSERT(number->IsNumber());
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3779 // NewNumberFromDouble may return a Smi instead of a Number object 3813 // NewNumberFromDouble may return a Smi instead of a Number object
3780 return Heap::NewNumberFromDouble(x); 3814 return Heap::NewNumberFromDouble(x);
3781 } 3815 }
3782 3816
3783 3817
3784 static Object* Runtime_StringAdd(Arguments args) { 3818 static Object* Runtime_StringAdd(Arguments args) {
3785 NoHandleAllocation ha; 3819 NoHandleAllocation ha;
3786 ASSERT(args.length() == 2); 3820 ASSERT(args.length() == 2);
3787 CONVERT_CHECKED(String, str1, args[0]); 3821 CONVERT_CHECKED(String, str1, args[0]);
3788 CONVERT_CHECKED(String, str2, args[1]); 3822 CONVERT_CHECKED(String, str2, args[1]);
3789 Counters::string_add_runtime.Increment(); 3823 INC_COUNTER(string_add_runtime);
3790 return Heap::AllocateConsString(str1, str2); 3824 return Heap::AllocateConsString(str1, str2);
3791 } 3825 }
3792 3826
3793 3827
3794 template<typename sinkchar> 3828 template<typename sinkchar>
3795 static inline void StringBuilderConcatHelper(String* special, 3829 static inline void StringBuilderConcatHelper(String* special,
3796 sinkchar* sink, 3830 sinkchar* sink,
3797 FixedArray* fixed_array, 3831 FixedArray* fixed_array,
3798 int array_length) { 3832 int array_length) {
3799 int position = 0; 3833 int position = 0;
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
4048 return Smi::FromInt(GREATER); 4082 return Smi::FromInt(GREATER);
4049 } 4083 }
4050 4084
4051 4085
4052 // Compare two Smis as if they were converted to strings and then 4086 // Compare two Smis as if they were converted to strings and then
4053 // compared lexicographically. 4087 // compared lexicographically.
4054 static Object* Runtime_SmiLexicographicCompare(Arguments args) { 4088 static Object* Runtime_SmiLexicographicCompare(Arguments args) {
4055 NoHandleAllocation ha; 4089 NoHandleAllocation ha;
4056 ASSERT(args.length() == 2); 4090 ASSERT(args.length() == 2);
4057 4091
4092 RuntimeData* const data = v8_context()->runtime_data_;
4058 // Arrays for the individual characters of the two Smis. Smis are 4093 // Arrays for the individual characters of the two Smis. Smis are
4059 // 31 bit integers and 10 decimal digits are therefore enough. 4094 // 31 bit integers and 10 decimal digits are therefore enough.
4060 static int x_elms[10]; 4095 int * const x_elms = data->x_elms_;
4061 static int y_elms[10]; 4096 int * const y_elms = data->y_elms_;
4062 4097
4063 // Extract the integer values from the Smis. 4098 // Extract the integer values from the Smis.
4064 CONVERT_CHECKED(Smi, x, args[0]); 4099 CONVERT_CHECKED(Smi, x, args[0]);
4065 CONVERT_CHECKED(Smi, y, args[1]); 4100 CONVERT_CHECKED(Smi, y, args[1]);
4066 int x_value = x->value(); 4101 int x_value = x->value();
4067 int y_value = y->value(); 4102 int y_value = y->value();
4068 4103
4069 // If the integers are equal so are the string representations. 4104 // If the integers are equal so are the string representations.
4070 if (x_value == y_value) return Smi::FromInt(EQUAL); 4105 if (x_value == y_value) return Smi::FromInt(EQUAL);
4071 4106
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
4125 return Smi::FromInt(LESS); 4160 return Smi::FromInt(LESS);
4126 } 4161 }
4127 4162
4128 int d = x->Get(0) - y->Get(0); 4163 int d = x->Get(0) - y->Get(0);
4129 if (d < 0) return Smi::FromInt(LESS); 4164 if (d < 0) return Smi::FromInt(LESS);
4130 else if (d > 0) return Smi::FromInt(GREATER); 4165 else if (d > 0) return Smi::FromInt(GREATER);
4131 4166
4132 x->TryFlattenIfNotFlat(); 4167 x->TryFlattenIfNotFlat();
4133 y->TryFlattenIfNotFlat(); 4168 y->TryFlattenIfNotFlat();
4134 4169
4135 static StringInputBuffer bufx; 4170 RuntimeData* const data = v8_context()->runtime_data_;
4136 static StringInputBuffer bufy; 4171 StringInputBuffer& bufx = data->bufx_;
4172 StringInputBuffer& bufy = data->bufy_;
4137 bufx.Reset(x); 4173 bufx.Reset(x);
4138 bufy.Reset(y); 4174 bufy.Reset(y);
4139 while (bufx.has_more() && bufy.has_more()) { 4175 while (bufx.has_more() && bufy.has_more()) {
4140 int d = bufx.GetNext() - bufy.GetNext(); 4176 int d = bufx.GetNext() - bufy.GetNext();
4141 if (d < 0) return Smi::FromInt(LESS); 4177 if (d < 0) return Smi::FromInt(LESS);
4142 else if (d > 0) return Smi::FromInt(GREATER); 4178 else if (d > 0) return Smi::FromInt(GREATER);
4143 } 4179 }
4144 4180
4145 // x is (non-trivial) prefix of y: 4181 // x is (non-trivial) prefix of y:
4146 if (bufy.has_more()) return Smi::FromInt(LESS); 4182 if (bufy.has_more()) return Smi::FromInt(LESS);
(...skipping 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
4498 4534
4499 bool first_allocation = !function->has_initial_map(); 4535 bool first_allocation = !function->has_initial_map();
4500 Handle<JSObject> result = Factory::NewJSObject(function); 4536 Handle<JSObject> result = Factory::NewJSObject(function);
4501 if (first_allocation) { 4537 if (first_allocation) {
4502 Handle<Map> map = Handle<Map>(function->initial_map()); 4538 Handle<Map> map = Handle<Map>(function->initial_map());
4503 Handle<Code> stub = Handle<Code>( 4539 Handle<Code> stub = Handle<Code>(
4504 ComputeConstructStub(Handle<SharedFunctionInfo>(function->shared()))); 4540 ComputeConstructStub(Handle<SharedFunctionInfo>(function->shared())));
4505 function->shared()->set_construct_stub(*stub); 4541 function->shared()->set_construct_stub(*stub);
4506 } 4542 }
4507 4543
4508 Counters::constructed_objects.Increment(); 4544 INC_COUNTER(constructed_objects);
4509 Counters::constructed_objects_runtime.Increment(); 4545 INC_COUNTER(constructed_objects_runtime);
4510 4546
4511 return *result; 4547 return *result;
4512 } 4548 }
4513 4549
4514 4550
4515 static Object* Runtime_LazyCompile(Arguments args) { 4551 static Object* Runtime_LazyCompile(Arguments args) {
4516 HandleScope scope; 4552 HandleScope scope;
4517 ASSERT(args.length() == 1); 4553 ASSERT(args.length() == 1);
4518 4554
4519 Handle<JSFunction> function = args.at<JSFunction>(0); 4555 Handle<JSFunction> function = args.at<JSFunction>(0);
(...skipping 3435 matching lines...) Expand 10 before | Expand all | Expand 10 after
7955 7991
7956 void Runtime::PerformGC(Object* result) { 7992 void Runtime::PerformGC(Object* result) {
7957 Failure* failure = Failure::cast(result); 7993 Failure* failure = Failure::cast(result);
7958 if (failure->IsRetryAfterGC()) { 7994 if (failure->IsRetryAfterGC()) {
7959 // Try to do a garbage collection; ignore it if it fails. The C 7995 // Try to do a garbage collection; ignore it if it fails. The C
7960 // entry stub will throw an out-of-memory exception in that case. 7996 // entry stub will throw an out-of-memory exception in that case.
7961 Heap::CollectGarbage(failure->requested(), failure->allocation_space()); 7997 Heap::CollectGarbage(failure->requested(), failure->allocation_space());
7962 } else { 7998 } else {
7963 // Handle last resort GC and make sure to allow future allocations 7999 // Handle last resort GC and make sure to allow future allocations
7964 // to grow the heap without causing GCs (if possible). 8000 // to grow the heap without causing GCs (if possible).
7965 Counters::gc_last_resort_from_js.Increment(); 8001 INC_COUNTER(gc_last_resort_from_js);
7966 Heap::CollectAllGarbage(false); 8002 Heap::CollectAllGarbage(false);
7967 } 8003 }
7968 } 8004 }
7969 8005
8006 void Runtime::PostConstruct() {
8007 v8_context()->runtime_data_ = new RuntimeData();
8008 }
8009
8010 void Runtime::PreDestroy() {
8011 delete v8_context()->runtime_data_;
8012 v8_context()->runtime_data_ = NULL;
8013 }
7970 8014
7971 } } // namespace v8::internal 8015 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | src/scanner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698