From 8f88467bf6f7c0a517ad90f145dc415f79dcf317 Mon Sep 17 00:00:00 2001 From: "svenpanne@chromium.org" Date: Wed, 20 Nov 2013 12:35:58 +0000 Subject: [PATCH] Removed unused --preallocate-message-memory flag. It results in a lot of dead code, and Isolate::PrintStack itself crashes most of the time when something went wrong earlier. Furthermore, we have plans do get better information into the minidump, anyway. R=bmeurer@chromium.org Review URL: https://codereview.chromium.org/78003002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@17918 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/allocation-inl.h | 49 ----- src/allocation.cc | 20 -- src/allocation.h | 28 --- src/flag-definitions.h | 2 - src/frames.cc | 2 - src/isolate.cc | 220 +------------------ src/isolate.h | 15 +- src/scopeinfo.cc | 2 - src/scopes.cc | 2 - src/string-stream.cc | 5 +- test/mjsunit/regexp-multiline-stack-trace.js | 116 ---------- 11 files changed, 4 insertions(+), 457 deletions(-) delete mode 100644 src/allocation-inl.h delete mode 100644 test/mjsunit/regexp-multiline-stack-trace.js diff --git a/src/allocation-inl.h b/src/allocation-inl.h deleted file mode 100644 index d32db4b17f..0000000000 --- a/src/allocation-inl.h +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright 2010 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. - -#ifndef V8_ALLOCATION_INL_H_ -#define V8_ALLOCATION_INL_H_ - -#include "allocation.h" - -namespace v8 { -namespace internal { - - -void* PreallocatedStorageAllocationPolicy::New(size_t size) { - return Isolate::Current()->PreallocatedStorageNew(size); -} - - -void PreallocatedStorageAllocationPolicy::Delete(void* p) { - return Isolate::Current()->PreallocatedStorageDelete(p); -} - - -} } // namespace v8::internal - -#endif // V8_ALLOCATION_INL_H_ diff --git a/src/allocation.cc b/src/allocation.cc index 94aaad3fd4..69edf6906c 100644 --- a/src/allocation.cc +++ b/src/allocation.cc @@ -100,24 +100,4 @@ char* StrNDup(const char* str, int n) { return result; } - -void PreallocatedStorage::LinkTo(PreallocatedStorage* other) { - next_ = other->next_; - other->next_->previous_ = this; - previous_ = other; - other->next_ = this; -} - - -void PreallocatedStorage::Unlink() { - next_->previous_ = previous_; - previous_->next_ = next_; -} - - -PreallocatedStorage::PreallocatedStorage(size_t size) - : size_(size) { - previous_ = next_ = this; -} - } } // namespace v8::internal diff --git a/src/allocation.h b/src/allocation.h index 45bde4c4cb..03cc8f5e73 100644 --- a/src/allocation.h +++ b/src/allocation.h @@ -109,34 +109,6 @@ class FreeStoreAllocationPolicy { }; -// Allocation policy for allocating in preallocated space. -// Used as an allocation policy for ScopeInfo when generating -// stack traces. -class PreallocatedStorage { - public: - explicit PreallocatedStorage(size_t size); - size_t size() { return size_; } - - private: - size_t size_; - PreallocatedStorage* previous_; - PreallocatedStorage* next_; - - void LinkTo(PreallocatedStorage* other); - void Unlink(); - - friend class Isolate; - - DISALLOW_IMPLICIT_CONSTRUCTORS(PreallocatedStorage); -}; - - -struct PreallocatedStorageAllocationPolicy { - INLINE(void* New(size_t size)); - INLINE(static void Delete(void* ptr)); -}; - - } } // namespace v8::internal #endif // V8_ALLOCATION_H_ diff --git a/src/flag-definitions.h b/src/flag-definitions.h index a5cf326ea2..e703b9e80c 100644 --- a/src/flag-definitions.h +++ b/src/flag-definitions.h @@ -600,8 +600,6 @@ DEFINE_bool(abort_on_uncaught_exception, false, "abort program (dump core) when an uncaught exception is thrown") DEFINE_bool(trace_exception, false, "print stack trace when throwing exceptions") -DEFINE_bool(preallocate_message_memory, false, - "preallocate some memory to build stack traces.") DEFINE_bool(randomize_hashes, true, "randomize hashes to avoid predictable hash collisions " "(with snapshots this option cannot override the baked-in seed)") diff --git a/src/frames.cc b/src/frames.cc index 4abacad9ef..912c822d17 100644 --- a/src/frames.cc +++ b/src/frames.cc @@ -38,8 +38,6 @@ #include "string-stream.h" #include "vm-state-inl.h" -#include "allocation-inl.h" - namespace v8 { namespace internal { diff --git a/src/isolate.cc b/src/isolate.cc index 700ca87c74..195a712afe 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -29,7 +29,6 @@ #include "v8.h" -#include "allocation-inl.h" #include "ast.h" #include "bootstrapper.h" #include "codegen.h" @@ -131,189 +130,6 @@ v8::TryCatch* ThreadLocalTop::TryCatchHandler() { } -// Create a dummy thread that will wait forever on a semaphore. The only -// purpose for this thread is to have some stack area to save essential data -// into for use by a stacks only core dump (aka minidump). -class PreallocatedMemoryThread: public Thread { - public: - char* data() { - if (data_ready_semaphore_ != NULL) { - // Initial access is guarded until the data has been published. - data_ready_semaphore_->Wait(); - delete data_ready_semaphore_; - data_ready_semaphore_ = NULL; - } - return data_; - } - - unsigned length() { - if (data_ready_semaphore_ != NULL) { - // Initial access is guarded until the data has been published. - data_ready_semaphore_->Wait(); - delete data_ready_semaphore_; - data_ready_semaphore_ = NULL; - } - return length_; - } - - // Stop the PreallocatedMemoryThread and release its resources. - void StopThread() { - keep_running_ = false; - wait_for_ever_semaphore_->Signal(); - - // Wait for the thread to terminate. - Join(); - - if (data_ready_semaphore_ != NULL) { - delete data_ready_semaphore_; - data_ready_semaphore_ = NULL; - } - - delete wait_for_ever_semaphore_; - wait_for_ever_semaphore_ = NULL; - } - - protected: - // When the thread starts running it will allocate a fixed number of bytes - // on the stack and publish the location of this memory for others to use. - void Run() { - EmbeddedVector local_buffer; - - // Initialize the buffer with a known good value. - OS::StrNCpy(local_buffer, "Trace data was not generated.\n", - local_buffer.length()); - - // Publish the local buffer and signal its availability. - data_ = local_buffer.start(); - length_ = local_buffer.length(); - data_ready_semaphore_->Signal(); - - while (keep_running_) { - // This thread will wait here until the end of time. - wait_for_ever_semaphore_->Wait(); - } - - // Make sure we access the buffer after the wait to remove all possibility - // of it being optimized away. - OS::StrNCpy(local_buffer, "PreallocatedMemoryThread shutting down.\n", - local_buffer.length()); - } - - - private: - PreallocatedMemoryThread() - : Thread("v8:PreallocMem"), - keep_running_(true), - wait_for_ever_semaphore_(new Semaphore(0)), - data_ready_semaphore_(new Semaphore(0)), - data_(NULL), - length_(0) { - } - - // Used to make sure that the thread keeps looping even for spurious wakeups. - bool keep_running_; - - // This semaphore is used by the PreallocatedMemoryThread to wait for ever. - Semaphore* wait_for_ever_semaphore_; - // Semaphore to signal that the data has been initialized. - Semaphore* data_ready_semaphore_; - - // Location and size of the preallocated memory block. - char* data_; - unsigned length_; - - friend class Isolate; - - DISALLOW_COPY_AND_ASSIGN(PreallocatedMemoryThread); -}; - - -void Isolate::PreallocatedMemoryThreadStart() { - if (preallocated_memory_thread_ != NULL) return; - preallocated_memory_thread_ = new PreallocatedMemoryThread(); - preallocated_memory_thread_->Start(); -} - - -void Isolate::PreallocatedMemoryThreadStop() { - if (preallocated_memory_thread_ == NULL) return; - preallocated_memory_thread_->StopThread(); - // Done with the thread entirely. - delete preallocated_memory_thread_; - preallocated_memory_thread_ = NULL; -} - - -void Isolate::PreallocatedStorageInit(size_t size) { - ASSERT(free_list_.next_ == &free_list_); - ASSERT(free_list_.previous_ == &free_list_); - PreallocatedStorage* free_chunk = - reinterpret_cast(new char[size]); - free_list_.next_ = free_list_.previous_ = free_chunk; - free_chunk->next_ = free_chunk->previous_ = &free_list_; - free_chunk->size_ = size - sizeof(PreallocatedStorage); - preallocated_storage_preallocated_ = true; -} - - -void* Isolate::PreallocatedStorageNew(size_t size) { - if (!preallocated_storage_preallocated_) { - return FreeStoreAllocationPolicy().New(size); - } - ASSERT(free_list_.next_ != &free_list_); - ASSERT(free_list_.previous_ != &free_list_); - - size = (size + kPointerSize - 1) & ~(kPointerSize - 1); - // Search for exact fit. - for (PreallocatedStorage* storage = free_list_.next_; - storage != &free_list_; - storage = storage->next_) { - if (storage->size_ == size) { - storage->Unlink(); - storage->LinkTo(&in_use_list_); - return reinterpret_cast(storage + 1); - } - } - // Search for first fit. - for (PreallocatedStorage* storage = free_list_.next_; - storage != &free_list_; - storage = storage->next_) { - if (storage->size_ >= size + sizeof(PreallocatedStorage)) { - storage->Unlink(); - storage->LinkTo(&in_use_list_); - PreallocatedStorage* left_over = - reinterpret_cast( - reinterpret_cast(storage + 1) + size); - left_over->size_ = storage->size_ - size - sizeof(PreallocatedStorage); - ASSERT(size + left_over->size_ + sizeof(PreallocatedStorage) == - storage->size_); - storage->size_ = size; - left_over->LinkTo(&free_list_); - return reinterpret_cast(storage + 1); - } - } - // Allocation failure. - ASSERT(false); - return NULL; -} - - -// We don't attempt to coalesce. -void Isolate::PreallocatedStorageDelete(void* p) { - if (p == NULL) { - return; - } - if (!preallocated_storage_preallocated_) { - FreeStoreAllocationPolicy::Delete(p); - return; - } - PreallocatedStorage* storage = reinterpret_cast(p) - 1; - ASSERT(storage->next_->previous_ == storage); - ASSERT(storage->previous_->next_ == storage); - storage->Unlink(); - storage->LinkTo(&free_list_); -} - Isolate* Isolate::default_isolate_ = NULL; Thread::LocalStorageKey Isolate::isolate_key_; Thread::LocalStorageKey Isolate::thread_id_key_; @@ -845,16 +661,9 @@ void Isolate::PrintStack() { void Isolate::PrintStack(FILE* out) { if (stack_trace_nesting_level_ == 0) { stack_trace_nesting_level_++; - - StringAllocator* allocator; - if (preallocated_message_space_ == NULL) { - allocator = new HeapStringAllocator(); - } else { - allocator = preallocated_message_space_; - } - StringStream::ClearMentionedObjectCache(this); - StringStream accumulator(allocator); + HeapStringAllocator allocator; + StringStream accumulator(&allocator); incomplete_message_ = &accumulator; PrintStack(&accumulator); accumulator.OutputToFile(out); @@ -862,10 +671,6 @@ void Isolate::PrintStack(FILE* out) { accumulator.Log(this); incomplete_message_ = NULL; stack_trace_nesting_level_ = 0; - if (preallocated_message_space_ == NULL) { - // Remove the HeapStringAllocator created above. - delete allocator; - } } else if (stack_trace_nesting_level_ == 1) { stack_trace_nesting_level_++; OS::PrintError( @@ -1724,8 +1529,6 @@ Isolate::Isolate() entry_stack_(NULL), stack_trace_nesting_level_(0), incomplete_message_(NULL), - preallocated_memory_thread_(NULL), - preallocated_message_space_(NULL), bootstrapper_(NULL), runtime_profiler_(NULL), compilation_cache_(NULL), @@ -1747,9 +1550,6 @@ Isolate::Isolate() handle_scope_implementer_(NULL), unicode_cache_(NULL), runtime_zone_(this), - in_use_list_(0), - free_list_(0), - preallocated_storage_preallocated_(false), inner_pointer_to_code_cache_(NULL), write_iterator_(NULL), global_handles_(NULL), @@ -1902,11 +1702,6 @@ void Isolate::Deinit() { builtins_.TearDown(); bootstrapper_->TearDown(); - // Remove the external reference to the preallocated stack memory. - delete preallocated_message_space_; - preallocated_message_space_ = NULL; - PreallocatedMemoryThreadStop(); - if (runtime_profiler_ != NULL) { runtime_profiler_->TearDown(); delete runtime_profiler_; @@ -2248,17 +2043,6 @@ bool Isolate::Init(Deserializer* des) { } } - // Only preallocate on the first initialization. - if (FLAG_preallocate_message_memory && preallocated_message_space_ == NULL) { - // Start the thread which will set aside some memory. - PreallocatedMemoryThreadStart(); - preallocated_message_space_ = - new NoAllocationStringAllocator( - preallocated_memory_thread_->data(), - preallocated_memory_thread_->length()); - PreallocatedStorageInit(preallocated_memory_thread_->length() / 4); - } - if (FLAG_preemption) { v8::Locker locker(reinterpret_cast(this)); v8::Locker::StartPreemption(reinterpret_cast(this), 100); diff --git a/src/isolate.h b/src/isolate.h index 1d45de97b8..3c55883a86 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -76,7 +76,6 @@ class HTracer; class InlineRuntimeFunctionsTable; class NoAllocationStringAllocator; class InnerPointerToCodeCache; -class PreallocatedMemoryThread; class RandomNumberGenerator; class RegExpStack; class SaveContext; @@ -331,7 +330,7 @@ class ThreadLocalTop BASE_EMBEDDED { V(uint32_t, private_random_seed, 2) \ ISOLATE_INIT_DEBUG_ARRAY_LIST(V) -typedef List DebugObjectCache; +typedef List DebugObjectCache; #define ISOLATE_INIT_LIST(V) \ /* SerializerDeserializer state. */ \ @@ -978,10 +977,6 @@ class Isolate { return &interp_canonicalize_mapping_; } - void* PreallocatedStorageNew(size_t size); - void PreallocatedStorageDelete(void* p); - void PreallocatedStorageInit(size_t size); - inline bool IsCodePreAgingActive(); #ifdef ENABLE_DEBUGGER_SUPPORT @@ -1242,8 +1237,6 @@ class Isolate { // at the same time, this should be prevented using external locking. void Exit(); - void PreallocatedMemoryThreadStart(); - void PreallocatedMemoryThreadStop(); void InitializeThreadLocal(); void PrintStackTrace(FILE* out, ThreadLocalTop* thread); @@ -1266,10 +1259,7 @@ class Isolate { EntryStackItem* entry_stack_; int stack_trace_nesting_level_; StringStream* incomplete_message_; - // The preallocated memory thread singleton. - PreallocatedMemoryThread* preallocated_memory_thread_; Address isolate_addresses_[kIsolateAddressCount + 1]; // NOLINT - NoAllocationStringAllocator* preallocated_message_space_; Bootstrapper* bootstrapper_; RuntimeProfiler* runtime_profiler_; CompilationCache* compilation_cache_; @@ -1296,9 +1286,6 @@ class Isolate { HandleScopeImplementer* handle_scope_implementer_; UnicodeCache* unicode_cache_; Zone runtime_zone_; - PreallocatedStorage in_use_list_; - PreallocatedStorage free_list_; - bool preallocated_storage_preallocated_; InnerPointerToCodeCache* inner_pointer_to_code_cache_; ConsStringIteratorOp* write_iterator_; GlobalHandles* global_handles_; diff --git a/src/scopeinfo.cc b/src/scopeinfo.cc index 04c0044d9d..03e69bf384 100644 --- a/src/scopeinfo.cc +++ b/src/scopeinfo.cc @@ -32,8 +32,6 @@ #include "scopeinfo.h" #include "scopes.h" -#include "allocation-inl.h" - namespace v8 { namespace internal { diff --git a/src/scopes.cc b/src/scopes.cc index 137ab68b2c..fefc696d1a 100644 --- a/src/scopes.cc +++ b/src/scopes.cc @@ -35,8 +35,6 @@ #include "messages.h" #include "scopeinfo.h" -#include "allocation-inl.h" - namespace v8 { namespace internal { diff --git a/src/string-stream.cc b/src/string-stream.cc index 45b675fa8b..e2d15f5405 100644 --- a/src/string-stream.cc +++ b/src/string-stream.cc @@ -30,8 +30,6 @@ #include "factory.h" #include "string-stream.h" -#include "allocation-inl.h" - namespace v8 { namespace internal { @@ -299,8 +297,7 @@ Handle StringStream::ToString(Isolate* isolate) { void StringStream::ClearMentionedObjectCache(Isolate* isolate) { isolate->set_string_stream_current_security_token(NULL); if (isolate->string_stream_debug_object_cache() == NULL) { - isolate->set_string_stream_debug_object_cache( - new List(0)); + isolate->set_string_stream_debug_object_cache(new DebugObjectCache(0)); } isolate->string_stream_debug_object_cache()->Clear(); } diff --git a/test/mjsunit/regexp-multiline-stack-trace.js b/test/mjsunit/regexp-multiline-stack-trace.js deleted file mode 100644 index fc248ef6a2..0000000000 --- a/test/mjsunit/regexp-multiline-stack-trace.js +++ /dev/null @@ -1,116 +0,0 @@ -// Copyright 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. - -// The flags below are to test the trace-calls functionality and the -// preallocated meessage memory. -// Flags: --trace-calls --preallocate-message-memory - -/** - * @fileoverview Check that various regexp constructs work as intended. - * Particularly those regexps that use ^ and $. - */ - -assertTrue(/^bar/.test("bar")); -assertTrue(/^bar/.test("bar\nfoo")); -assertFalse(/^bar/.test("foo\nbar")); -assertTrue(/^bar/m.test("bar")); -assertTrue(/^bar/m.test("bar\nfoo")); -assertTrue(/^bar/m.test("foo\nbar")); - -assertTrue(/bar$/.test("bar")); -assertFalse(/bar$/.test("bar\nfoo")); -assertTrue(/bar$/.test("foo\nbar")); -assertTrue(/bar$/m.test("bar")); -assertTrue(/bar$/m.test("bar\nfoo")); -assertTrue(/bar$/m.test("foo\nbar")); - -assertFalse(/^bxr/.test("bar")); -assertFalse(/^bxr/.test("bar\nfoo")); -assertFalse(/^bxr/m.test("bar")); -assertFalse(/^bxr/m.test("bar\nfoo")); -assertFalse(/^bxr/m.test("foo\nbar")); - -assertFalse(/bxr$/.test("bar")); -assertFalse(/bxr$/.test("foo\nbar")); -assertFalse(/bxr$/m.test("bar")); -assertFalse(/bxr$/m.test("bar\nfoo")); -assertFalse(/bxr$/m.test("foo\nbar")); - - -assertTrue(/^.*$/.test("")); -assertTrue(/^.*$/.test("foo")); -assertFalse(/^.*$/.test("\n")); -assertTrue(/^.*$/m.test("\n")); - -assertTrue(/^[\s]*$/.test(" ")); -assertTrue(/^[\s]*$/.test("\n")); - -assertTrue(/^[^]*$/.test("")); -assertTrue(/^[^]*$/.test("foo")); -assertTrue(/^[^]*$/.test("\n")); - -assertTrue(/^([()\s]|.)*$/.test("()\n()")); -assertTrue(/^([()\n]|.)*$/.test("()\n()")); -assertFalse(/^([()]|.)*$/.test("()\n()")); -assertTrue(/^([()]|.)*$/m.test("()\n()")); -assertTrue(/^([()]|.)*$/m.test("()\n")); -assertTrue(/^[()]*$/m.test("()\n.")); - -assertTrue(/^[\].]*$/.test("...]...")); - - -function check_case(lc, uc) { - var a = new RegExp("^" + lc + "$"); - assertFalse(a.test(uc)); - a = new RegExp("^" + lc + "$", "i"); - assertTrue(a.test(uc)); - - var A = new RegExp("^" + uc + "$"); - assertFalse(A.test(lc)); - A = new RegExp("^" + uc + "$", "i"); - assertTrue(A.test(lc)); - - a = new RegExp("^[" + lc + "]$"); - assertFalse(a.test(uc)); - a = new RegExp("^[" + lc + "]$", "i"); - assertTrue(a.test(uc)); - - A = new RegExp("^[" + uc + "]$"); - assertFalse(A.test(lc)); - A = new RegExp("^[" + uc + "]$", "i"); - assertTrue(A.test(lc)); -} - - -check_case("a", "A"); -// Aring -check_case(String.fromCharCode(229), String.fromCharCode(197)); -// Russian G -check_case(String.fromCharCode(0x413), String.fromCharCode(0x433)); - - -assertThrows("a = new RegExp('[z-a]');");