| Index: src/runtime.cc
|
| ===================================================================
|
| --- src/runtime.cc (revision 3427)
|
| +++ src/runtime.cc (working copy)
|
| @@ -92,10 +92,6 @@
|
| RUNTIME_ASSERT(obj->IsNumber()); \
|
| type name = NumberTo##Type(obj);
|
|
|
| -// Non-reentrant string buffer for efficient general use in this file.
|
| -static StaticResource<StringInputBuffer> runtime_string_input_buffer;
|
| -
|
| -
|
| static Object* DeepCopyBoilerplate(JSObject* boilerplate) {
|
| StackLimitCheck check;
|
| if (check.HasOverflowed()) return Top::StackOverflow();
|
| @@ -1910,10 +1906,31 @@
|
| DISALLOW_COPY_AND_ASSIGN(BMGoodSuffixBuffers);
|
| };
|
|
|
| -// buffers reused by BoyerMoore
|
| -static int bad_char_occurrence[kBMAlphabetSize];
|
| -static BMGoodSuffixBuffers bmgs_buffers;
|
| +class RuntimeData {
|
| + public:
|
| + // Non-reentrant string buffer for efficient general use in this file.
|
| + StaticResource<StringInputBuffer> runtime_string_input_buffer_;
|
| + // buffers reused by BoyerMoore
|
| + int bad_char_occurrence_[kBMAlphabetSize];
|
| + BMGoodSuffixBuffers bmgs_buffers_;
|
| + StringInputBuffer buf1_;
|
| + StringInputBuffer buf2_;
|
|
|
| + unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping_;
|
| + unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping_;
|
| +
|
| + // Arrays for the individual characters of the two Smis. Smis are
|
| + // 31 bit integers and 10 decimal digits are therefore enough.
|
| + int x_elms_[10];
|
| + int y_elms_[10];
|
| +
|
| + StringInputBuffer bufx_;
|
| + StringInputBuffer bufy_;
|
| +
|
| + RuntimeData() {}
|
| + DISALLOW_COPY_AND_ASSIGN(RuntimeData);
|
| +};
|
| +
|
| // Compute the bad-char table for Boyer-Moore in the static buffer.
|
| template <typename pchar>
|
| static void BoyerMoorePopulateBadCharTable(Vector<const pchar> pattern,
|
| @@ -1923,6 +1940,9 @@
|
| // Notice: Doesn't include the last character.
|
| int table_size = (sizeof(pchar) == 1) ? String::kMaxAsciiCharCode + 1
|
| : kBMAlphabetSize;
|
| + int* const bad_char_occurrence = v8_context()->runtime_data_->
|
| + bad_char_occurrence_;
|
| +
|
| if (start == 0) { // All patterns less than kBMMaxShift in length.
|
| memset(bad_char_occurrence, -1, table_size * sizeof(*bad_char_occurrence));
|
| } else {
|
| @@ -1943,6 +1963,8 @@
|
| int m = pattern.length();
|
| int len = m - start;
|
| // Compute Good Suffix tables.
|
| + BMGoodSuffixBuffers& bmgs_buffers =
|
| + v8_context()->runtime_data_->bmgs_buffers_;
|
| bmgs_buffers.init(m);
|
|
|
| bmgs_buffers.shift(m-1) = 1;
|
| @@ -1988,17 +2010,17 @@
|
| }
|
|
|
| template <typename schar, typename pchar>
|
| -static inline int CharOccurrence(int char_code) {
|
| +static inline int CharOccurrence(int char_code, RuntimeData* data) {
|
| if (sizeof(schar) == 1) {
|
| - return bad_char_occurrence[char_code];
|
| + return data->bad_char_occurrence_[char_code];
|
| }
|
| if (sizeof(pchar) == 1) {
|
| if (char_code > String::kMaxAsciiCharCode) {
|
| return -1;
|
| }
|
| - return bad_char_occurrence[char_code];
|
| + return data->bad_char_occurrence_[char_code];
|
| }
|
| - return bad_char_occurrence[char_code % kBMAlphabetSize];
|
| + return data->bad_char_occurrence_[char_code % kBMAlphabetSize];
|
| }
|
|
|
| // Restricted simplified Boyer-Moore string matching.
|
| @@ -2016,16 +2038,17 @@
|
|
|
| BoyerMoorePopulateBadCharTable(pattern, start);
|
|
|
| + RuntimeData* const data = v8_context()->runtime_data_;
|
| int badness = -m; // How bad we are doing without a good-suffix table.
|
| int idx; // No matches found prior to this index.
|
| pchar last_char = pattern[m - 1];
|
| - int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char);
|
| + int last_char_shift = m - 1 - CharOccurrence<schar, pchar>(last_char, data);
|
| // Perform search
|
| for (idx = start_index; idx <= n - m;) {
|
| int j = m - 1;
|
| int c;
|
| while (last_char != (c = subject[idx + j])) {
|
| - int bc_occ = CharOccurrence<schar, pchar>(c);
|
| + int bc_occ = CharOccurrence<schar, pchar>(c, data);
|
| int shift = j - bc_occ;
|
| idx += shift;
|
| badness += 1 - shift; // at most zero, so badness cannot increase.
|
| @@ -2069,12 +2092,14 @@
|
| // Build the Good Suffix table and continue searching.
|
| BoyerMoorePopulateGoodSuffixTable(pattern, start);
|
| pchar last_char = pattern[m - 1];
|
| + RuntimeData* runtime_data = v8_context()->runtime_data_;
|
| + BMGoodSuffixBuffers& bmgs_buffers = runtime_data->bmgs_buffers_;
|
| // Continue search from i.
|
| while (idx <= n - m) {
|
| int j = m - 1;
|
| schar c;
|
| while (last_char != (c = subject[idx + j])) {
|
| - int shift = j - CharOccurrence<schar, pchar>(c);
|
| + int shift = j - CharOccurrence<schar, pchar>(c, runtime_data);
|
| idx += shift;
|
| if (idx > n - m) {
|
| return -1;
|
| @@ -2086,10 +2111,10 @@
|
| } else if (j < start) {
|
| // we have matched more than our tables allow us to be smart about.
|
| // Fall back on BMH shift.
|
| - idx += m - 1 - CharOccurrence<schar, pchar>(last_char);
|
| + idx += m - 1 - CharOccurrence<schar, pchar>(last_char, runtime_data);
|
| } else {
|
| int gs_shift = bmgs_buffers.shift(j + 1); // Good suffix shift.
|
| - int bc_occ = CharOccurrence<schar, pchar>(c);
|
| + int bc_occ = CharOccurrence<schar, pchar>(c, runtime_data);
|
| int shift = j - bc_occ; // Bad-char shift.
|
| if (gs_shift > shift) {
|
| shift = gs_shift;
|
| @@ -2359,8 +2384,9 @@
|
| str1->TryFlattenIfNotFlat();
|
| str2->TryFlattenIfNotFlat();
|
|
|
| - static StringInputBuffer buf1;
|
| - static StringInputBuffer buf2;
|
| + RuntimeData* data = v8_context()->runtime_data_;
|
| + StringInputBuffer& buf1 = data->buf1_;
|
| + StringInputBuffer& buf2 = data->buf2_;
|
|
|
| buf1.Reset(str1);
|
| buf2.Reset(str2);
|
| @@ -3274,7 +3300,8 @@
|
| int escaped_length = 0;
|
| int length = source->length();
|
| {
|
| - Access<StringInputBuffer> buffer(&runtime_string_input_buffer);
|
| + Access<StringInputBuffer> buffer(
|
| + &v8_context()->runtime_data_->runtime_string_input_buffer_);
|
| buffer->Reset(source);
|
| while (buffer->has_more()) {
|
| uint16_t character = buffer->GetNext();
|
| @@ -3301,7 +3328,8 @@
|
| String* destination = String::cast(o);
|
| int dest_position = 0;
|
|
|
| - Access<StringInputBuffer> buffer(&runtime_string_input_buffer);
|
| + Access<StringInputBuffer> buffer(
|
| + &v8_context()->runtime_data_->runtime_string_input_buffer_);
|
| buffer->Rewind();
|
| while (buffer->has_more()) {
|
| uint16_t chr = buffer->GetNext();
|
| @@ -3427,7 +3455,9 @@
|
| int i;
|
|
|
| // Skip leading white space.
|
| - for (i = 0; i < len && Scanner::kIsWhiteSpace.get(s->Get(i)); i++) ;
|
| + unibrow::Predicate<unibrow::WhiteSpace, 128>& kIsWhiteSpace =
|
| + v8_context()->scanner_data_.kIsWhiteSpace_;
|
| + for (i = 0; i < len && kIsWhiteSpace.get(s->Get(i)); i++) ;
|
| if (i == len) return Heap::nan_value();
|
|
|
| // Compute the sign (default to +).
|
| @@ -3482,8 +3512,6 @@
|
| }
|
|
|
|
|
| -static unibrow::Mapping<unibrow::ToUppercase, 128> to_upper_mapping;
|
| -static unibrow::Mapping<unibrow::ToLowercase, 128> to_lower_mapping;
|
|
|
|
|
| template <class Converter>
|
| @@ -3511,7 +3539,8 @@
|
|
|
| // Convert all characters to upper case, assuming that they will fit
|
| // in the buffer
|
| - Access<StringInputBuffer> buffer(&runtime_string_input_buffer);
|
| + Access<StringInputBuffer> buffer(&v8_context()->runtime_data_->
|
| + runtime_string_input_buffer_);
|
| buffer->Reset(s);
|
| unibrow::uchar chars[Converter::kMaxWidth];
|
| // We can assume that the string is not empty
|
| @@ -3608,12 +3637,16 @@
|
|
|
|
|
| static Object* Runtime_StringToLowerCase(Arguments args) {
|
| - return ConvertCase<unibrow::ToLowercase>(args, &to_lower_mapping);
|
| + return ConvertCase<unibrow::ToLowercase>(
|
| + args,
|
| + &v8_context()->runtime_data_->to_lower_mapping_);
|
| }
|
|
|
|
|
| static Object* Runtime_StringToUpperCase(Arguments args) {
|
| - return ConvertCase<unibrow::ToUppercase>(args, &to_upper_mapping);
|
| + return ConvertCase<unibrow::ToUppercase>(
|
| + args,
|
| + &v8_context()->runtime_data_->to_upper_mapping_);
|
| }
|
|
|
| static inline bool IsTrimWhiteSpace(unibrow::uchar c) {
|
| @@ -3649,7 +3682,8 @@
|
|
|
| bool Runtime::IsUpperCaseChar(uint16_t ch) {
|
| unibrow::uchar chars[unibrow::ToUppercase::kMaxWidth];
|
| - int char_length = to_upper_mapping.get(ch, 0, chars);
|
| + int char_length = v8_context()->runtime_data_->
|
| + to_upper_mapping_.get(ch, 0, chars);
|
| return char_length == 0;
|
| }
|
|
|
| @@ -3786,7 +3820,7 @@
|
| ASSERT(args.length() == 2);
|
| CONVERT_CHECKED(String, str1, args[0]);
|
| CONVERT_CHECKED(String, str2, args[1]);
|
| - Counters::string_add_runtime.Increment();
|
| + INC_COUNTER(string_add_runtime);
|
| return Heap::AllocateConsString(str1, str2);
|
| }
|
|
|
| @@ -4055,10 +4089,11 @@
|
| NoHandleAllocation ha;
|
| ASSERT(args.length() == 2);
|
|
|
| + RuntimeData* const data = v8_context()->runtime_data_;
|
| // Arrays for the individual characters of the two Smis. Smis are
|
| // 31 bit integers and 10 decimal digits are therefore enough.
|
| - static int x_elms[10];
|
| - static int y_elms[10];
|
| + int * const x_elms = data->x_elms_;
|
| + int * const y_elms = data->y_elms_;
|
|
|
| // Extract the integer values from the Smis.
|
| CONVERT_CHECKED(Smi, x, args[0]);
|
| @@ -4132,8 +4167,9 @@
|
| x->TryFlattenIfNotFlat();
|
| y->TryFlattenIfNotFlat();
|
|
|
| - static StringInputBuffer bufx;
|
| - static StringInputBuffer bufy;
|
| + RuntimeData* const data = v8_context()->runtime_data_;
|
| + StringInputBuffer& bufx = data->bufx_;
|
| + StringInputBuffer& bufy = data->bufy_;
|
| bufx.Reset(x);
|
| bufy.Reset(y);
|
| while (bufx.has_more() && bufy.has_more()) {
|
| @@ -4505,8 +4541,8 @@
|
| function->shared()->set_construct_stub(*stub);
|
| }
|
|
|
| - Counters::constructed_objects.Increment();
|
| - Counters::constructed_objects_runtime.Increment();
|
| + INC_COUNTER(constructed_objects);
|
| + INC_COUNTER(constructed_objects_runtime);
|
|
|
| return *result;
|
| }
|
| @@ -7962,10 +7998,18 @@
|
| } else {
|
| // Handle last resort GC and make sure to allow future allocations
|
| // to grow the heap without causing GCs (if possible).
|
| - Counters::gc_last_resort_from_js.Increment();
|
| + INC_COUNTER(gc_last_resort_from_js);
|
| Heap::CollectAllGarbage(false);
|
| }
|
| }
|
|
|
| +void Runtime::PostConstruct() {
|
| + v8_context()->runtime_data_ = new RuntimeData();
|
| +}
|
|
|
| +void Runtime::PreDestroy() {
|
| + delete v8_context()->runtime_data_;
|
| + v8_context()->runtime_data_ = NULL;
|
| +}
|
| +
|
| } } // namespace v8::internal
|
|
|