From 74f190f320c8c4fc7b50b1324089f1f21943d3b7 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Wed, 5 Jun 2013 09:44:03 +0200 Subject: [PATCH 001/156] 8015972: Refactor the sending of the object count after GC event Reviewed-by: brutisso, pliden --- .../vm/gc_implementation/shared/gcTrace.cpp | 45 ++++++++++------ .../vm/gc_implementation/shared/gcTrace.hpp | 22 -------- .../gc_implementation/shared/gcTraceSend.cpp | 21 -------- .../shared/objectCountEventSender.cpp | 54 +++++++++++++++++++ .../shared/objectCountEventSender.hpp} | 20 ++++--- .../src/share/vm/memory/heapInspection.hpp | 7 ++- 6 files changed, 102 insertions(+), 67 deletions(-) create mode 100644 hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp rename hotspot/src/share/vm/{memory/klassInfoClosure.hpp => gc_implementation/shared/objectCountEventSender.hpp} (70%) diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp index 6c53670425b..d3a886d988b 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp @@ -23,10 +23,11 @@ */ #include "precompiled.hpp" +#include "gc_implementation/shared/copyFailedInfo.hpp" #include "gc_implementation/shared/gcHeapSummary.hpp" #include "gc_implementation/shared/gcTimer.hpp" #include "gc_implementation/shared/gcTrace.hpp" -#include "gc_implementation/shared/copyFailedInfo.hpp" +#include "gc_implementation/shared/objectCountEventSender.hpp" #include "memory/heapInspection.hpp" #include "memory/referenceProcessorStats.hpp" #include "utilities/globalDefinitions.hpp" @@ -91,26 +92,36 @@ void GCTracer::report_gc_reference_stats(const ReferenceProcessorStats& rps) con } #if INCLUDE_SERVICES -void ObjectCountEventSenderClosure::do_cinfo(KlassInfoEntry* entry) { - if (should_send_event(entry)) { - send_event(entry); +class ObjectCountEventSenderClosure : public KlassInfoClosure { + const GCId _gc_id; + const double _size_threshold_percentage; + const size_t _total_size_in_words; + + public: + ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words) : + _gc_id(gc_id), + _size_threshold_percentage(ObjectCountCutOffPercent / 100), + _total_size_in_words(total_size_in_words) + {} + + virtual void do_cinfo(KlassInfoEntry* entry) { + if (should_send_event(entry)) { + ObjectCountEventSender::send(entry, _gc_id); + } } -} -void ObjectCountEventSenderClosure::send_event(KlassInfoEntry* entry) { - _gc_tracer->send_object_count_after_gc_event(entry->klass(), entry->count(), - entry->words() * BytesPerWord); -} - -bool ObjectCountEventSenderClosure::should_send_event(KlassInfoEntry* entry) const { - double percentage_of_heap = ((double) entry->words()) / _total_size_in_words; - return percentage_of_heap > _size_threshold_percentage; -} + private: + bool should_send_event(const KlassInfoEntry* entry) const { + double percentage_of_heap = ((double) entry->words()) / _total_size_in_words; + return percentage_of_heap >= _size_threshold_percentage; + } +}; void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) { assert_set_gc_id(); + assert(is_alive_cl != NULL, "Must supply function to check liveness"); - if (should_send_object_count_after_gc_event()) { + if (ObjectCountEventSender::should_send_event()) { ResourceMark rm; KlassInfoTable cit(false); @@ -118,12 +129,12 @@ void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) { HeapInspection hi(false, false, false, NULL); hi.populate_table(&cit, is_alive_cl); - ObjectCountEventSenderClosure event_sender(this, cit.size_of_instances_in_words()); + ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words()); cit.iterate(&event_sender); } } } -#endif +#endif // INCLUDE_SERVICES void GCTracer::report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const { assert_set_gc_id(); diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp index 29ee55b685d..c157d86e7a3 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.hpp @@ -30,7 +30,6 @@ #include "gc_implementation/shared/gcWhen.hpp" #include "gc_implementation/shared/copyFailedInfo.hpp" #include "memory/allocation.hpp" -#include "memory/klassInfoClosure.hpp" #include "memory/referenceType.hpp" #if INCLUDE_ALL_GCS #include "gc_implementation/g1/g1YCTypes.hpp" @@ -113,7 +112,6 @@ class G1YoungGCInfo VALUE_OBJ_CLASS_SPEC { #endif // INCLUDE_ALL_GCS class GCTracer : public ResourceObj { - friend class ObjectCountEventSenderClosure; protected: SharedGCInfo _shared_gc_info; @@ -123,7 +121,6 @@ class GCTracer : public ResourceObj { void report_gc_heap_summary(GCWhen::Type when, const GCHeapSummary& heap_summary, const MetaspaceSummary& meta_space_summary) const; void report_gc_reference_stats(const ReferenceProcessorStats& rp) const; void report_object_count_after_gc(BoolObjectClosure* object_filter) NOT_SERVICES_RETURN; - bool has_reported_gc_start() const; protected: @@ -137,25 +134,6 @@ class GCTracer : public ResourceObj { void send_meta_space_summary_event(GCWhen::Type when, const MetaspaceSummary& meta_space_summary) const; void send_reference_stats_event(ReferenceType type, size_t count) const; void send_phase_events(TimePartitions* time_partitions) const; - void send_object_count_after_gc_event(Klass* klass, jlong count, julong total_size) const NOT_SERVICES_RETURN; - bool should_send_object_count_after_gc_event() const; -}; - -class ObjectCountEventSenderClosure : public KlassInfoClosure { - GCTracer* _gc_tracer; - const double _size_threshold_percentage; - const size_t _total_size_in_words; - public: - ObjectCountEventSenderClosure(GCTracer* gc_tracer, size_t total_size_in_words) : - _gc_tracer(gc_tracer), - _size_threshold_percentage(ObjectCountCutOffPercent / 100), - _total_size_in_words(total_size_in_words) - {} - virtual void do_cinfo(KlassInfoEntry* entry); - protected: - virtual void send_event(KlassInfoEntry* entry); - private: - bool should_send_event(KlassInfoEntry* entry) const; }; class YoungGCTracer : public GCTracer { diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp index 4af7e3c2fbf..da0c3856dd6 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTraceSend.cpp @@ -123,27 +123,6 @@ void OldGCTracer::send_concurrent_mode_failure_event() { } } -#if INCLUDE_SERVICES -void GCTracer::send_object_count_after_gc_event(Klass* klass, jlong count, julong total_size) const { - EventObjectCountAfterGC e; - if (e.should_commit()) { - e.set_gcId(_shared_gc_info.id()); - e.set_class(klass); - e.set_count(count); - e.set_totalSize(total_size); - e.commit(); - } -} -#endif - -bool GCTracer::should_send_object_count_after_gc_event() const { -#if INCLUDE_TRACE - return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId); -#else - return false; -#endif -} - #if INCLUDE_ALL_GCS void G1NewTracer::send_g1_young_gc_event() { EventGCG1GarbageCollection e(UNTIMED); diff --git a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp new file mode 100644 index 00000000000..2cdb9451167 --- /dev/null +++ b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + + +#include "precompiled.hpp" +#include "gc_implementation/shared/objectCountEventSender.hpp" +#include "memory/heapInspection.hpp" +#include "trace/tracing.hpp" +#include "utilities/globalDefinitions.hpp" + +#if INCLUDE_SERVICES + +void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id) { + assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), + "Only call this method if the event is enabled"); + + EventObjectCountAfterGC event; + event.set_gcId(gc_id); + event.set_class(entry->klass()); + event.set_count(entry->count()); + event.set_totalSize(entry->words() * BytesPerWord); + event.commit(); +} + +bool ObjectCountEventSender::should_send_event() { +#if INCLUDE_TRACE + return Tracing::is_event_enabled(EventObjectCountAfterGC::eventId); +#else + return false; +#endif // INCLUDE_TRACE +} + +#endif // INCLUDE_SERVICES diff --git a/hotspot/src/share/vm/memory/klassInfoClosure.hpp b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp similarity index 70% rename from hotspot/src/share/vm/memory/klassInfoClosure.hpp rename to hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp index b945a19e038..f51aa6aa0e4 100644 --- a/hotspot/src/share/vm/memory/klassInfoClosure.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp @@ -22,15 +22,23 @@ * */ -#ifndef SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP -#define SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP +#ifndef SHARE_VM_OBJECT_COUNT_EVENT_SENDER_HPP +#define SHARE_VM_OBJECT_COUNT_EVENT_SENDER_HPP + +#include "gc_implementation/shared/gcTrace.hpp" +#include "memory/allocation.hpp" +#include "utilities/macros.hpp" + +#if INCLUDE_SERVICES class KlassInfoEntry; -class KlassInfoClosure : public StackObj { +class ObjectCountEventSender : public AllStatic { public: - // Called for each KlassInfoEntry. - virtual void do_cinfo(KlassInfoEntry* cie) = 0; + static void send(const KlassInfoEntry* entry, GCId gc_id); + static bool should_send_event(); }; -#endif // SHARE_VM_MEMORY_KLASSINFOCLOSURE_HPP +#endif // INCLUDE_SERVICES + +#endif // SHARE_VM_OBJECT_COUNT_EVENT_SENDER diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp index c286e48658f..09558b0a2a9 100644 --- a/hotspot/src/share/vm/memory/heapInspection.hpp +++ b/hotspot/src/share/vm/memory/heapInspection.hpp @@ -26,7 +26,6 @@ #define SHARE_VM_MEMORY_HEAPINSPECTION_HPP #include "memory/allocation.inline.hpp" -#include "memory/klassInfoClosure.hpp" #include "oops/oop.inline.hpp" #include "oops/annotations.hpp" #include "utilities/macros.hpp" @@ -204,6 +203,12 @@ class KlassInfoEntry: public CHeapObj { const char* name() const; }; +class KlassInfoClosure : public StackObj { + public: + // Called for each KlassInfoEntry. + virtual void do_cinfo(KlassInfoEntry* cie) = 0; +}; + class KlassInfoBucket: public CHeapObj { private: KlassInfoEntry* _list; From c716fa083cd1226d7a41f2acb656923b440d338c Mon Sep 17 00:00:00 2001 From: Frederic Parain Date: Wed, 10 Jul 2013 15:49:15 +0000 Subject: [PATCH 002/156] 7143807: ResourceMark nesting problem in stringStream Reviewed-by: kvn, dcubed --- hotspot/src/share/vm/memory/resourceArea.hpp | 27 +++++++++++++++++++- hotspot/src/share/vm/runtime/thread.cpp | 1 + hotspot/src/share/vm/runtime/thread.hpp | 6 +++++ hotspot/src/share/vm/utilities/ostream.cpp | 3 +++ hotspot/src/share/vm/utilities/ostream.hpp | 3 +++ 5 files changed, 39 insertions(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/memory/resourceArea.hpp b/hotspot/src/share/vm/memory/resourceArea.hpp index 0699334a5e6..1357081fd67 100644 --- a/hotspot/src/share/vm/memory/resourceArea.hpp +++ b/hotspot/src/share/vm/memory/resourceArea.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -83,6 +83,10 @@ protected: Chunk *_chunk; // saved arena chunk char *_hwm, *_max; size_t _size_in_bytes; +#ifdef ASSERT + Thread* _thread; + ResourceMark* _previous_resource_mark; +#endif //ASSERT void initialize(Thread *thread) { _area = thread->resource_area(); @@ -92,6 +96,11 @@ protected: _size_in_bytes = _area->size_in_bytes(); debug_only(_area->_nesting++;) assert( _area->_nesting > 0, "must stack allocate RMs" ); +#ifdef ASSERT + _thread = thread; + _previous_resource_mark = thread->current_resource_mark(); + thread->set_current_resource_mark(this); +#endif // ASSERT } public: @@ -111,6 +120,17 @@ protected: _size_in_bytes = r->_size_in_bytes; debug_only(_area->_nesting++;) assert( _area->_nesting > 0, "must stack allocate RMs" ); +#ifdef ASSERT + Thread* thread = ThreadLocalStorage::thread(); + if (thread != NULL) { + _thread = thread; + _previous_resource_mark = thread->current_resource_mark(); + thread->set_current_resource_mark(this); + } else { + _thread = NULL; + _previous_resource_mark = NULL; + } +#endif // ASSERT } void reset_to_mark() { @@ -137,6 +157,11 @@ protected: assert( _area->_nesting > 0, "must stack allocate RMs" ); debug_only(_area->_nesting--;) reset_to_mark(); +#ifdef ASSERT + if (_thread != NULL) { + _thread->set_current_resource_mark(_previous_resource_mark); + } +#endif // ASSERT } diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index ef862012fcc..a491c4d26b8 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -218,6 +218,7 @@ Thread::Thread() { // allocated data structures set_osthread(NULL); set_resource_area(new (mtThread)ResourceArea()); + DEBUG_ONLY(_current_resource_mark = NULL;) set_handle_area(new (mtThread) HandleArea(NULL)); set_metadata_handles(new (ResourceObj::C_HEAP, mtClass) GrowableArray(30, true)); set_active_handles(NULL); diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 8b8e6dd4e62..13950ec169a 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -86,6 +86,8 @@ class GCTaskQueue; class ThreadClosure; class IdealGraphPrinter; +DEBUG_ONLY(class ResourceMark;) + class WorkerThread; // Class hierarchy @@ -531,6 +533,8 @@ public: // Thread local resource area for temporary allocation within the VM ResourceArea* _resource_area; + DEBUG_ONLY(ResourceMark* _current_resource_mark;) + // Thread local handle area for allocation of handles within the VM HandleArea* _handle_area; GrowableArray* _metadata_handles; @@ -585,6 +589,8 @@ public: // Deadlock detection bool allow_allocation() { return _allow_allocation_count == 0; } + ResourceMark* current_resource_mark() { return _current_resource_mark; } + void set_current_resource_mark(ResourceMark* rm) { _current_resource_mark = rm; } #endif void check_for_valid_safepoint_state(bool potential_vm_operation) PRODUCT_RETURN; diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp index 1d066ddde4c..2f04fa0e437 100644 --- a/hotspot/src/share/vm/utilities/ostream.cpp +++ b/hotspot/src/share/vm/utilities/ostream.cpp @@ -296,6 +296,7 @@ stringStream::stringStream(size_t initial_size) : outputStream() { buffer = NEW_RESOURCE_ARRAY(char, buffer_length); buffer_pos = 0; buffer_fixed = false; + DEBUG_ONLY(rm = Thread::current()->current_resource_mark();) } // useful for output to fixed chunks of memory, such as performance counters @@ -321,6 +322,8 @@ void stringStream::write(const char* s, size_t len) { end = buffer_length * 2; } char* oldbuf = buffer; + assert(rm == NULL || Thread::current()->current_resource_mark() == rm, + "stringStream is re-allocated with a different ResourceMark"); buffer = NEW_RESOURCE_ARRAY(char, end); strncpy(buffer, oldbuf, buffer_pos); buffer_length = end; diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp index 6b154184b01..4d13847663e 100644 --- a/hotspot/src/share/vm/utilities/ostream.hpp +++ b/hotspot/src/share/vm/utilities/ostream.hpp @@ -28,6 +28,8 @@ #include "memory/allocation.hpp" #include "runtime/timer.hpp" +DEBUG_ONLY(class ResourceMark;) + // Output streams for printing // // Printing guidelines: @@ -177,6 +179,7 @@ class stringStream : public outputStream { size_t buffer_pos; size_t buffer_length; bool buffer_fixed; + DEBUG_ONLY(ResourceMark* rm;) public: stringStream(size_t initial_bufsize = 256); stringStream(char* fixed_buffer, size_t fixed_buffer_size); From 9ff3405151e8efc4195a73402fed31bfde11cee5 Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Thu, 11 Jul 2013 13:15:12 -0400 Subject: [PATCH 003/156] 8012241: NMT huge memory footprint, it usually leads to OOME Enforce memory limitation on NMT to prevent JVM OOM Reviewed-by: acorn, dcubed, minqi --- hotspot/src/share/vm/services/memTracker.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/hotspot/src/share/vm/services/memTracker.cpp b/hotspot/src/share/vm/services/memTracker.cpp index e0a1b29a8e9..f8ff72be84d 100644 --- a/hotspot/src/share/vm/services/memTracker.cpp +++ b/hotspot/src/share/vm/services/memTracker.cpp @@ -385,6 +385,7 @@ void MemTracker::enqueue_pending_recorder(MemRecorder* rec) { #define SAFE_SEQUENCE_THRESHOLD 30 #define HIGH_GENERATION_THRESHOLD 60 #define MAX_RECORDER_THREAD_RATIO 30 +#define MAX_RECORDER_PER_THREAD 100 void MemTracker::sync() { assert(_tracking_level > NMT_off, "NMT is not enabled"); @@ -437,6 +438,11 @@ void MemTracker::sync() { // means that worker thread is lagging behind in processing them. if (!AutoShutdownNMT) { _slowdown_calling_thread = (MemRecorder::_instance_count > MAX_RECORDER_THREAD_RATIO * _thread_count); + } else { + // If auto shutdown is on, enforce MAX_RECORDER_PER_THREAD threshold to prevent OOM + if (MemRecorder::_instance_count >= _thread_count * MAX_RECORDER_PER_THREAD) { + shutdown(NMT_out_of_memory); + } } // check _worker_thread with lock to avoid racing condition From 221308625da2709ecc8e85b7417277ca9882acdb Mon Sep 17 00:00:00 2001 From: Peter Allwin Date: Fri, 12 Jul 2013 18:43:27 +0200 Subject: [PATCH 004/156] 7162400: Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand Intermittent java.io.IOException: Bad file number during HotSpotVirtualMachine.executeCommand Reviewed-by: dcubed, dholmes, sspitsyn, mgerdin, ctornqvi, dsamersoff --- hotspot/src/os/bsd/vm/attachListener_bsd.cpp | 26 +++- .../src/os/linux/vm/attachListener_linux.cpp | 26 +++- .../os/solaris/vm/attachListener_solaris.cpp | 26 +++- .../os/windows/vm/attachListener_windows.cpp | 6 +- hotspot/src/share/vm/runtime/thread.cpp | 1 + .../src/share/vm/services/attachListener.hpp | 1 + .../attach/AttachWithStalePidFile.java | 139 ++++++++++++++++++ .../attach/AttachWithStalePidFileTarget.java | 27 ++++ 8 files changed, 248 insertions(+), 4 deletions(-) create mode 100644 hotspot/test/serviceability/attach/AttachWithStalePidFile.java create mode 100644 hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java diff --git a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp index ee4feb8d046..6f128f2543b 100644 --- a/hotspot/src/os/bsd/vm/attachListener_bsd.cpp +++ b/hotspot/src/os/bsd/vm/attachListener_bsd.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -437,6 +437,30 @@ AttachOperation* AttachListener::dequeue() { return op; } + +// Performs initialization at vm startup +// For BSD we remove any stale .java_pid file which could cause +// an attaching process to think we are ready to receive on the +// domain socket before we are properly initialized + +void AttachListener::vm_start() { + char fn[UNIX_PATH_MAX]; + struct stat64 st; + int ret; + + int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); + + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == 0) { + ret = ::unlink(fn); + if (ret == -1) { + debug_only(warning("failed to remove stale attach pid file at %s", fn)); + } + } +} + int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); diff --git a/hotspot/src/os/linux/vm/attachListener_linux.cpp b/hotspot/src/os/linux/vm/attachListener_linux.cpp index 035d298a36c..700a09ff0c5 100644 --- a/hotspot/src/os/linux/vm/attachListener_linux.cpp +++ b/hotspot/src/os/linux/vm/attachListener_linux.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -432,6 +432,30 @@ AttachOperation* AttachListener::dequeue() { return op; } + +// Performs initialization at vm startup +// For Linux we remove any stale .java_pid file which could cause +// an attaching process to think we are ready to receive on the +// domain socket before we are properly initialized + +void AttachListener::vm_start() { + char fn[UNIX_PATH_MAX]; + struct stat64 st; + int ret; + + int n = snprintf(fn, UNIX_PATH_MAX, "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + assert(n < (int)UNIX_PATH_MAX, "java_pid file name buffer overflow"); + + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == 0) { + ret = ::unlink(fn); + if (ret == -1) { + debug_only(warning("failed to remove stale attach pid file at %s", fn)); + } + } +} + int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); diff --git a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp index 9cc66876268..37400795e13 100644 --- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp +++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -576,6 +576,30 @@ AttachOperation* AttachListener::dequeue() { return op; } + +// Performs initialization at vm startup +// For Solaris we remove any stale .java_pid file which could cause +// an attaching process to think we are ready to receive a door_call +// before we are properly initialized + +void AttachListener::vm_start() { + char fn[PATH_MAX+1]; + struct stat64 st; + int ret; + + int n = snprintf(fn, sizeof(fn), "%s/.java_pid%d", + os::get_temp_directory(), os::current_process_id()); + assert(n < sizeof(fn), "java_pid file name buffer overflow"); + + RESTARTABLE(::stat64(fn, &st), ret); + if (ret == 0) { + ret = ::unlink(fn); + if (ret == -1) { + debug_only(warning("failed to remove stale attach pid file at %s", fn)); + } + } +} + int AttachListener::pd_init() { JavaThread* thread = JavaThread::current(); ThreadBlockInVM tbivm(thread); diff --git a/hotspot/src/os/windows/vm/attachListener_windows.cpp b/hotspot/src/os/windows/vm/attachListener_windows.cpp index 1d5857f1c2f..34a454f6363 100644 --- a/hotspot/src/os/windows/vm/attachListener_windows.cpp +++ b/hotspot/src/os/windows/vm/attachListener_windows.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -358,6 +358,10 @@ AttachOperation* AttachListener::dequeue() { return op; } +void AttachListener::vm_start() { + // nothing to do +} + int AttachListener::pd_init() { return Win32AttachListener::init(); } diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index a491c4d26b8..3325479c04f 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -3637,6 +3637,7 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Start Attach Listener if +StartAttachListener or it can't be started lazily if (!DisableAttachMechanism) { + AttachListener::vm_start(); if (StartAttachListener || AttachListener::init_at_startup()) { AttachListener::init(); } diff --git a/hotspot/src/share/vm/services/attachListener.hpp b/hotspot/src/share/vm/services/attachListener.hpp index 2e7cff39537..6995a0f23ab 100644 --- a/hotspot/src/share/vm/services/attachListener.hpp +++ b/hotspot/src/share/vm/services/attachListener.hpp @@ -50,6 +50,7 @@ struct AttachOperationFunctionInfo { class AttachListener: AllStatic { public: + static void vm_start() NOT_SERVICES_RETURN; static void init() NOT_SERVICES_RETURN; static void abort() NOT_SERVICES_RETURN; diff --git a/hotspot/test/serviceability/attach/AttachWithStalePidFile.java b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java new file mode 100644 index 00000000000..fa74379b3a7 --- /dev/null +++ b/hotspot/test/serviceability/attach/AttachWithStalePidFile.java @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 7162400 + * @key regression + * @summary Regression test for attach issue where stale pid files in /tmp lead to connection issues + * @library /testlibrary + * @compile AttachWithStalePidFileTarget.java + * @run main AttachWithStalePidFile + */ + +import com.oracle.java.testlibrary.*; +import com.sun.tools.attach.VirtualMachine; +import sun.tools.attach.HotSpotVirtualMachine; +import java.lang.reflect.Field; +import java.nio.file.*; +import java.nio.file.attribute.*; +import java.io.*; + +public class AttachWithStalePidFile { + public static void main(String... args) throws Exception { + + // this test is only valid on non-Windows platforms + if(Platform.isWindows()) { + System.out.println("This test is only valid on non-Windows platforms."); + return; + } + + // Since there might be stale pid-files owned by different + // users on the system we may need to retry the test in case we + // are unable to remove the existing file. + int retries = 5; + while(!runTest() && --retries > 0); + + if(retries == 0) { + throw new RuntimeException("Test failed after 5 retries. " + + "Remove any /tmp/.java_pid* files and retry."); + } + } + + public static boolean runTest() throws Exception { + ProcessBuilder pb = ProcessTools.createJavaProcessBuilder( + "-XX:+UnlockDiagnosticVMOptions", "-XX:+PauseAtStartup", "AttachWithStalePidFileTarget"); + Process target = pb.start(); + Path pidFile = null; + + try { + int pid = getUnixProcessId(target); + + // create the stale .java_pid file. use hard-coded /tmp path as in th VM + pidFile = createJavaPidFile(pid); + if(pidFile == null) { + return false; + } + + // wait for vm.paused file to be created and delete it once we find it. + waitForAndResumeVM(pid); + + // unfortunately there's no reliable way to know the VM is ready to receive the + // attach request so we have to do an arbitrary sleep. + Thread.sleep(5000); + + HotSpotVirtualMachine vm = (HotSpotVirtualMachine)VirtualMachine.attach(((Integer)pid).toString()); + BufferedReader remoteDataReader = new BufferedReader(new InputStreamReader(vm.remoteDataDump())); + String line = null; + while((line = remoteDataReader.readLine()) != null); + + vm.detach(); + return true; + } + finally { + target.destroy(); + target.waitFor(); + + if(pidFile != null && Files.exists(pidFile)) { + Files.delete(pidFile); + } + } + } + + private static Path createJavaPidFile(int pid) throws Exception { + Path pidFile = Paths.get("/tmp/.java_pid" + pid); + if(Files.exists(pidFile)) { + try { + Files.delete(pidFile); + } + catch(FileSystemException e) { + if(e.getReason().equals("Operation not permitted")) { + System.out.println("Unable to remove exisiting stale PID file" + pidFile); + return null; + } + throw e; + } + } + return Files.createFile(pidFile, + PosixFilePermissions.asFileAttribute(PosixFilePermissions.fromString("rw-------"))); + } + + private static void waitForAndResumeVM(int pid) throws Exception { + Path pauseFile = Paths.get("vm.paused." + pid); + int retries = 60; + while(!Files.exists(pauseFile) && --retries > 0) { + Thread.sleep(1000); + } + if(retries == 0) { + throw new RuntimeException("Timeout waiting for VM to start. " + + "vm.paused file not created within 60 seconds."); + } + Files.delete(pauseFile); + } + + private static int getUnixProcessId(Process unixProcess) throws Exception { + Field pidField = unixProcess.getClass().getDeclaredField("pid"); + pidField.setAccessible(true); + return (Integer)pidField.get(unixProcess); + } +} diff --git a/hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java b/hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java new file mode 100644 index 00000000000..bf87fb47094 --- /dev/null +++ b/hotspot/test/serviceability/attach/AttachWithStalePidFileTarget.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +public class AttachWithStalePidFileTarget { + public static void main(String... args) throws Exception { + Thread.sleep(2*60*1000); + } +} From 2d5af88356da8562aaf18d9798d71b677eecc8a9 Mon Sep 17 00:00:00 2001 From: David Simms Date: Mon, 15 Jul 2013 11:35:10 +0200 Subject: [PATCH 005/156] 8019324: assert(_f2 == 0 || _f2 == f2) failed: illegal field change Reviewed-by: dholmes, rbackman --- hotspot/src/share/vm/oops/cpCache.hpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/oops/cpCache.hpp b/hotspot/src/share/vm/oops/cpCache.hpp index 27ca7980c07..c15b4a54bd6 100644 --- a/hotspot/src/share/vm/oops/cpCache.hpp +++ b/hotspot/src/share/vm/oops/cpCache.hpp @@ -140,8 +140,15 @@ class ConstantPoolCacheEntry VALUE_OBJ_CLASS_SPEC { _f1 = f1; } void release_set_f1(Metadata* f1); - void set_f2(intx f2) { assert(_f2 == 0 || _f2 == f2, "illegal field change"); _f2 = f2; } - void set_f2_as_vfinal_method(Method* f2) { assert(_f2 == 0 || _f2 == (intptr_t) f2, "illegal field change"); assert(is_vfinal(), "flags must be set"); _f2 = (intptr_t) f2; } + void set_f2(intx f2) { + intx existing_f2 = _f2; // read once + assert(existing_f2 == 0 || existing_f2 == f2, "illegal field change"); + _f2 = f2; + } + void set_f2_as_vfinal_method(Method* f2) { + assert(is_vfinal(), "flags must be set"); + set_f2((intx)f2); + } int make_flags(TosState state, int option_bits, int field_index_or_method_params); void set_flags(intx flags) { _flags = flags; } bool init_flags_atomic(intx flags); From a47de580e713f45d5dabdb8961f7156a89cb7909 Mon Sep 17 00:00:00 2001 From: Tim Bell Date: Mon, 15 Jul 2013 23:23:15 -0400 Subject: [PATCH 006/156] 8015759: hotspot changes needed to compile with Visual Studio 2012 Reviewed-by: anthony, dholmes, dcubed --- hotspot/make/windows/makefiles/compile.make | 26 ++++++++++++++++++- hotspot/make/windows/makefiles/sanity.make | 6 ++--- hotspot/make/windows/makefiles/vm.make | 4 +++ .../windows_x86/vm/unwind_windows_x86.hpp | 12 ++++++++- 4 files changed, 43 insertions(+), 5 deletions(-) diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make index ea16fca3dde..6f8dcce3406 100644 --- a/hotspot/make/windows/makefiles/compile.make +++ b/hotspot/make/windows/makefiles/compile.make @@ -1,5 +1,5 @@ # -# Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -110,6 +110,7 @@ CXX_FLAGS=$(CXX_FLAGS) /D TARGET_COMPILER_visCPP # 1400 is for VS2005 # 1500 is for VS2008 # 1600 is for VS2010 +# 1700 is for VS2012 # Do not confuse this MSC_VER with the predefined macro _MSC_VER that the # compiler provides, when MSC_VER==1399, _MSC_VER will be 1400. # Normally they are the same, but a pre-release of the VS2005 compilers @@ -142,6 +143,9 @@ COMPILER_NAME=VS2008 !if "$(MSC_VER)" == "1600" COMPILER_NAME=VS2010 !endif +!if "$(MSC_VER)" == "1700" +COMPILER_NAME=VS2012 +!endif !endif # By default, we do not want to use the debug version of the msvcrt.dll file @@ -151,9 +155,13 @@ MS_RUNTIME_OPTION = /MD MS_RUNTIME_OPTION = /MTd /D "_DEBUG" !endif +# VS2012 and later won't work with: +# /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB +!if "$(MSC_VER)" < "1700" # Always add the _STATIC_CPPLIB flag STATIC_CPPLIB_OPTION = /D _STATIC_CPPLIB /D _DISABLE_DEPRECATE_STATIC_CPPLIB MS_RUNTIME_OPTION = $(MS_RUNTIME_OPTION) $(STATIC_CPPLIB_OPTION) +!endif CXX_FLAGS=$(CXX_FLAGS) $(MS_RUNTIME_OPTION) # How /GX option is spelled @@ -221,6 +229,22 @@ LD_FLAGS = /SAFESEH $(LD_FLAGS) !endif !endif +!if "$(COMPILER_NAME)" == "VS2012" +PRODUCT_OPT_OPTION = /O2 /Oy- +FASTDEBUG_OPT_OPTION = /O2 /Oy- +DEBUG_OPT_OPTION = /Od +GX_OPTION = /EHsc +LD_FLAGS = /manifest $(LD_FLAGS) +# Manifest Tool - used in VS2005 and later to adjust manifests stored +# as resources inside build artifacts. +!if "x$(MT)" == "x" +MT=mt.exe +!endif +!if "$(BUILDARCH)" == "i486" +LD_FLAGS = /SAFESEH $(LD_FLAGS) +!endif +!endif + # If NO_OPTIMIZATIONS is defined in the environment, turn everything off !ifdef NO_OPTIMIZATIONS PRODUCT_OPT_OPTION = $(DEBUG_OPT_OPTION) diff --git a/hotspot/make/windows/makefiles/sanity.make b/hotspot/make/windows/makefiles/sanity.make index 86c6b59aefe..b502cfaa65f 100644 --- a/hotspot/make/windows/makefiles/sanity.make +++ b/hotspot/make/windows/makefiles/sanity.make @@ -1,5 +1,5 @@ # -# Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,9 @@ all: checkCL checkLink checkCL: - @ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" if "$(MSC_VER)" NEQ "1600" \ + @ if "$(MSC_VER)" NEQ "1310" if "$(MSC_VER)" NEQ "1399" if "$(MSC_VER)" NEQ "1400" if "$(MSC_VER)" NEQ "1500" if "$(MSC_VER)" NEQ "1600" if "$(MSC_VER)" NEQ "1700" \ echo *** WARNING *** unrecognized cl.exe version $(MSC_VER) ($(RAW_MSC_VER)). Use FORCE_MSC_VER to override automatic detection. checkLink: - @ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" \ + @ if "$(LD_VER)" NEQ "710" if "$(LD_VER)" NEQ "800" if "$(LD_VER)" NEQ "900" if "$(LD_VER)" NEQ "1000" if "$(LD_VER)" NEQ "1100" \ echo *** WARNING *** unrecognized link.exe version $(LD_VER) ($(RAW_LD_VER)). Use FORCE_LD_VER to override automatic detection. diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make index 54ba1eef5b8..b76443774de 100644 --- a/hotspot/make/windows/makefiles/vm.make +++ b/hotspot/make/windows/makefiles/vm.make @@ -132,6 +132,10 @@ CXX_DONT_USE_PCH=/D DONT_USE_PRECOMPILED_HEADER !if "$(USE_PRECOMPILED_HEADER)" != "0" CXX_USE_PCH=/Fp"vm.pch" /Yu"precompiled.hpp" +!if "$(COMPILER_NAME)" == "VS2012" +# VS2012 requires this object file to be listed: +LD_FLAGS=$(LD_FLAGS) _build_pch_file.obj +!endif !else CXX_USE_PCH=$(CXX_DONT_USE_PCH) !endif diff --git a/hotspot/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp index 00b9b6c305d..f4ea83debf4 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp +++ b/hotspot/src/os_cpu/windows_x86/vm/unwind_windows_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,15 @@ #ifdef AMD64 typedef unsigned char UBYTE; +#if _MSC_VER < 1700 + +/* Not needed for VS2012 compiler, comes from winnt.h. */ #define UNW_FLAG_EHANDLER 0x01 #define UNW_FLAG_UHANDLER 0x02 #define UNW_FLAG_CHAININFO 0x04 +#endif + // This structure is used to define an UNWIND_INFO that // only has an ExceptionHandler. There are no UnwindCodes // declared. @@ -59,6 +64,9 @@ typedef struct _RUNTIME_FUNCTION { } RUNTIME_FUNCTION, *PRUNTIME_FUNCTION; */ +#if _MSC_VER < 1700 + +/* Not needed for VS2012 compiler, comes from winnt.h. */ typedef struct _DISPATCHER_CONTEXT { ULONG64 ControlPc; ULONG64 ImageBase; @@ -71,6 +79,8 @@ typedef struct _DISPATCHER_CONTEXT { PVOID HandlerData; } DISPATCHER_CONTEXT, *PDISPATCHER_CONTEXT; +#endif + #if _MSC_VER < 1500 /* Not needed for VS2008 compiler, comes from winnt.h. */ From 1859ec255680a080dbecf7ef3c88767f7e5e71bf Mon Sep 17 00:00:00 2001 From: David Simms Date: Tue, 16 Jul 2013 07:33:29 +0200 Subject: [PATCH 007/156] 6671508: JNI GetPrimitiveArrayCritical should not be callable on object arrays Checked JNI now reports error for Get/ReleasePrimitiveArrayCritical on object arrays Reviewed-by: dholmes, acorn --- hotspot/src/share/vm/prims/jniCheck.cpp | 70 +++++++++++++++++-------- 1 file changed, 47 insertions(+), 23 deletions(-) diff --git a/hotspot/src/share/vm/prims/jniCheck.cpp b/hotspot/src/share/vm/prims/jniCheck.cpp index ad738b85ef9..baf770830e7 100644 --- a/hotspot/src/share/vm/prims/jniCheck.cpp +++ b/hotspot/src/share/vm/prims/jniCheck.cpp @@ -126,6 +126,7 @@ static const char * fatal_wrong_class_or_method = "Wrong object class or methodI static const char * fatal_non_weak_method = "non-weak methodID passed to JNI call"; static const char * fatal_unknown_array_object = "Unknown array object passed to JNI array operations"; static const char * fatal_object_array_expected = "Object array expected but not received for JNI array operation"; +static const char * fatal_prim_type_array_expected = "Primitive type array expected but not received for JNI array operation"; static const char * fatal_non_array = "Non-array passed to JNI array operations"; static const char * fatal_element_type_mismatch = "Array element type mismatch in JNI"; static const char * fatal_should_be_static = "Non-static field ID passed to JNI"; @@ -278,30 +279,53 @@ checkString(JavaThread* thr, jstring js) ReportJNIFatalError(thr, fatal_non_string); } -static inline void -checkArray(JavaThread* thr, jarray jArray, int elementType) +static inline arrayOop +check_is_array(JavaThread* thr, jarray jArray) { ASSERT_OOPS_ALLOWED; arrayOop aOop; aOop = (arrayOop)jniCheck::validate_object(thr, jArray); - if (aOop == NULL || !aOop->is_array()) + if (aOop == NULL || !aOop->is_array()) { ReportJNIFatalError(thr, fatal_non_array); + } + return aOop; +} - if (elementType != -1) { - if (aOop->is_typeArray()) { - BasicType array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); - if (array_type != elementType) - ReportJNIFatalError(thr, fatal_element_type_mismatch); - } else if (aOop->is_objArray()) { - if ( T_OBJECT != elementType) - ReportJNIFatalError(thr, fatal_object_array_expected); - } else { - ReportJNIFatalError(thr, fatal_unknown_array_object); - } +static inline arrayOop +check_is_primitive_array(JavaThread* thr, jarray jArray) { + arrayOop aOop = check_is_array(thr, jArray); + + if (!aOop->is_typeArray()) { + ReportJNIFatalError(thr, fatal_prim_type_array_expected); + } + return aOop; +} + +static inline void +check_primitive_array_type(JavaThread* thr, jarray jArray, BasicType elementType) +{ + BasicType array_type; + arrayOop aOop; + + aOop = check_is_primitive_array(thr, jArray); + array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); + if (array_type != elementType) { + ReportJNIFatalError(thr, fatal_element_type_mismatch); } } +static inline void +check_is_obj_array(JavaThread* thr, jarray jArray) { + BasicType array_type; + arrayOop aOop; + + aOop = check_is_array(thr, jArray); + array_type = TypeArrayKlass::cast(aOop->klass())->element_type(); + if (array_type != T_OBJECT) { + ReportJNIFatalError(thr, fatal_object_array_expected); + } +} oop jniCheck::validate_handle(JavaThread* thr, jobject obj) { if (JNIHandles::is_frame_handle(thr, obj) || @@ -1417,7 +1441,7 @@ JNI_ENTRY_CHECKED(jsize, jarray array)) functionEnter(thr); IN_VM( - checkArray(thr, array, -1); + check_is_array(thr, array); ) jsize result = UNCHECKED()->GetArrayLength(env,array); functionExit(env); @@ -1441,7 +1465,7 @@ JNI_ENTRY_CHECKED(jobject, jsize index)) functionEnter(thr); IN_VM( - checkArray(thr, array, T_OBJECT); + check_is_obj_array(thr, array); ) jobject result = UNCHECKED()->GetObjectArrayElement(env,array,index); functionExit(env); @@ -1455,7 +1479,7 @@ JNI_ENTRY_CHECKED(void, jobject val)) functionEnter(thr); IN_VM( - checkArray(thr, array, T_OBJECT); + check_is_obj_array(thr, array); ) UNCHECKED()->SetObjectArrayElement(env,array,index,val); functionExit(env); @@ -1487,7 +1511,7 @@ JNI_ENTRY_CHECKED(ElementType *, \ jboolean *isCopy)) \ functionEnter(thr); \ IN_VM( \ - checkArray(thr, array, ElementTag); \ + check_primitive_array_type(thr, array, ElementTag); \ ) \ ElementType *result = UNCHECKED()->Get##Result##ArrayElements(env, \ array, \ @@ -1513,7 +1537,7 @@ JNI_ENTRY_CHECKED(void, \ jint mode)) \ functionEnterExceptionAllowed(thr); \ IN_VM( \ - checkArray(thr, array, ElementTag); \ + check_primitive_array_type(thr, array, ElementTag); \ ASSERT_OOPS_ALLOWED; \ typeArrayOop a = typeArrayOop(JNIHandles::resolve_non_null(array)); \ /* cannot check validity of copy, unless every request is logged by @@ -1543,7 +1567,7 @@ JNI_ENTRY_CHECKED(void, \ ElementType *buf)) \ functionEnter(thr); \ IN_VM( \ - checkArray(thr, array, ElementTag); \ + check_primitive_array_type(thr, array, ElementTag); \ ) \ UNCHECKED()->Get##Result##ArrayRegion(env,array,start,len,buf); \ functionExit(env); \ @@ -1567,7 +1591,7 @@ JNI_ENTRY_CHECKED(void, \ const ElementType *buf)) \ functionEnter(thr); \ IN_VM( \ - checkArray(thr, array, ElementTag); \ + check_primitive_array_type(thr, array, ElementTag); \ ) \ UNCHECKED()->Set##Result##ArrayRegion(env,array,start,len,buf); \ functionExit(env); \ @@ -1669,7 +1693,7 @@ JNI_ENTRY_CHECKED(void *, jboolean *isCopy)) functionEnterCritical(thr); IN_VM( - checkArray(thr, array, -1); + check_is_primitive_array(thr, array); ) void *result = UNCHECKED()->GetPrimitiveArrayCritical(env, array, isCopy); functionExit(env); @@ -1683,7 +1707,7 @@ JNI_ENTRY_CHECKED(void, jint mode)) functionEnterCriticalExceptionAllowed(thr); IN_VM( - checkArray(thr, array, -1); + check_is_primitive_array(thr, array); ) /* The Hotspot JNI code does not use the parameters, so just check the * array parameter as a minor sanity check From 9a67229e2fe35136ddca7db0b78156d5a39e9902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rickard=20B=C3=A4ckman?= Date: Wed, 12 Jun 2013 11:17:39 +0200 Subject: [PATCH 008/156] 8016131: nsk/sysdict/vm/stress/chain tests crash the VM in 'entry_frame_is_first()' Reviewed-by: jrose, kvn, mgronlun --- hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp | 4 ++-- hotspot/src/cpu/x86/vm/frame_x86.inline.hpp | 5 ++--- hotspot/src/share/vm/prims/forte.cpp | 9 +++++++-- hotspot/src/share/vm/runtime/frame.cpp | 13 ++++++++++++- hotspot/src/share/vm/runtime/frame.hpp | 4 +++- hotspot/src/share/vm/runtime/javaCalls.hpp | 2 ++ hotspot/src/share/vm/runtime/thread.cpp | 8 ++++++++ hotspot/src/share/vm/runtime/thread.hpp | 3 +++ 8 files changed, 39 insertions(+), 9 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp index 71655f6d760..774e8f3f0f5 100644 --- a/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp +++ b/hotspot/src/cpu/sparc/vm/frame_sparc.inline.hpp @@ -240,10 +240,10 @@ inline ConstantPoolCache** frame::interpreter_frame_cache_addr() const { #endif // CC_INTERP -inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { +inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { // note: adjust this code if the link argument in StubGenerator::call_stub() changes! const Argument link = Argument(0, false); - return (JavaCallWrapper*)sp()[link.as_in().as_register()->sp_offset_in_saved_window()]; + return (JavaCallWrapper**)&sp()[link.as_in().as_register()->sp_offset_in_saved_window()]; } diff --git a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp index b15b00be586..3c5c225c399 100644 --- a/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp +++ b/hotspot/src/cpu/x86/vm/frame_x86.inline.hpp @@ -272,11 +272,10 @@ inline jint frame::interpreter_frame_expression_stack_direction() { return -1; } // Entry frames -inline JavaCallWrapper* frame::entry_frame_call_wrapper() const { - return (JavaCallWrapper*)at(entry_frame_call_wrapper_offset); +inline JavaCallWrapper** frame::entry_frame_call_wrapper_addr() const { + return (JavaCallWrapper**)addr_at(entry_frame_call_wrapper_offset); } - // Compiled frames inline int frame::local_offset_for_compiler(int local_index, int nof_args, int max_nof_locals, int max_nof_monitors) { diff --git a/hotspot/src/share/vm/prims/forte.cpp b/hotspot/src/share/vm/prims/forte.cpp index 43da7494417..4b1fbebc137 100644 --- a/hotspot/src/share/vm/prims/forte.cpp +++ b/hotspot/src/share/vm/prims/forte.cpp @@ -31,6 +31,7 @@ #include "oops/oop.inline.hpp" #include "oops/oop.inline2.hpp" #include "prims/forte.hpp" +#include "runtime/javaCalls.hpp" #include "runtime/thread.hpp" #include "runtime/vframe.hpp" #include "runtime/vframeArray.hpp" @@ -308,10 +309,14 @@ static bool find_initial_Java_frame(JavaThread* thread, for (loop_count = 0; loop_count < loop_max; loop_count++) { - if (candidate.is_first_frame()) { + if (candidate.is_entry_frame()) { + // jcw is NULL if the java call wrapper couldn't be found + JavaCallWrapper *jcw = candidate.entry_frame_call_wrapper_if_safe(thread); // If initial frame is frame from StubGenerator and there is no // previous anchor, there are no java frames associated with a method - return false; + if (jcw == NULL || jcw->is_first_frame()) { + return false; + } } if (candidate.is_interpreted_frame()) { diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp index 92af92e92eb..9ea7421cf06 100644 --- a/hotspot/src/share/vm/runtime/frame.cpp +++ b/hotspot/src/share/vm/runtime/frame.cpp @@ -221,9 +221,20 @@ bool frame::is_first_java_frame() const { bool frame::entry_frame_is_first() const { - return entry_frame_call_wrapper()->anchor()->last_Java_sp() == NULL; + return entry_frame_call_wrapper()->is_first_frame(); } +JavaCallWrapper* frame::entry_frame_call_wrapper_if_safe(JavaThread* thread) const { + JavaCallWrapper** jcw = entry_frame_call_wrapper_addr(); + address addr = (address) jcw; + + // addr must be within the usable part of the stack + if (thread->is_in_usable_stack(addr)) { + return *jcw; + } + + return NULL; +} bool frame::should_be_deoptimized() const { if (_deopt_state == is_deoptimized || diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp index 87581ab8da1..096b467b5f8 100644 --- a/hotspot/src/share/vm/runtime/frame.hpp +++ b/hotspot/src/share/vm/runtime/frame.hpp @@ -353,7 +353,9 @@ class frame VALUE_OBJ_CLASS_SPEC { public: // Entry frames - JavaCallWrapper* entry_frame_call_wrapper() const; + JavaCallWrapper* entry_frame_call_wrapper() const { return *entry_frame_call_wrapper_addr(); } + JavaCallWrapper* entry_frame_call_wrapper_if_safe(JavaThread* thread) const; + JavaCallWrapper** entry_frame_call_wrapper_addr() const; intptr_t* entry_frame_argument_at(int offset) const; // tells whether there is another chunk of Delta stack above diff --git a/hotspot/src/share/vm/runtime/javaCalls.hpp b/hotspot/src/share/vm/runtime/javaCalls.hpp index 08881fcbb88..7c397d9f4a9 100644 --- a/hotspot/src/share/vm/runtime/javaCalls.hpp +++ b/hotspot/src/share/vm/runtime/javaCalls.hpp @@ -80,6 +80,8 @@ class JavaCallWrapper: StackObj { oop receiver() { return _receiver; } void oops_do(OopClosure* f); + bool is_first_frame() const { return _anchor.last_Java_sp() == NULL; } + }; diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp index 3325479c04f..3cb61cfdb2d 100644 --- a/hotspot/src/share/vm/runtime/thread.cpp +++ b/hotspot/src/share/vm/runtime/thread.cpp @@ -954,6 +954,14 @@ bool Thread::is_in_stack(address adr) const { } +bool Thread::is_in_usable_stack(address adr) const { + size_t stack_guard_size = os::uses_stack_guard_pages() ? (StackYellowPages + StackRedPages) * os::vm_page_size() : 0; + size_t usable_stack_size = _stack_size - stack_guard_size; + + return ((adr < stack_base()) && (adr >= stack_base() - usable_stack_size)); +} + + // We had to move these methods here, because vm threads get into ObjectSynchronizer::enter // However, there is a note in JavaThread::is_lock_owned() about the VM threads not being // used for compilation in the future. If that change is made, the need for these methods diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp index 13950ec169a..cbb68ca6714 100644 --- a/hotspot/src/share/vm/runtime/thread.hpp +++ b/hotspot/src/share/vm/runtime/thread.hpp @@ -521,6 +521,9 @@ public: // Check if address is in the stack of the thread (not just for locks). // Warning: the method can only be used on the running thread bool is_in_stack(address adr) const; + // Check if address is in the usable part of the stack (excludes protected + // guard pages) + bool is_in_usable_stack(address adr) const; // Sets this thread as starting thread. Returns failure if thread // creation fails due to lack of memory, too many threads etc. From f9c8b8769ab189628b2ce0b15b16f7107910bdcc Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Wed, 12 Jun 2013 15:50:14 +0200 Subject: [PATCH 009/156] 8016170: GC id variable in gcTrace.cpp should use typedef GCId Reviewed-by: johnc, jwilhelm, jmasa --- hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp index d3a886d988b..41f6c7b347c 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp @@ -39,7 +39,7 @@ #define assert_unset_gc_id() assert(_shared_gc_info.id() == SharedGCInfo::UNSET_GCID, "GC already started?") #define assert_set_gc_id() assert(_shared_gc_info.id() != SharedGCInfo::UNSET_GCID, "GC not started?") -static jlong GCTracer_next_gc_id = 0; +static GCId GCTracer_next_gc_id = 0; static GCId create_new_gc_id() { return GCTracer_next_gc_id++; } From 2eab1610b07aef6aea0f5a619873e0b0ffc39774 Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Wed, 12 Jun 2013 15:21:41 +0200 Subject: [PATCH 010/156] 8015683: object_count_after_gc should have the same timestamp for all events Reviewed-by: mgerdin, stefank --- .../share/vm/gc_implementation/shared/gcTrace.cpp | 12 ++++++++---- .../shared/objectCountEventSender.cpp | 5 +++-- .../shared/objectCountEventSender.hpp | 2 +- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp index 41f6c7b347c..555e2ed9cf8 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/gcTrace.cpp @@ -30,6 +30,7 @@ #include "gc_implementation/shared/objectCountEventSender.hpp" #include "memory/heapInspection.hpp" #include "memory/referenceProcessorStats.hpp" +#include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" #if INCLUDE_ALL_GCS @@ -96,17 +97,19 @@ class ObjectCountEventSenderClosure : public KlassInfoClosure { const GCId _gc_id; const double _size_threshold_percentage; const size_t _total_size_in_words; + const jlong _timestamp; public: - ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words) : + ObjectCountEventSenderClosure(GCId gc_id, size_t total_size_in_words, jlong timestamp) : _gc_id(gc_id), _size_threshold_percentage(ObjectCountCutOffPercent / 100), - _total_size_in_words(total_size_in_words) + _total_size_in_words(total_size_in_words), + _timestamp(timestamp) {} virtual void do_cinfo(KlassInfoEntry* entry) { if (should_send_event(entry)) { - ObjectCountEventSender::send(entry, _gc_id); + ObjectCountEventSender::send(entry, _gc_id, _timestamp); } } @@ -129,7 +132,8 @@ void GCTracer::report_object_count_after_gc(BoolObjectClosure* is_alive_cl) { HeapInspection hi(false, false, false, NULL); hi.populate_table(&cit, is_alive_cl); - ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words()); + jlong timestamp = os::elapsed_counter(); + ObjectCountEventSenderClosure event_sender(_shared_gc_info.id(), cit.size_of_instances_in_words(), timestamp); cit.iterate(&event_sender); } } diff --git a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp index 2cdb9451167..cf95bdd505e 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp +++ b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.cpp @@ -31,15 +31,16 @@ #if INCLUDE_SERVICES -void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id) { +void ObjectCountEventSender::send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp) { assert(Tracing::is_event_enabled(EventObjectCountAfterGC::eventId), "Only call this method if the event is enabled"); - EventObjectCountAfterGC event; + EventObjectCountAfterGC event(UNTIMED); event.set_gcId(gc_id); event.set_class(entry->klass()); event.set_count(entry->count()); event.set_totalSize(entry->words() * BytesPerWord); + event.set_endtime(timestamp); event.commit(); } diff --git a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp index f51aa6aa0e4..b83e1fa737d 100644 --- a/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp +++ b/hotspot/src/share/vm/gc_implementation/shared/objectCountEventSender.hpp @@ -35,7 +35,7 @@ class KlassInfoEntry; class ObjectCountEventSender : public AllStatic { public: - static void send(const KlassInfoEntry* entry, GCId gc_id); + static void send(const KlassInfoEntry* entry, GCId gc_id, jlong timestamp); static bool should_send_event(); }; From ef69ce852cb50f7844a2bc0b18d696665146d866 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Thu, 20 Jun 2013 15:02:05 +0200 Subject: [PATCH 011/156] 8016697: Use stubs to implement safefetch Implement Safefetch as stub routines. This reduces compiler and os dependencies. Reviewed-by: twisti, kvn --- .../src/cpu/sparc/vm/stubGenerator_sparc.cpp | 53 +++++++++++++++++++ .../src/cpu/x86/vm/stubGenerator_x86_32.cpp | 41 ++++++++++++++ .../src/cpu/x86/vm/stubGenerator_x86_64.cpp | 46 ++++++++++++++++ hotspot/src/os/windows/vm/os_windows.cpp | 5 ++ hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s | 18 ------- hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s | 22 -------- hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp | 19 ++----- .../src/os_cpu/linux_sparc/vm/linux_sparc.s | 36 ------------- .../os_cpu/linux_sparc/vm/os_linux_sparc.cpp | 13 +---- .../src/os_cpu/linux_x86/vm/linux_x86_32.s | 18 ------- .../src/os_cpu/linux_x86/vm/linux_x86_64.s | 22 -------- .../src/os_cpu/linux_x86/vm/os_linux_x86.cpp | 19 ++----- .../solaris_sparc/vm/os_solaris_sparc.cpp | 20 ++----- .../os_cpu/solaris_sparc/vm/solaris_sparc.s | 41 -------------- .../os_cpu/solaris_x86/vm/os_solaris_x86.cpp | 20 ++----- .../os_cpu/solaris_x86/vm/solaris_x86_32.s | 14 ----- .../os_cpu/solaris_x86/vm/solaris_x86_64.s | 52 ++++++------------ .../os_cpu/windows_x86/vm/os_windows_x86.cpp | 18 ------- hotspot/src/share/vm/runtime/os.hpp | 4 +- hotspot/src/share/vm/runtime/stubRoutines.cpp | 7 +++ hotspot/src/share/vm/runtime/stubRoutines.hpp | 47 ++++++++++++++++ 21 files changed, 231 insertions(+), 304 deletions(-) diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp index 494c1bc405a..214940cdbfb 100644 --- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp +++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp @@ -410,6 +410,51 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Safefetch stubs. + void generate_safefetch(const char* name, int size, address* entry, + address* fault_pc, address* continuation_pc) { + // safefetch signatures: + // int SafeFetch32(int* adr, int errValue); + // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); + // + // arguments: + // o0 = adr + // o1 = errValue + // + // result: + // o0 = *adr or errValue + + StubCodeMark mark(this, "StubRoutines", name); + + // Entry point, pc or function descriptor. + __ align(CodeEntryAlignment); + *entry = __ pc(); + + __ mov(O0, G1); // g1 = o0 + __ mov(O1, O0); // o0 = o1 + // Load *adr into c_rarg1, may fault. + *fault_pc = __ pc(); + switch (size) { + case 4: + // int32_t + __ ldsw(G1, 0, O0); // o0 = [g1] + break; + case 8: + // int64_t + __ ldx(G1, 0, O0); // o0 = [g1] + break; + default: + ShouldNotReachHere(); + } + + // return errValue or *adr + *continuation_pc = __ pc(); + // By convention with the trap handler we ensure there is a non-CTI + // instruction in the trap shadow. + __ nop(); + __ retl(); + __ delayed()->nop(); + } //------------------------------------------------------------------------------------------------------------------------ // Continuation point for throwing of implicit exceptions that are not handled in @@ -3315,6 +3360,14 @@ class StubGenerator: public StubCodeGenerator { // Don't initialize the platform math functions since sparc // doesn't have intrinsics for these operations. + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp index 82e4183ef47..a8abfea6bcd 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp @@ -2766,6 +2766,39 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Safefetch stubs. + void generate_safefetch(const char* name, int size, address* entry, + address* fault_pc, address* continuation_pc) { + // safefetch signatures: + // int SafeFetch32(int* adr, int errValue); + // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); + + StubCodeMark mark(this, "StubRoutines", name); + + // Entry point, pc or function descriptor. + *entry = __ pc(); + + __ movl(rax, Address(rsp, 0x8)); + __ movl(rcx, Address(rsp, 0x4)); + // Load *adr into eax, may fault. + *fault_pc = __ pc(); + switch (size) { + case 4: + // int32_t + __ movl(rax, Address(rcx, 0)); + break; + case 8: + // int64_t + Unimplemented(); + break; + default: + ShouldNotReachHere(); + } + + // Return errValue or *adr. + *continuation_pc = __ pc(); + __ ret(0); + } public: // Information about frame layout at time of blocking runtime call. @@ -2978,6 +3011,14 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt(); } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + StubRoutines::_safefetchN_entry = StubRoutines::_safefetch32_entry; + StubRoutines::_safefetchN_fault_pc = StubRoutines::_safefetch32_fault_pc; + StubRoutines::_safefetchN_continuation_pc = StubRoutines::_safefetch32_continuation_pc; } diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp index 2d94642f828..c80f1807936 100644 --- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp +++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp @@ -3357,7 +3357,45 @@ class StubGenerator: public StubCodeGenerator { return start; } + // Safefetch stubs. + void generate_safefetch(const char* name, int size, address* entry, + address* fault_pc, address* continuation_pc) { + // safefetch signatures: + // int SafeFetch32(int* adr, int errValue); + // intptr_t SafeFetchN (intptr_t* adr, intptr_t errValue); + // + // arguments: + // c_rarg0 = adr + // c_rarg1 = errValue + // + // result: + // PPC_RET = *adr or errValue + StubCodeMark mark(this, "StubRoutines", name); + + // Entry point, pc or function descriptor. + *entry = __ pc(); + + // Load *adr into c_rarg1, may fault. + *fault_pc = __ pc(); + switch (size) { + case 4: + // int32_t + __ movl(c_rarg1, Address(c_rarg0, 0)); + break; + case 8: + // int64_t + __ movq(c_rarg1, Address(c_rarg0, 0)); + break; + default: + ShouldNotReachHere(); + } + + // return errValue or *adr + *continuation_pc = __ pc(); + __ movq(rax, c_rarg1); + __ ret(0); + } // This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time // to hide instruction latency @@ -3833,6 +3871,14 @@ class StubGenerator: public StubCodeGenerator { StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt(); StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel(); } + + // Safefetch stubs. + generate_safefetch("SafeFetch32", sizeof(int), &StubRoutines::_safefetch32_entry, + &StubRoutines::_safefetch32_fault_pc, + &StubRoutines::_safefetch32_continuation_pc); + generate_safefetch("SafeFetchN", sizeof(intptr_t), &StubRoutines::_safefetchN_entry, + &StubRoutines::_safefetchN_fault_pc, + &StubRoutines::_safefetchN_continuation_pc); } public: diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp index cc43934d423..d875e875e45 100644 --- a/hotspot/src/os/windows/vm/os_windows.cpp +++ b/hotspot/src/os/windows/vm/os_windows.cpp @@ -2317,6 +2317,11 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { #endif Thread* t = ThreadLocalStorage::get_thread_slow(); // slow & steady + // Handle SafeFetch32 and SafeFetchN exceptions. + if (StubRoutines::is_safefetch_fault(pc)) { + return Handle_Exception(exceptionInfo, StubRoutines::continuation_for_safefetch_fault(pc)); + } + #ifndef _WIN64 // Execution protection violation - win32 running on AMD64 only // Handled first to avoid misdiagnosis as a "normal" access violation; diff --git a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s index 402c8da11a6..3275996f0c7 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s +++ b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_32.s @@ -63,24 +63,6 @@ SYMBOL(fixcw): popl %eax ret - .globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume) - .globl SYMBOL(SafeFetchN) - ## TODO: avoid exposing Fetch32PFI and Fetch32Resume. - ## Instead, the signal handler would call a new SafeFetchTriage(FaultingEIP) - ## routine to vet the address. If the address is the faulting LD then - ## SafeFetchTriage() would return the resume-at EIP, otherwise null. - ELF_TYPE(SafeFetch32,@function) - .p2align 4,,15 -SYMBOL(SafeFetch32): -SYMBOL(SafeFetchN): - movl 0x8(%esp), %eax - movl 0x4(%esp), %ecx -SYMBOL(Fetch32PFI): - movl (%ecx), %eax -SYMBOL(Fetch32Resume): - ret - - .globl SYMBOL(SpinPause) ELF_TYPE(SpinPause,@function) .p2align 4,,15 diff --git a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s index 65d2db45f70..2f70fce77a3 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s +++ b/hotspot/src/os_cpu/bsd_x86/vm/bsd_x86_64.s @@ -46,28 +46,6 @@ .text - .globl SYMBOL(SafeFetch32), SYMBOL(Fetch32PFI), SYMBOL(Fetch32Resume) - .p2align 4,,15 - ELF_TYPE(SafeFetch32,@function) - // Prototype: int SafeFetch32 (int * Adr, int ErrValue) -SYMBOL(SafeFetch32): - movl %esi, %eax -SYMBOL(Fetch32PFI): - movl (%rdi), %eax -SYMBOL(Fetch32Resume): - ret - - .globl SYMBOL(SafeFetchN), SYMBOL(FetchNPFI), SYMBOL(FetchNResume) - .p2align 4,,15 - ELF_TYPE(SafeFetchN,@function) - // Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue) -SYMBOL(SafeFetchN): - movq %rsi, %rax -SYMBOL(FetchNPFI): - movq (%rdi), %rax -SYMBOL(FetchNResume): - ret - .globl SYMBOL(SpinPause) .p2align 4,,15 ELF_TYPE(SpinPause,@function) diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp index aa36599ea2a..55ef24b899d 100644 --- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp +++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp @@ -385,13 +385,6 @@ enum { trap_page_fault = 0xE }; -extern "C" void Fetch32PFI () ; -extern "C" void Fetch32Resume () ; -#ifdef AMD64 -extern "C" void FetchNPFI () ; -extern "C" void FetchNResume () ; -#endif // AMD64 - extern "C" JNIEXPORT int JVM_handle_bsd_signal(int sig, siginfo_t* info, @@ -454,16 +447,10 @@ JVM_handle_bsd_signal(int sig, if (info != NULL && uc != NULL && thread != NULL) { pc = (address) os::Bsd::ucontext_get_pc(uc); - if (pc == (address) Fetch32PFI) { - uc->context_pc = intptr_t(Fetch32Resume) ; - return 1 ; + if (StubRoutines::is_safefetch_fault(pc)) { + uc->context_pc = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc)); + return 1; } -#ifdef AMD64 - if (pc == (address) FetchNPFI) { - uc->context_pc = intptr_t (FetchNResume) ; - return 1 ; - } -#endif // AMD64 // Handle ALL stack overflow variations here if (sig == SIGSEGV || sig == SIGBUS) { diff --git a/hotspot/src/os_cpu/linux_sparc/vm/linux_sparc.s b/hotspot/src/os_cpu/linux_sparc/vm/linux_sparc.s index e04f871f49e..d7c2ce87414 100644 --- a/hotspot/src/os_cpu/linux_sparc/vm/linux_sparc.s +++ b/hotspot/src/os_cpu/linux_sparc/vm/linux_sparc.s @@ -21,42 +21,6 @@ # questions. # - # Prototype: int SafeFetch32 (int * adr, int ErrValue) - # The "ld" at Fetch32 is potentially faulting instruction. - # If the instruction traps the trap handler will arrange - # for control to resume at Fetch32Resume. - # By convention with the trap handler we ensure there is a non-CTI - # instruction in the trap shadow. - - - .globl SafeFetch32, Fetch32PFI, Fetch32Resume - .globl SafeFetchN - .align 32 - .type SafeFetch32,@function -SafeFetch32: - mov %o0, %g1 - mov %o1, %o0 -Fetch32PFI: - # <-- Potentially faulting instruction - ld [%g1], %o0 -Fetch32Resume: - nop - retl - nop - - .globl SafeFetchN, FetchNPFI, FetchNResume - .type SafeFetchN,@function - .align 32 -SafeFetchN: - mov %o0, %g1 - mov %o1, %o0 -FetchNPFI: - ldn [%g1], %o0 -FetchNResume: - nop - retl - nop - # Possibilities: # -- membar # -- CAS (SP + BIAS, G0, G0) diff --git a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp index d97f0e041bf..2367e2a0604 100644 --- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp +++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp @@ -366,18 +366,9 @@ intptr_t* os::Linux::ucontext_get_fp(ucontext_t *uc) { // Utility functions -extern "C" void Fetch32PFI(); -extern "C" void Fetch32Resume(); -extern "C" void FetchNPFI(); -extern "C" void FetchNResume(); - inline static bool checkPrefetch(sigcontext* uc, address pc) { - if (pc == (address) Fetch32PFI) { - set_cont_address(uc, address(Fetch32Resume)); - return true; - } - if (pc == (address) FetchNPFI) { - set_cont_address(uc, address(FetchNResume)); + if (StubRoutines::is_safefetch_fault(pc)) { + set_cont_address(uc, address(StubRoutines::continuation_for_safefetch_fault(pc))); return true; } return false; diff --git a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.s b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.s index d29d31df464..7936cbf52bd 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.s +++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_32.s @@ -42,24 +42,6 @@ .text - .globl SafeFetch32, Fetch32PFI, Fetch32Resume - .globl SafeFetchN - ## TODO: avoid exposing Fetch32PFI and Fetch32Resume. - ## Instead, the signal handler would call a new SafeFetchTriage(FaultingEIP) - ## routine to vet the address. If the address is the faulting LD then - ## SafeFetchTriage() would return the resume-at EIP, otherwise null. - .type SafeFetch32,@function - .p2align 4,,15 -SafeFetch32: -SafeFetchN: - movl 0x8(%esp), %eax - movl 0x4(%esp), %ecx -Fetch32PFI: - movl (%ecx), %eax -Fetch32Resume: - ret - - .globl SpinPause .type SpinPause,@function .p2align 4,,15 diff --git a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.s b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.s index 8be68610e80..fb688e7a7b6 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.s +++ b/hotspot/src/os_cpu/linux_x86/vm/linux_x86_64.s @@ -38,28 +38,6 @@ .text - .globl SafeFetch32, Fetch32PFI, Fetch32Resume - .align 16 - .type SafeFetch32,@function - // Prototype: int SafeFetch32 (int * Adr, int ErrValue) -SafeFetch32: - movl %esi, %eax -Fetch32PFI: - movl (%rdi), %eax -Fetch32Resume: - ret - - .globl SafeFetchN, FetchNPFI, FetchNResume - .align 16 - .type SafeFetchN,@function - // Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue) -SafeFetchN: - movq %rsi, %rax -FetchNPFI: - movq (%rdi), %rax -FetchNResume: - ret - .globl SpinPause .align 16 .type SpinPause,@function diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp index 4fc3b76d228..f7a57773fe9 100644 --- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp +++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp @@ -209,13 +209,6 @@ enum { trap_page_fault = 0xE }; -extern "C" void Fetch32PFI () ; -extern "C" void Fetch32Resume () ; -#ifdef AMD64 -extern "C" void FetchNPFI () ; -extern "C" void FetchNResume () ; -#endif // AMD64 - extern "C" JNIEXPORT int JVM_handle_linux_signal(int sig, siginfo_t* info, @@ -278,16 +271,10 @@ JVM_handle_linux_signal(int sig, if (info != NULL && uc != NULL && thread != NULL) { pc = (address) os::Linux::ucontext_get_pc(uc); - if (pc == (address) Fetch32PFI) { - uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ; - return 1 ; + if (StubRoutines::is_safefetch_fault(pc)) { + uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc)); + return 1; } -#ifdef AMD64 - if (pc == (address) FetchNPFI) { - uc->uc_mcontext.gregs[REG_PC] = intptr_t (FetchNResume) ; - return 1 ; - } -#endif // AMD64 #ifndef AMD64 // Halt if SI_KERNEL before more crashes get misdiagnosed as Java bugs diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp index 939def32fec..4257f4e460b 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp +++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp @@ -303,11 +303,6 @@ bool os::is_allocatable(size_t bytes) { #endif } -extern "C" void Fetch32PFI () ; -extern "C" void Fetch32Resume () ; -extern "C" void FetchNPFI () ; -extern "C" void FetchNResume () ; - extern "C" JNIEXPORT int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { @@ -379,17 +374,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, npc = (address) uc->uc_mcontext.gregs[REG_nPC]; // SafeFetch() support - // Implemented with either a fixed set of addresses such - // as Fetch32*, or with Thread._OnTrap. - if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(Fetch32PFI)) { - uc->uc_mcontext.gregs [REG_PC] = intptr_t(Fetch32Resume) ; - uc->uc_mcontext.gregs [REG_nPC] = intptr_t(Fetch32Resume) + 4 ; - return true ; - } - if (uc->uc_mcontext.gregs[REG_PC] == intptr_t(FetchNPFI)) { - uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ; - uc->uc_mcontext.gregs [REG_nPC] = intptr_t(FetchNResume) + 4 ; - return true ; + if (StubRoutines::is_safefetch_fault(pc)) { + uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc)); + uc->uc_mcontext.gregs[REG_nPC] = uc->uc_mcontext.gregs[REG_PC] + 4; + return 1; } // Handle ALL stack overflow variations here diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.s b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.s index aa526a09d08..39aaa77f664 100644 --- a/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.s +++ b/hotspot/src/os_cpu/solaris_sparc/vm/solaris_sparc.s @@ -21,47 +21,6 @@ !! questions. !! - !! Prototype: int SafeFetch32 (int * adr, int ErrValue) - !! The "ld" at Fetch32 is potentially faulting instruction. - !! If the instruction traps the trap handler will arrange - !! for control to resume at Fetch32Resume. - !! By convention with the trap handler we ensure there is a non-CTI - !! instruction in the trap shadow. - !! - !! The reader might be tempted to move this service to .il. - !! Don't. Sun's CC back-end reads and optimize code emitted - !! by the .il "call", in some cases optimizing the code, completely eliding it, - !! or by moving the code from the "call site". - - !! ASM better know we may use G6 for our own purposes - .register %g6, #ignore - - .globl SafeFetch32 - .align 32 - .global Fetch32PFI, Fetch32Resume -SafeFetch32: - mov %o0, %g1 - mov %o1, %o0 -Fetch32PFI: - ld [%g1], %o0 !! <-- Potentially faulting instruction -Fetch32Resume: - nop - retl - nop - - .globl SafeFetchN - .align 32 - .globl FetchNPFI, FetchNResume -SafeFetchN: - mov %o0, %g1 - mov %o1, %o0 -FetchNPFI: - ldn [%g1], %o0 -FetchNResume: - nop - retl - nop - !! Possibilities: !! -- membar !! -- CAS (SP + BIAS, G0, G0) diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp index 4ed094db734..f479ffbb193 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp +++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp @@ -352,13 +352,6 @@ bool os::is_allocatable(size_t bytes) { } -extern "C" void Fetch32PFI () ; -extern "C" void Fetch32Resume () ; -#ifdef AMD64 -extern "C" void FetchNPFI () ; -extern "C" void FetchNResume () ; -#endif // AMD64 - extern "C" JNIEXPORT int JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, int abort_if_unrecognized) { @@ -436,17 +429,10 @@ JVM_handle_solaris_signal(int sig, siginfo_t* info, void* ucVoid, // factor me: getPCfromContext pc = (address) uc->uc_mcontext.gregs[REG_PC]; - // SafeFetch32() support - if (pc == (address) Fetch32PFI) { - uc->uc_mcontext.gregs[REG_PC] = intptr_t(Fetch32Resume) ; - return true ; + if (StubRoutines::is_safefetch_fault(pc)) { + uc->uc_mcontext.gregs[REG_PC] = intptr_t(StubRoutines::continuation_for_safefetch_fault(pc)); + return true; } -#ifdef AMD64 - if (pc == (address) FetchNPFI) { - uc->uc_mcontext.gregs [REG_PC] = intptr_t(FetchNResume) ; - return true ; - } -#endif // AMD64 // Handle ALL stack overflow variations here if (sig == SIGSEGV && info->si_code == SEGV_ACCERR) { diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.s b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.s index 1fac3b25f11..19e790b6013 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.s +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.s @@ -54,20 +54,6 @@ fixcw: popl %eax ret - .align 16 - .globl SafeFetch32 - .globl SafeFetchN - .globl Fetch32PFI, Fetch32Resume -SafeFetch32: -SafeFetchN: - movl 0x8(%esp), %eax - movl 0x4(%esp), %ecx -Fetch32PFI: - movl (%ecx), %eax -Fetch32Resume: - ret - - .align 16 .globl SpinPause SpinPause: diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.s b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.s index 95050af24f0..487b569e58c 100644 --- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.s +++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.s @@ -21,54 +21,34 @@ / questions. / - .globl fs_load - .globl fs_thread + .globl fs_load + .globl fs_thread // NOTE WELL! The _Copy functions are called directly - // from server-compiler-generated code via CallLeafNoFP, - // which means that they *must* either not use floating - // point or use it in the same manner as does the server - // compiler. + // from server-compiler-generated code via CallLeafNoFP, + // which means that they *must* either not use floating + // point or use it in the same manner as does the server + // compiler. .globl _Copy_arrayof_conjoint_bytes .globl _Copy_conjoint_jshorts_atomic - .globl _Copy_arrayof_conjoint_jshorts + .globl _Copy_arrayof_conjoint_jshorts .globl _Copy_conjoint_jints_atomic .globl _Copy_arrayof_conjoint_jints - .globl _Copy_conjoint_jlongs_atomic + .globl _Copy_conjoint_jlongs_atomic .globl _Copy_arrayof_conjoint_jlongs - .section .text,"ax" + .section .text,"ax" / Fast thread accessors, used by threadLS_solaris_amd64.cpp - .align 16 + .align 16 fs_load: - movq %fs:(%rdi),%rax - ret - - .align 16 -fs_thread: - movq %fs:0x0,%rax - ret - - .globl SafeFetch32, Fetch32PFI, Fetch32Resume - .align 16 - // Prototype: int SafeFetch32 (int * Adr, int ErrValue) -SafeFetch32: - movl %esi, %eax -Fetch32PFI: - movl (%rdi), %eax -Fetch32Resume: + movq %fs:(%rdi),%rax ret - .globl SafeFetchN, FetchNPFI, FetchNResume - .align 16 - // Prototype: intptr_t SafeFetchN (intptr_t * Adr, intptr_t ErrValue) -SafeFetchN: - movq %rsi, %rax -FetchNPFI: - movq (%rdi), %rax -FetchNResume: + .align 16 +fs_thread: + movq %fs:0x0,%rax ret .globl SpinPause @@ -78,7 +58,7 @@ SpinPause: nop movq $1, %rax ret - + / Support for void Copy::arrayof_conjoint_bytes(void* from, / void* to, @@ -340,7 +320,7 @@ aci_CopyLeft: addq $4,%rdx jg 1b ret - + / Support for void Copy::arrayof_conjoint_jlongs(jlong* from, / jlong* to, / size_t count) diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp index 1ef29f99a55..a0f2a7680be 100644 --- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp +++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp @@ -518,24 +518,6 @@ void os::print_register_info(outputStream *st, void *context) { st->cr(); } -extern "C" int SafeFetch32 (int * adr, int Err) { - int rv = Err ; - _try { - rv = *((volatile int *) adr) ; - } __except(EXCEPTION_EXECUTE_HANDLER) { - } - return rv ; -} - -extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t Err) { - intptr_t rv = Err ; - _try { - rv = *((volatile intptr_t *) adr) ; - } __except(EXCEPTION_EXECUTE_HANDLER) { - } - return rv ; -} - extern "C" int SpinPause () { #ifdef AMD64 return 0 ; diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp index e1866919df4..aeade2bbd11 100644 --- a/hotspot/src/share/vm/runtime/os.hpp +++ b/hotspot/src/share/vm/runtime/os.hpp @@ -915,8 +915,6 @@ class os: AllStatic { // of the global SpinPause() with C linkage. // It'd also be eligible for inlining on many platforms. -extern "C" int SpinPause () ; -extern "C" int SafeFetch32 (int * adr, int errValue) ; -extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) ; +extern "C" int SpinPause(); #endif // SHARE_VM_RUNTIME_OS_HPP diff --git a/hotspot/src/share/vm/runtime/stubRoutines.cpp b/hotspot/src/share/vm/runtime/stubRoutines.cpp index a1179acd543..ff12ca65163 100644 --- a/hotspot/src/share/vm/runtime/stubRoutines.cpp +++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp @@ -136,6 +136,13 @@ double (* StubRoutines::_intrinsic_sin )(double) = NULL; double (* StubRoutines::_intrinsic_cos )(double) = NULL; double (* StubRoutines::_intrinsic_tan )(double) = NULL; +address StubRoutines::_safefetch32_entry = NULL; +address StubRoutines::_safefetch32_fault_pc = NULL; +address StubRoutines::_safefetch32_continuation_pc = NULL; +address StubRoutines::_safefetchN_entry = NULL; +address StubRoutines::_safefetchN_fault_pc = NULL; +address StubRoutines::_safefetchN_continuation_pc = NULL; + // Initialization // // Note: to break cycle with universe initialization, stubs are generated in two phases. diff --git a/hotspot/src/share/vm/runtime/stubRoutines.hpp b/hotspot/src/share/vm/runtime/stubRoutines.hpp index b8d61ea0cbf..e43e3ab0e7b 100644 --- a/hotspot/src/share/vm/runtime/stubRoutines.hpp +++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp @@ -221,6 +221,14 @@ class StubRoutines: AllStatic { static double (*_intrinsic_cos)(double); static double (*_intrinsic_tan)(double); + // Safefetch stubs. + static address _safefetch32_entry; + static address _safefetch32_fault_pc; + static address _safefetch32_continuation_pc; + static address _safefetchN_entry; + static address _safefetchN_fault_pc; + static address _safefetchN_continuation_pc; + public: // Initialization/Testing static void initialize1(); // must happen before universe::genesis @@ -381,6 +389,34 @@ class StubRoutines: AllStatic { return _intrinsic_tan(d); } + // + // Safefetch stub support + // + + typedef int (*SafeFetch32Stub)(int* adr, int errValue); + typedef intptr_t (*SafeFetchNStub) (intptr_t* adr, intptr_t errValue); + + static SafeFetch32Stub SafeFetch32_stub() { return CAST_TO_FN_PTR(SafeFetch32Stub, _safefetch32_entry); } + static SafeFetchNStub SafeFetchN_stub() { return CAST_TO_FN_PTR(SafeFetchNStub, _safefetchN_entry); } + + static bool is_safefetch_fault(address pc) { + return pc != NULL && + (pc == _safefetch32_fault_pc || + pc == _safefetchN_fault_pc); + } + + static address continuation_for_safefetch_fault(address pc) { + assert(_safefetch32_continuation_pc != NULL && + _safefetchN_continuation_pc != NULL, + "not initialized"); + + if (pc == _safefetch32_fault_pc) return _safefetch32_continuation_pc; + if (pc == _safefetchN_fault_pc) return _safefetchN_continuation_pc; + + ShouldNotReachHere(); + return NULL; + } + // // Default versions of the above arraycopy functions for platforms which do // not have specialized versions @@ -400,4 +436,15 @@ class StubRoutines: AllStatic { static void arrayof_oop_copy_uninit(HeapWord* src, HeapWord* dest, size_t count); }; +// Safefetch allows to load a value from a location that's not known +// to be valid. If the load causes a fault, the error value is returned. +inline int SafeFetch32(int* adr, int errValue) { + assert(StubRoutines::SafeFetch32_stub(), "stub not yet generated"); + return StubRoutines::SafeFetch32_stub()(adr, errValue); +} +inline intptr_t SafeFetchN(intptr_t* adr, intptr_t errValue) { + assert(StubRoutines::SafeFetchN_stub(), "stub not yet generated"); + return StubRoutines::SafeFetchN_stub()(adr, errValue); +} + #endif // SHARE_VM_RUNTIME_STUBROUTINES_HPP From 22b6014ba6b633b5bf588b6fc7c352181a0a24cb Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 3 Jul 2013 00:08:45 +0530 Subject: [PATCH 012/156] 8019629: void operator should always evaluate to undefined Reviewed-by: jlaskey --- .../jdk/nashorn/internal/codegen/Attr.java | 5 +-- .../internal/codegen/CodeGenerator.java | 8 ++++ .../jdk/nashorn/internal/ir/RuntimeNode.java | 2 - .../internal/runtime/ScriptRuntime.java | 17 -------- nashorn/test/script/basic/JDK-8019629.js | 42 +++++++++++++++++++ 5 files changed, 51 insertions(+), 23 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8019629.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 3a442a7d8f2..d4b3405fb26 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -1009,10 +1009,7 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveVOID(final UnaryNode unaryNode) { - final RuntimeNode runtimeNode = (RuntimeNode)new RuntimeNode(unaryNode, Request.VOID).accept(this); - assert runtimeNode.getSymbol().getSymbolType().isObject(); - end(unaryNode); - return runtimeNode; + return end(ensureSymbol(Type.OBJECT, unaryNode)); } /** diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 414d1bb8bc3..d0bf7cd563e 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -2335,6 +2335,14 @@ final class CodeGenerator extends NodeOperatorVisitor { NEW, /** Typeof operator */ TYPEOF, - /** void type */ - VOID, /** Reference error type */ REFERENCE_ERROR, /** Delete operator */ diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index 15c915cf0e4..1144c57d76d 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -600,23 +600,6 @@ public final class ScriptRuntime { return JSType.of(obj).typeName(); } - /** - * ECMA 11.4.2 - void operator - * - * @param object object to evaluate - * - * @return Undefined as the object type - */ - public static Object VOID(final Object object) { - if (object instanceof Number) { - if (Double.isNaN(((Number)object).doubleValue())) { - return Double.NaN; - } - } - - return UNDEFINED; - } - /** * Throw ReferenceError when LHS of assignment or increment/decrement * operator is not an assignable node (say a literal) diff --git a/nashorn/test/script/basic/JDK-8019629.js b/nashorn/test/script/basic/JDK-8019629.js new file mode 100644 index 00000000000..2d284d05150 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019629.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019629: void operator should always evaluate to undefined + * + * @test + * @run + */ + +function check(str) { + var val = eval(str); + if (typeof val !== 'undefined') { + print("FAILED: " + str + " does not evaluate to 'undefined'"); + } +} + +check("void +this"); +check("void +(void 0)"); +check("(function f(){return void +(void 0)})()"); +check("void function() {}"); + From 5ccee02c35e76a4aeb54e3155d1b8c188a6bf609 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 3 Jul 2013 13:13:17 +0530 Subject: [PATCH 013/156] 8019783: typeof does not work properly for java methods and foreign objects Reviewed-by: hannesw --- .../jdk/nashorn/internal/runtime/JSType.java | 10 ++++ .../internal/runtime/ScriptRuntime.java | 2 + nashorn/test/script/basic/JDK-8019783.js | 55 +++++++++++++++++++ .../test/script/basic/JDK-8019783.js.EXPECTED | 9 +++ .../test/script/basic/NASHORN-759.js.EXPECTED | 2 +- 5 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8019783.js create mode 100644 nashorn/test/script/basic/JDK-8019783.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java index 9507f0d3205..4d1d825c852 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java @@ -29,7 +29,9 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import java.util.Locale; +import jdk.internal.dynalink.beans.BeansLinker; import jdk.internal.dynalink.beans.StaticClass; +import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.codegen.CompilerConstants.Call; import jdk.nashorn.internal.parser.Lexer; @@ -151,6 +153,14 @@ public enum JSType { return JSType.FUNCTION; } + if (BeansLinker.isDynamicMethod(obj)) { + return JSType.FUNCTION; + } + + if (obj instanceof ScriptObjectMirror) { + return ((ScriptObjectMirror)obj).isFunction()? JSType.FUNCTION : JSType.OBJECT; + } + return JSType.OBJECT; } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java index 1144c57d76d..f0b68c52ddf 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java @@ -592,6 +592,8 @@ public final class ScriptRuntime { throw typeError("cant.get.property", safeToString(property), "null"); } else if (JSType.isPrimitive(obj)) { obj = ((ScriptObject)JSType.toScriptObject(obj)).get(property); + } else if (obj instanceof ScriptObjectMirror) { + obj = ((ScriptObjectMirror)obj).getMember(property.toString()); } else { obj = UNDEFINED; } diff --git a/nashorn/test/script/basic/JDK-8019783.js b/nashorn/test/script/basic/JDK-8019783.js new file mode 100644 index 00000000000..27afcaf2a85 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019783.js @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019783: typeof does not work properly for java methods and foreign objects + * + * @test + * @run + */ + +function printTypeof(str) { + print("typeof(" + str + ") = " + eval('typeof ' + str)); +} + +// Java methods +printTypeof("java.lang.System.exit"); +printTypeof("java.lang.System['exit']"); +// full signature +printTypeof("java.lang.System['exit(int)']"); +// overloaded method +printTypeof("java.security.AccessController.doPrivileged"); +printTypeof("java.security.AccessController['doPrivileged']"); + +// foreign objects +var global = loadWithNewGlobal({ name: "t", script: "this" }); +print("typeof(global.Object) = " + (typeof global.Object)); +print("typeof(new global.Object()) = " + (typeof (new global.Object()))); + +// foreign engine objects +var m = new javax.script.ScriptEngineManager(); +var engine = m.getEngineByName("nashorn"); +var engineGlobal = engine.eval("this"); + +print("typeof(engineGlobal.Object) = " + (typeof engineGlobal.Object)); +print("typeof(new engineGlobal.Object()) = " + (typeof (new engineGlobal.Object()))); diff --git a/nashorn/test/script/basic/JDK-8019783.js.EXPECTED b/nashorn/test/script/basic/JDK-8019783.js.EXPECTED new file mode 100644 index 00000000000..f2a5588bea6 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019783.js.EXPECTED @@ -0,0 +1,9 @@ +typeof(java.lang.System.exit) = function +typeof(java.lang.System['exit']) = function +typeof(java.lang.System['exit(int)']) = function +typeof(java.security.AccessController.doPrivileged) = function +typeof(java.security.AccessController['doPrivileged']) = function +typeof(global.Object) = function +typeof(new global.Object()) = object +typeof(engineGlobal.Object) = function +typeof(new engineGlobal.Object()) = object diff --git a/nashorn/test/script/basic/NASHORN-759.js.EXPECTED b/nashorn/test/script/basic/NASHORN-759.js.EXPECTED index ccb88e0f00e..5d0001ef327 100644 --- a/nashorn/test/script/basic/NASHORN-759.js.EXPECTED +++ b/nashorn/test/script/basic/NASHORN-759.js.EXPECTED @@ -11,7 +11,7 @@ number true object -object +function false T,h,e, ,q,u,i,c,k, ,g,r,a,y, ,n,a,s,h,o,r,n, ,j,u,m,p,s, ,o,v,e,r, ,t,h,e, ,l,a,z,y, ,z,e,b,r,a,. From 6dfb638284f1dc7d5f4e5770f592ac3a0d0a789d Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 3 Jul 2013 14:08:00 +0530 Subject: [PATCH 014/156] 8019791: ~ is a unary operator Reviewed-by: hannesw --- .../nashorn/internal/parser/TokenType.java | 2 +- nashorn/test/script/basic/JDK-8019791.js | 50 +++++++++++++++++++ .../test/script/basic/JDK-8019791.js.EXPECTED | 6 +++ 3 files changed, 57 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8019791.js create mode 100644 nashorn/test/script/basic/JDK-8019791.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/parser/TokenType.java b/nashorn/src/jdk/nashorn/internal/parser/TokenType.java index 92f3ad745be..c92b9e98284 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/TokenType.java +++ b/nashorn/src/jdk/nashorn/internal/parser/TokenType.java @@ -93,7 +93,7 @@ public enum TokenType { ASSIGN_BIT_OR (BINARY, "|=", 2, false), OR (BINARY, "||", 4, true), RBRACE (BRACKET, "}"), - BIT_NOT (BINARY, "~", 14, false), + BIT_NOT (UNARY, "~", 14, false), // ECMA 7.6.1.1 Keywords, 7.6.1.2 Future Reserved Words. // All other Java keywords are commented out. diff --git a/nashorn/test/script/basic/JDK-8019791.js b/nashorn/test/script/basic/JDK-8019791.js new file mode 100644 index 00000000000..75e92819d89 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019791.js @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019791: ~ is a unary operator + * + * @test + * @run + */ + +// Used to crash instead of SyntaxError +try { + eval('"" ~ ""'); + print("FAILED: SyntaxError expected for: \"\" ~ \"\""); +} catch (e) { + print(e.toString().replace(/\\/g, '/')); +} + +// Used to crash instead of SyntaxError +try { + eval("function() { if (1~0) return 0; return 1 }"); + print("FAILED: SyntaxError expected for: if (1~0) "); +} catch (e) { + print(e.toString().replace(/\\/g, '/')); +} + +// The following are valid, but used to crash +Function("0 \n ~ 2 \n ~ 1")(); + +Function("~ ~ 0 \n ~ ~ 1")(); diff --git a/nashorn/test/script/basic/JDK-8019791.js.EXPECTED b/nashorn/test/script/basic/JDK-8019791.js.EXPECTED new file mode 100644 index 00000000000..5aec5909ada --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019791.js.EXPECTED @@ -0,0 +1,6 @@ +SyntaxError: test/script/basic/JDK-8019791.js#33:1:3 Expected ; but found ~ +"" ~ "" + ^ +SyntaxError: test/script/basic/JDK-8019791.js#41:1:18 Expected ) but found ~ +function() { if (1~0) return 0; return 1 } + ^ From 92bcfea39aeb7cf2b8f010a99c4d20f1eeef846a Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Wed, 3 Jul 2013 12:39:28 +0200 Subject: [PATCH 015/156] 8010946: AccessControl.doPrivileged is broken when called from js script Reviewed-by: jlaskey, sundar --- nashorn/make/build.xml | 55 ++-- .../dynalink/beans/AbstractJavaLinker.java | 232 +++++++++++----- .../beans/ApplicableOverloadedMethods.java | 27 +- .../beans/CallerSensitiveDetector.java | 148 ++++++++++ .../beans/CallerSensitiveDynamicMethod.java | 158 +++++++++++ .../internal/dynalink/beans/ClassString.java | 4 +- .../dynalink/beans/DynamicMethod.java | 38 +-- .../dynalink/beans/DynamicMethodLinker.java | 13 +- .../dynalink/beans/FacetIntrospector.java | 4 - .../dynalink/beans/MaximallySpecific.java | 68 ++++- .../beans/OverloadedDynamicMethod.java | 92 +++---- .../dynalink/beans/OverloadedMethod.java | 4 +- .../dynalink/beans/SimpleDynamicMethod.java | 144 ++-------- .../dynalink/beans/SingleDynamicMethod.java | 255 ++++++++++++++++++ .../beans/StaticClassIntrospector.java | 10 +- .../dynalink/beans/StaticClassLinker.java | 24 +- .../support/AbstractCallSiteDescriptor.java | 3 +- .../jdk/internal/dynalink/support/Lookup.java | 25 +- .../internal/runtime/linker/Bootstrap.java | 16 +- .../runtime/linker/JavaAdapterFactory.java | 11 +- .../runtime/linker/LinkerCallSite.java | 7 +- .../linker/NashornCallSiteDescriptor.java | 54 ++-- nashorn/test/script/basic/JDK-8010946-2.js | 38 +++ .../script/basic/JDK-8010946-2.js.EXPECTED | 3 + .../script/basic/JDK-8010946-privileged.js | 47 ++++ nashorn/test/script/basic/JDK-8010946.js | 51 ++++ .../test/script/basic/JDK-8010946.js.EXPECTED | 5 + 27 files changed, 1133 insertions(+), 403 deletions(-) create mode 100644 nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java create mode 100644 nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java create mode 100644 nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java create mode 100644 nashorn/test/script/basic/JDK-8010946-2.js create mode 100644 nashorn/test/script/basic/JDK-8010946-2.js.EXPECTED create mode 100644 nashorn/test/script/basic/JDK-8010946-privileged.js create mode 100644 nashorn/test/script/basic/JDK-8010946.js create mode 100644 nashorn/test/script/basic/JDK-8010946.js.EXPECTED diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index 7e2d999d328..58a1d116be1 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -235,44 +235,31 @@ - + - - - - - - - +grant codeBase "file:/${basedir}/${nashorn.internal.tests.jar}" { + permission java.security.AllPermission; +}; - - - - - - - +grant codeBase "file:/${basedir}/${file.reference.testng.jar}" { + permission java.security.AllPermission; +}; - - - - - - - +grant codeBase "file:/${basedir}/test/script/trusted/*" { + permission java.security.AllPermission; +}; - - - - - - - - - - - - +grant codeBase "file:/${basedir}/test/script/basic/*" { + permission java.io.FilePermission "${basedir}/test/script/-", "read"; + permission java.io.FilePermission "$${user.dir}", "read"; + permission java.util.PropertyPermission "user.dir", "read"; + permission java.util.PropertyPermission "nashorn.test.*", "read"; +}; + +grant codeBase "file:/${basedir}/test/script/basic/JDK-8010946-privileged.js" { + permission java.util.PropertyPermission "java.security.policy", "read"; +}; + \/ /// diff --git a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java index 702c1509fd4..f541fa65d2a 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/AbstractJavaLinker.java @@ -86,7 +86,10 @@ package jdk.internal.dynalink.beans; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; import java.lang.reflect.Field; +import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.HashMap; @@ -109,10 +112,11 @@ import jdk.internal.dynalink.support.Lookup; * @author Attila Szegedi */ abstract class AbstractJavaLinker implements GuardingDynamicLinker { + final Class clazz; private final MethodHandle classGuard; private final MethodHandle assignableGuard; - private final Map propertyGetters = new HashMap<>(); + private final Map propertyGetters = new HashMap<>(); private final Map propertySetters = new HashMap<>(); private final Map methods = new HashMap<>(); @@ -129,22 +133,19 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // Add methods and properties for(Method method: introspector.getMethods()) { final String name = method.getName(); - final MethodHandle methodHandle = introspector.unreflect(method); // Add method - addMember(name, methodHandle, methods); + addMember(name, method, methods); // Add the method as a property getter and/or setter if(name.startsWith("get") && name.length() > 3 && method.getParameterTypes().length == 0) { // Property getter - setPropertyGetter(decapitalize(name.substring(3)), introspector.unreflect( - getMostGenericGetter(method)), ValidationType.INSTANCE_OF); + setPropertyGetter(method, 3); } else if(name.startsWith("is") && name.length() > 2 && method.getParameterTypes().length == 0 && method.getReturnType() == boolean.class) { // Boolean property getter - setPropertyGetter(decapitalize(name.substring(2)), introspector.unreflect( - getMostGenericGetter(method)), ValidationType.INSTANCE_OF); + setPropertyGetter(method, 2); } else if(name.startsWith("set") && name.length() > 3 && method.getParameterTypes().length == 1) { // Property setter - addMember(decapitalize(name.substring(3)), methodHandle, propertySetters); + addMember(decapitalize(name.substring(3)), method, propertySetters); } } @@ -156,7 +157,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { setPropertyGetter(name, introspector.unreflectGetter(field), ValidationType.EXACT_CLASS); } if(!(Modifier.isFinal(field.getModifiers()) || propertySetters.containsKey(name))) { - addMember(name, introspector.unreflectSetter(field), propertySetters); + addMember(name, new SimpleDynamicMethod(introspector.unreflectSetter(field), clazz, name), + propertySetters); } } @@ -192,38 +194,119 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { abstract FacetIntrospector createFacetIntrospector(); - void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) { - propertyGetters.put(name, new AnnotatedMethodHandle(handle, validationType)); + /** + * Sets the specified dynamic method to be the property getter for the specified property. Note that you can only + * use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties + * that are caller-sensitive, you must use {@link #setPropertyGetter(String, SingleDynamicMethod, ValidationType)} + * instead. + * @param name name of the property + * @param handle the method handle that implements the property getter + * @param validationType the validation type for the property + */ + private void setPropertyGetter(String name, SingleDynamicMethod handle, ValidationType validationType) { + propertyGetters.put(name, new AnnotatedDynamicMethod(handle, validationType)); } - private void addMember(String name, MethodHandle mh, Map methodMap) { + /** + * Sets the specified reflective method to be the property getter for the specified property. + * @param getter the getter method + * @param prefixLen the getter prefix in the method name; should be 3 for getter names starting with "get" and 2 for + * names starting with "is". + */ + private void setPropertyGetter(Method getter, int prefixLen) { + setPropertyGetter(decapitalize(getter.getName().substring(prefixLen)), createDynamicMethod( + getMostGenericGetter(getter)), ValidationType.INSTANCE_OF); + } + + /** + * Sets the specified method handle to be the property getter for the specified property. Note that you can only + * use this when you're certain that the method handle does not belong to a caller-sensitive method. For properties + * that are caller-sensitive, you must use {@link #setPropertyGetter(String, SingleDynamicMethod, ValidationType)} + * instead. + * @param name name of the property + * @param handle the method handle that implements the property getter + * @param validationType the validation type for the property + */ + void setPropertyGetter(String name, MethodHandle handle, ValidationType validationType) { + setPropertyGetter(name, new SimpleDynamicMethod(handle, clazz, name), validationType); + } + + private void addMember(String name, AccessibleObject ao, Map methodMap) { + addMember(name, createDynamicMethod(ao), methodMap); + } + + private void addMember(String name, SingleDynamicMethod method, Map methodMap) { final DynamicMethod existingMethod = methodMap.get(name); - final DynamicMethod newMethod = addMember(mh, existingMethod, clazz, name); + final DynamicMethod newMethod = mergeMethods(method, existingMethod, clazz, name); if(newMethod != existingMethod) { methodMap.put(name, newMethod); } } - static DynamicMethod createDynamicMethod(Iterable methodHandles, Class clazz, String name) { + /** + * Given one or more reflective methods or constructors, creates a dynamic method that represents them all. The + * methods should represent all overloads of the same name (or all constructors of the class). + * @param members the reflective members + * @param clazz the class declaring the reflective members + * @param name the common name of the reflective members. + * @return a dynamic method representing all the specified reflective members. + */ + static DynamicMethod createDynamicMethod(Iterable members, Class clazz, String name) { DynamicMethod dynMethod = null; - for(MethodHandle methodHandle: methodHandles) { - dynMethod = addMember(methodHandle, dynMethod, clazz, name); + for(AccessibleObject method: members) { + dynMethod = mergeMethods(createDynamicMethod(method), dynMethod, clazz, name); } return dynMethod; } - private static DynamicMethod addMember(MethodHandle mh, DynamicMethod existing, Class clazz, String name) { + /** + * Given a reflective method or a constructor, creates a dynamic method that represents it. This method will + * distinguish between caller sensitive and ordinary methods/constructors, and create appropriate caller sensitive + * dynamic method when needed. + * @param m the reflective member + * @return the single dynamic method representing the reflective member + */ + private static SingleDynamicMethod createDynamicMethod(AccessibleObject m) { + if(CallerSensitiveDetector.isCallerSensitive(m)) { + return new CallerSensitiveDynamicMethod(m); + } + final Member member = (Member)m; + return new SimpleDynamicMethod(unreflectSafely(m), member.getDeclaringClass(), member.getName()); + } + + /** + * Unreflects a method handle from a Method or a Constructor using safe (zero-privilege) unreflection. Should be + * only used for methods and constructors that are not caller sensitive. If a caller sensitive method were + * unreflected through this mechanism, it would not be a security issue, but would be bound to the zero-privilege + * unreflector as its caller, and thus completely useless. + * @param m the method or constructor + * @return the method handle + */ + private static MethodHandle unreflectSafely(AccessibleObject m) { + if(m instanceof Method) { + final Method reflMethod = (Method)m; + final MethodHandle handle = SafeUnreflector.unreflect(reflMethod); + if(Modifier.isStatic(reflMethod.getModifiers())) { + return StaticClassIntrospector.editStaticMethodHandle(handle); + } + return handle; + } + return StaticClassIntrospector.editConstructorMethodHandle(SafeUnreflector.unreflectConstructor( + (Constructor)m)); + } + + private static DynamicMethod mergeMethods(SingleDynamicMethod method, DynamicMethod existing, Class clazz, String name) { if(existing == null) { - return new SimpleDynamicMethod(mh, clazz, name); - } else if(existing.contains(mh)) { + return method; + } else if(existing.contains(method)) { return existing; - } else if(existing instanceof SimpleDynamicMethod) { + } else if(existing instanceof SingleDynamicMethod) { final OverloadedDynamicMethod odm = new OverloadedDynamicMethod(clazz, name); - odm.addMethod(((SimpleDynamicMethod)existing)); - odm.addMethod(mh); + odm.addMethod(((SingleDynamicMethod)existing)); + odm.addMethod(method); return odm; } else if(existing instanceof OverloadedDynamicMethod) { - ((OverloadedDynamicMethod)existing).addMethod(mh); + ((OverloadedDynamicMethod)existing).addMethod(method); return existing; } throw new AssertionError(); @@ -296,7 +379,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { private GuardedInvocation getCallPropWithThis(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) { switch(callSiteDescriptor.getNameTokenCount()) { case 3: { - return createGuardedDynamicMethodInvocation(callSiteDescriptor.getMethodType(), linkerServices, + return createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices, callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), methods); } default: { @@ -305,16 +388,16 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { } } - private GuardedInvocation createGuardedDynamicMethodInvocation(MethodType callSiteType, + private GuardedInvocation createGuardedDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices, String methodName, Map methodMap){ - final MethodHandle inv = getDynamicMethodInvocation(callSiteType, linkerServices, methodName, methodMap); - return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteType)); + final MethodHandle inv = getDynamicMethodInvocation(callSiteDescriptor, linkerServices, methodName, methodMap); + return inv == null ? null : new GuardedInvocation(inv, getClassGuard(callSiteDescriptor.getMethodType())); } - private static MethodHandle getDynamicMethodInvocation(MethodType callSiteType, LinkerServices linkerServices, - String methodName, Map methodMap) { + private static MethodHandle getDynamicMethodInvocation(CallSiteDescriptor callSiteDescriptor, + LinkerServices linkerServices, String methodName, Map methodMap) { final DynamicMethod dynaMethod = getDynamicMethod(methodName, methodMap); - return dynaMethod != null ? dynaMethod.getInvocation(callSiteType, linkerServices) : null; + return dynaMethod != null ? dynaMethod.getInvocation(callSiteDescriptor, linkerServices) : null; } private static DynamicMethod getDynamicMethod(String methodName, Map methodMap) { @@ -322,13 +405,13 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { return dynaMethod != null ? dynaMethod : getExplicitSignatureDynamicMethod(methodName, methodMap); } - private static SimpleDynamicMethod getExplicitSignatureDynamicMethod(String methodName, + private static SingleDynamicMethod getExplicitSignatureDynamicMethod(String methodName, Map methodsMap) { // What's below is meant to support the "name(type, type, ...)" syntax that programmers can use in a method name // to manually pin down an exact overloaded variant. This is not usually required, as the overloaded method // resolution works correctly in almost every situation. However, in presence of many language-specific // conversions with a radically dynamic language, most overloaded methods will end up being constantly selected - // at invocation time, so a programmer knowledgable of the situation might choose to pin down an exact overload + // at invocation time, so a programmer knowledgeable of the situation might choose to pin down an exact overload // for performance reasons. // Is the method name lexically of the form "name(types)"? @@ -377,8 +460,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { final MethodType setterType = type.dropParameterTypes(1, 2); // Bind property setter handle to the expected setter type and linker services. Type is // MethodHandle(Object, String, Object) - final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, setterType, - linkerServices); + final MethodHandle boundGetter = MethodHandles.insertArguments(getPropertySetterHandle, 0, + CallSiteDescriptorFactory.dropParameterTypes(callSiteDescriptor, 1, 2), linkerServices); // Cast getter to MethodHandle(O, N, V) final MethodHandle typedGetter = linkerServices.asType(boundGetter, type.changeReturnType( @@ -415,9 +498,8 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { case 3: { // Must have two arguments: target object and property value assertParameterCount(callSiteDescriptor, 2); - final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor.getMethodType(), - linkerServices, callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), - propertySetters); + final GuardedInvocation gi = createGuardedDynamicMethodInvocation(callSiteDescriptor, linkerServices, + callSiteDescriptor.getNameToken(CallSiteDescriptor.NAME_OPERAND), propertySetters); // If we have a property setter with this name, this composite operation will always stop here if(gi != null) { return new GuardedInvocationComponent(gi, clazz, ValidationType.EXACT_CLASS); @@ -435,14 +517,13 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { private static final Lookup privateLookup = new Lookup(MethodHandles.lookup()); - private static final MethodHandle IS_ANNOTATED_HANDLE_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType( - boolean.class, AnnotatedMethodHandle.class)); - private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_HANDLE = MethodHandles.dropArguments( - MethodHandles.constant(Object.class, null), 0, AnnotatedMethodHandle.class); - private static final MethodHandle GET_ANNOTATED_HANDLE = privateLookup.findGetter(AnnotatedMethodHandle.class, - "handle", MethodHandle.class); - private static final MethodHandle GENERIC_PROPERTY_GETTER_HANDLER_INVOKER = MethodHandles.filterArguments( - MethodHandles.invoker(MethodType.methodType(Object.class, Object.class)), 0, GET_ANNOTATED_HANDLE); + private static final MethodHandle IS_ANNOTATED_METHOD_NOT_NULL = Guards.isNotNull().asType(MethodType.methodType( + boolean.class, AnnotatedDynamicMethod.class)); + private static final MethodHandle CONSTANT_NULL_DROP_ANNOTATED_METHOD = MethodHandles.dropArguments( + MethodHandles.constant(Object.class, null), 0, AnnotatedDynamicMethod.class); + private static final MethodHandle GET_ANNOTATED_METHOD = privateLookup.findVirtual(AnnotatedDynamicMethod.class, + "getTarget", MethodType.methodType(MethodHandle.class, MethodHandles.Lookup.class)); + private static final MethodHandle GETTER_INVOKER = MethodHandles.invoker(MethodType.methodType(Object.class, Object.class)); private GuardedInvocationComponent getPropertyGetter(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices, List ops) throws Exception { @@ -455,16 +536,20 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // What's below is basically: // foldArguments(guardWithTest(isNotNull, invoke(get_handle), null|nextComponent.invocation), get_getter_handle) // only with a bunch of method signature adjustments. Basically, retrieve method getter - // AnnotatedMethodHandle; if it is non-null, invoke its "handle" field, otherwise either return null, + // AnnotatedDynamicMethod; if it is non-null, invoke its "handle" field, otherwise either return null, // or delegate to next component's invocation. final MethodHandle typedGetter = linkerServices.asType(getPropertyGetterHandle, type.changeReturnType( - AnnotatedMethodHandle.class)); - // Object(AnnotatedMethodHandle, Object)->R(AnnotatedMethodHandle, T0) - final MethodHandle invokeHandleTyped = linkerServices.asType(GENERIC_PROPERTY_GETTER_HANDLER_INVOKER, - MethodType.methodType(type.returnType(), AnnotatedMethodHandle.class, type.parameterType(0))); + AnnotatedDynamicMethod.class)); + final MethodHandle callSiteBoundMethodGetter = MethodHandles.insertArguments( + GET_ANNOTATED_METHOD, 1, callSiteDescriptor.getLookup()); + final MethodHandle callSiteBoundInvoker = MethodHandles.filterArguments(GETTER_INVOKER, 0, + callSiteBoundMethodGetter); + // Object(AnnotatedDynamicMethod, Object)->R(AnnotatedDynamicMethod, T0) + final MethodHandle invokeHandleTyped = linkerServices.asType(callSiteBoundInvoker, + MethodType.methodType(type.returnType(), AnnotatedDynamicMethod.class, type.parameterType(0))); // Since it's in the target of a fold, drop the unnecessary second argument - // R(AnnotatedMethodHandle, T0)->R(AnnotatedMethodHandle, T0, T1) + // R(AnnotatedDynamicMethod, T0)->R(AnnotatedDynamicMethod, T0, T1) final MethodHandle invokeHandleFolded = MethodHandles.dropArguments(invokeHandleTyped, 2, type.parameterType(1)); final GuardedInvocationComponent nextComponent = getGuardedInvocationComponent(callSiteDescriptor, @@ -472,19 +557,19 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { final MethodHandle fallbackFolded; if(nextComponent == null) { - // Object(AnnotatedMethodHandle)->R(AnnotatedMethodHandle, T0, T1); returns constant null - fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_HANDLE, 1, - type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedMethodHandle.class)); + // Object(AnnotatedDynamicMethod)->R(AnnotatedDynamicMethod, T0, T1); returns constant null + fallbackFolded = MethodHandles.dropArguments(CONSTANT_NULL_DROP_ANNOTATED_METHOD, 1, + type.parameterList()).asType(type.insertParameterTypes(0, AnnotatedDynamicMethod.class)); } else { - // R(T0, T1)->R(AnnotatedMethodHAndle, T0, T1); adapts the next component's invocation to drop the + // R(T0, T1)->R(AnnotatedDynamicMethod, T0, T1); adapts the next component's invocation to drop the // extra argument resulting from fold fallbackFolded = MethodHandles.dropArguments(nextComponent.getGuardedInvocation().getInvocation(), - 0, AnnotatedMethodHandle.class); + 0, AnnotatedDynamicMethod.class); } - // fold(R(AnnotatedMethodHandle, T0, T1), AnnotatedMethodHandle(T0, T1)) + // fold(R(AnnotatedDynamicMethod, T0, T1), AnnotatedDynamicMethod(T0, T1)) final MethodHandle compositeGetter = MethodHandles.foldArguments(MethodHandles.guardWithTest( - IS_ANNOTATED_HANDLE_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter); + IS_ANNOTATED_METHOD_NOT_NULL, invokeHandleFolded, fallbackFolded), typedGetter); if(nextComponent == null) { return getClassGuardedInvocationComponent(compositeGetter, type); } @@ -494,13 +579,13 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // Must have exactly one argument: receiver assertParameterCount(callSiteDescriptor, 1); // Fixed name - final AnnotatedMethodHandle annGetter = propertyGetters.get(callSiteDescriptor.getNameToken( + final AnnotatedDynamicMethod annGetter = propertyGetters.get(callSiteDescriptor.getNameToken( CallSiteDescriptor.NAME_OPERAND)); if(annGetter == null) { // We have no such property, always delegate to the next component operation return getGuardedInvocationComponent(callSiteDescriptor, linkerServices, ops); } - final MethodHandle getter = annGetter.handle; + final MethodHandle getter = annGetter.getInvocation(callSiteDescriptor, linkerServices); // NOTE: since property getters (not field getters!) are no-arg, we don't have to worry about them being // overloaded in a subclass. Therefore, we can discover the most abstract superclass that has the // method, and use that as the guard with Guards.isInstance() for a more stably linked call site. If @@ -508,6 +593,7 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // NOTE: No delegation to the next component operation if we have a property with this name, even if its // value is null. final ValidationType validationType = annGetter.validationType; + // TODO: we aren't using the type that declares the most generic getter here! return new GuardedInvocationComponent(linkerServices.asType(getter, type), getGuard(validationType, type), clazz, validationType); } @@ -623,14 +709,15 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { // args are dropped; this makes handles with first three args conform to "Object, String, Object" though, which is // a typical property setter with variable name signature (target, name, value). private static final MethodHandle GET_PROPERTY_SETTER_HANDLE = MethodHandles.dropArguments(MethodHandles.dropArguments( - privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, MethodType.class, + privateLookup.findOwnSpecial("getPropertySetterHandle", MethodHandle.class, CallSiteDescriptor.class, LinkerServices.class, Object.class), 3, Object.class), 5, Object.class); // Type is MethodHandle(MethodType, LinkerServices, Object, String, Object) private final MethodHandle getPropertySetterHandle = GET_PROPERTY_SETTER_HANDLE.bindTo(this); @SuppressWarnings("unused") - private MethodHandle getPropertySetterHandle(MethodType setterType, LinkerServices linkerServices, Object id) { - return getDynamicMethodInvocation(setterType, linkerServices, String.valueOf(id), propertySetters); + private MethodHandle getPropertySetterHandle(CallSiteDescriptor setterDescriptor, LinkerServices linkerServices, + Object id) { + return getDynamicMethodInvocation(setterDescriptor, linkerServices, String.valueOf(id), propertySetters); } private static MethodHandle GET_DYNAMIC_METHOD = MethodHandles.dropArguments(privateLookup.findOwnSpecial( @@ -689,13 +776,24 @@ abstract class AbstractJavaLinker implements GuardingDynamicLinker { return null; } - private static final class AnnotatedMethodHandle { - final MethodHandle handle; + private static final class AnnotatedDynamicMethod { + private final SingleDynamicMethod method; /*private*/ final ValidationType validationType; - AnnotatedMethodHandle(MethodHandle handle, ValidationType validationType) { - this.handle = handle; + AnnotatedDynamicMethod(SingleDynamicMethod method, ValidationType validationType) { + this.method = method; this.validationType = validationType; } + + MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) { + return method.getInvocation(callSiteDescriptor, linkerServices); + } + + @SuppressWarnings("unused") + MethodHandle getTarget(MethodHandles.Lookup lookup) { + MethodHandle inv = method.getTarget(lookup); + assert inv != null; + return inv; + } } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java b/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java index a232caf137a..39a03a8ef96 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java +++ b/nashorn/src/jdk/internal/dynalink/beans/ApplicableOverloadedMethods.java @@ -83,7 +83,6 @@ package jdk.internal.dynalink.beans; -import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; import java.util.LinkedList; import java.util.List; @@ -95,7 +94,7 @@ import jdk.internal.dynalink.support.TypeUtilities; * @author Attila Szegedi */ class ApplicableOverloadedMethods { - private final List methods; + private final List methods; private final boolean varArgs; /** @@ -106,10 +105,10 @@ class ApplicableOverloadedMethods { * @param test applicability test. One of {@link #APPLICABLE_BY_SUBTYPING}, * {@link #APPLICABLE_BY_METHOD_INVOCATION_CONVERSION}, or {@link #APPLICABLE_BY_VARIABLE_ARITY}. */ - ApplicableOverloadedMethods(final List methods, final MethodType callSiteType, + ApplicableOverloadedMethods(final List methods, final MethodType callSiteType, final ApplicabilityTest test) { this.methods = new LinkedList<>(); - for(MethodHandle m: methods) { + for(SingleDynamicMethod m: methods) { if(test.isApplicable(callSiteType, m)) { this.methods.add(m); } @@ -122,7 +121,7 @@ class ApplicableOverloadedMethods { * * @return list of all methods. */ - List getMethods() { + List getMethods() { return methods; } @@ -131,12 +130,12 @@ class ApplicableOverloadedMethods { * * @return a list of maximally specific methods. */ - List findMaximallySpecificMethods() { + List findMaximallySpecificMethods() { return MaximallySpecific.getMaximallySpecificMethods(methods, varArgs); } abstract static class ApplicabilityTest { - abstract boolean isApplicable(MethodType callSiteType, MethodHandle method); + abstract boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method); } /** @@ -144,8 +143,8 @@ class ApplicableOverloadedMethods { */ static final ApplicabilityTest APPLICABLE_BY_SUBTYPING = new ApplicabilityTest() { @Override - boolean isApplicable(MethodType callSiteType, MethodHandle method) { - final MethodType methodType = method.type(); + boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) { + final MethodType methodType = method.getMethodType(); final int methodArity = methodType.parameterCount(); if(methodArity != callSiteType.parameterCount()) { return false; @@ -166,8 +165,8 @@ class ApplicableOverloadedMethods { */ static final ApplicabilityTest APPLICABLE_BY_METHOD_INVOCATION_CONVERSION = new ApplicabilityTest() { @Override - boolean isApplicable(MethodType callSiteType, MethodHandle method) { - final MethodType methodType = method.type(); + boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) { + final MethodType methodType = method.getMethodType(); final int methodArity = methodType.parameterCount(); if(methodArity != callSiteType.parameterCount()) { return false; @@ -189,11 +188,11 @@ class ApplicableOverloadedMethods { */ static final ApplicabilityTest APPLICABLE_BY_VARIABLE_ARITY = new ApplicabilityTest() { @Override - boolean isApplicable(MethodType callSiteType, MethodHandle method) { - if(!method.isVarargsCollector()) { + boolean isApplicable(MethodType callSiteType, SingleDynamicMethod method) { + if(!method.isVarArgs()) { return false; } - final MethodType methodType = method.type(); + final MethodType methodType = method.getMethodType(); final int methodArity = methodType.parameterCount(); final int fixArity = methodArity - 1; final int callSiteArity = callSiteType.parameterCount(); diff --git a/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java new file mode 100644 index 00000000000..466bafe65dc --- /dev/null +++ b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDetector.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + 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 the copyright holder nor the names of + 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 COPYRIGHT HOLDER + 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. +*/ + +package jdk.internal.dynalink.beans; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AccessibleObject; +import sun.reflect.CallerSensitive; + +/** + * Utility class that determines if a method or constructor is caller sensitive. It actually encapsulates two different + * strategies for determining caller sensitivity; a more robust one that works if Dynalink runs as code with access + * to {@code sun.reflect} package, and an unprivileged one that is used when Dynalink doesn't have access to that + * package. Note that even the unprivileged strategy is ordinarily robust, but it relies on the {@code toString} method + * of the annotation. If an attacker were to use a different annotation to spoof the string representation of the + * {@code CallerSensitive} annotation, they could designate their own methods as caller sensitive. This however does not + * escalate privileges, only causes Dynalink to never cache method handles for such methods, so all it would do would + * decrease the performance in linking such methods. In the opposite case when an attacker could trick Dynalink into not + * recognizing genuine {@code CallerSensitive} annotations, Dynalink would treat caller sensitive methods as ordinary + * methods, and would cache them bound to a zero-privilege delegate as the caller (just what Dynalink did before it + * could handle caller-sensitive methods). That would practically render caller-sensitive methods exposed through + * Dynalink unusable, but again, can not lead to any privilege escalations. Therefore, even the less robust unprivileged + * strategy is safe; the worst thing a successful attack against it can achieve is slight reduction in Dynalink-exposed + * functionality or performance. + */ +public class CallerSensitiveDetector { + + private static final DetectionStrategy DETECTION_STRATEGY = getDetectionStrategy(); + + static boolean isCallerSensitive(AccessibleObject ao) { + return DETECTION_STRATEGY.isCallerSensitive(ao); + } + + private static DetectionStrategy getDetectionStrategy() { + try { + return new PrivilegedDetectionStrategy(); + } catch(Throwable t) { + return new UnprivilegedDetectionStrategy(); + } + } + + private abstract static class DetectionStrategy { + abstract boolean isCallerSensitive(AccessibleObject ao); + } + + private static class PrivilegedDetectionStrategy extends DetectionStrategy { + private static final Class CALLER_SENSITIVE_ANNOTATION_CLASS = CallerSensitive.class; + + @Override + boolean isCallerSensitive(AccessibleObject ao) { + return ao.getAnnotation(CALLER_SENSITIVE_ANNOTATION_CLASS) != null; + } + } + + private static class UnprivilegedDetectionStrategy extends DetectionStrategy { + private static final String CALLER_SENSITIVE_ANNOTATION_STRING = "@sun.reflect.CallerSensitive()"; + + @Override + boolean isCallerSensitive(AccessibleObject o) { + for(Annotation a: o.getAnnotations()) { + if(String.valueOf(a).equals(CALLER_SENSITIVE_ANNOTATION_STRING)) { + return true; + } + } + return false; + } + } +} diff --git a/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java new file mode 100644 index 00000000000..1e274d516e9 --- /dev/null +++ b/nashorn/src/jdk/internal/dynalink/beans/CallerSensitiveDynamicMethod.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + 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 the copyright holder nor the names of + 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 COPYRIGHT HOLDER + 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. +*/ + +package jdk.internal.dynalink.beans; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Constructor; +import java.lang.reflect.Member; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import jdk.internal.dynalink.support.Lookup; + +/** + * A dynamic method bound to exactly one Java method or constructor that is caller sensitive. Since the target method is + * caller sensitive, it doesn't cache a method handle but rather uses the passed lookup object in + * {@link #getTarget(java.lang.invoke.MethodHandles.Lookup)} to unreflect a method handle from the reflective member on + * every request. + * + * @author Attila Szegedi + */ +class CallerSensitiveDynamicMethod extends SingleDynamicMethod { + // Typed as "AccessibleObject" as it can be either a method or a constructor. + // If we were Java8-only, we could use java.lang.reflect.Executable + private final AccessibleObject target; + private final MethodType type; + + public CallerSensitiveDynamicMethod(AccessibleObject target) { + super(getName(target)); + this.target = target; + this.type = getMethodType(target); + } + + private static String getName(AccessibleObject target) { + final Member m = (Member)target; + return getMethodNameWithSignature(getMethodType(target), getClassAndMethodName(m.getDeclaringClass(), + m.getName())); + } + + @Override + MethodType getMethodType() { + return type; + } + + private static MethodType getMethodType(AccessibleObject ao) { + final boolean isMethod = ao instanceof Method; + final Class rtype = isMethod ? ((Method)ao).getReturnType() : ((Constructor)ao).getDeclaringClass(); + final Class[] ptypes = isMethod ? ((Method)ao).getParameterTypes() : ((Constructor)ao).getParameterTypes(); + final MethodType type = MethodType.methodType(rtype, ptypes); + final Member m = (Member)ao; + return type.insertParameterTypes(0, + isMethod ? + Modifier.isStatic(m.getModifiers()) ? + Object.class : + m.getDeclaringClass() : + StaticClass.class); + } + + @Override + boolean isVarArgs() { + return target instanceof Method ? ((Method)target).isVarArgs() : ((Constructor)target).isVarArgs(); + } + + @Override + MethodHandle getTarget(MethodHandles.Lookup lookup) { + if(target instanceof Method) { + final MethodHandle mh = Lookup.unreflect(lookup, (Method)target); + if(Modifier.isStatic(((Member)target).getModifiers())) { + return StaticClassIntrospector.editStaticMethodHandle(mh); + } + return mh; + } + return StaticClassIntrospector.editConstructorMethodHandle(Lookup.unreflectConstructor(lookup, + (Constructor)target)); + } +} diff --git a/nashorn/src/jdk/internal/dynalink/beans/ClassString.java b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java index dfcb378662f..8ab45727de6 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/ClassString.java +++ b/nashorn/src/jdk/internal/dynalink/beans/ClassString.java @@ -155,8 +155,8 @@ final class ClassString { } List getMaximallySpecifics(List methods, LinkerServices linkerServices, boolean varArg) { - return MaximallySpecific.getMaximallySpecificMethods(getApplicables(methods, linkerServices, varArg), varArg, - classes, linkerServices); + return MaximallySpecific.getMaximallySpecificMethodHandles(getApplicables(methods, linkerServices, varArg), + varArg, classes, linkerServices); } /** diff --git a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java index aee69ff722e..6beb92b12f7 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethod.java @@ -84,8 +84,7 @@ package jdk.internal.dynalink.beans; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodType; -import java.util.StringTokenizer; +import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.LinkerServices; /** @@ -116,45 +115,28 @@ abstract class DynamicMethod { * is a variable arguments (vararg) method, it will pack the extra arguments in an array before the invocation of * the underlying method if it is not already done. * - * @param callSiteType the method type at a call site + * @param callSiteDescriptor the descriptor of the call site * @param linkerServices linker services. Used for language-specific type conversions. * @return an invocation suitable for calling the method from the specified call site. */ - abstract MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices); + abstract MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices); /** - * Returns a simple dynamic method representing a single underlying Java method (possibly selected among several + * Returns a single dynamic method representing a single underlying Java method (possibly selected among several * overloads) with formal parameter types exactly matching the passed signature. * @param paramTypes the comma-separated list of requested parameter type names. The names will match both * qualified and unqualified type names. - * @return a simple dynamic method representing a single underlying Java method, or null if none of the Java methods + * @return a single dynamic method representing a single underlying Java method, or null if none of the Java methods * behind this dynamic method exactly match the requested parameter types. */ - abstract SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes); + abstract SingleDynamicMethod getMethodForExactParamTypes(String paramTypes); /** - * True if this dynamic method already contains a method handle with an identical signature as the passed in method - * handle. - * @param mh the method handle to check - * @return true if it already contains an equivalent method handle. + * True if this dynamic method already contains a method with an identical signature as the passed in method. + * @param method the method to check + * @return true if it already contains an equivalent method. */ - abstract boolean contains(MethodHandle mh); - - static boolean typeMatchesDescription(String paramTypes, MethodType type) { - final StringTokenizer tok = new StringTokenizer(paramTypes, ", "); - for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver - if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) { - return false; - } - } - return !tok.hasMoreTokens(); - } - - private static boolean typeNameMatches(String typeName, Class type) { - final int lastDot = typeName.lastIndexOf('.'); - final String fullTypeName = type.getCanonicalName(); - return lastDot != -1 && fullTypeName.endsWith(typeName.substring(lastDot)) || typeName.equals(fullTypeName); - } + abstract boolean contains(SingleDynamicMethod method); static String getClassAndMethodName(Class clazz, String name) { final String clazzName = clazz.getCanonicalName(); diff --git a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java index d8ceeea0045..32942b9a423 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/DynamicMethodLinker.java @@ -85,12 +85,12 @@ package jdk.internal.dynalink.beans; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; +import jdk.internal.dynalink.support.CallSiteDescriptorFactory; import jdk.internal.dynalink.support.Guards; /** @@ -110,19 +110,18 @@ class DynamicMethodLinker implements TypeBasedGuardingDynamicLinker { return null; } final CallSiteDescriptor desc = linkRequest.getCallSiteDescriptor(); - if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") { + if(desc.getNameTokenCount() != 2 && desc.getNameToken(CallSiteDescriptor.SCHEME) != "dyn") { return null; } final String operator = desc.getNameToken(CallSiteDescriptor.OPERATOR); if(operator == "call") { - final MethodType type = desc.getMethodType(); - final MethodHandle invocation = ((DynamicMethod)receiver).getInvocation(type.dropParameterTypes(0, 1), - linkerServices); + final MethodHandle invocation = ((DynamicMethod)receiver).getInvocation( + CallSiteDescriptorFactory.dropParameterTypes(desc, 0, 1), linkerServices); if(invocation == null) { return null; } - return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0, type.parameterType(0)), - Guards.getIdentityGuard(receiver)); + return new GuardedInvocation(MethodHandles.dropArguments(invocation, 0, + desc.getMethodType().parameterType(0)), Guards.getIdentityGuard(receiver)); } return null; } diff --git a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java index f4fbd8244f1..97e431ca24b 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/FacetIntrospector.java @@ -167,10 +167,6 @@ abstract class FacetIntrospector { return editMethodHandle(SafeUnreflector.unreflectSetter(field)); } - MethodHandle unreflect(Method method) { - return editMethodHandle(SafeUnreflector.unreflect(method)); - } - /** * Returns an edited method handle. A facet might need to edit an unreflected method handle before it is usable with * the facet. By default, returns the passed method handle unchanged. The class' static facet will introduce a diff --git a/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java b/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java index 182fd01695d..3ee8e41ab30 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java +++ b/nashorn/src/jdk/internal/dynalink/beans/MaximallySpecific.java @@ -105,10 +105,58 @@ class MaximallySpecific { * @param varArgs whether to assume the methods are varargs * @return the list of maximally specific methods. */ - static List getMaximallySpecificMethods(List methods, boolean varArgs) { - return getMaximallySpecificMethods(methods, varArgs, null, null); + static List getMaximallySpecificMethods(List methods, boolean varArgs) { + return getMaximallySpecificSingleDynamicMethods(methods, varArgs, null, null); } + private abstract static class MethodTypeGetter { + abstract MethodType getMethodType(T t); + } + + private static final MethodTypeGetter METHOD_HANDLE_TYPE_GETTER = + new MethodTypeGetter() { + @Override + MethodType getMethodType(MethodHandle t) { + return t.type(); + } + }; + + private static final MethodTypeGetter DYNAMIC_METHOD_TYPE_GETTER = + new MethodTypeGetter() { + @Override + MethodType getMethodType(SingleDynamicMethod t) { + return t.getMethodType(); + } + }; + + /** + * Given a list of methods handles, returns a list of maximally specific methods, applying language-runtime + * specific conversion preferences. + * + * @param methods the list of method handles + * @param varArgs whether to assume the method handles are varargs + * @param argTypes concrete argument types for the invocation + * @return the list of maximally specific method handles. + */ + static List getMaximallySpecificMethodHandles(List methods, boolean varArgs, + Class[] argTypes, LinkerServices ls) { + return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, METHOD_HANDLE_TYPE_GETTER); + } + + /** + * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific + * conversion preferences. + * + * @param methods the list of methods + * @param varArgs whether to assume the methods are varargs + * @param argTypes concrete argument types for the invocation + * @return the list of maximally specific methods. + */ + static List getMaximallySpecificSingleDynamicMethods(List methods, + boolean varArgs, Class[] argTypes, LinkerServices ls) { + return getMaximallySpecificMethods(methods, varArgs, argTypes, ls, DYNAMIC_METHOD_TYPE_GETTER); + } + /** * Given a list of methods, returns a list of maximally specific methods, applying language-runtime specific * conversion preferences. @@ -118,18 +166,18 @@ class MaximallySpecific { * @param argTypes concrete argument types for the invocation * @return the list of maximally specific methods. */ - static List getMaximallySpecificMethods(List methods, boolean varArgs, - Class[] argTypes, LinkerServices ls) { + private static List getMaximallySpecificMethods(List methods, boolean varArgs, + Class[] argTypes, LinkerServices ls, MethodTypeGetter methodTypeGetter) { if(methods.size() < 2) { return methods; } - final LinkedList maximals = new LinkedList<>(); - for(MethodHandle m: methods) { - final MethodType methodType = m.type(); + final LinkedList maximals = new LinkedList<>(); + for(T m: methods) { + final MethodType methodType = methodTypeGetter.getMethodType(m); boolean lessSpecific = false; - for(Iterator maximal = maximals.iterator(); maximal.hasNext();) { - final MethodHandle max = maximal.next(); - switch(isMoreSpecific(methodType, max.type(), varArgs, argTypes, ls)) { + for(Iterator maximal = maximals.iterator(); maximal.hasNext();) { + final T max = maximal.next(); + switch(isMoreSpecific(methodType, methodTypeGetter.getMethodType(max), varArgs, argTypes, ls)) { case TYPE_1_BETTER: { maximal.remove(); break; diff --git a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java index 7873cf1520e..407d2b8310f 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedDynamicMethod.java @@ -84,16 +84,21 @@ package jdk.internal.dynalink.beans; import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; +import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; +import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.support.TypeUtilities; /** - * Represents an overloaded method. + * Represents a group of {@link SingleDynamicMethod} objects that represents all overloads of a particular name (or all + * constructors) for a particular class. Correctly handles overload resolution, variable arity methods, and caller + * sensitive methods within the overloads. * * @author Attila Szegedi */ @@ -101,7 +106,7 @@ class OverloadedDynamicMethod extends DynamicMethod { /** * Holds a list of all methods. */ - private final LinkedList methods; + private final LinkedList methods; private final ClassLoader classLoader; /** @@ -111,21 +116,22 @@ class OverloadedDynamicMethod extends DynamicMethod { * @param name the name of the method */ OverloadedDynamicMethod(Class clazz, String name) { - this(new LinkedList(), clazz.getClassLoader(), getClassAndMethodName(clazz, name)); + this(new LinkedList(), clazz.getClassLoader(), getClassAndMethodName(clazz, name)); } - private OverloadedDynamicMethod(LinkedList methods, ClassLoader classLoader, String name) { + private OverloadedDynamicMethod(LinkedList methods, ClassLoader classLoader, String name) { super(name); this.methods = methods; this.classLoader = classLoader; } @Override - SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes) { - final LinkedList matchingMethods = new LinkedList<>(); - for(MethodHandle method: methods) { - if(typeMatchesDescription(paramTypes, method.type())) { - matchingMethods.add(method); + SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) { + final LinkedList matchingMethods = new LinkedList<>(); + for(SingleDynamicMethod method: methods) { + final SingleDynamicMethod matchingMethod = method.getMethodForExactParamTypes(paramTypes); + if(matchingMethod != null) { + matchingMethods.add(matchingMethod); } } switch(matchingMethods.size()) { @@ -133,8 +139,7 @@ class OverloadedDynamicMethod extends DynamicMethod { return null; } case 1: { - final MethodHandle target = matchingMethods.get(0); - return new SimpleDynamicMethod(target, SimpleDynamicMethod.getMethodNameWithSignature(target, getName())); + return matchingMethods.getFirst(); } default: { throw new BootstrapMethodError("Can't choose among " + matchingMethods + " for argument types " @@ -144,7 +149,8 @@ class OverloadedDynamicMethod extends DynamicMethod { } @Override - public MethodHandle getInvocation(final MethodType callSiteType, final LinkerServices linkerServices) { + public MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final LinkerServices linkerServices) { + final MethodType callSiteType = callSiteDescriptor.getMethodType(); // First, find all methods applicable to the call site by subtyping (JLS 15.12.2.2) final ApplicableOverloadedMethods subtypingApplicables = getApplicables(callSiteType, ApplicableOverloadedMethods.APPLICABLE_BY_SUBTYPING); @@ -156,7 +162,7 @@ class OverloadedDynamicMethod extends DynamicMethod { ApplicableOverloadedMethods.APPLICABLE_BY_VARIABLE_ARITY); // Find the methods that are maximally specific based on the call site signature - List maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); + List maximallySpecifics = subtypingApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { maximallySpecifics = methodInvocationApplicables.findMaximallySpecificMethods(); if(maximallySpecifics.isEmpty()) { @@ -171,12 +177,12 @@ class OverloadedDynamicMethod extends DynamicMethod { // (Object, Object), and we have a method whose parameter types are (String, int). None of the JLS applicability // rules will trigger, but we must consider the method, as it can be the right match for a concrete invocation. @SuppressWarnings({ "unchecked", "rawtypes" }) - final List invokables = (List)methods.clone(); + final List invokables = (List)methods.clone(); invokables.removeAll(subtypingApplicables.getMethods()); invokables.removeAll(methodInvocationApplicables.getMethods()); invokables.removeAll(variableArityApplicables.getMethods()); - for(final Iterator it = invokables.iterator(); it.hasNext();) { - final MethodHandle m = it.next(); + for(final Iterator it = invokables.iterator(); it.hasNext();) { + final SingleDynamicMethod m = it.next(); if(!isApplicableDynamically(linkerServices, callSiteType, m)) { it.remove(); } @@ -199,54 +205,45 @@ class OverloadedDynamicMethod extends DynamicMethod { } case 1: { // Very lucky, we ended up with a single candidate method handle based on the call site signature; we - // can link it very simply by delegating to a SimpleDynamicMethod. - final MethodHandle mh = invokables.iterator().next(); - return new SimpleDynamicMethod(mh).getInvocation(callSiteType, linkerServices); + // can link it very simply by delegating to the SingleDynamicMethod. + invokables.iterator().next().getInvocation(callSiteDescriptor, linkerServices); } default: { // We have more than one candidate. We have no choice but to link to a method that resolves overloads on // every invocation (alternatively, we could opportunistically link the one method that resolves for the // current arguments, but we'd need to install a fairly complex guard for that and when it'd fail, we'd - // go back all the way to candidate selection. - // TODO: cache per call site type - return new OverloadedMethod(invokables, this, callSiteType, linkerServices).getInvoker(); + // go back all the way to candidate selection. Note that we're resolving any potential caller sensitive + // methods here to their handles, as the OverloadedMethod instance is specific to a call site, so it + // has an already determined Lookup. + final List methodHandles = new ArrayList<>(invokables.size()); + final MethodHandles.Lookup lookup = callSiteDescriptor.getLookup(); + for(SingleDynamicMethod method: invokables) { + methodHandles.add(method.getTarget(lookup)); + } + return new OverloadedMethod(methodHandles, this, callSiteType, linkerServices).getInvoker(); } } } @Override - public boolean contains(MethodHandle mh) { - final MethodType type = mh.type(); - for(MethodHandle method: methods) { - if(typesEqualNoReceiver(type, method.type())) { + public boolean contains(SingleDynamicMethod m) { + for(SingleDynamicMethod method: methods) { + if(method.contains(m)) { return true; } } return false; } - private static boolean typesEqualNoReceiver(MethodType type1, MethodType type2) { - final int pc = type1.parameterCount(); - if(pc != type2.parameterCount()) { - return false; - } - for(int i = 1; i < pc; ++i) { // i = 1: ignore receiver - if(type1.parameterType(i) != type2.parameterType(i)) { - return false; - } - } - return true; - } - ClassLoader getClassLoader() { return classLoader; } private static boolean isApplicableDynamically(LinkerServices linkerServices, MethodType callSiteType, - MethodHandle m) { - final MethodType methodType = m.type(); - final boolean varArgs = m.isVarargsCollector(); + SingleDynamicMethod m) { + final MethodType methodType = m.getMethodType(); + final boolean varArgs = m.isVarArgs(); final int fixedArgLen = methodType.parameterCount() - (varArgs ? 1 : 0); final int callSiteArgLen = callSiteType.parameterCount(); @@ -300,21 +297,12 @@ class OverloadedDynamicMethod extends DynamicMethod { return new ApplicableOverloadedMethods(methods, callSiteType, test); } - /** - * Add a method identified by a {@link SimpleDynamicMethod} to this overloaded method's set. - * - * @param method the method to add. - */ - void addMethod(SimpleDynamicMethod method) { - addMethod(method.getTarget()); - } - /** * Add a method to this overloaded method's set. * * @param method a method to add */ - public void addMethod(MethodHandle method) { + public void addMethod(SingleDynamicMethod method) { methods.add(method); } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java b/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java index 7093e757497..f711489b037 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/OverloadedMethod.java @@ -135,7 +135,7 @@ class OverloadedMethod { varArgMethods.trimToSize(); final MethodHandle bound = SELECT_METHOD.bindTo(this); - final MethodHandle collecting = SimpleDynamicMethod.collectArguments(bound, argNum).asType( + final MethodHandle collecting = SingleDynamicMethod.collectArguments(bound, argNum).asType( callSiteType.changeReturnType(MethodHandle.class)); invoker = MethodHandles.foldArguments(MethodHandles.exactInvoker(callSiteType), collecting); } @@ -167,7 +167,7 @@ class OverloadedMethod { break; } case 1: { - method = new SimpleDynamicMethod(methods.get(0)).getInvocation(callSiteType, linkerServices); + method = SingleDynamicMethod.getInvocation(methods.get(0), callSiteType, linkerServices); break; } default: { diff --git a/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java index 1fbf7dbb1a0..9d4d6961081 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java +++ b/nashorn/src/jdk/internal/dynalink/beans/SimpleDynamicMethod.java @@ -84,28 +84,21 @@ package jdk.internal.dynalink.beans; import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; -import java.lang.reflect.Array; -import jdk.internal.dynalink.linker.LinkerServices; -import jdk.internal.dynalink.support.Guards; /** - * A dynamic method bound to exactly one, non-overloaded Java method. Handles varargs. + * A dynamic method bound to exactly one Java method or constructor that is not caller sensitive. Since its target is + * not caller sensitive, this class pre-caches its method handle and always returns it from the call to + * {@link #getTarget(Lookup)}. Can be used in general to represents dynamic methods bound to a single method handle, + * even if that handle is not mapped to a Java method, i.e. as a wrapper around field getters/setters, array element + * getters/setters, etc. * * @author Attila Szegedi */ -class SimpleDynamicMethod extends DynamicMethod { +class SimpleDynamicMethod extends SingleDynamicMethod { private final MethodHandle target; - /** - * Creates a simple dynamic method with no name. - * @param target the target method handle - */ - SimpleDynamicMethod(MethodHandle target) { - this(target, null); - } - /** * Creates a new simple dynamic method, with a name constructed from the class name, method name, and handle * signature. @@ -115,125 +108,26 @@ class SimpleDynamicMethod extends DynamicMethod { * @param name the simple name of the method */ SimpleDynamicMethod(MethodHandle target, Class clazz, String name) { - this(target, getName(target, clazz, name)); - } - - SimpleDynamicMethod(MethodHandle target, String name) { - super(name); + super(getName(target, clazz, name)); this.target = target; } private static String getName(MethodHandle target, Class clazz, String name) { - return getMethodNameWithSignature(target, getClassAndMethodName(clazz, name)); + return getMethodNameWithSignature(target.type(), getClassAndMethodName(clazz, name)); } - static String getMethodNameWithSignature(MethodHandle target, String methodName) { - final String typeStr = target.type().toString(); - final int retTypeIndex = typeStr.lastIndexOf(')') + 1; - int secondParamIndex = typeStr.indexOf(',') + 1; - if(secondParamIndex == 0) { - secondParamIndex = retTypeIndex - 1; - } - return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex); + @Override + boolean isVarArgs() { + return target.isVarargsCollector(); } - /** - * Returns the target of this dynamic method - * - * @return the target of this dynamic method - */ - MethodHandle getTarget() { + @Override + MethodType getMethodType() { + return target.type(); + } + + @Override + MethodHandle getTarget(Lookup lookup) { return target; } - - @Override - SimpleDynamicMethod getMethodForExactParamTypes(String paramTypes) { - return typeMatchesDescription(paramTypes, target.type()) ? this : null; - } - - @Override - MethodHandle getInvocation(MethodType callSiteType, LinkerServices linkerServices) { - final MethodType methodType = target.type(); - final int paramsLen = methodType.parameterCount(); - final boolean varArgs = target.isVarargsCollector(); - final MethodHandle fixTarget = varArgs ? target.asFixedArity() : target; - final int fixParamsLen = varArgs ? paramsLen - 1 : paramsLen; - final int argsLen = callSiteType.parameterCount(); - if(argsLen < fixParamsLen) { - // Less actual arguments than number of fixed declared arguments; can't invoke. - return null; - } - // Method handle has the same number of fixed arguments as the call site type - if(argsLen == fixParamsLen) { - // Method handle that matches the number of actual arguments as the number of fixed arguments - final MethodHandle matchedMethod; - if(varArgs) { - // If vararg, add a zero-length array of the expected type as the last argument to signify no variable - // arguments. - matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance( - methodType.parameterType(fixParamsLen).getComponentType(), 0)); - } else { - // Otherwise, just use the method - matchedMethod = fixTarget; - } - return createConvertingInvocation(matchedMethod, linkerServices, callSiteType); - } - - // What's below only works for varargs - if(!varArgs) { - return null; - } - - final Class varArgType = methodType.parameterType(fixParamsLen); - // Handle a somewhat sinister corner case: caller passes exactly one argument in the vararg position, and we - // must handle both a prepacked vararg array as well as a genuine 1-long vararg sequence. - if(argsLen == paramsLen) { - final Class callSiteLastArgType = callSiteType.parameterType(fixParamsLen); - if(varArgType.isAssignableFrom(callSiteLastArgType)) { - // Call site signature guarantees we'll always be passed a single compatible array; just link directly - // to the method. - return createConvertingInvocation(fixTarget, linkerServices, callSiteType); - } - if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) { - // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive); - // link immediately to a vararg-packing method handle. - return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType); - } - // Call site signature makes no guarantees that the single argument in the vararg position will be - // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg - // method when it is not. - return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType), - createConvertingInvocation(fixTarget, linkerServices, callSiteType), - createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType)); - } - - // Remaining case: more than one vararg. - return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType); - } - - @Override - public boolean contains(MethodHandle mh) { - return target.type().parameterList().equals(mh.type().parameterList()); - } - - /** - * Creates a method handle out of the original target that will collect the varargs for the exact component type of - * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs - * for which it is necessary when later passed to linkerServices.convertArguments(). - * - * @param target the original method handle - * @param parameterCount the total number of arguments in the new method handle - * @return a collecting method handle - */ - static MethodHandle collectArguments(MethodHandle target, final int parameterCount) { - final MethodType methodType = target.type(); - final int fixParamsLen = methodType.parameterCount() - 1; - final Class arrayType = methodType.parameterType(fixParamsLen); - return target.asCollector(arrayType, parameterCount - fixParamsLen); - } - - private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod, - final LinkerServices linkerServices, final MethodType callSiteType) { - return linkerServices.asType(sizedMethod, callSiteType); - } } diff --git a/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java b/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java new file mode 100644 index 00000000000..d15fab9966e --- /dev/null +++ b/nashorn/src/jdk/internal/dynalink/beans/SingleDynamicMethod.java @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * This file is available under and governed by the GNU General Public + * License version 2 only, as published by the Free Software Foundation. + * However, the following notice accompanied the original version of this + * file, and Oracle licenses the original version of this file under the BSD + * license: + */ +/* + Copyright 2009-2013 Attila Szegedi + + Licensed under both the Apache License, Version 2.0 (the "Apache License") + and the BSD License (the "BSD License"), with licensee being free to + choose either of the two at their discretion. + + You may not use this file except in compliance with either the Apache + License or the BSD License. + + If you choose to use this file in compliance with the Apache License, the + following notice applies to you: + + You may obtain a copy of the Apache License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. + + If you choose to use this file in compliance with the BSD License, the + following notice applies to you: + + 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 the copyright holder nor the names of + 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 COPYRIGHT HOLDER + 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. +*/ + +package jdk.internal.dynalink.beans; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import java.lang.reflect.Array; +import java.util.StringTokenizer; +import jdk.internal.dynalink.CallSiteDescriptor; +import jdk.internal.dynalink.linker.LinkerServices; +import jdk.internal.dynalink.support.Guards; + +/** + * Base class for dynamic methods that dispatch to a single target Java method or constructor. Handles adaptation of the + * target method to a call site type (including mapping variable arity methods to a call site signature with different + * arity). + * @author Attila Szegedi + * @version $Id: $ + */ +abstract class SingleDynamicMethod extends DynamicMethod { + SingleDynamicMethod(String name) { + super(name); + } + + /** + * Returns true if this method is variable arity. + * @return true if this method is variable arity. + */ + abstract boolean isVarArgs(); + + /** + * Returns this method's native type. + * @return this method's native type. + */ + abstract MethodType getMethodType(); + + /** + * Given a specified lookup, returns a method handle to this method's target. + * @param lookup the lookup to use. + * @return the handle to this method's target method. + */ + abstract MethodHandle getTarget(MethodHandles.Lookup lookup); + + @Override + MethodHandle getInvocation(CallSiteDescriptor callSiteDescriptor, LinkerServices linkerServices) { + return getInvocation(getTarget(callSiteDescriptor.getLookup()), callSiteDescriptor.getMethodType(), + linkerServices); + } + + @Override + SingleDynamicMethod getMethodForExactParamTypes(String paramTypes) { + return typeMatchesDescription(paramTypes, getMethodType()) ? this : null; + } + + @Override + boolean contains(SingleDynamicMethod method) { + return getMethodType().parameterList().equals(method.getMethodType().parameterList()); + } + + static String getMethodNameWithSignature(MethodType type, String methodName) { + final String typeStr = type.toString(); + final int retTypeIndex = typeStr.lastIndexOf(')') + 1; + int secondParamIndex = typeStr.indexOf(',') + 1; + if(secondParamIndex == 0) { + secondParamIndex = retTypeIndex - 1; + } + return typeStr.substring(retTypeIndex) + " " + methodName + "(" + typeStr.substring(secondParamIndex, retTypeIndex); + } + + /** + * Given a method handle and a call site type, adapts the method handle to the call site type. Performs type + * conversions as needed using the specified linker services, and in case that the method handle is a vararg + * collector, matches it to the arity of the call site. + * @param target the method handle to adapt + * @param callSiteType the type of the call site + * @param linkerServices the linker services used for type conversions + * @return the adapted method handle. + */ + static MethodHandle getInvocation(MethodHandle target, MethodType callSiteType, LinkerServices linkerServices) { + final MethodType methodType = target.type(); + final int paramsLen = methodType.parameterCount(); + final boolean varArgs = target.isVarargsCollector(); + final MethodHandle fixTarget = varArgs ? target.asFixedArity() : target; + final int fixParamsLen = varArgs ? paramsLen - 1 : paramsLen; + final int argsLen = callSiteType.parameterCount(); + if(argsLen < fixParamsLen) { + // Less actual arguments than number of fixed declared arguments; can't invoke. + return null; + } + // Method handle has the same number of fixed arguments as the call site type + if(argsLen == fixParamsLen) { + // Method handle that matches the number of actual arguments as the number of fixed arguments + final MethodHandle matchedMethod; + if(varArgs) { + // If vararg, add a zero-length array of the expected type as the last argument to signify no variable + // arguments. + matchedMethod = MethodHandles.insertArguments(fixTarget, fixParamsLen, Array.newInstance( + methodType.parameterType(fixParamsLen).getComponentType(), 0)); + } else { + // Otherwise, just use the method + matchedMethod = fixTarget; + } + return createConvertingInvocation(matchedMethod, linkerServices, callSiteType); + } + + // What's below only works for varargs + if(!varArgs) { + return null; + } + + final Class varArgType = methodType.parameterType(fixParamsLen); + // Handle a somewhat sinister corner case: caller passes exactly one argument in the vararg position, and we + // must handle both a prepacked vararg array as well as a genuine 1-long vararg sequence. + if(argsLen == paramsLen) { + final Class callSiteLastArgType = callSiteType.parameterType(fixParamsLen); + if(varArgType.isAssignableFrom(callSiteLastArgType)) { + // Call site signature guarantees we'll always be passed a single compatible array; just link directly + // to the method, introducing necessary conversions. Also, preserve it being a variable arity method. + return createConvertingInvocation(target, linkerServices, callSiteType).asVarargsCollector( + callSiteLastArgType); + } + if(!linkerServices.canConvert(callSiteLastArgType, varArgType)) { + // Call site signature guarantees the argument can definitely not be an array (i.e. it is primitive); + // link immediately to a vararg-packing method handle. + return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType); + } + // Call site signature makes no guarantees that the single argument in the vararg position will be + // compatible across all invocations. Need to insert an appropriate guard and fall back to generic vararg + // method when it is not. + return MethodHandles.guardWithTest(Guards.isInstance(varArgType, fixParamsLen, callSiteType), + createConvertingInvocation(fixTarget, linkerServices, callSiteType), + createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType)); + } + + // Remaining case: more than one vararg. + return createConvertingInvocation(collectArguments(fixTarget, argsLen), linkerServices, callSiteType); + } + + /** + * Creates a method handle out of the original target that will collect the varargs for the exact component type of + * the varArg array. Note that this will nicely trigger language-specific type converters for exactly those varargs + * for which it is necessary when later passed to linkerServices.convertArguments(). + * + * @param target the original method handle + * @param parameterCount the total number of arguments in the new method handle + * @return a collecting method handle + */ + static MethodHandle collectArguments(MethodHandle target, final int parameterCount) { + final MethodType methodType = target.type(); + final int fixParamsLen = methodType.parameterCount() - 1; + final Class arrayType = methodType.parameterType(fixParamsLen); + return target.asCollector(arrayType, parameterCount - fixParamsLen); + } + + private static MethodHandle createConvertingInvocation(final MethodHandle sizedMethod, + final LinkerServices linkerServices, final MethodType callSiteType) { + return linkerServices.asType(sizedMethod, callSiteType); + } + + private static boolean typeMatchesDescription(String paramTypes, MethodType type) { + final StringTokenizer tok = new StringTokenizer(paramTypes, ", "); + for(int i = 1; i < type.parameterCount(); ++i) { // i = 1 as we ignore the receiver + if(!(tok.hasMoreTokens() && typeNameMatches(tok.nextToken(), type.parameterType(i)))) { + return false; + } + } + return !tok.hasMoreTokens(); + } + + private static boolean typeNameMatches(String typeName, Class type) { + return typeName.equals(typeName.indexOf('.') == -1 ? type.getSimpleName() : type.getCanonicalName()); + } +} diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java index 214152a41ec..62ce41a95a6 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java +++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassIntrospector.java @@ -106,10 +106,18 @@ class StaticClassIntrospector extends FacetIntrospector { @Override MethodHandle editMethodHandle(MethodHandle mh) { + return editStaticMethodHandle(mh); + } + + static MethodHandle editStaticMethodHandle(MethodHandle mh) { return dropReceiver(mh, Object.class); } - static MethodHandle dropReceiver(final MethodHandle mh, final Class receiverClass) { + static MethodHandle editConstructorMethodHandle(MethodHandle cmh) { + return dropReceiver(cmh, StaticClass.class); + } + + private static MethodHandle dropReceiver(final MethodHandle mh, final Class receiverClass) { MethodHandle newHandle = MethodHandles.dropArguments(mh, 0, receiverClass); // NOTE: this is a workaround for the fact that dropArguments doesn't preserve vararg collector state. if(mh.isVarargsCollector() && !newHandle.isVarargsCollector()) { diff --git a/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java index d6096fe559b..8cd221f3df4 100644 --- a/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java +++ b/nashorn/src/jdk/internal/dynalink/beans/StaticClassLinker.java @@ -87,9 +87,7 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import java.lang.reflect.Array; -import java.lang.reflect.Constructor; -import java.util.ArrayList; -import java.util.List; +import java.util.Arrays; import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.beans.GuardedInvocationComponent.ValidationType; import jdk.internal.dynalink.linker.GuardedInvocation; @@ -131,20 +129,11 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { private static DynamicMethod createConstructorMethod(Class clazz) { if(clazz.isArray()) { final MethodHandle boundArrayCtor = ARRAY_CTOR.bindTo(clazz.getComponentType()); - return new SimpleDynamicMethod(drop(boundArrayCtor.asType(boundArrayCtor.type().changeReturnType( - clazz))), clazz, ""); + return new SimpleDynamicMethod(StaticClassIntrospector.editConstructorMethodHandle( + boundArrayCtor.asType(boundArrayCtor.type().changeReturnType(clazz))), clazz, ""); } - final Constructor[] ctrs = clazz.getConstructors(); - final List mhs = new ArrayList<>(ctrs.length); - for(int i = 0; i < ctrs.length; ++i) { - mhs.add(drop(SafeUnreflector.unreflectConstructor(ctrs[i]))); - } - return createDynamicMethod(mhs, clazz, ""); - } - - private static MethodHandle drop(MethodHandle mh) { - return StaticClassIntrospector.dropReceiver(mh, StaticClass.class); + return createDynamicMethod(Arrays.asList(clazz.getConstructors()), clazz, ""); } @Override @@ -161,11 +150,10 @@ class StaticClassLinker implements TypeBasedGuardingDynamicLinker { } final CallSiteDescriptor desc = request.getCallSiteDescriptor(); final String op = desc.getNameToken(CallSiteDescriptor.OPERATOR); - final MethodType methodType = desc.getMethodType(); if("new" == op && constructor != null) { - final MethodHandle ctorInvocation = constructor.getInvocation(methodType, linkerServices); + final MethodHandle ctorInvocation = constructor.getInvocation(desc, linkerServices); if(ctorInvocation != null) { - return new GuardedInvocation(ctorInvocation, getClassGuard(methodType)); + return new GuardedInvocation(ctorInvocation, getClassGuard(desc.getMethodType())); } } return null; diff --git a/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java b/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java index e51f6fe2f2a..3161cf50a76 100644 --- a/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java +++ b/nashorn/src/jdk/internal/dynalink/support/AbstractCallSiteDescriptor.java @@ -139,8 +139,9 @@ public abstract class AbstractCallSiteDescriptor implements CallSiteDescriptor { @Override public int hashCode() { + final MethodHandles.Lookup lookup = getLookup(); + int h = lookup.lookupClass().hashCode() + 31 * lookup.lookupModes(); final int c = getNameTokenCount(); - int h = 0; for(int i = 0; i < c; ++i) { h = h * 31 + getNameToken(i).hashCode(); } diff --git a/nashorn/src/jdk/internal/dynalink/support/Lookup.java b/nashorn/src/jdk/internal/dynalink/support/Lookup.java index 52a610246a8..4b21e1c4af4 100644 --- a/nashorn/src/jdk/internal/dynalink/support/Lookup.java +++ b/nashorn/src/jdk/internal/dynalink/support/Lookup.java @@ -122,6 +122,18 @@ public class Lookup { * @return the unreflected method handle. */ public MethodHandle unreflect(Method m) { + return unreflect(lookup, m); + } + + /** + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflect(Method)}, converting any encountered + * {@link IllegalAccessException} into an {@link IllegalAccessError}. + * + * @param lookup the lookup used to unreflect + * @param m the method to unreflect + * @return the unreflected method handle. + */ + public static MethodHandle unreflect(MethodHandles.Lookup lookup, Method m) { try { return lookup.unreflect(m); } catch(IllegalAccessException e) { @@ -131,7 +143,6 @@ public class Lookup { } } - /** * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter(Field)}, converting any encountered * {@link IllegalAccessException} into an {@link IllegalAccessError}. @@ -202,6 +213,18 @@ public class Lookup { * @return the unreflected constructor handle. */ public MethodHandle unreflectConstructor(Constructor c) { + return unreflectConstructor(lookup, c); + } + + /** + * Performs a {@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor(Constructor)}, converting any + * encountered {@link IllegalAccessException} into an {@link IllegalAccessError}. + * + * @param lookup the lookup used to unreflect + * @param c the constructor to unreflect + * @return the unreflected constructor handle. + */ + public static MethodHandle unreflectConstructor(MethodHandles.Lookup lookup, Constructor c) { try { return lookup.unreflectConstructor(c); } catch(IllegalAccessException e) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java index 6b55656ba17..3f3c2a5b8b3 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java @@ -78,7 +78,7 @@ public final class Bootstrap { * @return CallSite with MethodHandle to appropriate method or null if not found. */ public static CallSite bootstrap(final Lookup lookup, final String opDesc, final MethodType type, final int flags) { - return dynamicLinker.link(LinkerCallSite.newLinkerCallSite(opDesc, type, flags)); + return dynamicLinker.link(LinkerCallSite.newLinkerCallSite(lookup, opDesc, type, flags)); } /** @@ -94,12 +94,12 @@ public final class Bootstrap { return new RuntimeCallSite(type, initialName); } - /** - * Returns a dynamic invoker for a specified dynamic operation. You can use this method to create a method handle - * that when invoked acts completely as if it were a Nashorn-linked call site. An overview of available dynamic - * operations can be found in the Dynalink User Guide, - * but we'll show few examples here: + * Returns a dynamic invoker for a specified dynamic operation using the public lookup. You can use this method to + * create a method handle that when invoked acts completely as if it were a Nashorn-linked call site. An overview of + * available dynamic operations can be found in the + * Dynalink User Guide, but we'll show few + * examples here: *
    *
  • Get a named property with fixed name: *
    @@ -196,7 +196,7 @@ public final class Bootstrap {
         }
     
         /**
    -     * Returns a dynamic invoker for a specified dynamic operation. Similar to
    +     * Returns a dynamic invoker for a specified dynamic operation using the public lookup. Similar to
          * {@link #createDynamicInvoker(String, Class, Class...)} but with return and parameter types composed into a
          * method type in the signature. See the discussion of that method for details.
          * @param opDesc Dynalink dynamic operation descriptor.
    @@ -204,7 +204,7 @@ public final class Bootstrap {
          * @return MethodHandle for invoking the operation.
          */
         public static MethodHandle createDynamicInvoker(final String opDesc, final MethodType type) {
    -        return bootstrap(null, opDesc, type, 0).dynamicInvoker();
    +        return bootstrap(MethodHandles.publicLookup(), opDesc, type, 0).dynamicInvoker();
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
    index ecec63bcbad..f207d37cf66 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java
    @@ -28,6 +28,7 @@ package jdk.nashorn.internal.runtime.linker;
     import static jdk.nashorn.internal.lookup.Lookup.MH;
     
     import java.lang.invoke.MethodHandle;
    +import java.lang.invoke.MethodHandles;
     import java.lang.invoke.MethodType;
     import java.lang.reflect.Modifier;
     import java.security.AccessController;
    @@ -39,7 +40,6 @@ import java.util.Collections;
     import java.util.HashMap;
     import java.util.List;
     import java.util.Map;
    -
     import jdk.internal.dynalink.beans.StaticClass;
     import jdk.internal.dynalink.support.LinkRequestImpl;
     import jdk.nashorn.internal.objects.NativeJava;
    @@ -119,9 +119,12 @@ public final class JavaAdapterFactory {
             return AccessController.doPrivileged(new PrivilegedExceptionAction() {
                 @Override
                 public MethodHandle run() throws Exception {
    -                return  MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(NashornCallSiteDescriptor.get(
    -                    "dyn:new", MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
    -                    adapterClass, null)).getInvocation(), adapterClass);
    +                // NOTE: we use publicLookup(), but none of our adapter constructors are caller sensitive, so this is
    +                // okay, we won't artificially limit access.
    +                return  MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
    +                        NashornCallSiteDescriptor.get(MethodHandles.publicLookup(),  "dyn:new",
    +                                MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
    +                                adapterClass, null)).getInvocation(), adapterClass);
                 }
             });
         }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
    index 7457641e987..5665f02f3e4 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/LinkerCallSite.java
    @@ -25,7 +25,6 @@
     
     package jdk.nashorn.internal.runtime.linker;
     
    -import jdk.nashorn.internal.lookup.MethodHandleFactory;
     import static jdk.nashorn.internal.lookup.Lookup.MH;
     
     import java.io.FileNotFoundException;
    @@ -47,6 +46,7 @@ import java.util.concurrent.atomic.AtomicInteger;
     import jdk.internal.dynalink.ChainedCallSite;
     import jdk.internal.dynalink.DynamicLinker;
     import jdk.internal.dynalink.linker.GuardedInvocation;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory;
     import jdk.nashorn.internal.runtime.Context;
     import jdk.nashorn.internal.runtime.Debug;
     import jdk.nashorn.internal.runtime.ScriptObject;
    @@ -79,8 +79,9 @@ public class LinkerCallSite extends ChainedCallSite {
          * @param flags    Call site specific flags.
          * @return New LinkerCallSite.
          */
    -    static LinkerCallSite newLinkerCallSite(final String name, final MethodType type, final int flags) {
    -        final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(name, type, flags);
    +    static LinkerCallSite newLinkerCallSite(final MethodHandles.Lookup lookup, final String name, final MethodType type,
    +            final int flags) {
    +        final NashornCallSiteDescriptor desc = NashornCallSiteDescriptor.get(lookup, name, type, flags);
     
             if (desc.isProfile()) {
                 return ProfilingLinkerCallSite.newProfilingLinkerCallSite(desc);
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
    index 8cb360c4fcf..58ef2703882 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornCallSiteDescriptor.java
    @@ -25,9 +25,12 @@
     
     package jdk.nashorn.internal.runtime.linker;
     
    +import java.lang.invoke.MethodHandles;
    +import java.lang.invoke.MethodHandles.Lookup;
     import java.lang.invoke.MethodType;
    -import java.lang.ref.WeakReference;
    -import java.util.WeakHashMap;
    +import java.util.Map;
    +import java.util.concurrent.ConcurrentHashMap;
    +import java.util.concurrent.ConcurrentMap;
     import jdk.internal.dynalink.CallSiteDescriptor;
     import jdk.internal.dynalink.support.AbstractCallSiteDescriptor;
     import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
    @@ -70,9 +73,15 @@ public class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
          * set. */
         public static final int CALLSITE_TRACE_SCOPE      = 0x200;
     
    -    private static final WeakHashMap> canonicals =
    -            new WeakHashMap<>();
    +    private static final ClassValue> canonicals =
    +            new ClassValue>() {
    +        @Override
    +        protected ConcurrentMap computeValue(Class type) {
    +            return new ConcurrentHashMap<>();
    +        }
    +    };
     
    +    private final MethodHandles.Lookup lookup;
         private final String operator;
         private final String operand;
         private final MethodType methodType;
    @@ -81,39 +90,35 @@ public class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
         /**
          * Retrieves a Nashorn call site descriptor with the specified values. Since call site descriptors are immutable
          * this method is at liberty to retrieve canonicalized instances (although it is not guaranteed it will do so).
    +     * @param lookup the lookup describing the script
          * @param name the name at the call site, e.g. {@code "dyn:getProp|getElem|getMethod:color"}.
          * @param methodType the method type at the call site
          * @param flags Nashorn-specific call site flags
          * @return a call site descriptor with the specified values.
          */
    -    public static NashornCallSiteDescriptor get(final String name, final MethodType methodType, final int flags) {
    +    public static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String name,
    +            final MethodType methodType, final int flags) {
             final String[] tokenizedName = CallSiteDescriptorFactory.tokenizeName(name);
             assert tokenizedName.length == 2 || tokenizedName.length == 3;
             assert "dyn".equals(tokenizedName[0]);
             assert tokenizedName[1] != null;
             // TODO: see if we can move mangling/unmangling into Dynalink
    -        return get(tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
    +        return get(lookup, tokenizedName[1], tokenizedName.length == 3 ? tokenizedName[2].intern() : null,
                     methodType, flags);
         }
     
    -    private static NashornCallSiteDescriptor get(final String operator, final String operand, final MethodType methodType, final int flags) {
    -        final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(operator, operand, methodType, flags);
    +    private static NashornCallSiteDescriptor get(final MethodHandles.Lookup lookup, final String operator, final String operand, final MethodType methodType, final int flags) {
    +        final NashornCallSiteDescriptor csd = new NashornCallSiteDescriptor(lookup, operator, operand, methodType, flags);
             // Many of these call site descriptors are identical (e.g. every getter for a property color will be
    -        // "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them in a weak map
    -        synchronized(canonicals) {
    -            final WeakReference ref = canonicals.get(csd);
    -            if(ref != null) {
    -                final NashornCallSiteDescriptor canonical = ref.get();
    -                if(canonical != null) {
    -                    return canonical;
    -                }
    -            }
    -            canonicals.put(csd, new WeakReference<>(csd));
    -        }
    -        return csd;
    +        // "dyn:getProp:color(Object)Object", so it makes sense canonicalizing them.
    +        final Map classCanonicals = canonicals.get(lookup.lookupClass());
    +        final NashornCallSiteDescriptor canonical = classCanonicals.putIfAbsent(csd, csd);
    +        return canonical != null ? canonical : csd;
         }
     
    -    private NashornCallSiteDescriptor(final String operator, final String operand, final MethodType methodType, final int flags) {
    +    private NashornCallSiteDescriptor(final MethodHandles.Lookup lookup, final String operator, final String operand,
    +            final MethodType methodType, final int flags) {
    +        this.lookup = lookup;
             this.operator = operator;
             this.operand = operand;
             this.methodType = methodType;
    @@ -141,6 +146,11 @@ public class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
             throw new IndexOutOfBoundsException(String.valueOf(i));
         }
     
    +    @Override
    +    public Lookup getLookup() {
    +        return lookup;
    +    }
    +
         @Override
         public boolean equals(final CallSiteDescriptor csd) {
             return super.equals(csd) && flags == getFlags(csd);
    @@ -279,6 +289,6 @@ public class NashornCallSiteDescriptor extends AbstractCallSiteDescriptor {
     
         @Override
         public CallSiteDescriptor changeMethodType(final MethodType newMethodType) {
    -        return get(operator, operand, newMethodType, flags);
    +        return get(getLookup(), operator, operand, newMethodType, flags);
         }
     }
    diff --git a/nashorn/test/script/basic/JDK-8010946-2.js b/nashorn/test/script/basic/JDK-8010946-2.js
    new file mode 100644
    index 00000000000..c3dc2889a6c
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010946-2.js
    @@ -0,0 +1,38 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8010946: AccessController.doPrivileged() doesn't work as expected.
    + * This is actually a broader issue of having Dynalink correctly handle
    + * caller-sensitive methods.
    + *
    + * @test
    + * @run
    + */
    +
    +// Ensure these are CallerSensitiveDynamicMethods
    +print(java.security.AccessController["doPrivileged(PrivilegedAction)"])
    +print(java.lang.Class["forName(String)"])
    +
    +// Ensure this is not
    +print(java.lang.String["valueOf(char)"])
    diff --git a/nashorn/test/script/basic/JDK-8010946-2.js.EXPECTED b/nashorn/test/script/basic/JDK-8010946-2.js.EXPECTED
    new file mode 100644
    index 00000000000..d573510c9de
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010946-2.js.EXPECTED
    @@ -0,0 +1,3 @@
    +[jdk.internal.dynalink.beans.CallerSensitiveDynamicMethod Object java.security.AccessController.doPrivileged(PrivilegedAction)]
    +[jdk.internal.dynalink.beans.CallerSensitiveDynamicMethod Class java.lang.Class.forName(String)]
    +[jdk.internal.dynalink.beans.SimpleDynamicMethod String java.lang.String.valueOf(char)]
    diff --git a/nashorn/test/script/basic/JDK-8010946-privileged.js b/nashorn/test/script/basic/JDK-8010946-privileged.js
    new file mode 100644
    index 00000000000..fc409f97172
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010946-privileged.js
    @@ -0,0 +1,47 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8010946: AccessController.doPrivileged() doesn't work as expected.
    + * This is actually a broader issue of having Dynalink correctly handle
    + * caller-sensitive methods.
    + * 
    + * NOTE: This is not a standalone test file, it is loaded by JDK-801946.js
    + * @subtest
    + */
    +
    +(function() {
    +    var getProperty = java.lang.System.getProperty
    +    var doPrivileged = java.security.AccessController["doPrivileged(PrivilegedAction)"]
    +
    +    this.executeUnprivileged = function() {
    +        var x = getProperty("java.security.policy")
    +        if(x != null) {
    +            print("Successfully retrieved restricted system property.")
    +        }
    +    }
    +
    +    this.executePrivileged = function() {
    +        doPrivileged(executeUnprivileged)
    +    }
    +})();
    diff --git a/nashorn/test/script/basic/JDK-8010946.js b/nashorn/test/script/basic/JDK-8010946.js
    new file mode 100644
    index 00000000000..4f0124273e0
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010946.js
    @@ -0,0 +1,51 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8010946: AccessController.doPrivileged() doesn't work as expected.
    + * This is actually a broader issue of having Dynalink correctly handle
    + * caller-sensitive methods.
    + *
    + * @test
    + * @run
    + */
    +
    +// This is unprivileged code that loads privileged code.
    +load(__DIR__ + "JDK-8010946-privileged.js")
    +
    +try {
    +    // This should fail, even though the code itself resides in the 
    +    // privileged script, as we're invoking it without going through
    +    // doPrivileged()
    +    print("Attempting unprivileged execution...")
    +    executeUnprivileged()
    +    print("FAIL: Unprivileged execution succeeded!")
    +} catch(e) {
    +    print("Unprivileged execution failed with " + e)
    +}
    +
    +print()
    +
    +// This should succeed, as it's going through doPrivileged().
    +print("Attempting privileged execution...")
    +executePrivileged()
    diff --git a/nashorn/test/script/basic/JDK-8010946.js.EXPECTED b/nashorn/test/script/basic/JDK-8010946.js.EXPECTED
    new file mode 100644
    index 00000000000..f78956a884b
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8010946.js.EXPECTED
    @@ -0,0 +1,5 @@
    +Attempting unprivileged execution...
    +Unprivileged execution failed with java.security.AccessControlException: access denied ("java.util.PropertyPermission" "java.security.policy" "read")
    +
    +Attempting privileged execution...
    +Successfully retrieved restricted system property.
    
    From 62fb002570c159e70c4533eea2436200ece9ab27 Mon Sep 17 00:00:00 2001
    From: Marcus Lagergren 
    Date: Wed, 3 Jul 2013 13:03:36 +0200
    Subject: [PATCH 016/156] 8019585: Sometimes a var declaration using itself in
     its init wasn't declared as canBeUndefined, causing erroneous bytecode
    
    Reviewed-by: sundar, attila
    ---
     .../api/scripting/NashornException.java       |  4 +--
     .../jdk/nashorn/internal/codegen/Attr.java    | 19 ++++++++++-
     .../internal/codegen/CodeGenerator.java       |  2 +-
     .../internal/objects/ArrayBufferView.java     |  1 +
     .../jdk/nashorn/internal/objects/Global.java  |  1 +
     .../nashorn/internal/objects/NativeError.java |  5 +--
     .../internal/objects/NativeFloat32Array.java  |  1 +
     .../internal/objects/NativeFloat64Array.java  |  1 +
     .../internal/objects/NativeFunction.java      |  2 ++
     .../internal/objects/NativeInt16Array.java    |  1 +
     .../internal/objects/NativeInt32Array.java    |  1 +
     .../internal/objects/NativeInt8Array.java     |  1 +
     .../nashorn/internal/objects/NativeJava.java  |  2 ++
     .../internal/objects/NativeObject.java        |  2 +-
     .../internal/objects/NativeRegExp.java        |  1 +
     .../internal/objects/NativeUint16Array.java   |  1 +
     .../internal/objects/NativeUint32Array.java   |  1 +
     .../internal/objects/NativeUint8Array.java    |  1 +
     .../objects/NativeUint8ClampedArray.java      |  1 +
     .../internal/objects/ScriptFunctionImpl.java  |  9 ++---
     .../runtime/arrays/ObjectArrayData.java       |  2 +-
     nashorn/test/script/basic/JDK-8019585.js      | 34 +++++++++++++++++++
     22 files changed, 81 insertions(+), 12 deletions(-)
     create mode 100644 nashorn/test/script/basic/JDK-8019585.js
    
    diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
    index 3cd687cce08..d5ec5bb4a60 100644
    --- a/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
    +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornException.java
    @@ -146,7 +146,7 @@ public abstract class NashornException extends RuntimeException {
          * @return array of javascript stack frames
          */
         public static StackTraceElement[] getScriptFrames(final Throwable exception) {
    -        final StackTraceElement[] frames = ((Throwable)exception).getStackTrace();
    +        final StackTraceElement[] frames = exception.getStackTrace();
             final List filtered = new ArrayList<>();
             for (final StackTraceElement st : frames) {
                 if (ECMAErrors.isScriptFrame(st)) {
    @@ -170,7 +170,7 @@ public abstract class NashornException extends RuntimeException {
          */
         public static String getScriptStackString(final Throwable exception) {
             final StringBuilder buf = new StringBuilder();
    -        final StackTraceElement[] frames = getScriptFrames((Throwable)exception);
    +        final StackTraceElement[] frames = getScriptFrames(exception);
             for (final StackTraceElement st : frames) {
                 buf.append("\tat ");
                 buf.append(st.getMethodName());
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
    index d4b3405fb26..e9cc259fb3d 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
    @@ -54,6 +54,7 @@ import java.util.HashSet;
     import java.util.Iterator;
     import java.util.List;
     import java.util.Set;
    +
     import jdk.nashorn.internal.codegen.types.Type;
     import jdk.nashorn.internal.ir.AccessNode;
     import jdk.nashorn.internal.ir.BinaryNode;
    @@ -234,10 +235,25 @@ final class Attr extends NodeOperatorVisitor {
                 @Override
                 public boolean enterVarNode(final VarNode varNode) {
                     final String name = varNode.getName().getName();
    -                //if this is used the var node symbol needs to be tagged as can be undefined
    +                //if this is used before the var node, the var node symbol needs to be tagged as can be undefined
                     if (uses.contains(name)) {
                         canBeUndefined.add(name);
                     }
    +
    +                // all uses of the declared varnode inside the var node are potentially undefined
    +                // however this is a bit conservative as e.g. var x = 17; var x = 1 + x; does work
    +                if (!varNode.isFunctionDeclaration() && varNode.getInit() != null) {
    +                    varNode.getInit().accept(new NodeVisitor(new LexicalContext()) {
    +                       @Override
    +                       public boolean enterIdentNode(final IdentNode identNode) {
    +                           if (name.equals(identNode.getName())) {
    +                              canBeUndefined.add(name);
    +                           }
    +                           return false;
    +                       }
    +                    });
    +                }
    +
                     return true;
                 }
     
    @@ -257,6 +273,7 @@ final class Attr extends NodeOperatorVisitor {
                         }
                         return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
                     }
    +
                     return varNode;
                 }
             });
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    index d0bf7cd563e..6ea53a408fa 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    @@ -1847,7 +1847,7 @@ final class CodeGenerator extends NodeOperatorVisitor exprClass = type.getTypeClass();
                     method.invoke(staticCallNoLookup(ScriptRuntime.class, "switchTagAsInt", int.class, exprClass.isPrimitive()? exprClass : Object.class, int.class));
                 }
     
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
    index 312d521c65e..6e58c4cdbae 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
    @@ -40,6 +40,7 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.rangeError;
     abstract class ArrayBufferView extends ScriptObject {
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java
    index 5644c510642..f1b65e5cb02 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java
    @@ -382,6 +382,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
         private final Context context;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    index 07f5d65aa7b..b8f69c502e4 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    @@ -119,6 +119,7 @@ public final class NativeError extends ScriptObject {
          * Nashorn extension: Error.captureStackTrace. Capture stack trace at the point of call into the Error object provided.
          *
          * @param self self reference
    +     * @param errorObj the error object
          * @return undefined
          */
         @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
    @@ -286,9 +287,9 @@ public final class NativeError extends ScriptObject {
             final Object exception = ECMAException.getException(sobj);
             if (exception instanceof Throwable) {
                 return getScriptStackString(sobj, (Throwable)exception);
    -        } else {
    -            return "";
             }
    +
    +        return "";
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    index beb7d50e542..852f448dd1e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    @@ -48,6 +48,7 @@ public final class NativeFloat32Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 4;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    index 3451e31527c..4ea52991243 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    @@ -48,6 +48,7 @@ public final class NativeFloat64Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 8;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    index 7df1b521027..5e5f42f0475 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    @@ -29,6 +29,7 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
     import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
     
     import java.util.List;
    +
     import jdk.nashorn.api.scripting.ScriptObjectMirror;
     import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Constructor;
    @@ -55,6 +56,7 @@ import jdk.nashorn.internal.runtime.Source;
     public final class NativeFunction {
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         // do *not* create me!
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    index d05c69d70a5..24b2383756c 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    @@ -42,6 +42,7 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
     public final class NativeInt16Array extends ArrayBufferView {
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    index 596b935cb7d..a89d8350a50 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    @@ -47,6 +47,7 @@ public final class NativeInt32Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 4;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    index f1a9b7f7100..316fdab50d8 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    @@ -47,6 +47,7 @@ public final class NativeInt8Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 1;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    index 7a9ec38fe87..288770b45ef 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    @@ -32,6 +32,7 @@ import java.lang.reflect.Array;
     import java.util.Collection;
     import java.util.Deque;
     import java.util.List;
    +
     import jdk.internal.dynalink.beans.StaticClass;
     import jdk.internal.dynalink.support.TypeUtilities;
     import jdk.nashorn.internal.objects.annotations.Attribute;
    @@ -54,6 +55,7 @@ import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
     public final class NativeJava {
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private NativeJava() {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    index 1034034506b..7112557e1d0 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    @@ -27,7 +27,6 @@ package jdk.nashorn.internal.objects;
     
     import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
     import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
    -
     import jdk.nashorn.api.scripting.ScriptObjectMirror;
     import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Constructor;
    @@ -55,6 +54,7 @@ public final class NativeObject {
         private static final InvokeByName TO_STRING = new InvokeByName("toString", ScriptObject.class);
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private NativeObject() {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    index bec8b37db0a..1ba8b4df01b 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    @@ -68,6 +68,7 @@ public final class NativeRegExp extends ScriptObject {
         private Global globalObject;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         NativeRegExp(final String input, final String flagString) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    index 39c19131280..d19e787195d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    @@ -47,6 +47,7 @@ public final class NativeUint16Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 2;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    index 37102bae590..87a383cb555 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    @@ -48,6 +48,7 @@ public final class NativeUint32Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 4;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    index aa6f89bec67..6ae786f3fda 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    @@ -47,6 +47,7 @@ public final class NativeUint8Array extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 1;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    index 4467c856f06..02b7a4edcd0 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    @@ -48,6 +48,7 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
         public static final int BYTES_PER_ELEMENT = 1;
     
         // initialized by nasgen
    +    @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
         private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    index 6834ef4b701..d49f4d3331b 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    @@ -149,12 +149,13 @@ public class ScriptFunctionImpl extends ScriptFunction {
             return typeErrorThrower;
         }
     
    -    private static PropertyMap createStrictModeMap(PropertyMap map) {
    +    private static PropertyMap createStrictModeMap(final PropertyMap map) {
             final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE;
    +        PropertyMap newMap = map;
             // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors.
    -        map = map.addProperty(map.newUserAccessors("arguments", flags));
    -        map = map.addProperty(map.newUserAccessors("caller", flags));
    -        return map;
    +        newMap = newMap.addProperty(map.newUserAccessors("arguments", flags));
    +        newMap = newMap.addProperty(map.newUserAccessors("caller", flags));
    +        return newMap;
         }
     
         // Choose the map based on strict mode!
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
    index 4b1f58a430a..41c4d5ced30 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/arrays/ObjectArrayData.java
    @@ -146,7 +146,7 @@ final class ObjectArrayData extends ArrayData {
     
         @Override
         public ArrayData setEmpty(final long lo, final long hi) {
    -        Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, (long)Integer.MAX_VALUE), ScriptRuntime.EMPTY);
    +        Arrays.fill(array, (int)Math.max(lo, 0L), (int)Math.min(hi, Integer.MAX_VALUE), ScriptRuntime.EMPTY);
             return this;
         }
     
    diff --git a/nashorn/test/script/basic/JDK-8019585.js b/nashorn/test/script/basic/JDK-8019585.js
    new file mode 100644
    index 00000000000..58d18f35a7f
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019585.js
    @@ -0,0 +1,34 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019585 - use before def issues with vars using the declared var
    + * legal - but needs to set "a" as undefined
    + *
    + * @test
    + * @run
    + */
    +
    +function f() {
    +    var a = b == 17 && (a = toto(b)) && toto2(a); 
    +}
    
    From 72a7034a41cbce7843bc66442136a3b490b826a5 Mon Sep 17 00:00:00 2001
    From: Athijegannathan Sundararajan 
    Date: Wed, 3 Jul 2013 17:26:31 +0530
    Subject: [PATCH 017/156] 8019805: for each (init; test; modify) is invalid
    
    Reviewed-by: lagergren, jlaskey
    ---
     .../jdk/nashorn/internal/parser/Parser.java   |  6 ++++
     .../runtime/resources/Messages.properties     |  1 +
     nashorn/test/script/basic/JDK-8019805.js      | 36 +++++++++++++++++++
     .../test/script/basic/JDK-8019805.js.EXPECTED |  3 ++
     nashorn/test/script/basic/forin.js            |  5 ---
     nashorn/test/script/basic/forin.js.EXPECTED   | 10 ------
     6 files changed, 46 insertions(+), 15 deletions(-)
     create mode 100644 nashorn/test/script/basic/JDK-8019805.js
     create mode 100644 nashorn/test/script/basic/JDK-8019805.js.EXPECTED
    
    diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
    index 181dcf83dd4..efd6eda6435 100644
    --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java
    +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
    @@ -1084,6 +1084,12 @@ loop:
                 switch (type) {
                 case SEMICOLON:
                     // for (init; test; modify)
    +
    +                // for each (init; test; modify) is invalid
    +                if (forNode.isForEach()) {
    +                    throw error(AbstractParser.message("for.each.without.in"), token);
    +                }
    +
                     expect(SEMICOLON);
                     if (type != SEMICOLON) {
                         forNode = forNode.setTest(lc, expression());
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
    index 83c0a5abb00..8ec4f7e17f1 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
    @@ -50,6 +50,7 @@ parser.error.no.func.decl.here=Function declarations can only occur at program o
     parser.error.no.func.decl.here.warn=Function declarations should only occur at program or function body level. Function declaration in nested block was converted to a function expression.
     parser.error.property.redefinition=Property "{0}" already defined
     parser.error.unexpected.token=Unexpected token: {0}
    +parser.error.for.each.without.in=for each can only be used with for..in
     parser.error.many.vars.in.for.in.loop=Only one variable allowed in for..in loop
     parser.error.not.lvalue.for.in.loop=Invalid left side value of for..in loop
     parser.error.missing.catch.or.finally=Missing catch or finally after try
    diff --git a/nashorn/test/script/basic/JDK-8019805.js b/nashorn/test/script/basic/JDK-8019805.js
    new file mode 100644
    index 00000000000..70371fb85e0
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019805.js
    @@ -0,0 +1,36 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019805: for each (init; test; modify) is invalid
    + *
    + * @test
    + * @run
    + */
    +
    +try {
    +    eval("for each(var v=0;false;);");
    +    print("FAILED: for each(var v=0; false;); should have thrown error");
    +} catch (e) {
    +    print(e.toString().replace(/\\/g, '/'));
    +}
    diff --git a/nashorn/test/script/basic/JDK-8019805.js.EXPECTED b/nashorn/test/script/basic/JDK-8019805.js.EXPECTED
    new file mode 100644
    index 00000000000..154c3326372
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019805.js.EXPECTED
    @@ -0,0 +1,3 @@
    +SyntaxError: test/script/basic/JDK-8019805.js#32:1:16 for each can only be used with for..in
    +for each(var v=0;false;);
    +                ^
    diff --git a/nashorn/test/script/basic/forin.js b/nashorn/test/script/basic/forin.js
    index ee3fa89b64a..2a60a660c56 100644
    --- a/nashorn/test/script/basic/forin.js
    +++ b/nashorn/test/script/basic/forin.js
    @@ -49,8 +49,3 @@ for each (i in s) print(i);
     // 'each' is a contextual keyword. Ok to use as identifier elsewhere..
     var each = "This is each";
     print(each);
    -
    -// it is ok to use "each" is usual for loop. Ignored as noise word.
    -for each (var i = 0; i < 10; i++) {
    -    print(i);
    -}
    diff --git a/nashorn/test/script/basic/forin.js.EXPECTED b/nashorn/test/script/basic/forin.js.EXPECTED
    index 159e43ba843..f5b96f12ba7 100644
    --- a/nashorn/test/script/basic/forin.js.EXPECTED
    +++ b/nashorn/test/script/basic/forin.js.EXPECTED
    @@ -25,13 +25,3 @@ apple
     bear
     car
     This is each
    -0
    -1
    -2
    -3
    -4
    -5
    -6
    -7
    -8
    -9
    
    From 047d1b732f383ea4f65723ab99ec73ef2eccf3dc Mon Sep 17 00:00:00 2001
    From: Marcus Lagergren 
    Date: Wed, 3 Jul 2013 15:46:03 +0200
    Subject: [PATCH 018/156] 8019811: Static calls - self referential functions
     needed a return type conversion if they were specialized, as they can't use
     the same mechanism as indy calls
    
    Reviewed-by: sundar, jlaskey
    ---
     .../internal/codegen/CodeGenerator.java       | 20 ++++----
     nashorn/test/script/basic/JDK-8016667.js      | 20 ++++++++
     nashorn/test/script/basic/JDK-8019808.js      | 39 +++++++++++++++
     nashorn/test/script/basic/JDK-8019810.js      | 36 ++++++++++++++
     .../test/script/basic/JDK-8019810.js.EXPECTED |  1 +
     nashorn/test/script/basic/JDK-8019811.js      | 47 +++++++++++++++++++
     nashorn/test/script/basic/JDK-8019817.js      | 37 +++++++++++++++
     .../script/currently-failing/JDK-8019809.js   | 37 +++++++++++++++
     8 files changed, 228 insertions(+), 9 deletions(-)
     create mode 100644 nashorn/test/script/basic/JDK-8019808.js
     create mode 100644 nashorn/test/script/basic/JDK-8019810.js
     create mode 100644 nashorn/test/script/basic/JDK-8019810.js.EXPECTED
     create mode 100644 nashorn/test/script/basic/JDK-8019811.js
     create mode 100644 nashorn/test/script/basic/JDK-8019817.js
     create mode 100644 nashorn/test/script/currently-failing/JDK-8019809.js
    
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    index 6ea53a408fa..df6906c6bb7 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    @@ -578,6 +578,7 @@ final class CodeGenerator extends NodeOperatorVisitor(new LexicalContext()) {
     
    @@ -593,7 +594,7 @@ final class CodeGenerator extends NodeOperatorVisitor> window;
    +}
    +
    +Function("L:if((function x ()3)() + arguments++) {return; } else if (new gc()) while(((x2.prop = functional)) && 0){ }"); 
    +
    +Function("var x = x -= '' "); 
    +
    +Function("switch((Math.pow ? x = 1.2e3 : 3)) { default: return; }") 
    +
    +Function("x = 0.1, x\ntrue\n~this");
    +
    +Function("with((function (x)x2)() ^ this){return; }");
    + 
    \ No newline at end of file
    diff --git a/nashorn/test/script/basic/JDK-8019817.js b/nashorn/test/script/basic/JDK-8019817.js
    new file mode 100644
    index 00000000000..6611e9b49e7
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019817.js
    @@ -0,0 +1,37 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019817: More number coercion issues
    + *
    + * @test
    + * @run
    + */
    +var y = 17.17;
    +
    +Function("return y % function(q) { return q; }();"); 
    +
    +function f() {
    +    return y % function(q) { return q; }();
    +}
    +f();
    diff --git a/nashorn/test/script/currently-failing/JDK-8019809.js b/nashorn/test/script/currently-failing/JDK-8019809.js
    new file mode 100644
    index 00000000000..cc31bd86201
    --- /dev/null
    +++ b/nashorn/test/script/currently-failing/JDK-8019809.js
    @@ -0,0 +1,37 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019809: Break return combo that generates erroneous bytecode
    + *
    + * @test
    + * @run
    + */
    +
    +//Function("L: {break L;return; }"); 
    +
    +function f() {
    +    L: { break L; return; }
    +}
    +
    +f();
    
    From 1e6e9dc0c6f6815196453949fd4958ca07b94b88 Mon Sep 17 00:00:00 2001
    From: Athijegannathan Sundararajan 
    Date: Wed, 3 Jul 2013 19:20:29 +0530
    Subject: [PATCH 019/156] 8019814: Add regression test for passing cases
    
    Reviewed-by: jlaskey, lagergren
    ---
     .../nashorn/internal/runtime/ListAdapter.java | 25 +++++++
     nashorn/test/script/basic/JDK-8019814.js      | 73 +++++++++++++++++++
     .../test/script/basic/JDK-8019814.js.EXPECTED |  6 ++
     3 files changed, 104 insertions(+)
     create mode 100644 nashorn/test/script/basic/JDK-8019814.js
     create mode 100644 nashorn/test/script/basic/JDK-8019814.js.EXPECTED
    
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java
    index 428cb555fb0..194bd132000 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/ListAdapter.java
    @@ -1,3 +1,28 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.  Oracle designates this
    + * particular file as subject to the "Classpath" exception as provided
    + * by Oracle in the LICENSE file that accompanied this code.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
     package jdk.nashorn.internal.runtime;
     
     import java.util.AbstractList;
    diff --git a/nashorn/test/script/basic/JDK-8019814.js b/nashorn/test/script/basic/JDK-8019814.js
    new file mode 100644
    index 00000000000..24abf53b77e
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019814.js
    @@ -0,0 +1,73 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019814: Add regression test for passing cases
    + *
    + * @test
    + * @run
    + */
    +
    +// java.lang.VerifyError: Bad type on operand stack
    +Function("switch([]) { case 7: }");
    +
    +// java.lang.AssertionError: expecting integer type or object for jump, but found double
    +Function("with(\nnull == (this % {}))( /x/g );");
    +
    +// java.lang.AssertionError: expecting equivalent types on stack but got double and int 
    +try {
    +    eval('Function("/*infloop*/while(((function ()4.)([z1,,], [,,]) - true++))switch(1e+81.x) { default: break; \u0009 }")');
    +} catch (e) {
    +    print(e.toString().replace(/\\/g, '/'));
    +}
    +
    +// java.lang.VerifyError: get long/double overflows locals
    +Function("var x = x -= '' ");
    +
    +// java.lang.AssertionError: object is not compatible with boolean
    +Function("return (null != [,,] <= this);");
    +
    +// java.lang.AssertionError: Only return value on stack allowed at return point
    +// - depth=2 stack = jdk.nashorn.internal.codegen.Label$Stack@4bd0d62f 
    +Function("x = 0.1, x\ntrue\n~this");
    +
    +// java.lang.AssertionError: node NaN ~ window class jdk.nashorn.internal.ir.BinaryNode
    +// has no symbol! [object] function _L1() 
    +Function("throw NaN\n~window;");
    +
    +// java.lang.AssertionError: array element type doesn't match array type
    +Function("if(([(this >>> 4.)].map(gc))) x;");
    +
    +try {
    +    eval('Function("if(--) y;")');
    +} catch (e) {
    +    print(e.toString().replace(/\\/g, '/'));
    +}
    +
    +// java.lang.AssertionError: stacks jdk.nashorn.internal.codegen.Label$Stack@4918f90f
    +// is not equivalent with jdk.nashorn.internal.codegen.Label$Stack@5f9b21a1 at join point 
    +Function("if((null ^ [1]) !== (this.yoyo(false))) {var NaN, x;x\n~[,,z1] }");
    +
    +// java.lang.AssertionError
    +//    at jdk.nashorn.internal.codegen.Attr.enterFunctionBody(Attr.java:276) 
    +Function("return (void ({ set each (x2)y }));"); 
    diff --git a/nashorn/test/script/basic/JDK-8019814.js.EXPECTED b/nashorn/test/script/basic/JDK-8019814.js.EXPECTED
    new file mode 100644
    index 00000000000..51db7b5e953
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019814.js.EXPECTED
    @@ -0,0 +1,6 @@
    +ReferenceError: :1:50 Invalid left hand side for assignment
    +/*infloop*/while(((function ()4.)([z1,,], [,,]) - true++))switch(1e+81.x) { default: break; 	 }
    +                                                  ^
    +SyntaxError: :1:5 Expected l-value but found )
    +if(--) y;
    +     ^
    
    From 45d608aa5bd713a25f1a1819f2f2087096e20280 Mon Sep 17 00:00:00 2001
    From: Sergey Bylokhov 
    Date: Wed, 3 Jul 2013 19:00:10 +0400
    Subject: [PATCH 020/156] 8004859: Graphics.getClipBounds/getClip return
     difference nonequivalent bounds, depending from transform
    
    Reviewed-by: prr, flar
    ---
     .../classes/sun/java2d/SunGraphics2D.java     |  42 ++++----
     .../Graphics2D/Test8004859/Test8004859.java   | 102 ++++++++++++++++++
     2 files changed, 126 insertions(+), 18 deletions(-)
     create mode 100644 jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java
    
    diff --git a/jdk/src/share/classes/sun/java2d/SunGraphics2D.java b/jdk/src/share/classes/sun/java2d/SunGraphics2D.java
    index 3699b5d5174..3921bbcd2ac 100644
    --- a/jdk/src/share/classes/sun/java2d/SunGraphics2D.java
    +++ b/jdk/src/share/classes/sun/java2d/SunGraphics2D.java
    @@ -1795,20 +1795,10 @@ public final class SunGraphics2D
         }
     
         public Rectangle getClipBounds() {
    -        Rectangle r;
             if (clipState == CLIP_DEVICE) {
    -            r = null;
    -        } else if (transformState <= TRANSFORM_INT_TRANSLATE) {
    -            if (usrClip instanceof Rectangle) {
    -                r = new Rectangle((Rectangle) usrClip);
    -            } else {
    -                r = usrClip.getBounds();
    -            }
    -            r.translate(-transX, -transY);
    -        } else {
    -            r = getClip().getBounds();
    +            return null;
             }
    -        return r;
    +        return getClipBounds(new Rectangle());
         }
     
         public Rectangle getClipBounds(Rectangle r) {
    @@ -1817,11 +1807,11 @@ public final class SunGraphics2D
                     if (usrClip instanceof Rectangle) {
                         r.setBounds((Rectangle) usrClip);
                     } else {
    -                    r.setBounds(usrClip.getBounds());
    +                    r.setFrame(usrClip.getBounds2D());
                     }
                     r.translate(-transX, -transY);
                 } else {
    -                r.setBounds(getClip().getBounds());
    +                r.setFrame(getClip().getBounds2D());
                 }
             } else if (r == null) {
                 throw new NullPointerException("null rectangle parameter");
    @@ -1996,10 +1986,10 @@ public final class SunGraphics2D
                 matrix[2] = matrix[0] + rect.getWidth();
                 matrix[3] = matrix[1] + rect.getHeight();
                 tx.transform(matrix, 0, matrix, 0, 2);
    -            rect = new Rectangle2D.Float();
    -            rect.setFrameFromDiagonal(matrix[0], matrix[1],
    -                                      matrix[2], matrix[3]);
    -            return rect;
    +            fixRectangleOrientation(matrix, rect);
    +            return new Rectangle2D.Double(matrix[0], matrix[1],
    +                                          matrix[2] - matrix[0],
    +                                          matrix[3] - matrix[1]);
             }
     
             if (tx.isIdentity()) {
    @@ -2009,6 +1999,22 @@ public final class SunGraphics2D
             return tx.createTransformedShape(clip);
         }
     
    +    /**
    +     * Sets orientation of the rectangle according to the clip.
    +     */
    +    private static void fixRectangleOrientation(double[] m, Rectangle2D clip) {
    +        if (clip.getWidth() > 0 != (m[2] - m[0] > 0)) {
    +            double t = m[0];
    +            m[0] = m[2];
    +            m[2] = t;
    +        }
    +        if (clip.getHeight() > 0 != (m[3] - m[1] > 0)) {
    +            double t = m[1];
    +            m[1] = m[3];
    +            m[3] = t;
    +        }
    +    }
    +
         public void clipRect(int x, int y, int w, int h) {
             clip(new Rectangle(x, y, w, h));
         }
    diff --git a/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java b/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java
    new file mode 100644
    index 00000000000..73e0acaeace
    --- /dev/null
    +++ b/jdk/test/java/awt/Graphics2D/Test8004859/Test8004859.java
    @@ -0,0 +1,102 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +import java.awt.Graphics2D;
    +import java.awt.Rectangle;
    +import java.awt.Shape;
    +import java.awt.geom.NoninvertibleTransformException;
    +import java.awt.image.BufferedImage;
    +
    +import sun.java2d.SunGraphics2D;
    +
    +/**
    + * @test
    + * @bug 8004859
    + * @summary getClipBounds/getClip should return equivalent bounds.
    + * @author Sergey Bylokhov
    + */
    +public final class Test8004859 {
    +
    +    private static Shape[] clips = {new Rectangle(0, 0, 1, 1), new Rectangle(
    +            100, 100, -100, -100)};
    +
    +    private static boolean status = true;
    +
    +    public static void main(final String[] args)
    +            throws NoninvertibleTransformException {
    +        final BufferedImage bi = new BufferedImage(300, 300,
    +                                                   BufferedImage.TYPE_INT_RGB);
    +        final Graphics2D g = (Graphics2D) bi.getGraphics();
    +        test(g);
    +        g.translate(2.0, 2.0);
    +        test(g);
    +        g.translate(-4.0, -4.0);
    +        test(g);
    +        g.scale(2.0, 2.0);
    +        test(g);
    +        g.scale(-4.0, -4.0);
    +        test(g);
    +        g.rotate(Math.toRadians(90));
    +        test(g);
    +        g.rotate(Math.toRadians(90));
    +        test(g);
    +        g.rotate(Math.toRadians(90));
    +        test(g);
    +        g.rotate(Math.toRadians(90));
    +        test(g);
    +        g.dispose();
    +        if (!status) {
    +            throw new RuntimeException("Test failed");
    +        }
    +    }
    +
    +    private static void test(final Graphics2D g) {
    +        for (final Shape clip : clips) {
    +            g.setClip(clip);
    +            if (!g.getClip().equals(clip)) {
    +                System.err.println("Expected clip: " + clip);
    +                System.err.println("Actual clip: " + g.getClip());
    +                System.err.println("bounds="+g.getClip().getBounds2D());
    +                System.err.println("bounds="+g.getClip().getBounds());
    +                status = false;
    +            }
    +            final Rectangle bounds = g.getClipBounds();
    +            if (!clip.equals(bounds)) {
    +                System.err.println("Expected getClipBounds(): " + clip);
    +                System.err.println("Actual getClipBounds(): " + bounds);
    +                status = false;
    +            }
    +            g.getClipBounds(bounds);
    +            if (!clip.equals(bounds)) {
    +                System.err.println("Expected getClipBounds(r): " + clip);
    +                System.err.println("Actual getClipBounds(r): " + bounds);
    +                status = false;
    +            }
    +            if (!clip.getBounds2D().isEmpty() && ((SunGraphics2D) g).clipRegion
    +                    .isEmpty()) {
    +                System.err.println("clipRegion should not be empty");
    +                status = false;
    +            }
    +        }
    +    }
    +}
    
    From 75501c69930ef905a0ea2997e29a2c3a978b09c1 Mon Sep 17 00:00:00 2001
    From: Attila Szegedi 
    Date: Wed, 3 Jul 2013 18:10:12 +0200
    Subject: [PATCH 021/156] 8017768: allow dot as inner class name separator for
     Java.type
    
    Reviewed-by: jlaskey, sundar
    ---
     .../docs/JavaScriptingProgrammersGuide.html   |  9 +++-
     .../nashorn/internal/objects/NativeJava.java  | 45 +++++++++++++++++--
     nashorn/test/script/basic/JDK-8017768.js      | 35 +++++++++++++++
     .../test/script/basic/JDK-8017768.js.EXPECTED |  4 ++
     .../jdk/nashorn/test/models/OuterClass.java   |  4 ++
     5 files changed, 91 insertions(+), 6 deletions(-)
     create mode 100644 nashorn/test/script/basic/JDK-8017768.js
     create mode 100644 nashorn/test/script/basic/JDK-8017768.js.EXPECTED
    
    diff --git a/nashorn/docs/JavaScriptingProgrammersGuide.html b/nashorn/docs/JavaScriptingProgrammersGuide.html
    index 18ae823d82e..dd74d74903e 100644
    --- a/nashorn/docs/JavaScriptingProgrammersGuide.html
    +++ b/nashorn/docs/JavaScriptingProgrammersGuide.html
    @@ -501,14 +501,19 @@ or
      var anArrayListWithSize = new ArrayList(16)
     
    -In the special case of inner classes, you need to use the JVM fully qualified name, meaning using $ sign in the class name: +In the special case of inner classes, you can either use the JVM fully qualified name, meaning using the dollar sign in the class name, or you can use the dot:
    
      var ftype = Java.type("java.awt.geom.Arc2D$Float")
     
    +and + +
    
    + var ftype = Java.type("java.awt.geom.Arc2D.Float")
    +
    -However, once you retrieved the outer class, you can access the inner class as a property on it: +both work. Note however that using the dollar sign is faster, as Java.type first tries to resolve the class name as it is originally specified, and the internal JVM names for inner classes use the dollar sign. If you use the dot, Java.type will internally get a ClassNotFoundException and subsequently retry by changing the last dot to dollar sign. As a matter of fact, it'll keep replacing dots with dollar signs until it either successfully loads the class or runs out of all dots in the name. This way it can correctly resolve and load even multiply nested inner classes with the dot notation. Again, this will be slower than using the dollar signs in the name. An alternative way to access the inner class is as a property of the outer class:
    
      var arctype = Java.type("java.awt.geom.Arc2D")
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    index 288770b45ef..8303c39367a 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    @@ -39,6 +39,7 @@ import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Function;
     import jdk.nashorn.internal.objects.annotations.ScriptClass;
     import jdk.nashorn.internal.objects.annotations.Where;
    +import jdk.nashorn.internal.runtime.Context;
     import jdk.nashorn.internal.runtime.JSType;
     import jdk.nashorn.internal.runtime.ListAdapter;
     import jdk.nashorn.internal.runtime.PropertyMap;
    @@ -105,12 +106,22 @@ public final class NativeJava {
          * var anArrayList = new ArrayList
          * var anArrayListWithSize = new ArrayList(16)
          * 
    - * In the special case of inner classes, you need to use the JVM fully qualified name, meaning using {@code $} sign - * in the class name: + * In the special case of inner classes, you can either use the JVM fully qualified name, meaning using {@code $} + * sign in the class name, or you can use the dot: *
          * var ftype = Java.type("java.awt.geom.Arc2D$Float")
          * 
    - * However, once you retrieved the outer class, you can access the inner class as a property on it: + * and + *
    +     * var ftype = Java.type("java.awt.geom.Arc2D.Float")
    +     * 
    + * both work. Note however that using the dollar sign is faster, as Java.type first tries to resolve the class name + * as it is originally specified, and the internal JVM names for inner classes use the dollar sign. If you use the + * dot, Java.type will internally get a ClassNotFoundException and subsequently retry by changing the last dot to + * dollar sign. As a matter of fact, it'll keep replacing dots with dollar signs until it either successfully loads + * the class or runs out of all dots in the name. This way it can correctly resolve and load even multiply nested + * inner classes with the dot notation. Again, this will be slower than using the dollar signs in the name. An + * alternative way to access the inner class is as a property of the outer class: *
          * var arctype = Java.type("java.awt.geom.Arc2D")
          * var ftype = arctype.Float
    @@ -390,7 +401,33 @@ public final class NativeJava {
     
         private static Class simpleType(final String typeName) throws ClassNotFoundException {
             final Class primClass = TypeUtilities.getPrimitiveTypeByName(typeName);
    -        return primClass != null ? primClass : Global.getThisContext().findClass(typeName);
    +        if(primClass != null) {
    +            return primClass;
    +        }
    +        final Context ctx = Global.getThisContext();
    +        try {
    +            return ctx.findClass(typeName);
    +        } catch(ClassNotFoundException e) {
    +            // The logic below compensates for a frequent user error - when people use dot notation to separate inner
    +            // class names, i.e. "java.lang.Character.UnicodeBlock" vs."java.lang.Character$UnicodeBlock". The logic
    +            // below will try alternative class names, replacing dots at the end of the name with dollar signs.
    +            final StringBuilder nextName = new StringBuilder(typeName);
    +            int lastDot = nextName.length();
    +            for(;;) {
    +                lastDot = nextName.lastIndexOf(".", lastDot - 1);
    +                if(lastDot == -1) {
    +                    // Exhausted the search space, class not found - rethrow the original exception.
    +                    throw e;
    +                }
    +                nextName.setCharAt(lastDot, '$');
    +                try {
    +                    return ctx.findClass(nextName.toString());
    +                } catch(ClassNotFoundException cnfe) {
    +                    // Intentionally ignored, so the loop retries with the next name
    +                }
    +            }
    +        }
    +
         }
     
         private static Class arrayType(final String typeName) throws ClassNotFoundException {
    diff --git a/nashorn/test/script/basic/JDK-8017768.js b/nashorn/test/script/basic/JDK-8017768.js
    new file mode 100644
    index 00000000000..c91f6d1f74a
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8017768.js
    @@ -0,0 +1,35 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8017768: Allow use of dot notation for inner class names.
    + * 
    + * @test
    + * @run
    + */
    +
    +print(Java.type("java.awt.geom.Arc2D.Float") === Java.type("java.awt.geom.Arc2D$Float"))
    +var iisc = Java.type("jdk.nashorn.test.models.OuterClass$InnerStaticClass$InnerInnerStaticClass")
    +print(Java.type("jdk.nashorn.test.models.OuterClass.InnerStaticClass.InnerInnerStaticClass") === iisc)
    +print(Java.type("jdk.nashorn.test.models.OuterClass$InnerStaticClass.InnerInnerStaticClass") === iisc)
    +print(Java.type("jdk.nashorn.test.models.OuterClass.InnerStaticClass$InnerInnerStaticClass") === iisc)
    diff --git a/nashorn/test/script/basic/JDK-8017768.js.EXPECTED b/nashorn/test/script/basic/JDK-8017768.js.EXPECTED
    new file mode 100644
    index 00000000000..1140ff52e2b
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8017768.js.EXPECTED
    @@ -0,0 +1,4 @@
    +true
    +true
    +true
    +true
    diff --git a/nashorn/test/src/jdk/nashorn/test/models/OuterClass.java b/nashorn/test/src/jdk/nashorn/test/models/OuterClass.java
    index 5db86f28c1b..fc280f65734 100644
    --- a/nashorn/test/src/jdk/nashorn/test/models/OuterClass.java
    +++ b/nashorn/test/src/jdk/nashorn/test/models/OuterClass.java
    @@ -33,6 +33,10 @@ public class OuterClass {
         }
     
         public static class InnerStaticClass {
    +
    +        public static class InnerInnerStaticClass {
    +        }
    +
             private final String value;
     
             public InnerStaticClass(String value) {
    
    From 8ebb701354d6b1eca995cceba78eb0b36b17de5e Mon Sep 17 00:00:00 2001
    From: James Laskey 
    Date: Wed, 3 Jul 2013 13:41:18 -0300
    Subject: [PATCH 022/156] 8011629: Object.defineProperty performance issue
    
    Reviewed-by: sundar, attila
    ---
     .../internal/runtime/AccessorProperty.java    | 55 ++++++++++---------
     1 file changed, 30 insertions(+), 25 deletions(-)
    
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
    index bfdfa71995d..1144eb630bd 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
    @@ -75,6 +75,8 @@ public class AccessorProperty extends Property {
     
         private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
         private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
    +    private static final MethodType ACCESSOR_GETTER_PRIMITIVE_TYPE;
    +    private static final MethodType ACCESSOR_SETTER_PRIMITIVE_TYPE;
         private static final MethodHandle SPILL_ELEMENT_GETTER;
         private static final MethodHandle SPILL_ELEMENT_SETTER;
     
    @@ -82,13 +84,25 @@ public class AccessorProperty extends Property {
         private static final MethodHandle[] SPILL_ACCESSORS = new MethodHandle[SPILL_CACHE_SIZE * 2];
     
         static {
    +        MethodType getterPrimitiveType = null;
    +        MethodType setterPrimitiveType = null;
    +
             for (int i = 0; i < NOOF_TYPES; i++) {
                 final Type type = ACCESSOR_TYPES.get(i);
                 ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
                 ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
    +
    +            if (type == PRIMITIVE_TYPE) {
    +                getterPrimitiveType = ACCESSOR_GETTER_TYPES[i];
    +                setterPrimitiveType = ACCESSOR_SETTER_TYPES[i];
    +            }
             }
     
    -        final MethodHandle spillGetter = MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class);
    +        ACCESSOR_GETTER_PRIMITIVE_TYPE = getterPrimitiveType;
    +        ACCESSOR_SETTER_PRIMITIVE_TYPE = setterPrimitiveType;
    +
    +        final MethodType spillGetterType = MethodType.methodType(Object[].class, Object.class);
    +        final MethodHandle spillGetter = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), spillGetterType);
             SPILL_ELEMENT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, spillGetter);
             SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
         }
    @@ -177,9 +191,8 @@ public class AccessorProperty extends Property {
                         ACCESSOR_GETTER_TYPES[i]);
                 }
             } else {
    -            //this will work as the object setter and getter will be converted appropriately
    -            objectGetter = getter;
    -            objectSetter = setter;
    +            objectGetter = getter.type() != Lookup.GET_OBJECT_TYPE ? MH.asType(getter, Lookup.GET_OBJECT_TYPE) : getter;
    +            objectSetter = setter != null && setter.type() != Lookup.SET_OBJECT_TYPE ? MH.asType(setter, Lookup.SET_OBJECT_TYPE) : setter;
             }
     
             setCurrentType(getterType);
    @@ -195,8 +208,8 @@ public class AccessorProperty extends Property {
                 setters = new MethodHandle[fieldCount];
                 for(int i = 0; i < fieldCount; ++i) {
                     final String fieldName = ObjectClassGenerator.getFieldName(i, Type.OBJECT);
    -                getters[i] = MH.getter(lookup, structure, fieldName, Type.OBJECT.getTypeClass());
    -                setters[i] = MH.setter(lookup, structure, fieldName, Type.OBJECT.getTypeClass());
    +                getters[i] = MH.asType(MH.getter(lookup, structure, fieldName, Type.OBJECT.getTypeClass()), Lookup.GET_OBJECT_TYPE);
    +                setters[i] = MH.asType(MH.setter(lookup, structure, fieldName, Type.OBJECT.getTypeClass()), Lookup.SET_OBJECT_TYPE);
                 }
             }
         }
    @@ -224,17 +237,18 @@ public class AccessorProperty extends Property {
                 final MethodHandle arguments   = MH.getter(lookup, structure, "arguments", Object.class);
                 final MethodHandle argumentsSO = MH.asType(arguments, arguments.type().changeReturnType(ScriptObject.class));
     
    -            objectGetter = MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
    -            objectSetter = MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot);
    +            objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.GET_OBJECT_TYPE);
    +            objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.SET_OBJECT_TYPE);
             } else {
                 final GettersSetters gs = GETTERS_SETTERS.get(structure);
                 objectGetter = gs.getters[slot];
                 objectSetter = gs.setters[slot];
     
                 if (!OBJECT_FIELDS_ONLY) {
    -                final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, ObjectClassGenerator.PRIMITIVE_TYPE);
    -                primitiveGetter = MH.getter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
    -                primitiveSetter = MH.setter(lookup, structure, fieldNamePrimitive, PRIMITIVE_TYPE.getTypeClass());
    +                final String fieldNamePrimitive = ObjectClassGenerator.getFieldName(slot, PRIMITIVE_TYPE);
    +                final Class typeClass = PRIMITIVE_TYPE.getTypeClass();
    +                primitiveGetter = MH.asType(MH.getter(lookup, structure, fieldNamePrimitive, typeClass), ACCESSOR_GETTER_PRIMITIVE_TYPE);
    +                primitiveSetter = MH.asType(MH.setter(lookup, structure, fieldNamePrimitive, typeClass), ACCESSOR_SETTER_PRIMITIVE_TYPE);
                 }
             }
     
    @@ -325,16 +339,8 @@ public class AccessorProperty extends Property {
             final int i = getAccessorTypeIndex(type);
             if (getters[i] == null) {
                 getters[i] = debug(
    -                MH.asType(
    -                    createGetter(
    -                        currentType,
    -                        type,
    -                        primitiveGetter,
    -                        objectGetter),
    -                    ACCESSOR_GETTER_TYPES[i]),
    -                currentType,
    -                type,
    -                "get");
    +                createGetter(currentType, type, primitiveGetter, objectGetter),
    +                currentType, type, "get");
             }
     
             return getters[i];
    @@ -370,7 +376,6 @@ public class AccessorProperty extends Property {
                 objectSetter = getSpillSetter();
             }
             MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
    -        mh = MH.asType(mh, ACCESSOR_SETTER_TYPES[getAccessorTypeIndex(type)]); //has to be the case for invokeexact to work in ScriptObject
             mh = debug(mh, currentType, type, "set");
             return mh;
         }
    @@ -423,9 +428,9 @@ public class AccessorProperty extends Property {
             final int slot = getSlot();
             MethodHandle getter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2] : null;
             if (getter == null) {
    -            getter = MH.asType(MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot), Lookup.GET_OBJECT_TYPE);
    +            getter = MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot);
                 if (slot < SPILL_CACHE_SIZE) {
    -                SPILL_ACCESSORS[slot * 2] = getter;
    +                SPILL_ACCESSORS[slot * 2 + 0] = getter;
                 }
             }
             return getter;
    @@ -435,7 +440,7 @@ public class AccessorProperty extends Property {
             final int slot = getSlot();
             MethodHandle setter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2 + 1] : null;
             if (setter == null) {
    -            setter = MH.asType(MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot), Lookup.SET_OBJECT_TYPE);
    +            setter = MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot);
                 if (slot < SPILL_CACHE_SIZE) {
                     SPILL_ACCESSORS[slot * 2 + 1] = setter;
                 }
    
    From f530400e5c5e0e7bca681b99de63736d875ee0bb Mon Sep 17 00:00:00 2001
    From: Johnny Chen 
    Date: Wed, 3 Jul 2013 10:22:13 -0700
    Subject: [PATCH 023/156] 8014497: [parfait] Potential null pointer dereference
     in jdk/src/share/native/sun/java2d/cmm/lcms/cmsgamma.c
    
    Reviewed-by: bae, prr
    ---
     jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c | 4 ++++
     1 file changed, 4 insertions(+)
    
    diff --git a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c
    index 7086109cecb..281f722f9f6 100644
    --- a/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c
    +++ b/jdk/src/share/native/sun/java2d/cmm/lcms/cmsopt.c
    @@ -548,6 +548,10 @@ cmsBool FixWhiteMisalignment(cmsPipeline* Lut, cmsColorSpaceSignature EntryColor
             for (i=0; i < nOuts; i++) {
     
                 cmsToneCurve* InversePostLin = cmsReverseToneCurve(Curves[i]);
    +            if (InversePostLin == NULL) {
    +                WhiteOut[i] = 0;
    +                continue;
    +            }
                 WhiteOut[i] = cmsEvalToneCurve16(InversePostLin, WhitePointOut[i]);
                 cmsFreeToneCurve(InversePostLin);
             }
    
    From eeba729b553f50c5d95b5f128b60a235fd885205 Mon Sep 17 00:00:00 2001
    From: Sylvestre Ledru 
    Date: Wed, 3 Jul 2013 13:45:39 -0400
    Subject: [PATCH 024/156] 8019833: Wrong JNI error code for preexisting JVM
    
    Return the appropriate JNI error message (instead of the generic one) when the JVM is already started
    
    Reviewed-by: coleenp, hseigel
    ---
     hotspot/src/share/vm/prims/jni.cpp | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
    index f37ea34c46d..42930ff7408 100644
    --- a/hotspot/src/share/vm/prims/jni.cpp
    +++ b/hotspot/src/share/vm/prims/jni.cpp
    @@ -5097,7 +5097,7 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v
       // function used to determine this will always return false. Atomic::xchg
       // does not have this problem.
       if (Atomic::xchg(1, &vm_created) == 1) {
    -    return JNI_ERR;   // already created, or create attempt in progress
    +    return JNI_EEXIST;   // already created, or create attempt in progress
       }
       if (Atomic::xchg(0, &safe_to_recreate_vm) == 0) {
         return JNI_ERR;  // someone tried and failed and retry not allowed.
    
    From b454ece6d7d9cbfebc9d2df0cdb657ce4886e41f Mon Sep 17 00:00:00 2001
    From: Jiangli Zhou 
    Date: Wed, 3 Jul 2013 17:26:59 -0400
    Subject: [PATCH 025/156] 7133260: AllocationProfiler uses space in metadata
     and doesn't seem to do anything useful
    
    Remove -Xaprof and Klass::_alloc_count & ArrayKlass::_alloc_size.
    
    Reviewed-by: stefank, coleenp
    ---
     .../sun/jvm/hotspot/oops/ArrayKlass.java      |   4 -
     .../classes/sun/jvm/hotspot/oops/Klass.java   |   4 -
     .../compactibleFreeListSpace.cpp              |   6 -
     .../compactibleFreeListSpace.hpp              |   1 -
     .../concurrentMarkSweepGeneration.cpp         |  20 ---
     .../concurrentMarkSweepGeneration.hpp         |   1 -
     .../gc_implementation/g1/g1CollectedHeap.cpp  |   8 -
     .../gc_implementation/g1/g1CollectedHeap.hpp  |   5 -
     .../vm/gc_implementation/g1/g1MarkSweep.cpp   |   1 -
     .../src/share/vm/memory/defNewGeneration.cpp  |   5 -
     .../src/share/vm/memory/defNewGeneration.hpp  |   1 -
     .../src/share/vm/memory/genCollectedHeap.cpp  |   9 --
     .../src/share/vm/memory/genCollectedHeap.hpp  |   1 -
     hotspot/src/share/vm/memory/generation.cpp    |  10 --
     hotspot/src/share/vm/memory/generation.hpp    |   7 -
     hotspot/src/share/vm/memory/sharedHeap.hpp    |   5 -
     hotspot/src/share/vm/memory/universe.cpp      |   1 -
     hotspot/src/share/vm/oops/arrayKlass.cpp      |   7 -
     hotspot/src/share/vm/oops/arrayKlass.hpp      |   6 -
     hotspot/src/share/vm/oops/instanceKlass.cpp   |   6 -
     hotspot/src/share/vm/oops/instanceKlass.hpp   |   5 -
     hotspot/src/share/vm/oops/klass.cpp           |   7 -
     hotspot/src/share/vm/oops/klass.hpp           |   9 --
     hotspot/src/share/vm/runtime/aprofiler.cpp    | 143 ------------------
     hotspot/src/share/vm/runtime/aprofiler.hpp    |  71 ---------
     hotspot/src/share/vm/runtime/arguments.cpp    |  21 ---
     hotspot/src/share/vm/runtime/arguments.hpp    |   4 +-
     hotspot/src/share/vm/runtime/java.cpp         |  11 --
     hotspot/src/share/vm/runtime/thread.cpp       |   2 -
     hotspot/src/share/vm/runtime/vmStructs.cpp    |  14 +-
     30 files changed, 7 insertions(+), 388 deletions(-)
     delete mode 100644 hotspot/src/share/vm/runtime/aprofiler.cpp
     delete mode 100644 hotspot/src/share/vm/runtime/aprofiler.hpp
    
    diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java
    index f7cfb046d7d..9530cdd977a 100644
    --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java
    +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ArrayKlass.java
    @@ -49,7 +49,6 @@ public class ArrayKlass extends Klass {
         higherDimension    = new MetadataField(type.getAddressField("_higher_dimension"), 0);
         lowerDimension     = new MetadataField(type.getAddressField("_lower_dimension"), 0);
         vtableLen          = new CIntField(type.getCIntegerField("_vtable_len"), 0);
    -    allocSize          = new CIntField(type.getCIntegerField("_alloc_size"), 0);
         componentMirror    = new OopField(type.getOopField("_component_mirror"), 0);
         javaLangCloneableName = null;
         javaLangObjectName = null;
    @@ -64,7 +63,6 @@ public class ArrayKlass extends Klass {
       private static MetadataField  higherDimension;
       private static MetadataField  lowerDimension;
       private static CIntField vtableLen;
    -  private static CIntField allocSize;
       private static OopField  componentMirror;
     
       public Klass getJavaSuper() {
    @@ -76,7 +74,6 @@ public class ArrayKlass extends Klass {
       public Klass getHigherDimension() { return (Klass) higherDimension.getValue(this); }
       public Klass getLowerDimension()  { return (Klass) lowerDimension.getValue(this); }
       public long  getVtableLen()       { return         vtableLen.getValue(this); }
    -  public long  getAllocSize()       { return         allocSize.getValue(this); }
       public Oop   getComponentMirror() { return         componentMirror.getValue(this); }
     
       // constant class names - javaLangCloneable, javaIoSerializable, javaLangObject
    @@ -147,7 +144,6 @@ public class ArrayKlass extends Klass {
         visitor.doMetadata(higherDimension, true);
         visitor.doMetadata(lowerDimension, true);
           visitor.doCInt(vtableLen, true);
    -      visitor.doCInt(allocSize, true);
           visitor.doOop(componentMirror, true);
         }
       }
    diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java
    index 63ac006ebb9..19a3668c7f3 100644
    --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java
    +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Klass.java
    @@ -57,7 +57,6 @@ public class Klass extends Metadata implements ClassConstants {
         accessFlags  = new CIntField(type.getCIntegerField("_access_flags"), 0);
         subklass     = new MetadataField(type.getAddressField("_subklass"), 0);
         nextSibling  = new MetadataField(type.getAddressField("_next_sibling"), 0);
    -    allocCount   = new CIntField(type.getCIntegerField("_alloc_count"), 0);
     
         LH_INSTANCE_SLOW_PATH_BIT  = db.lookupIntConstant("Klass::_lh_instance_slow_path_bit").intValue();
         LH_LOG2_ELEMENT_SIZE_SHIFT = db.lookupIntConstant("Klass::_lh_log2_element_size_shift").intValue();
    @@ -87,7 +86,6 @@ public class Klass extends Metadata implements ClassConstants {
       private static CIntField accessFlags;
       private static MetadataField  subklass;
       private static MetadataField  nextSibling;
    -  private static CIntField allocCount;
     
       private Address getValue(AddressField field) {
         return addr.getAddressAt(field.getOffset());
    @@ -108,7 +106,6 @@ public class Klass extends Metadata implements ClassConstants {
       public AccessFlags getAccessFlagsObj(){ return new AccessFlags(getAccessFlags());      }
       public Klass    getSubklassKlass()    { return (Klass)    subklass.getValue(this);     }
       public Klass    getNextSiblingKlass() { return (Klass)    nextSibling.getValue(this);  }
    -  public long     getAllocCount()       { return            allocCount.getValue(this);   }
     
       // computed access flags - takes care of inner classes etc.
       // This is closer to actual source level than getAccessFlags() etc.
    @@ -172,7 +169,6 @@ public class Klass extends Metadata implements ClassConstants {
           visitor.doCInt(accessFlags, true);
         visitor.doMetadata(subklass, true);
         visitor.doMetadata(nextSibling, true);
    -      visitor.doCInt(allocCount, true);
         }
     
       public long getObjectSize() {
    diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
    index d91f907a2c0..b87efd7bc2a 100644
    --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
    +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
    @@ -2017,12 +2017,6 @@ oop_since_save_marks_iterate##nv_suffix(OopClosureType* blk) {              \
     
     ALL_SINCE_SAVE_MARKS_CLOSURES(CFLS_OOP_SINCE_SAVE_MARKS_DEFN)
     
    -
    -void CompactibleFreeListSpace::object_iterate_since_last_GC(ObjectClosure* cl) {
    -  // ugghh... how would one do this efficiently for a non-contiguous space?
    -  guarantee(false, "NYI");
    -}
    -
     bool CompactibleFreeListSpace::linearAllocationWouldFail() const {
       return _smallLinearAllocBlock._word_size == 0;
     }
    diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
    index 23c95897cfa..74c97e8df9d 100644
    --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
    +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
    @@ -396,7 +396,6 @@ class CompactibleFreeListSpace: public CompactibleSpace {
       // iteration support for promotion
       void save_marks();
       bool no_allocs_since_save_marks();
    -  void object_iterate_since_last_GC(ObjectClosure* cl);
     
       // iteration support for sweeping
       void save_sweep_limit() {
    diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
    index 85c7b73172e..ced79cbcf69 100644
    --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
    +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
    @@ -3129,26 +3129,6 @@ oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl) {   \
     
     ALL_SINCE_SAVE_MARKS_CLOSURES(CMS_SINCE_SAVE_MARKS_DEFN)
     
    -void
    -ConcurrentMarkSweepGeneration::object_iterate_since_last_GC(ObjectClosure* blk)
    -{
    -  // Not currently implemented; need to do the following. -- ysr.
    -  // dld -- I think that is used for some sort of allocation profiler.  So it
    -  // really means the objects allocated by the mutator since the last
    -  // GC.  We could potentially implement this cheaply by recording only
    -  // the direct allocations in a side data structure.
    -  //
    -  // I think we probably ought not to be required to support these
    -  // iterations at any arbitrary point; I think there ought to be some
    -  // call to enable/disable allocation profiling in a generation/space,
    -  // and the iterator ought to return the objects allocated in the
    -  // gen/space since the enable call, or the last iterator call (which
    -  // will probably be at a GC.)  That way, for gens like CM&S that would
    -  // require some extra data structure to support this, we only pay the
    -  // cost when it's in use...
    -  cmsSpace()->object_iterate_since_last_GC(blk);
    -}
    -
     void
     ConcurrentMarkSweepGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
       cl->set_generation(this);
    diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
    index bb485f4a83e..3806b896d26 100644
    --- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
    +++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
    @@ -1273,7 +1273,6 @@ class ConcurrentMarkSweepGeneration: public CardGeneration {
       // Iteration support and related enquiries
       void save_marks();
       bool no_allocs_since_save_marks();
    -  void object_iterate_since_last_GC(ObjectClosure* cl);
       void younger_refs_iterate(OopsInGenClosure* cl);
     
       // Iteration support specific to CMS generations
    diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
    index db8f863ad25..bdd3027b995 100644
    --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
    +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
    @@ -54,7 +54,6 @@
     #include "memory/referenceProcessor.hpp"
     #include "oops/oop.inline.hpp"
     #include "oops/oop.pcgc.inline.hpp"
    -#include "runtime/aprofiler.hpp"
     #include "runtime/vmThread.hpp"
     
     size_t G1CollectedHeap::_humongous_object_threshold_in_words = 0;
    @@ -2665,11 +2664,6 @@ void G1CollectedHeap::object_iterate(ObjectClosure* cl) {
       heap_region_iterate(&blk);
     }
     
    -void G1CollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) {
    -  // FIXME: is this right?
    -  guarantee(false, "object_iterate_since_last_GC not supported by G1 heap");
    -}
    -
     // Calls a SpaceClosure on a HeapRegion.
     
     class SpaceClosureRegionClosure: public HeapRegionClosure {
    @@ -3598,8 +3592,6 @@ G1CollectedHeap* G1CollectedHeap::heap() {
     void G1CollectedHeap::gc_prologue(bool full /* Ignored */) {
       // always_do_update_barrier = false;
       assert(InlineCacheBuffer::is_empty(), "should have cleaned up ICBuffer");
    -  // Call allocation profiler
    -  AllocationProfiler::iterate_since_last_gc();
       // Fill TLAB's and such
       ensure_parsability(true);
     }
    diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
    index 6843d13f736..9b52304c996 100644
    --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
    +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
    @@ -1360,11 +1360,6 @@ public:
         object_iterate(cl);
       }
     
    -  // Iterate over all objects allocated since the last collection, calling
    -  // "cl.do_object" on each.  The heap must have been initialized properly
    -  // to support this function, or else this call will fail.
    -  virtual void object_iterate_since_last_GC(ObjectClosure* cl);
    -
       // Iterate over all spaces in use in the heap, in ascending address order.
       virtual void space_iterate(SpaceClosure* cl);
     
    diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
    index adde08f2177..74aabc1298d 100644
    --- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
    +++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
    @@ -43,7 +43,6 @@
     #include "oops/instanceRefKlass.hpp"
     #include "oops/oop.inline.hpp"
     #include "prims/jvmtiExport.hpp"
    -#include "runtime/aprofiler.hpp"
     #include "runtime/biasedLocking.hpp"
     #include "runtime/fprofiler.hpp"
     #include "runtime/synchronizer.hpp"
    diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp
    index 88afd70a739..177569294af 100644
    --- a/hotspot/src/share/vm/memory/defNewGeneration.cpp
    +++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp
    @@ -450,11 +450,6 @@ void DefNewGeneration::compute_new_size() {
       }
     }
     
    -void DefNewGeneration::object_iterate_since_last_GC(ObjectClosure* cl) {
    -  // $$$ This may be wrong in case of "scavenge failure"?
    -  eden()->object_iterate(cl);
    -}
    -
     void DefNewGeneration::younger_refs_iterate(OopsInGenClosure* cl) {
       assert(false, "NYI -- are you sure you want to call this?");
     }
    diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp
    index c538e0a4f35..0623d446ad3 100644
    --- a/hotspot/src/share/vm/memory/defNewGeneration.hpp
    +++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp
    @@ -252,7 +252,6 @@ protected:
     
       // Iteration
       void object_iterate(ObjectClosure* blk);
    -  void object_iterate_since_last_GC(ObjectClosure* cl);
     
       void younger_refs_iterate(OopsInGenClosure* cl);
     
    diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
    index a74533d4321..ebdb77f6734 100644
    --- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp
    +++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
    @@ -42,7 +42,6 @@
     #include "memory/space.hpp"
     #include "oops/oop.inline.hpp"
     #include "oops/oop.inline2.hpp"
    -#include "runtime/aprofiler.hpp"
     #include "runtime/biasedLocking.hpp"
     #include "runtime/fprofiler.hpp"
     #include "runtime/handles.hpp"
    @@ -873,12 +872,6 @@ void GenCollectedHeap::safe_object_iterate(ObjectClosure* cl) {
       }
     }
     
    -void GenCollectedHeap::object_iterate_since_last_GC(ObjectClosure* cl) {
    -  for (int i = 0; i < _n_gens; i++) {
    -    _gens[i]->object_iterate_since_last_GC(cl);
    -  }
    -}
    -
     Space* GenCollectedHeap::space_containing(const void* addr) const {
       for (int i = 0; i < _n_gens; i++) {
         Space* res = _gens[i]->space_containing(addr);
    @@ -1186,8 +1179,6 @@ void GenCollectedHeap::gc_prologue(bool full) {
       CollectedHeap::accumulate_statistics_all_tlabs();
       ensure_parsability(true);   // retire TLABs
     
    -  // Call allocation profiler
    -  AllocationProfiler::iterate_since_last_gc();
       // Walk generations
       GenGCPrologueClosure blk(full);
       generation_iterate(&blk, false);  // not old-to-young.
    diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
    index 783cd372d7c..43338c4da46 100644
    --- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp
    +++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
    @@ -222,7 +222,6 @@ public:
       void oop_iterate(MemRegion mr, ExtendedOopClosure* cl);
       void object_iterate(ObjectClosure* cl);
       void safe_object_iterate(ObjectClosure* cl);
    -  void object_iterate_since_last_GC(ObjectClosure* cl);
       Space* space_containing(const void* addr) const;
     
       // A CollectedHeap is divided into a dense sequence of "blocks"; that is,
    diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp
    index 9fa46b34af4..f9c986fa7a0 100644
    --- a/hotspot/src/share/vm/memory/generation.cpp
    +++ b/hotspot/src/share/vm/memory/generation.cpp
    @@ -811,16 +811,6 @@ void OneContigSpaceCardGeneration::space_iterate(SpaceClosure* blk,
       blk->do_space(_the_space);
     }
     
    -void OneContigSpaceCardGeneration::object_iterate_since_last_GC(ObjectClosure* blk) {
    -  // Deal with delayed initialization of _the_space,
    -  // and lack of initialization of _last_gc.
    -  if (_last_gc.space() == NULL) {
    -    assert(the_space() != NULL, "shouldn't be NULL");
    -    _last_gc = the_space()->bottom_mark();
    -  }
    -  the_space()->object_iterate_from(_last_gc, blk);
    -}
    -
     void OneContigSpaceCardGeneration::younger_refs_iterate(OopsInGenClosure* blk) {
       blk->set_generation(this);
       younger_refs_in_space_iterate(_the_space, blk);
    diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp
    index feb4fde18af..44d641feedd 100644
    --- a/hotspot/src/share/vm/memory/generation.hpp
    +++ b/hotspot/src/share/vm/memory/generation.hpp
    @@ -551,12 +551,6 @@ class Generation: public CHeapObj {
       // the heap.  This defaults to object_iterate() unless overridden.
       virtual void safe_object_iterate(ObjectClosure* cl);
     
    -  // Iterate over all objects allocated in the generation since the last
    -  // collection, calling "cl.do_object" on each.  The generation must have
    -  // been initialized properly to support this function, or else this call
    -  // will fail.
    -  virtual void object_iterate_since_last_GC(ObjectClosure* cl) = 0;
    -
       // Apply "cl->do_oop" to (the address of) all and only all the ref fields
       // in the current generation that contain pointers to objects in younger
       // generations. Objects allocated since the last "save_marks" call are
    @@ -724,7 +718,6 @@ class OneContigSpaceCardGeneration: public CardGeneration {
       // Iteration
       void object_iterate(ObjectClosure* blk);
       void space_iterate(SpaceClosure* blk, bool usedOnly = false);
    -  void object_iterate_since_last_GC(ObjectClosure* cl);
     
       void younger_refs_iterate(OopsInGenClosure* blk);
     
    diff --git a/hotspot/src/share/vm/memory/sharedHeap.hpp b/hotspot/src/share/vm/memory/sharedHeap.hpp
    index b13bf15b846..cd810c036d4 100644
    --- a/hotspot/src/share/vm/memory/sharedHeap.hpp
    +++ b/hotspot/src/share/vm/memory/sharedHeap.hpp
    @@ -166,11 +166,6 @@ public:
       // Same as above, restricted to a memory region.
       virtual void oop_iterate(MemRegion mr, ExtendedOopClosure* cl) = 0;
     
    -  // Iterate over all objects allocated since the last collection, calling
    -  // "cl->do_object" on each.  The heap must have been initialized properly
    -  // to support this function, or else this call will fail.
    -  virtual void object_iterate_since_last_GC(ObjectClosure* cl) = 0;
    -
       // Iterate over all spaces in use in the heap, in an undefined order.
       virtual void space_iterate(SpaceClosure* cl) = 0;
     
    diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
    index 3514886d0d9..511610bd3bf 100644
    --- a/hotspot/src/share/vm/memory/universe.cpp
    +++ b/hotspot/src/share/vm/memory/universe.cpp
    @@ -52,7 +52,6 @@
     #include "oops/oop.inline.hpp"
     #include "oops/typeArrayKlass.hpp"
     #include "prims/jvmtiRedefineClassesTrace.hpp"
    -#include "runtime/aprofiler.hpp"
     #include "runtime/arguments.hpp"
     #include "runtime/deoptimization.hpp"
     #include "runtime/fprofiler.hpp"
    diff --git a/hotspot/src/share/vm/oops/arrayKlass.cpp b/hotspot/src/share/vm/oops/arrayKlass.cpp
    index ef1c20e972b..6e04c3ac145 100644
    --- a/hotspot/src/share/vm/oops/arrayKlass.cpp
    +++ b/hotspot/src/share/vm/oops/arrayKlass.cpp
    @@ -71,7 +71,6 @@ Method* ArrayKlass::uncached_lookup_method(Symbol* name, Symbol* signature) cons
     }
     
     ArrayKlass::ArrayKlass(Symbol* name) {
    -  set_alloc_size(0);
       set_name(name);
     
       set_super(Universe::is_bootstrapping() ? (Klass*)NULL : SystemDictionary::Object_klass());
    @@ -161,12 +160,6 @@ void ArrayKlass::array_klasses_do(void f(Klass* k)) {
       }
     }
     
    -
    -void ArrayKlass::with_array_klasses_do(void f(Klass* k)) {
    -  array_klasses_do(f);
    -}
    -
    -
     // GC support
     
     void ArrayKlass::oops_do(OopClosure* cl) {
    diff --git a/hotspot/src/share/vm/oops/arrayKlass.hpp b/hotspot/src/share/vm/oops/arrayKlass.hpp
    index acf920e16d1..4b06f1c0ed6 100644
    --- a/hotspot/src/share/vm/oops/arrayKlass.hpp
    +++ b/hotspot/src/share/vm/oops/arrayKlass.hpp
    @@ -39,7 +39,6 @@ class ArrayKlass: public Klass {
       Klass* volatile _higher_dimension;  // Refers the (n+1)'th-dimensional array (if present).
       Klass* volatile _lower_dimension;   // Refers the (n-1)'th-dimensional array (if present).
       int      _vtable_len;        // size of vtable for this klass
    -  juint    _alloc_size;        // allocation profiling support
       oop      _component_mirror;  // component type, as a java/lang/Class
     
      protected:
    @@ -65,10 +64,6 @@ class ArrayKlass: public Klass {
       void set_lower_dimension(Klass* k)  { _lower_dimension = k; }
       Klass** adr_lower_dimension()       { return (Klass**)&this->_lower_dimension;}
     
    -  // Allocation profiling support
    -  juint alloc_size() const              { return _alloc_size; }
    -  void set_alloc_size(juint n)          { _alloc_size = n; }
    -
       // offset of first element, including any padding for the sake of alignment
       int  array_header_in_bytes() const    { return layout_helper_header_size(layout_helper()); }
       int  log2_element_size() const        { return layout_helper_log2_element_size(layout_helper()); }
    @@ -126,7 +121,6 @@ class ArrayKlass: public Klass {
       // Iterators
       void array_klasses_do(void f(Klass* k));
       void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
    -  void with_array_klasses_do(void f(Klass* k));
     
       // GC support
       virtual void oops_do(OopClosure* cl);
    diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
    index 886746d6bb6..55348bf8bc1 100644
    --- a/hotspot/src/share/vm/oops/instanceKlass.cpp
    +++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
    @@ -1321,12 +1321,6 @@ void InstanceKlass::array_klasses_do(void f(Klass* k)) {
         ArrayKlass::cast(array_klasses())->array_klasses_do(f);
     }
     
    -
    -void InstanceKlass::with_array_klasses_do(void f(Klass* k)) {
    -  f(this);
    -  array_klasses_do(f);
    -}
    -
     #ifdef ASSERT
     static int linear_search(Array* methods, Symbol* name, Symbol* signature) {
       int len = methods->length();
    diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
    index 6c56a519558..b658f3a0335 100644
    --- a/hotspot/src/share/vm/oops/instanceKlass.hpp
    +++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
    @@ -794,7 +794,6 @@ class InstanceKlass: public Klass {
       void methods_do(void f(Method* method));
       void array_klasses_do(void f(Klass* k));
       void array_klasses_do(void f(Klass* k, TRAPS), TRAPS);
    -  void with_array_klasses_do(void f(Klass* k));
       bool super_types_do(SuperTypeClosure* blk);
     
       // Casting from Klass*
    @@ -874,10 +873,6 @@ class InstanceKlass: public Klass {
         }
       }
     
    -  // Allocation profiling support
    -  juint alloc_size() const            { return _alloc_count * size_helper(); }
    -  void set_alloc_size(juint n)        {}
    -
       // Use this to return the size of an instance in heap words:
       int size_helper() const {
         return layout_helper_to_size_helper(layout_helper());
    diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
    index a719b88bbbe..41d5ec31c73 100644
    --- a/hotspot/src/share/vm/oops/klass.cpp
    +++ b/hotspot/src/share/vm/oops/klass.cpp
    @@ -168,7 +168,6 @@ Klass::Klass() {
       set_subklass(NULL);
       set_next_sibling(NULL);
       set_next_link(NULL);
    -  set_alloc_count(0);
       TRACE_INIT_ID(this);
     
       set_prototype_header(markOopDesc::prototype());
    @@ -543,12 +542,6 @@ Klass* Klass::array_klass_impl(bool or_null, TRAPS) {
       return NULL;
     }
     
    -
    -void Klass::with_array_klasses_do(void f(Klass* k)) {
    -  f(this);
    -}
    -
    -
     oop Klass::class_loader() const { return class_loader_data()->class_loader(); }
     
     const char* Klass::external_name() const {
    diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
    index 5f4094d4f1e..1ca027a3762 100644
    --- a/hotspot/src/share/vm/oops/klass.hpp
    +++ b/hotspot/src/share/vm/oops/klass.hpp
    @@ -79,7 +79,6 @@
     //    [last_biased_lock_bulk_revocation_time] (64 bits)
     //    [prototype_header]
     //    [biased_lock_revocation_count]
    -//    [alloc_count   ]
     //    [_modified_oops]
     //    [_accumulated_modified_oops]
     //    [trace_id]
    @@ -171,8 +170,6 @@ class Klass : public Metadata {
       markOop  _prototype_header;   // Used when biased locking is both enabled and disabled for this type
       jint     _biased_lock_revocation_count;
     
    -  juint    _alloc_count;        // allocation profiling support
    -
       TRACE_DEFINE_KLASS_TRACE_ID;
     
       // Remembered sets support for the oops in the klasses.
    @@ -290,11 +287,6 @@ class Klass : public Metadata {
       void     set_next_sibling(Klass* s);
     
      public:
    -  // Allocation profiling support
    -  juint alloc_count() const          { return _alloc_count; }
    -  void set_alloc_count(juint n)      { _alloc_count = n; }
    -  virtual juint alloc_size() const = 0;
    -  virtual void set_alloc_size(juint n) = 0;
     
       // Compiler support
       static ByteSize super_offset()                 { return in_ByteSize(offset_of(Klass, _super)); }
    @@ -677,7 +669,6 @@ class Klass : public Metadata {
     #endif // INCLUDE_ALL_GCS
     
       virtual void array_klasses_do(void f(Klass* k)) {}
    -  virtual void with_array_klasses_do(void f(Klass* k));
     
       // Return self, except for abstract classes with exactly 1
       // implementor.  Then return the 1 concrete implementation.
    diff --git a/hotspot/src/share/vm/runtime/aprofiler.cpp b/hotspot/src/share/vm/runtime/aprofiler.cpp
    deleted file mode 100644
    index e71bfb587ef..00000000000
    --- a/hotspot/src/share/vm/runtime/aprofiler.cpp
    +++ /dev/null
    @@ -1,143 +0,0 @@
    -/*
    - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code 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 General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - *
    - */
    -
    -#include "precompiled.hpp"
    -#include "classfile/systemDictionary.hpp"
    -#include "gc_interface/collectedHeap.inline.hpp"
    -#include "memory/resourceArea.hpp"
    -#include "memory/space.hpp"
    -#include "oops/oop.inline.hpp"
    -#include "oops/oop.inline2.hpp"
    -#include "runtime/aprofiler.hpp"
    -
    -
    -bool AllocationProfiler::_active = false;
    -GrowableArray* AllocationProfiler::_print_array = NULL;
    -
    -
    -class AllocProfClosure : public ObjectClosure {
    - public:
    -  void do_object(oop obj) {
    -    Klass* k = obj->klass();
    -    k->set_alloc_count(k->alloc_count() + 1);
    -    k->set_alloc_size(k->alloc_size() + obj->size());
    -  }
    -};
    -
    -
    -void AllocationProfiler::iterate_since_last_gc() {
    -  if (is_active()) {
    -    AllocProfClosure blk;
    -    GenCollectedHeap* heap = GenCollectedHeap::heap();
    -    heap->object_iterate_since_last_GC(&blk);
    -  }
    -}
    -
    -
    -void AllocationProfiler::engage() {
    -  _active = true;
    -}
    -
    -
    -void AllocationProfiler::disengage() {
    -  _active = false;
    -}
    -
    -
    -void AllocationProfiler::add_class_to_array(Klass* k) {
    -  _print_array->append(k);
    -}
    -
    -
    -void AllocationProfiler::add_classes_to_array(Klass* k) {
    -  // Iterate over klass and all array klasses for klass
    -  k->with_array_klasses_do(&AllocationProfiler::add_class_to_array);
    -}
    -
    -
    -int AllocationProfiler::compare_classes(Klass** k1, Klass** k2) {
    -  // Sort by total allocation size
    -  return (*k2)->alloc_size() - (*k1)->alloc_size();
    -}
    -
    -
    -int AllocationProfiler::average(size_t alloc_size, int alloc_count) {
    -  return (int) ((double) (alloc_size * BytesPerWord) / MAX2(alloc_count, 1) + 0.5);
    -}
    -
    -
    -void AllocationProfiler::sort_and_print_array(size_t cutoff) {
    -  _print_array->sort(&AllocationProfiler::compare_classes);
    -  tty->print_cr("________________Size"
    -                "__Instances"
    -                "__Average"
    -                "__Class________________");
    -  size_t total_alloc_size = 0;
    -  int total_alloc_count = 0;
    -  for (int index = 0; index < _print_array->length(); index++) {
    -    Klass* k = _print_array->at(index);
    -    size_t alloc_size = k->alloc_size();
    -    if (alloc_size > cutoff) {
    -      int alloc_count = k->alloc_count();
    -#ifdef PRODUCT
    -      const char* name = k->external_name();
    -#else
    -      const char* name = k->internal_name();
    -#endif
    -      tty->print_cr("%20u %10u %8u  %s",
    -        alloc_size * BytesPerWord,
    -        alloc_count,
    -        average(alloc_size, alloc_count),
    -        name);
    -      total_alloc_size += alloc_size;
    -      total_alloc_count += alloc_count;
    -    }
    -    k->set_alloc_count(0);
    -    k->set_alloc_size(0);
    -  }
    -  tty->print_cr("%20u %10u %8u  --total--",
    -    total_alloc_size * BytesPerWord,
    -    total_alloc_count,
    -    average(total_alloc_size, total_alloc_count));
    -  tty->cr();
    -}
    -
    -
    -void AllocationProfiler::print(size_t cutoff) {
    -  ResourceMark rm;
    -  assert(!is_active(), "AllocationProfiler cannot be active while printing profile");
    -
    -  tty->cr();
    -  tty->print_cr("Allocation profile (sizes in bytes, cutoff = " SIZE_FORMAT " bytes):", cutoff * BytesPerWord);
    -  tty->cr();
    -
    -  // Print regular instance klasses and basic type array klasses
    -  _print_array = new GrowableArray(SystemDictionary::number_of_classes()*2);
    -  SystemDictionary::classes_do(&add_classes_to_array);
    -  Universe::basic_type_classes_do(&add_classes_to_array);
    -  sort_and_print_array(cutoff);
    -
    -  // This used to print metadata in the permgen but since there isn't a permgen
    -  // anymore, it is not yet implemented.
    -}
    diff --git a/hotspot/src/share/vm/runtime/aprofiler.hpp b/hotspot/src/share/vm/runtime/aprofiler.hpp
    deleted file mode 100644
    index ba4dd7aa5c4..00000000000
    --- a/hotspot/src/share/vm/runtime/aprofiler.hpp
    +++ /dev/null
    @@ -1,71 +0,0 @@
    -/*
    - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
    - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    - *
    - * This code is free software; you can redistribute it and/or modify it
    - * under the terms of the GNU General Public License version 2 only, as
    - * published by the Free Software Foundation.
    - *
    - * This code 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 General Public License
    - * version 2 for more details (a copy is included in the LICENSE file that
    - * accompanied this code).
    - *
    - * You should have received a copy of the GNU General Public License version
    - * 2 along with this work; if not, write to the Free Software Foundation,
    - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    - *
    - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    - * or visit www.oracle.com if you need additional information or have any
    - * questions.
    - *
    - */
    -
    -#ifndef SHARE_VM_RUNTIME_APROFILER_HPP
    -#define SHARE_VM_RUNTIME_APROFILER_HPP
    -
    -#include "memory/allocation.hpp"
    -#include "memory/universe.hpp"
    -#include "oops/klass.hpp"
    -#include "utilities/top.hpp"
    -
    -// A simple allocation profiler for Java. The profiler collects and prints
    -// the number and total size of instances allocated per class, including
    -// array classes.
    -//
    -// The profiler is currently global for all threads. It can be changed to a
    -// per threads profiler by keeping a more elaborate data structure and calling
    -// iterate_since_last_scavenge at thread switches.
    -
    -
    -class AllocationProfiler: AllStatic {
    -  friend class GenCollectedHeap;
    -  friend class G1CollectedHeap;
    -  friend class MarkSweep;
    - private:
    -  static bool _active;                          // tells whether profiler is active
    -  static GrowableArray* _print_array; // temporary array for printing
    -
    -  // Utility printing functions
    -  static void add_class_to_array(Klass* k);
    -  static void add_classes_to_array(Klass* k);
    -  static int  compare_classes(Klass** k1, Klass** k2);
    -  static int  average(size_t alloc_size, int alloc_count);
    -  static void sort_and_print_array(size_t cutoff);
    -
    -  // Call for collecting allocation information. Called at scavenge, mark-sweep and disengage.
    -  static void iterate_since_last_gc();
    -
    - public:
    -  // Start profiler
    -  static void engage();
    -  // Stop profiler
    -  static void disengage();
    -  // Tells whether profiler is active
    -  static bool is_active()                   { return _active; }
    -  // Print profile
    -  static void print(size_t cutoff);   // Cutoff in total allocation size (in words)
    -};
    -
    -#endif // SHARE_VM_RUNTIME_APROFILER_HPP
    diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
    index 625feda03f9..5fe1e276239 100644
    --- a/hotspot/src/share/vm/runtime/arguments.cpp
    +++ b/hotspot/src/share/vm/runtime/arguments.cpp
    @@ -68,7 +68,6 @@ char*  Arguments::_java_command                 = NULL;
     SystemProperty* Arguments::_system_properties   = NULL;
     const char*  Arguments::_gc_log_filename        = NULL;
     bool   Arguments::_has_profile                  = false;
    -bool   Arguments::_has_alloc_profile            = false;
     uintx  Arguments::_min_heap_size                = 0;
     Arguments::Mode Arguments::_mode                = _mixed;
     bool   Arguments::_java_compiler                = false;
    @@ -1976,23 +1975,6 @@ bool Arguments::check_vm_args_consistency() {
       status = status && check_gc_consistency();
       status = status && check_stack_pages();
     
    -  if (_has_alloc_profile) {
    -    if (UseParallelGC || UseParallelOldGC) {
    -      jio_fprintf(defaultStream::error_stream(),
    -                  "error:  invalid argument combination.\n"
    -                  "Allocation profiling (-Xaprof) cannot be used together with "
    -                  "Parallel GC (-XX:+UseParallelGC or -XX:+UseParallelOldGC).\n");
    -      status = false;
    -    }
    -    if (UseConcMarkSweepGC) {
    -      jio_fprintf(defaultStream::error_stream(),
    -                  "error:  invalid argument combination.\n"
    -                  "Allocation profiling (-Xaprof) cannot be used together with "
    -                  "the CMS collector (-XX:+UseConcMarkSweepGC).\n");
    -      status = false;
    -    }
    -  }
    -
       if (CMSIncrementalMode) {
         if (!UseConcMarkSweepGC) {
           jio_fprintf(defaultStream::error_stream(),
    @@ -2667,9 +2649,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
             "Flat profiling is not supported in this VM.\n");
           return JNI_ERR;
     #endif // INCLUDE_FPROF
    -    // -Xaprof
    -    } else if (match_option(option, "-Xaprof", &tail)) {
    -      _has_alloc_profile = true;
         // -Xconcurrentio
         } else if (match_option(option, "-Xconcurrentio", &tail)) {
           FLAG_SET_CMDLINE(bool, UseLWPSynchronization, true);
    diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
    index 0e84208a218..89b171f0d46 100644
    --- a/hotspot/src/share/vm/runtime/arguments.hpp
    +++ b/hotspot/src/share/vm/runtime/arguments.hpp
    @@ -262,7 +262,6 @@ class Arguments : AllStatic {
     
       // Option flags
       static bool   _has_profile;
    -  static bool   _has_alloc_profile;
       static const char*  _gc_log_filename;
       static uintx  _min_heap_size;
     
    @@ -464,9 +463,8 @@ class Arguments : AllStatic {
       // -Xloggc:, if not specified will be NULL
       static const char* gc_log_filename()      { return _gc_log_filename; }
     
    -  // -Xprof/-Xaprof
    +  // -Xprof
       static bool has_profile()                 { return _has_profile; }
    -  static bool has_alloc_profile()           { return _has_alloc_profile; }
     
       // -Xms, -Xmx
       static uintx min_heap_size()              { return _min_heap_size; }
    diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
    index 7795fb92a87..ebc4e087578 100644
    --- a/hotspot/src/share/vm/runtime/java.cpp
    +++ b/hotspot/src/share/vm/runtime/java.cpp
    @@ -42,7 +42,6 @@
     #include "oops/oop.inline.hpp"
     #include "oops/symbol.hpp"
     #include "prims/jvmtiExport.hpp"
    -#include "runtime/aprofiler.hpp"
     #include "runtime/arguments.hpp"
     #include "runtime/biasedLocking.hpp"
     #include "runtime/compilationPolicy.hpp"
    @@ -509,16 +508,6 @@ void before_exit(JavaThread * thread) {
         }
       }
     
    -
    -  if (Arguments::has_alloc_profile()) {
    -    HandleMark hm;
    -    // Do one last collection to enumerate all the objects
    -    // allocated since the last one.
    -    Universe::heap()->collect(GCCause::_allocation_profiler);
    -    AllocationProfiler::disengage();
    -    AllocationProfiler::print(0);
    -  }
    -
       if (PrintBytecodeHistogram) {
         BytecodeHistogram::print();
       }
    diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
    index eb2e256b1a0..ef862012fcc 100644
    --- a/hotspot/src/share/vm/runtime/thread.cpp
    +++ b/hotspot/src/share/vm/runtime/thread.cpp
    @@ -45,7 +45,6 @@
     #include "prims/jvmtiExport.hpp"
     #include "prims/jvmtiThreadState.hpp"
     #include "prims/privilegedStack.hpp"
    -#include "runtime/aprofiler.hpp"
     #include "runtime/arguments.hpp"
     #include "runtime/biasedLocking.hpp"
     #include "runtime/deoptimization.hpp"
    @@ -3677,7 +3676,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) {
       }
     
       if (Arguments::has_profile())       FlatProfiler::engage(main_thread, true);
    -  if (Arguments::has_alloc_profile()) AllocationProfiler::engage();
       if (MemProfiling)                   MemProfiler::engage();
       StatSampler::engage();
       if (CheckJNICalls)                  JniPeriodicChecker::engage();
    diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
    index 94b24eec8ea..e7de9601c96 100644
    --- a/hotspot/src/share/vm/runtime/vmStructs.cpp
    +++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
    @@ -263,7 +263,7 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
                        unchecked_c2_static_field) \
                                                                                                                                          \
       /******************************************************************/                                                               \
    -  /* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */                                                               \
    +  /* OopDesc and Klass hierarchies (NOTE: MethodData* incomplete) */                                                                 \
       /******************************************************************/                                                               \
                                                                                                                                          \
       volatile_nonstatic_field(oopDesc,            _mark,                                         markOop)                               \
    @@ -274,21 +274,20 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
       volatile_nonstatic_field(ArrayKlass,         _higher_dimension,                             Klass*)                                \
       volatile_nonstatic_field(ArrayKlass,         _lower_dimension,                              Klass*)                                \
       nonstatic_field(ArrayKlass,                  _vtable_len,                                   int)                                   \
    -  nonstatic_field(ArrayKlass,                  _alloc_size,                                   juint)                                 \
       nonstatic_field(ArrayKlass,                  _component_mirror,                             oop)                                   \
    -  nonstatic_field(CompiledICHolder,     _holder_method,                                Method*)                        \
    +  nonstatic_field(CompiledICHolder,     _holder_method,                                Method*)                               \
       nonstatic_field(CompiledICHolder,     _holder_klass,                                 Klass*)                                \
       nonstatic_field(ConstantPool,         _tags,                                         Array*)                            \
    -  nonstatic_field(ConstantPool,         _cache,                                        ConstantPoolCache*)             \
    +  nonstatic_field(ConstantPool,         _cache,                                        ConstantPoolCache*)                    \
       nonstatic_field(ConstantPool,         _pool_holder,                                  InstanceKlass*)                        \
       nonstatic_field(ConstantPool,         _operands,                                     Array*)                            \
       nonstatic_field(ConstantPool,         _length,                                       int)                                   \
       nonstatic_field(ConstantPool,         _resolved_references,                          jobject)                               \
       nonstatic_field(ConstantPool,         _reference_map,                                Array*)                            \
       nonstatic_field(ConstantPoolCache,    _length,                                       int)                                   \
    -  nonstatic_field(ConstantPoolCache,    _constant_pool,                                ConstantPool*)                  \
    +  nonstatic_field(ConstantPoolCache,    _constant_pool,                                ConstantPool*)                         \
       nonstatic_field(InstanceKlass,               _array_klasses,                                Klass*)                                \
    -  nonstatic_field(InstanceKlass,               _methods,                                      Array*)                \
    +  nonstatic_field(InstanceKlass,               _methods,                                      Array*)                       \
       nonstatic_field(InstanceKlass,               _local_interfaces,                             Array*)                        \
       nonstatic_field(InstanceKlass,               _transitive_interfaces,                        Array*)                        \
       nonstatic_field(InstanceKlass,               _fields,                                       Array*)                            \
    @@ -336,9 +335,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
       nonstatic_field(Klass,                       _access_flags,                                 AccessFlags)                           \
       nonstatic_field(Klass,                       _subklass,                                     Klass*)                                \
       nonstatic_field(Klass,                       _next_sibling,                                 Klass*)                                \
    -  nonstatic_field(Klass,                       _alloc_count,                                  juint)                                 \
       nonstatic_field(MethodData,           _size,                                         int)                                   \
    -  nonstatic_field(MethodData,           _method,                                       Method*)                        \
    +  nonstatic_field(MethodData,           _method,                                       Method*)                               \
       nonstatic_field(MethodData,           _data_size,                                    int)                                   \
       nonstatic_field(MethodData,           _data[0],                                      intptr_t)                              \
       nonstatic_field(MethodData,           _nof_decompiles,                               uint)                                  \
    
    From 8277af52eea7594c2c4e961dc48bbd2241618213 Mon Sep 17 00:00:00 2001
    From: Vicente Romero 
    Date: Thu, 4 Jul 2013 10:35:33 +0100
    Subject: [PATCH 026/156] 8009924: some langtools tools do not accept -cp as an
     alias for -classpath
    
    Reviewed-by: jjg
    ---
     .../tools/doclets/internal/toolkit/Configuration.java    | 2 +-
     .../src/share/classes/com/sun/tools/doclint/DocLint.java | 2 ++
     .../com/sun/tools/doclint/resources/doclint.properties   | 2 +-
     .../share/classes/com/sun/tools/javadoc/ToolOption.java  | 9 ++++++++-
     .../com/sun/tools/javadoc/resources/javadoc.properties   | 1 +
     .../src/share/classes/com/sun/tools/javah/JavahTask.java | 2 +-
     .../com/sun/tools/javah/resources/l10n.properties        | 5 ++++-
     .../src/share/classes/com/sun/tools/javap/JavapTask.java | 2 +-
     .../com/sun/tools/javap/resources/javap.properties       | 5 ++++-
     langtools/test/tools/doclint/tool/HelpTest.out           | 2 +-
     10 files changed, 24 insertions(+), 8 deletions(-)
    
    diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
    index b45b944416a..633e941041a 100644
    --- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
    +++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
    @@ -467,7 +467,7 @@ public abstract class Configuration {
                     nodeprecated = true;
                 } else if (opt.equals("-sourcepath")) {
                     sourcepath = os[1];
    -            } else if (opt.equals("-classpath") &&
    +            } else if ((opt.equals("-classpath") || opt.equals("-cp")) &&
                            sourcepath.length() == 0) {
                     sourcepath = os[1];
                 } else if (opt.equals("-excludedocfilessubdir")) {
    diff --git a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java
    index c1d8d994316..181b70015c8 100644
    --- a/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java
    +++ b/langtools/src/share/classes/com/sun/tools/doclint/DocLint.java
    @@ -187,6 +187,8 @@ public class DocLint implements Plugin {
                     javacBootClassPath = splitPath(args[++i]);
                 } else if (arg.equals("-classpath") && i + 1 < args.length) {
                     javacClassPath = splitPath(args[++i]);
    +            } else if (arg.equals("-cp") && i + 1 < args.length) {
    +                javacClassPath = splitPath(args[++i]);
                 } else if (arg.equals("-sourcepath") && i + 1 < args.length) {
                     javacSourcePath = splitPath(args[++i]);
                 } else if (arg.equals(XMSGS_OPTION)) {
    diff --git a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties
    index 995cb335087..8905235d082 100644
    --- a/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties
    +++ b/langtools/src/share/classes/com/sun/tools/doclint/resources/doclint.properties
    @@ -109,7 +109,7 @@ Options:\n\
     \    Show this message.\n\
     \n\
     The following javac options are also supported\n\
    -\  -bootclasspath, -classpath, -sourcepath, -Xmaxerrs, -Xmaxwarns\n\
    +\  -bootclasspath, -classpath, -cp, -sourcepath, -Xmaxerrs, -Xmaxwarns\n\
     \n\
     To run doclint on part of a project, put the compiled classes for your\n\
     project on the classpath (or bootclasspath), then specify the source files\n\
    diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java b/langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java
    index 7b0936e77b8..2bd68ed0b18 100644
    --- a/langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java
    +++ b/langtools/src/share/classes/com/sun/tools/javadoc/ToolOption.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -56,6 +56,13 @@ public enum ToolOption {
             }
         },
     
    +    CP("-cp", true) {
    +        @Override
    +        public void process(Helper helper, String arg) {
    +            helper.setCompilerOpt(opt, arg);
    +        }
    +    },
    +
         EXTDIRS("-extdirs", true) {
             @Override
             public void process(Helper helper, String arg) {
    diff --git a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
    index 3e384a165de..8ac2c3480e7 100644
    --- a/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
    +++ b/langtools/src/share/classes/com/sun/tools/javadoc/resources/javadoc.properties
    @@ -39,6 +39,7 @@ main.usage=Usage: javadoc [options] [packagenames] [sourcefiles] [@files]\n\
     \  -docletpath                Specify where to find doclet class files\n\
     \  -sourcepath            Specify where to find source files\n\
     \  -classpath             Specify where to find user class files\n\
    +\  -cp                    Specify where to find user class files\n\
     \  -exclude                Specify a list of packages to exclude\n\
     \  -subpackages         Specify subpackages to recursively load\n\
     \  -breakiterator                   Compute first sentence with BreakIterator\n\
    diff --git a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
    index d203f1140bb..84b7c2b699d 100644
    --- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
    +++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
    @@ -531,7 +531,7 @@ public class JavahTask implements NativeHeaderTool.NativeHeaderTask {
                 String name = o.aliases[0].substring(1); // there must always be at least one name
                 log.println(getMessage("main.opt." + name));
             }
    -        String[] fmOptions = { "-classpath", "-bootclasspath" };
    +        String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
             for (String o: fmOptions) {
                 if (fileManager.isSupportedOption(o) == -1)
                     continue;
    diff --git a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties
    index 632cd1581f9..875816b2050 100644
    --- a/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties
    +++ b/langtools/src/share/classes/com/sun/tools/javah/resources/l10n.properties
    @@ -1,5 +1,5 @@
     #
    -# Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
    +# Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
     # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     #
     # This code is free software; you can redistribute it and/or modify it
    @@ -77,6 +77,7 @@ where [options] include:\n\
     \n\t\
     -help                 Print this help message and exit\n\t\
     -classpath      Path from which to load classes\n\t\
    +-cp             Path from which to load classes\n\t\
     -bootclasspath  Path from which to load bootstrap classes\n\t\
     -d               Output directory\n\t\
     -o              Output file (only one of -d or -o may be used)\n\t\
    @@ -108,6 +109,8 @@ main.opt.force=\
     \  -force                   Always write output files
     main.opt.classpath=\
     \  -classpath         Path from which to load classes
    +main.opt.cp=\
    +\  -cp                Path from which to load classes
     main.opt.bootclasspath=\
     \  -bootclasspath     Path from which to load bootstrap classes
     main.usage.foot=\
    diff --git a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
    index 77f9c3c8991..0cafe023cca 100644
    --- a/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
    +++ b/langtools/src/share/classes/com/sun/tools/javap/JavapTask.java
    @@ -885,7 +885,7 @@ public class JavapTask implements DisassemblerTool.DisassemblerTask, Messages {
                     continue;
                 log.println(getMessage("main.opt." + name));
             }
    -        String[] fmOptions = { "-classpath", "-bootclasspath" };
    +        String[] fmOptions = { "-classpath", "-cp", "-bootclasspath" };
             for (String o: fmOptions) {
                 if (fileManager.isSupportedOption(o) == -1)
                     continue;
    diff --git a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties
    index 4a13d601970..c77024f75f5 100644
    --- a/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties
    +++ b/langtools/src/share/classes/com/sun/tools/javap/resources/javap.properties
    @@ -1,5 +1,5 @@
     
    -err.prefix=Error: 
    +err.prefix=Error:
     
     err.bad.constant.pool=error while reading constant pool for {0}: {1}
     err.class.not.found=class not found: {0}
    @@ -73,6 +73,9 @@ main.opt.s=\
     main.opt.classpath=\
     \  -classpath         Specify where to find user class files
     
    +main.opt.cp=\
    +\  -cp                Specify where to find user class files
    +
     main.opt.bootclasspath=\
     \  -bootclasspath     Override location of bootstrap class files
     
    diff --git a/langtools/test/tools/doclint/tool/HelpTest.out b/langtools/test/tools/doclint/tool/HelpTest.out
    index 78db573f178..0d7d4020a7c 100644
    --- a/langtools/test/tools/doclint/tool/HelpTest.out
    +++ b/langtools/test/tools/doclint/tool/HelpTest.out
    @@ -36,7 +36,7 @@ Options:
         Show this message.
     
     The following javac options are also supported
    -  -bootclasspath, -classpath, -sourcepath, -Xmaxerrs, -Xmaxwarns
    +  -bootclasspath, -classpath, -cp, -sourcepath, -Xmaxerrs, -Xmaxwarns
     
     To run doclint on part of a project, put the compiled classes for your
     project on the classpath (or bootclasspath), then specify the source files
    
    From 684d5ec76d311670f2a763561b27bc6b6d6314b9 Mon Sep 17 00:00:00 2001
    From: Vicente Romero 
    Date: Thu, 4 Jul 2013 10:41:08 +0100
    Subject: [PATCH 027/156] 6356530: -Xlint:serial does not flag abstract classes
     with concrete methods/members
    
    Reviewed-by: mcimadamore
    ---
     .../com/sun/tools/javac/code/Scope.java       |  7 ++-
     .../com/sun/tools/javac/comp/Attr.java        | 18 ++++++-
     ...stractClassWithNonAbstractMethodsTest.java | 48 +++++++++++++++++++
     ...bstractClassWithNonAbstractMethodsTest.out |  5 ++
     4 files changed, 76 insertions(+), 2 deletions(-)
     create mode 100644 langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java
     create mode 100644 langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out
    
    diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
    index e8153da2703..3697e05dead 100644
    --- a/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
    +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Scope.java
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -316,6 +316,7 @@ public class Scope {
         public Entry lookup(Name name) {
             return lookup(name, noFilter);
         }
    +
         public Entry lookup(Name name, Filter sf) {
             Entry e = table[getIndex(name)];
             if (e == null || e == sentinel)
    @@ -361,6 +362,10 @@ public class Scope {
             }
         }
     
    +    public boolean anyMatch(Filter sf) {
    +        return getElements(sf).iterator().hasNext();
    +    }
    +
         public Iterable getElements() {
             return getElements(noFilter);
         }
    diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
    index 1be8604319f..91bc4e9b39e 100644
    --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
    +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
    @@ -4301,7 +4301,7 @@ public class Attr extends JCTree.Visitor {
             if (env.info.lint.isEnabled(LintCategory.SERIAL) &&
                 isSerializable(c) &&
                 (c.flags() & Flags.ENUM) == 0 &&
    -            (c.flags() & ABSTRACT) == 0) {
    +            checkForSerial(c)) {
                 checkSerialVersionUID(tree, c);
             }
             if (allowTypeAnnos) {
    @@ -4313,6 +4313,22 @@ public class Attr extends JCTree.Visitor {
             }
         }
             // where
    +        boolean checkForSerial(ClassSymbol c) {
    +            if ((c.flags() & ABSTRACT) == 0) {
    +                return true;
    +            } else {
    +                return c.members().anyMatch(anyNonAbstractOrDefaultMethod);
    +            }
    +        }
    +
    +        public static final Filter anyNonAbstractOrDefaultMethod = new Filter() {
    +            @Override
    +            public boolean accepts(Symbol s) {
    +                return s.kind == Kinds.MTH &&
    +                       (s.flags() & (DEFAULT | ABSTRACT)) != ABSTRACT;
    +            }
    +        };
    +
             /** get a diagnostic position for an attribute of Type t, or null if attribute missing */
             private DiagnosticPosition getDiagnosticPosition(JCClassDecl tree, Type t) {
                 for(List al = tree.mods.annotations; !al.isEmpty(); al = al.tail) {
    diff --git a/langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java b/langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java
    new file mode 100644
    index 00000000000..ffdf34d5c8e
    --- /dev/null
    +++ b/langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.java
    @@ -0,0 +1,48 @@
    +/*
    + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + *
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + *
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + *
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + *
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/*
    + * @test
    + * @bug 6356530
    + * @summary -Xlint:serial does not flag abstract classes with concrete methods/members
    + * @compile/fail/ref=SerializableAbstractClassWithNonAbstractMethodsTest.out -XDrawDiagnostics -Werror -Xlint:serial SerializableAbstractClassWithNonAbstractMethodsTest.java
    + */
    +
    +abstract class SerializableAbstractClassWithNonAbstractMethodsTest implements java.io.Serializable {
    +    void m1() {}
    +    abstract void m2();
    +
    +    abstract class AWithUID implements java.io.Serializable {
    +        private static final long serialVersionUID = 0;
    +        void m(){}
    +    }
    +
    +    interface IDefault extends java.io.Serializable {
    +        default int m() { return 1; }
    +    }
    +
    +    interface IDefaultAndUID extends java.io.Serializable {
    +        static final long serialVersionUID = 0;
    +        default int m() { return 1; }
    +    }
    +}
    diff --git a/langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out b/langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out
    new file mode 100644
    index 00000000000..b6007717746
    --- /dev/null
    +++ b/langtools/test/tools/javac/T6356530/SerializableAbstractClassWithNonAbstractMethodsTest.out
    @@ -0,0 +1,5 @@
    +SerializableAbstractClassWithNonAbstractMethodsTest.java:40:5: compiler.warn.missing.SVUID: SerializableAbstractClassWithNonAbstractMethodsTest.IDefault
    +SerializableAbstractClassWithNonAbstractMethodsTest.java:31:10: compiler.warn.missing.SVUID: SerializableAbstractClassWithNonAbstractMethodsTest
    +- compiler.err.warnings.and.werror
    +1 error
    +2 warnings
    
    From 3e8c767620a9c28927b41c15c5ab5cb46bb4a136 Mon Sep 17 00:00:00 2001
    From: Zhengyu Gu 
    Date: Thu, 4 Jul 2013 06:24:08 -0400
    Subject: [PATCH 028/156] 8016074: NMT: assertion failed:
     assert(thread->thread_state() == from) failed: coming from wrong thread state
    
    Uses os::NakedYield() on Solaris instead of os::yield_all()
    
    Reviewed-by: acorn, coleenp, hseigel
    ---
     hotspot/src/share/vm/services/memTracker.hpp | 14 ++++++++++++++
     1 file changed, 14 insertions(+)
    
    diff --git a/hotspot/src/share/vm/services/memTracker.hpp b/hotspot/src/share/vm/services/memTracker.hpp
    index dc7b78859d3..364c6b4f235 100644
    --- a/hotspot/src/share/vm/services/memTracker.hpp
    +++ b/hotspot/src/share/vm/services/memTracker.hpp
    @@ -470,7 +470,21 @@ class MemTracker : AllStatic {
       static void check_NMT_load(Thread* thr) {
         assert(thr != NULL, "Sanity check");
         if (_slowdown_calling_thread && thr != _worker_thread) {
    +#ifdef _WINDOWS
    +      // On Windows, os::NakedYield() does not work as well
    +      // as os::yield_all()
           os::yield_all();
    +#else
    +     // On Solaris, os::yield_all() depends on os::sleep()
    +     // which requires JavaTherad in _thread_in_vm state.
    +     // Transits thread to _thread_in_vm state can be dangerous
    +     // if caller holds lock, as it may deadlock with Threads_lock.
    +     // So use NaKedYield instead.
    +     //
    +     // Linux and BSD, NakedYield() and yield_all() implementations
    +     // are the same.
    +      os::NakedYield();
    +#endif
         }
       }
     
    
    From b75b83da3e089598067d43f6b0200310791a4604 Mon Sep 17 00:00:00 2001
    From: Anton Litvinov 
    Date: Thu, 4 Jul 2013 16:06:11 +0400
    Subject: [PATCH 029/156] 8015730: PIT: On Linux, OGL=true and fbobject=false
     leads to deadlock or infinite loop
    
    Reviewed-by: art, anthony
    ---
     .../classes/sun/awt/X11/XErrorHandlerUtil.java |  8 +++++++-
     jdk/src/solaris/native/sun/awt/awt_util.h      | 18 ++++++++++++++----
     .../native/sun/java2d/opengl/GLXSurfaceData.c  | 10 ++++++----
     3 files changed, 27 insertions(+), 9 deletions(-)
    
    diff --git a/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java b/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java
    index e45f67ffde9..da12cd9ef89 100644
    --- a/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java
    +++ b/jdk/src/solaris/classes/sun/awt/X11/XErrorHandlerUtil.java
    @@ -105,9 +105,15 @@ public final class XErrorHandlerUtil {
          * Unsets a current synthetic error handler. Must be called with the acquired AWT lock.
          */
         public static void RESTORE_XERROR_HANDLER() {
    +        RESTORE_XERROR_HANDLER(true);
    +    }
    +
    +    private static void RESTORE_XERROR_HANDLER(boolean doXSync) {
             // Wait until all requests are processed by the X server
             // and only then uninstall the error handler.
    -        XSync();
    +        if (doXSync) {
    +            XSync();
    +        }
             current_error_handler = null;
         }
     
    diff --git a/jdk/src/solaris/native/sun/awt/awt_util.h b/jdk/src/solaris/native/sun/awt/awt_util.h
    index 6e350727806..b93f7744cd6 100644
    --- a/jdk/src/solaris/native/sun/awt/awt_util.h
    +++ b/jdk/src/solaris/native/sun/awt/awt_util.h
    @@ -46,11 +46,11 @@
     
     /*
      * Expected types of arguments of the macro.
    - * (JNIEnv*)
    + * (JNIEnv*, jboolean)
      */
    -#define RESTORE_XERROR_HANDLER(env) do {                                                          \
    +#define RESTORE_XERROR_HANDLER(env, doXSync) do {                                                 \
         JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XErrorHandlerUtil",                        \
    -        "RESTORE_XERROR_HANDLER", "()V");                                                         \
    +        "RESTORE_XERROR_HANDLER", "(Z)V", doXSync);                                               \
     } while (0)
     
     /*
    @@ -64,8 +64,18 @@
         do {                                                                                          \
             code;                                                                                     \
         } while (0);                                                                                  \
    -    RESTORE_XERROR_HANDLER(env);                                                                  \
    +    RESTORE_XERROR_HANDLER(env, JNI_TRUE);                                                        \
         if (handlerHasFlag == JNI_TRUE) {                                                             \
    +        GET_HANDLER_ERROR_OCCURRED_FLAG(env, handlerRef, errorOccurredFlag);                      \
    +    }                                                                                             \
    +} while (0)
    +
    +/*
    + * Expected types of arguments of the macro.
    + * (JNIEnv*, jobject, jboolean)
    + */
    +#define GET_HANDLER_ERROR_OCCURRED_FLAG(env, handlerRef, errorOccurredFlag) do {                  \
    +    if (handlerRef != NULL) {                                                                     \
             errorOccurredFlag = JNU_CallMethodByName(env, NULL, handlerRef, "getErrorOccurredFlag",   \
                 "()Z").z;                                                                             \
         }                                                                                             \
    diff --git a/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c b/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
    index 4a4e75f6228..e1cf2c57501 100644
    --- a/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
    +++ b/jdk/src/solaris/native/sun/java2d/opengl/GLXSurfaceData.c
    @@ -392,10 +392,12 @@ Java_sun_java2d_opengl_GLXSurfaceData_initPbuffer
         attrlist[3] = height;
     
         errorOccurredFlag = JNI_FALSE;
    -    EXEC_WITH_XERROR_HANDLER(env, "sun/awt/X11/XErrorHandler$GLXBadAllocHandler",
    -        "()Lsun/awt/X11/XErrorHandler$GLXBadAllocHandler;", JNI_TRUE,
    -        errorHandlerRef, errorOccurredFlag,
    -        pbuffer = j2d_glXCreatePbuffer(awt_display, glxinfo->fbconfig, attrlist));
    +    WITH_XERROR_HANDLER(env, "sun/awt/X11/XErrorHandler$GLXBadAllocHandler",
    +        "()Lsun/awt/X11/XErrorHandler$GLXBadAllocHandler;", JNI_TRUE, errorHandlerRef);
    +    pbuffer = j2d_glXCreatePbuffer(awt_display, glxinfo->fbconfig, attrlist);
    +    XSync(awt_display, False);
    +    RESTORE_XERROR_HANDLER(env, JNI_FALSE);
    +    GET_HANDLER_ERROR_OCCURRED_FLAG(env, errorHandlerRef, errorOccurredFlag);
     
         if ((pbuffer == 0) || errorOccurredFlag) {
             J2dRlsTraceLn(J2D_TRACE_ERROR,
    
    From f495ca639cb298ccf27dc44ac5fac0f9070eb790 Mon Sep 17 00:00:00 2001
    From: Attila Szegedi 
    Date: Thu, 4 Jul 2013 14:10:18 +0200
    Subject: [PATCH 030/156] 8019809: return after break incorrectly sets the
     block as terminal
    
    Reviewed-by: jlaskey, lagergren
    ---
     .../jdk/nashorn/internal/codegen/Lower.java   | 24 ++++++++++++++-----
     .../internal/ir/BlockLexicalContext.java      | 19 ++++++++++-----
     .../JDK-8019809.js                            |  0
     3 files changed, 31 insertions(+), 12 deletions(-)
     rename nashorn/test/script/{currently-failing => basic}/JDK-8019809.js (100%)
    
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
    index 013564c2760..880fea67640 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
    @@ -32,6 +32,7 @@ import static jdk.nashorn.internal.codegen.CompilerConstants.THIS;
     import java.util.ArrayList;
     import java.util.Arrays;
     import java.util.List;
    +import java.util.ListIterator;
     import jdk.nashorn.internal.ir.BaseNode;
     import jdk.nashorn.internal.ir.BinaryNode;
     import jdk.nashorn.internal.ir.Block;
    @@ -115,6 +116,21 @@ final class Lower extends NodeOperatorVisitor {
                     }
                     return newStatements;
                 }
    +
    +            @Override
    +            protected Block afterSetStatements(final Block block) {
    +                final List stmts = block.getStatements();
    +                for(final ListIterator li = stmts.listIterator(stmts.size()); li.hasPrevious();) {
    +                    final Statement stmt = li.previous();
    +                    // popStatements() guarantees that the only thing after a terminal statement are uninitialized
    +                    // VarNodes. We skip past those, and set the terminal state of the block to the value of the
    +                    // terminal state of the first statement that is not an uninitialized VarNode.
    +                    if(!(stmt instanceof VarNode && ((VarNode)stmt).getInit() == null)) {
    +                        return block.setIsTerminal(this, stmt.isTerminal());
    +                    }
    +                }
    +                return block.setIsTerminal(this, false);
    +            }
             });
         }
     
    @@ -132,11 +148,11 @@ final class Lower extends NodeOperatorVisitor {
             //now we have committed the entire statement list to the block, but we need to truncate
             //whatever is after the last terminal. block append won't append past it
     
    -        Statement last = lc.getLastStatement();
     
             if (lc.isFunctionBody()) {
                 final FunctionNode currentFunction = lc.getCurrentFunction();
                 final boolean isProgram = currentFunction.isProgram();
    +            final Statement last = lc.getLastStatement();
                 final ReturnNode returnNode = new ReturnNode(
                     last == null ? block.getLineNumber() : last.getLineNumber(), //TODO?
                     currentFunction.getToken(),
    @@ -145,11 +161,7 @@ final class Lower extends NodeOperatorVisitor {
                         compilerConstant(RETURN) :
                         LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED));
     
    -            last = (Statement)returnNode.accept(this);
    -        }
    -
    -        if (last != null && last.isTerminal()) {
    -            return block.setIsTerminal(lc, true);
    +            returnNode.accept(this);
             }
     
             return block;
    diff --git a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
    index 71c80a6b04f..8fecddd0b90 100644
    --- a/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
    +++ b/nashorn/src/jdk/nashorn/internal/ir/BlockLexicalContext.java
    @@ -29,7 +29,6 @@ import java.util.ArrayDeque;
     import java.util.ArrayList;
     import java.util.Deque;
     import java.util.List;
    -import java.util.ListIterator;
     
     /**
      * This is a subclass of lexical context used for filling
    @@ -63,6 +62,16 @@ public class BlockLexicalContext extends LexicalContext {
             return sstack.pop();
         }
     
    +    /**
    +     * Override this method to perform some additional processing on the block after its statements have been set. By
    +     * default does nothing and returns the original block.
    +     * @param block the block to operate on
    +     * @return a modified block.
    +     */
    +    protected Block afterSetStatements(Block block) {
    +        return block;
    +    }
    +
         @SuppressWarnings("unchecked")
         @Override
         public  T pop(final T node) {
    @@ -70,6 +79,7 @@ public class BlockLexicalContext extends LexicalContext {
             if (node instanceof Block) {
                 final List newStatements = popStatements();
                 expected = (T)((Block)node).setStatements(this, newStatements);
    +            expected = (T)afterSetStatements((Block)expected);
                 if (!sstack.isEmpty()) {
                     lastStatement = lastStatement(sstack.peek());
                 }
    @@ -107,10 +117,7 @@ public class BlockLexicalContext extends LexicalContext {
         }
     
         private static Statement lastStatement(final List statements) {
    -        for (final ListIterator iter = statements.listIterator(statements.size()); iter.hasPrevious(); ) {
    -            final Statement node = iter.previous();
    -            return node;
    -        }
    -        return null;
    +        final int s = statements.size();
    +        return s == 0 ? null : statements.get(s - 1);
         }
     }
    diff --git a/nashorn/test/script/currently-failing/JDK-8019809.js b/nashorn/test/script/basic/JDK-8019809.js
    similarity index 100%
    rename from nashorn/test/script/currently-failing/JDK-8019809.js
    rename to nashorn/test/script/basic/JDK-8019809.js
    
    From 0807ef36381851d17375331ae67f8a54bcfb34a5 Mon Sep 17 00:00:00 2001
    From: Marcus Lagergren 
    Date: Thu, 4 Jul 2013 17:27:33 +0200
    Subject: [PATCH 031/156] 8019821: allInteger switches were confused by boolean
     cases, as they are a narrower type than int
    
    Reviewed-by: sundar, hannesw
    ---
     .../jdk/nashorn/internal/codegen/Attr.java    |  3 ++
     nashorn/test/script/basic/JDK-8019821.js      | 37 +++++++++++++++++++
     2 files changed, 40 insertions(+)
     create mode 100644 nashorn/test/script/basic/JDK-8019821.js
    
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
    index e9cc259fb3d..d72e6a76c72 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
    @@ -791,6 +791,9 @@ final class Attr extends NodeOperatorVisitor {
                     }
     
                     type = Type.widest(type, newCaseNode.getTest().getType());
    +                if (type.isBoolean()) {
    +                    type = Type.OBJECT; //booleans and integers aren't assignment compatible
    +                }
                 }
     
                 newCases.add(newCaseNode);
    diff --git a/nashorn/test/script/basic/JDK-8019821.js b/nashorn/test/script/basic/JDK-8019821.js
    new file mode 100644
    index 00000000000..c296ac3c8e8
    --- /dev/null
    +++ b/nashorn/test/script/basic/JDK-8019821.js
    @@ -0,0 +1,37 @@
    +/*
    + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    + * 
    + * This code is free software; you can redistribute it and/or modify it
    + * under the terms of the GNU General Public License version 2 only, as
    + * published by the Free Software Foundation.
    + * 
    + * This code 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 General Public License
    + * version 2 for more details (a copy is included in the LICENSE file that
    + * accompanied this code).
    + * 
    + * You should have received a copy of the GNU General Public License version
    + * 2 along with this work; if not, write to the Free Software Foundation,
    + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    + * 
    + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    + * or visit www.oracle.com if you need additional information or have any
    + * questions.
    + */
    +
    +/**
    + * JDK-8019821: boolean switch value accidentally triggered "allInts" case 
    + * as boolean is considered narrower than int. This caused a ClassCastException
    + *
    + * @test
    + * @run
    + */
    +
    +function f() { 
    +    switch(gc()) { 
    +    case true: 
    +    case 1:  
    +    }
    +}
    
    From b5efe058f7347c61ccb67eafa39dcdf3106255c0 Mon Sep 17 00:00:00 2001
    From: Alejandro Murillo 
    Date: Thu, 4 Jul 2013 14:56:49 -0700
    Subject: [PATCH 032/156] 8019934: new hotspot build - hs25-b41
    
    Reviewed-by: jcoomes
    ---
     hotspot/make/hotspot_version | 2 +-
     1 file changed, 1 insertion(+), 1 deletion(-)
    
    diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
    index b597ff990be..8d98d13fbaf 100644
    --- a/hotspot/make/hotspot_version
    +++ b/hotspot/make/hotspot_version
    @@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
     
     HS_MAJOR_VER=25
     HS_MINOR_VER=0
    -HS_BUILD_NUMBER=40
    +HS_BUILD_NUMBER=41
     
     JDK_MAJOR_VER=1
     JDK_MINOR_VER=8
    
    From 765f5cd4e735f1224fe4e2058e56a0a029acc10f Mon Sep 17 00:00:00 2001
    From: "Daniel D. Daugherty" 
    Date: Thu, 4 Jul 2013 21:10:17 -0700
    Subject: [PATCH 033/156] 8015884: runThese crashed with SIGSEGV, hs_err has an
     error instead of stacktrace
    
    Dl_info struct should only be used if dladdr() has returned non-zero (no errors) and always check the dladdr() return value; Dl_info.dli_sname and Dl_info.dli_saddr fields should only be used if non-NULL; update/improve runtime/6888954/vmerrors.sh test
    
    Reviewed-by: dsamersoff, zgu, hseigel, coleenp
    ---
     hotspot/src/os/bsd/vm/os_bsd.cpp              | 163 ++++++++------
     hotspot/src/os/linux/vm/os_linux.cpp          |  76 ++++---
     hotspot/src/os/solaris/vm/os_solaris.cpp      | 211 ++++++++++--------
     hotspot/src/os/windows/vm/os_windows.cpp      |  49 ++--
     hotspot/src/os/windows/vm/os_windows.hpp      |   6 +-
     .../src/os/windows/vm/os_windows.inline.hpp   |   6 +
     hotspot/src/share/vm/prims/jni.cpp            |  18 +-
     hotspot/src/share/vm/runtime/os.hpp           |  10 +-
     hotspot/src/share/vm/utilities/debug.cpp      |  17 +-
     hotspot/src/share/vm/utilities/debug.hpp      |   4 +-
     hotspot/test/runtime/6888954/vmerrors.sh      |  23 +-
     11 files changed, 351 insertions(+), 232 deletions(-)
    
    diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
    index 2db740583e8..55043ad243a 100644
    --- a/hotspot/src/os/bsd/vm/os_bsd.cpp
    +++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
    @@ -1234,12 +1234,13 @@ bool os::address_is_in_vm(address addr) {
       Dl_info dlinfo;
     
       if (libjvm_base_addr == NULL) {
    -    dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
    -    libjvm_base_addr = (address)dlinfo.dli_fbase;
    +    if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
    +      libjvm_base_addr = (address)dlinfo.dli_fbase;
    +    }
         assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
       }
     
    -  if (dladdr((void *)addr, &dlinfo)) {
    +  if (dladdr((void *)addr, &dlinfo) != 0) {
         if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
       }
     
    @@ -1251,35 +1252,40 @@ bool os::address_is_in_vm(address addr) {
     
     bool os::dll_address_to_function_name(address addr, char *buf,
                                           int buflen, int *offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       Dl_info dlinfo;
       char localbuf[MACH_MAXSYMLEN];
     
    -  // dladdr will find names of dynamic functions only, but does
    -  // it set dli_fbase with mach_header address when it "fails" ?
    -  if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
    -    if (buf != NULL) {
    -      if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
    +  if (dladdr((void*)addr, &dlinfo) != 0) {
    +    // see if we have a matching symbol
    +    if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
    +      if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
             jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
           }
    +      if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    +      return true;
         }
    -    if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    -    return true;
    -  } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    -    if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    -       buf, buflen, offset, dlinfo.dli_fname)) {
    -       return true;
    +    // no matching symbol so try for just file info
    +    if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
    +      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    +                          buf, buflen, offset, dlinfo.dli_fname)) {
    +         return true;
    +      }
         }
    -  }
     
    -  // Handle non-dymanic manually:
    -  if (dlinfo.dli_fbase != NULL &&
    -      Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) {
    -    if(!Decoder::demangle(localbuf, buf, buflen)) {
    -      jio_snprintf(buf, buflen, "%s", localbuf);
    +    // Handle non-dynamic manually:
    +    if (dlinfo.dli_fbase != NULL &&
    +        Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset,
    +                        dlinfo.dli_fbase)) {
    +      if (!Decoder::demangle(localbuf, buf, buflen)) {
    +        jio_snprintf(buf, buflen, "%s", localbuf);
    +      }
    +      return true;
         }
    -    return true;
       }
    -  if (buf != NULL) buf[0] = '\0';
    +  buf[0] = '\0';
       if (offset != NULL) *offset = -1;
       return false;
     }
    @@ -1287,17 +1293,24 @@ bool os::dll_address_to_function_name(address addr, char *buf,
     // ported from solaris version
     bool os::dll_address_to_library_name(address addr, char* buf,
                                          int buflen, int* offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       Dl_info dlinfo;
     
    -  if (dladdr((void*)addr, &dlinfo)){
    -     if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
    -     if (offset) *offset = addr - (address)dlinfo.dli_fbase;
    -     return true;
    -  } else {
    -     if (buf) buf[0] = '\0';
    -     if (offset) *offset = -1;
    -     return false;
    +  if (dladdr((void*)addr, &dlinfo) != 0) {
    +    if (dlinfo.dli_fname != NULL) {
    +      jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
    +    }
    +    if (dlinfo.dli_fbase != NULL && offset != NULL) {
    +      *offset = addr - (address)dlinfo.dli_fbase;
    +    }
    +    return true;
       }
    +
    +  buf[0] = '\0';
    +  if (offset) *offset = -1;
    +  return false;
     }
     
     // Loads .dll/.so and
    @@ -1520,49 +1533,50 @@ static bool _print_ascii_file(const char* filename, outputStream* st) {
     }
     
     void os::print_dll_info(outputStream *st) {
    -   st->print_cr("Dynamic libraries:");
    +  st->print_cr("Dynamic libraries:");
     #ifdef RTLD_DI_LINKMAP
    -    Dl_info dli;
    -    void *handle;
    -    Link_map *map;
    -    Link_map *p;
    +  Dl_info dli;
    +  void *handle;
    +  Link_map *map;
    +  Link_map *p;
     
    -    if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) {
    -        st->print_cr("Error: Cannot print dynamic libraries.");
    -        return;
    -    }
    -    handle = dlopen(dli.dli_fname, RTLD_LAZY);
    -    if (handle == NULL) {
    -        st->print_cr("Error: Cannot print dynamic libraries.");
    -        return;
    -    }
    -    dlinfo(handle, RTLD_DI_LINKMAP, &map);
    -    if (map == NULL) {
    -        st->print_cr("Error: Cannot print dynamic libraries.");
    -        return;
    -    }
    +  if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
    +      dli.dli_fname == NULL) {
    +    st->print_cr("Error: Cannot print dynamic libraries.");
    +    return;
    +  }
    +  handle = dlopen(dli.dli_fname, RTLD_LAZY);
    +  if (handle == NULL) {
    +    st->print_cr("Error: Cannot print dynamic libraries.");
    +    return;
    +  }
    +  dlinfo(handle, RTLD_DI_LINKMAP, &map);
    +  if (map == NULL) {
    +    st->print_cr("Error: Cannot print dynamic libraries.");
    +    return;
    +  }
     
    -    while (map->l_prev != NULL)
    -        map = map->l_prev;
    +  while (map->l_prev != NULL)
    +    map = map->l_prev;
     
    -    while (map != NULL) {
    -        st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
    -        map = map->l_next;
    -    }
    +  while (map != NULL) {
    +    st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
    +    map = map->l_next;
    +  }
     
    -    dlclose(handle);
    +  dlclose(handle);
     #elif defined(__APPLE__)
    -    uint32_t count;
    -    uint32_t i;
    +  uint32_t count;
    +  uint32_t i;
     
    -    count = _dyld_image_count();
    -    for (i = 1; i < count; i++) {
    -        const char *name = _dyld_get_image_name(i);
    -        intptr_t slide = _dyld_get_image_vmaddr_slide(i);
    -        st->print_cr(PTR_FORMAT " \t%s", slide, name);
    -    }
    +  count = _dyld_image_count();
    +  for (i = 1; i < count; i++) {
    +    const char *name = _dyld_get_image_name(i);
    +    intptr_t slide = _dyld_get_image_vmaddr_slide(i);
    +    st->print_cr(PTR_FORMAT " \t%s", slide, name);
    +  }
     #else
    -   st->print_cr("Error: Cannot print dynamic libraries.");
    +  st->print_cr("Error: Cannot print dynamic libraries.");
     #endif
     }
     
    @@ -1707,8 +1721,11 @@ void os::jvm_path(char *buf, jint buflen) {
       bool ret = dll_address_to_library_name(
                     CAST_FROM_FN_PTR(address, os::jvm_path),
                     dli_fname, sizeof(dli_fname), NULL);
    -  assert(ret != 0, "cannot locate libjvm");
    -  char *rp = realpath(dli_fname, buf);
    +  assert(ret, "cannot locate libjvm");
    +  char *rp = NULL;
    +  if (ret && dli_fname[0] != '\0') {
    +    rp = realpath(dli_fname, buf);
    +  }
       if (rp == NULL)
         return;
     
    @@ -3747,20 +3764,20 @@ int os::Bsd::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mutex,
     bool os::find(address addr, outputStream* st) {
       Dl_info dlinfo;
       memset(&dlinfo, 0, sizeof(dlinfo));
    -  if (dladdr(addr, &dlinfo)) {
    +  if (dladdr(addr, &dlinfo) != 0) {
         st->print(PTR_FORMAT ": ", addr);
    -    if (dlinfo.dli_sname != NULL) {
    +    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
           st->print("%s+%#x", dlinfo.dli_sname,
                      addr - (intptr_t)dlinfo.dli_saddr);
    -    } else if (dlinfo.dli_fname) {
    +    } else if (dlinfo.dli_fbase != NULL) {
           st->print("", addr - (intptr_t)dlinfo.dli_fbase);
         } else {
           st->print("");
         }
    -    if (dlinfo.dli_fname) {
    +    if (dlinfo.dli_fname != NULL) {
           st->print(" in %s", dlinfo.dli_fname);
         }
    -    if (dlinfo.dli_fbase) {
    +    if (dlinfo.dli_fbase != NULL) {
           st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
         }
         st->cr();
    @@ -3773,7 +3790,7 @@ bool os::find(address addr, outputStream* st) {
           if (!lowest)  lowest = (address) dlinfo.dli_fbase;
           if (begin < lowest)  begin = lowest;
           Dl_info dlinfo2;
    -      if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
    +      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
               && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
             end = (address) dlinfo2.dli_saddr;
           Disassembler::decode(begin, end, st);
    diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
    index 53bfe4e7369..df58be635d1 100644
    --- a/hotspot/src/os/linux/vm/os_linux.cpp
    +++ b/hotspot/src/os/linux/vm/os_linux.cpp
    @@ -1682,12 +1682,13 @@ bool os::address_is_in_vm(address addr) {
       Dl_info dlinfo;
     
       if (libjvm_base_addr == NULL) {
    -    dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
    -    libjvm_base_addr = (address)dlinfo.dli_fbase;
    +    if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
    +      libjvm_base_addr = (address)dlinfo.dli_fbase;
    +    }
         assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
       }
     
    -  if (dladdr((void *)addr, &dlinfo)) {
    +  if (dladdr((void *)addr, &dlinfo) != 0) {
         if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
       }
     
    @@ -1696,24 +1697,30 @@ bool os::address_is_in_vm(address addr) {
     
     bool os::dll_address_to_function_name(address addr, char *buf,
                                           int buflen, int *offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       Dl_info dlinfo;
     
    -  if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
    -    if (buf != NULL) {
    -      if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
    +  if (dladdr((void*)addr, &dlinfo) != 0) {
    +    // see if we have a matching symbol
    +    if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
    +      if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
             jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
           }
    +      if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    +      return true;
         }
    -    if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    -    return true;
    -  } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    -    if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    -        buf, buflen, offset, dlinfo.dli_fname)) {
    -       return true;
    +    // no matching symbol so try for just file info
    +    if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
    +      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    +                          buf, buflen, offset, dlinfo.dli_fname)) {
    +        return true;
    +      }
         }
       }
     
    -  if (buf != NULL) buf[0] = '\0';
    +  buf[0] = '\0';
       if (offset != NULL) *offset = -1;
       return false;
     }
    @@ -1764,6 +1771,9 @@ static int address_to_library_name_callback(struct dl_phdr_info *info,
     
     bool os::dll_address_to_library_name(address addr, char* buf,
                                          int buflen, int* offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       Dl_info dlinfo;
       struct _address_to_library_name data;
     
    @@ -1782,15 +1792,20 @@ bool os::dll_address_to_library_name(address addr, char* buf,
          // buf already contains library name
          if (offset) *offset = addr - data.base;
          return true;
    -  } else if (dladdr((void*)addr, &dlinfo)){
    -     if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
    -     if (offset) *offset = addr - (address)dlinfo.dli_fbase;
    -     return true;
    -  } else {
    -     if (buf) buf[0] = '\0';
    -     if (offset) *offset = -1;
    -     return false;
       }
    +  if (dladdr((void*)addr, &dlinfo) != 0) {
    +    if (dlinfo.dli_fname != NULL) {
    +      jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
    +    }
    +    if (dlinfo.dli_fbase != NULL && offset != NULL) {
    +      *offset = addr - (address)dlinfo.dli_fbase;
    +    }
    +    return true;
    +  }
    +
    +  buf[0] = '\0';
    +  if (offset) *offset = -1;
    +  return false;
     }
     
       // Loads .dll/.so and
    @@ -2317,8 +2332,11 @@ void os::jvm_path(char *buf, jint buflen) {
       bool ret = dll_address_to_library_name(
                     CAST_FROM_FN_PTR(address, os::jvm_path),
                     dli_fname, sizeof(dli_fname), NULL);
    -  assert(ret != 0, "cannot locate libjvm");
    -  char *rp = realpath(dli_fname, buf);
    +  assert(ret, "cannot locate libjvm");
    +  char *rp = NULL;
    +  if (ret && dli_fname[0] != '\0') {
    +    rp = realpath(dli_fname, buf);
    +  }
       if (rp == NULL)
         return;
     
    @@ -4730,20 +4748,20 @@ int os::Linux::safe_cond_timedwait(pthread_cond_t *_cond, pthread_mutex_t *_mute
     bool os::find(address addr, outputStream* st) {
       Dl_info dlinfo;
       memset(&dlinfo, 0, sizeof(dlinfo));
    -  if (dladdr(addr, &dlinfo)) {
    +  if (dladdr(addr, &dlinfo) != 0) {
         st->print(PTR_FORMAT ": ", addr);
    -    if (dlinfo.dli_sname != NULL) {
    +    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
           st->print("%s+%#x", dlinfo.dli_sname,
                      addr - (intptr_t)dlinfo.dli_saddr);
    -    } else if (dlinfo.dli_fname) {
    +    } else if (dlinfo.dli_fbase != NULL) {
           st->print("", addr - (intptr_t)dlinfo.dli_fbase);
         } else {
           st->print("");
         }
    -    if (dlinfo.dli_fname) {
    +    if (dlinfo.dli_fname != NULL) {
           st->print(" in %s", dlinfo.dli_fname);
         }
    -    if (dlinfo.dli_fbase) {
    +    if (dlinfo.dli_fbase != NULL) {
           st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
         }
         st->cr();
    @@ -4756,7 +4774,7 @@ bool os::find(address addr, outputStream* st) {
           if (!lowest)  lowest = (address) dlinfo.dli_fbase;
           if (begin < lowest)  begin = lowest;
           Dl_info dlinfo2;
    -      if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
    +      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
               && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
             end = (address) dlinfo2.dli_saddr;
           Disassembler::decode(begin, end, st);
    diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
    index ad8c52914be..14fd8b76b06 100644
    --- a/hotspot/src/os/solaris/vm/os_solaris.cpp
    +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
    @@ -1924,12 +1924,13 @@ bool os::address_is_in_vm(address addr) {
       Dl_info dlinfo;
     
       if (libjvm_base_addr == NULL) {
    -    dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
    -    libjvm_base_addr = (address)dlinfo.dli_fbase;
    +    if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
    +      libjvm_base_addr = (address)dlinfo.dli_fbase;
    +    }
         assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
       }
     
    -  if (dladdr((void *)addr, &dlinfo)) {
    +  if (dladdr((void *)addr, &dlinfo) != 0) {
         if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
       }
     
    @@ -1941,114 +1942,133 @@ static dladdr1_func_type dladdr1_func = NULL;
     
     bool os::dll_address_to_function_name(address addr, char *buf,
                                           int buflen, int * offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       Dl_info dlinfo;
     
       // dladdr1_func was initialized in os::init()
    -  if (dladdr1_func){
    -      // yes, we have dladdr1
    +  if (dladdr1_func != NULL) {
    +    // yes, we have dladdr1
     
    -      // Support for dladdr1 is checked at runtime; it may be
    -      // available even if the vm is built on a machine that does
    -      // not have dladdr1 support.  Make sure there is a value for
    -      // RTLD_DL_SYMENT.
    -      #ifndef RTLD_DL_SYMENT
    -      #define RTLD_DL_SYMENT 1
    -      #endif
    +    // Support for dladdr1 is checked at runtime; it may be
    +    // available even if the vm is built on a machine that does
    +    // not have dladdr1 support.  Make sure there is a value for
    +    // RTLD_DL_SYMENT.
    +    #ifndef RTLD_DL_SYMENT
    +    #define RTLD_DL_SYMENT 1
    +    #endif
     #ifdef _LP64
    -      Elf64_Sym * info;
    +    Elf64_Sym * info;
     #else
    -      Elf32_Sym * info;
    +    Elf32_Sym * info;
     #endif
    -      if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
    -                       RTLD_DL_SYMENT)) {
    -        if ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
    -          if (buf != NULL) {
    -            if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
    -              jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
    -            }
    -            if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    -            return true;
    -        }
    -      }
    -      if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    -        if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    -           buf, buflen, offset, dlinfo.dli_fname)) {
    +    if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
    +                     RTLD_DL_SYMENT) != 0) {
    +      // see if we have a matching symbol that covers our address
    +      if (dlinfo.dli_saddr != NULL &&
    +          (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
    +        if (dlinfo.dli_sname != NULL) {
    +          if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
    +            jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
    +          }
    +          if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
               return true;
             }
           }
    -      if (buf != NULL) buf[0] = '\0';
    -      if (offset != NULL) *offset  = -1;
    -      return false;
    -  } else {
    -      // no, only dladdr is available
    -      if (dladdr((void *)addr, &dlinfo)) {
    -        if (buf != NULL) {
    -          if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen))
    -            jio_snprintf(buf, buflen, dlinfo.dli_sname);
    -        }
    -        if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    -        return true;
    -      } else if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != 0) {
    +      // no matching symbol so try for just file info
    +      if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
             if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    -          buf, buflen, offset, dlinfo.dli_fname)) {
    +                            buf, buflen, offset, dlinfo.dli_fname)) {
               return true;
             }
           }
    -      if (buf != NULL) buf[0] = '\0';
    -      if (offset != NULL) *offset  = -1;
    -      return false;
    +    }
    +    buf[0] = '\0';
    +    if (offset != NULL) *offset  = -1;
    +    return false;
       }
    +
    +  // no, only dladdr is available
    +  if (dladdr((void *)addr, &dlinfo) != 0) {
    +    // see if we have a matching symbol
    +    if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
    +      if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
    +        jio_snprintf(buf, buflen, dlinfo.dli_sname);
    +      }
    +      if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
    +      return true;
    +    }
    +    // no matching symbol so try for just file info
    +    if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
    +      if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
    +                          buf, buflen, offset, dlinfo.dli_fname)) {
    +        return true;
    +      }
    +    }
    +  }
    +  buf[0] = '\0';
    +  if (offset != NULL) *offset  = -1;
    +  return false;
     }
     
     bool os::dll_address_to_library_name(address addr, char* buf,
                                          int buflen, int* offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       Dl_info dlinfo;
     
    -  if (dladdr((void*)addr, &dlinfo)){
    -     if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
    -     if (offset) *offset = addr - (address)dlinfo.dli_fbase;
    -     return true;
    -  } else {
    -     if (buf) buf[0] = '\0';
    -     if (offset) *offset = -1;
    -     return false;
    +  if (dladdr((void*)addr, &dlinfo) != 0) {
    +    if (dlinfo.dli_fname != NULL) {
    +      jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
    +    }
    +    if (dlinfo.dli_fbase != NULL && offset != NULL) {
    +      *offset = addr - (address)dlinfo.dli_fbase;
    +    }
    +    return true;
       }
    +
    +  buf[0] = '\0';
    +  if (offset) *offset = -1;
    +  return false;
     }
     
     // Prints the names and full paths of all opened dynamic libraries
     // for current process
     void os::print_dll_info(outputStream * st) {
    -    Dl_info dli;
    -    void *handle;
    -    Link_map *map;
    -    Link_map *p;
    +  Dl_info dli;
    +  void *handle;
    +  Link_map *map;
    +  Link_map *p;
     
    -    st->print_cr("Dynamic libraries:"); st->flush();
    +  st->print_cr("Dynamic libraries:"); st->flush();
     
    -    if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) {
    -        st->print_cr("Error: Cannot print dynamic libraries.");
    -        return;
    -    }
    -    handle = dlopen(dli.dli_fname, RTLD_LAZY);
    -    if (handle == NULL) {
    -        st->print_cr("Error: Cannot print dynamic libraries.");
    -        return;
    -    }
    -    dlinfo(handle, RTLD_DI_LINKMAP, &map);
    -    if (map == NULL) {
    -        st->print_cr("Error: Cannot print dynamic libraries.");
    -        return;
    -    }
    +  if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
    +      dli.dli_fname == NULL) {
    +    st->print_cr("Error: Cannot print dynamic libraries.");
    +    return;
    +  }
    +  handle = dlopen(dli.dli_fname, RTLD_LAZY);
    +  if (handle == NULL) {
    +    st->print_cr("Error: Cannot print dynamic libraries.");
    +    return;
    +  }
    +  dlinfo(handle, RTLD_DI_LINKMAP, &map);
    +  if (map == NULL) {
    +    st->print_cr("Error: Cannot print dynamic libraries.");
    +    return;
    +  }
     
    -    while (map->l_prev != NULL)
    -        map = map->l_prev;
    +  while (map->l_prev != NULL)
    +    map = map->l_prev;
     
    -    while (map != NULL) {
    -        st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
    -        map = map->l_next;
    -    }
    +  while (map != NULL) {
    +    st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
    +    map = map->l_next;
    +  }
     
    -    dlclose(handle);
    +  dlclose(handle);
     }
     
       // Loads .dll/.so and
    @@ -2475,7 +2495,12 @@ void os::jvm_path(char *buf, jint buflen) {
       Dl_info dlinfo;
       int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
       assert(ret != 0, "cannot locate libjvm");
    -  realpath((char *)dlinfo.dli_fname, buf);
    +  if (ret != 0 && dlinfo.dli_fname != NULL) {
    +    realpath((char *)dlinfo.dli_fname, buf);
    +  } else {
    +    buf[0] = '\0';
    +    return;
    +  }
     
       if (Arguments::created_by_gamma_launcher()) {
         // Support for the gamma launcher.  Typical value for buf is
    @@ -6077,24 +6102,20 @@ int os::loadavg(double loadavg[], int nelem) {
     bool os::find(address addr, outputStream* st) {
       Dl_info dlinfo;
       memset(&dlinfo, 0, sizeof(dlinfo));
    -  if (dladdr(addr, &dlinfo)) {
    -#ifdef _LP64
    -    st->print("0x%016lx: ", addr);
    -#else
    -    st->print("0x%08x: ", addr);
    -#endif
    -    if (dlinfo.dli_sname != NULL)
    +  if (dladdr(addr, &dlinfo) != 0) {
    +    st->print(PTR_FORMAT ": ", addr);
    +    if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
           st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
    -    else if (dlinfo.dli_fname)
    +    } else if (dlinfo.dli_fbase != NULL)
           st->print("", addr-(intptr_t)dlinfo.dli_fbase);
         else
           st->print("");
    -    if (dlinfo.dli_fname)  st->print(" in %s", dlinfo.dli_fname);
    -#ifdef _LP64
    -    if (dlinfo.dli_fbase)  st->print(" at 0x%016lx", dlinfo.dli_fbase);
    -#else
    -    if (dlinfo.dli_fbase)  st->print(" at 0x%08x", dlinfo.dli_fbase);
    -#endif
    +    if (dlinfo.dli_fname != NULL) {
    +      st->print(" in %s", dlinfo.dli_fname);
    +    }
    +    if (dlinfo.dli_fbase != NULL) {
    +      st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
    +    }
         st->cr();
     
         if (Verbose) {
    @@ -6105,7 +6126,7 @@ bool os::find(address addr, outputStream* st) {
           if (!lowest)  lowest = (address) dlinfo.dli_fbase;
           if (begin < lowest)  begin = lowest;
           Dl_info dlinfo2;
    -      if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
    +      if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
               && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
             end = (address) dlinfo2.dli_saddr;
           Disassembler::decode(begin, end, st);
    diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
    index cc43934d423..23d2efb3692 100644
    --- a/hotspot/src/os/windows/vm/os_windows.cpp
    +++ b/hotspot/src/os/windows/vm/os_windows.cpp
    @@ -1420,34 +1420,40 @@ static int _locate_module_by_addr(int pid, char * mod_fname, address base_addr,
     
     bool os::dll_address_to_library_name(address addr, char* buf,
                                          int buflen, int* offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
     // NOTE: the reason we don't use SymGetModuleInfo() is it doesn't always
     //       return the full path to the DLL file, sometimes it returns path
     //       to the corresponding PDB file (debug info); sometimes it only
     //       returns partial path, which makes life painful.
     
    -   struct _modinfo mi;
    -   mi.addr      = addr;
    -   mi.full_path = buf;
    -   mi.buflen    = buflen;
    -   int pid = os::current_process_id();
    -   if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {
    -      // buf already contains path name
    -      if (offset) *offset = addr - mi.base_addr;
    -      return true;
    -   } else {
    -      if (buf) buf[0] = '\0';
    -      if (offset) *offset = -1;
    -      return false;
    -   }
    +  struct _modinfo mi;
    +  mi.addr      = addr;
    +  mi.full_path = buf;
    +  mi.buflen    = buflen;
    +  int pid = os::current_process_id();
    +  if (enumerate_modules(pid, _locate_module_by_addr, (void *)&mi)) {
    +    // buf already contains path name
    +    if (offset) *offset = addr - mi.base_addr;
    +    return true;
    +  }
    +
    +  buf[0] = '\0';
    +  if (offset) *offset = -1;
    +  return false;
     }
     
     bool os::dll_address_to_function_name(address addr, char *buf,
                                           int buflen, int *offset) {
    +  // buf is not optional, but offset is optional
    +  assert(buf != NULL, "sanity check");
    +
       if (Decoder::decode(addr, buf, buflen, offset)) {
         return true;
       }
       if (offset != NULL)  *offset  = -1;
    -  if (buf != NULL) buf[0] = '\0';
    +  buf[0] = '\0';
       return false;
     }
     
    @@ -2689,6 +2695,19 @@ address os::win32::fast_jni_accessor_wrapper(BasicType type) {
     }
     #endif
     
    +#ifndef PRODUCT
    +void os::win32::call_test_func_with_wrapper(void (*funcPtr)(void)) {
    +  // Install a win32 structured exception handler around the test
    +  // function call so the VM can generate an error dump if needed.
    +  __try {
    +    (*funcPtr)();
    +  } __except(topLevelExceptionFilter(
    +             (_EXCEPTION_POINTERS*)_exception_info())) {
    +    // Nothing to do.
    +  }
    +}
    +#endif
    +
     // Virtual Memory
     
     int os::vm_page_size() { return os::win32::vm_page_size(); }
    diff --git a/hotspot/src/os/windows/vm/os_windows.hpp b/hotspot/src/os/windows/vm/os_windows.hpp
    index f3196af9afc..d9efe1e32e9 100644
    --- a/hotspot/src/os/windows/vm/os_windows.hpp
    +++ b/hotspot/src/os/windows/vm/os_windows.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -94,6 +94,10 @@ class win32 {
       static address fast_jni_accessor_wrapper(BasicType);
     #endif
     
    +#ifndef PRODUCT
    +  static void call_test_func_with_wrapper(void (*funcPtr)(void));
    +#endif
    +
       // filter function to ignore faults on serializations page
       static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
     };
    diff --git a/hotspot/src/os/windows/vm/os_windows.inline.hpp b/hotspot/src/os/windows/vm/os_windows.inline.hpp
    index 5b1c46dfc59..5303743aee4 100644
    --- a/hotspot/src/os/windows/vm/os_windows.inline.hpp
    +++ b/hotspot/src/os/windows/vm/os_windows.inline.hpp
    @@ -106,4 +106,10 @@ inline size_t os::write(int fd, const void *buf, unsigned int nBytes) {
     inline int os::close(int fd) {
       return ::close(fd);
     }
    +
    +#ifndef PRODUCT
    +  #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) \
    +            os::win32::call_test_func_with_wrapper(f)
    +#endif
    +
     #endif // OS_WINDOWS_VM_OS_WINDOWS_INLINE_HPP
    diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
    index 42930ff7408..188cf4a6e60 100644
    --- a/hotspot/src/share/vm/prims/jni.cpp
    +++ b/hotspot/src/share/vm/prims/jni.cpp
    @@ -5138,9 +5138,21 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v
           event.commit();
         }
     
    +#ifndef PRODUCT
    +  #ifndef TARGET_OS_FAMILY_windows
    +    #define CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(f) f()
    +  #endif
    +
         // Check if we should compile all classes on bootclasspath
    -    NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();)
    -    NOT_PRODUCT(if (ReplayCompiles) ciReplay::replay(thread);)
    +    if (CompileTheWorld) ClassLoader::compile_the_world();
    +    if (ReplayCompiles) ciReplay::replay(thread);
    +
    +    // Some platforms (like Win*) need a wrapper around these test
    +    // functions in order to properly handle error conditions.
    +    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(test_error_handler);
    +    CALL_TEST_FUNC_WITH_WRAPPER_IF_NEEDED(execute_internal_vm_tests);
    +#endif
    +
         // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving.
         ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native);
       } else {
    @@ -5157,8 +5169,6 @@ _JNI_IMPORT_OR_EXPORT_ jint JNICALL JNI_CreateJavaVM(JavaVM **vm, void **penv, v
         OrderAccess::release_store(&vm_created, 0);
       }
     
    -  NOT_PRODUCT(test_error_handler(ErrorHandlerTest));
    -  NOT_PRODUCT(execute_internal_vm_tests());
       return result;
     }
     
    diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
    index e1866919df4..0d0e59efa4b 100644
    --- a/hotspot/src/share/vm/runtime/os.hpp
    +++ b/hotspot/src/share/vm/runtime/os.hpp
    @@ -507,16 +507,16 @@ class os: AllStatic {
     
       // Symbol lookup, find nearest function name; basically it implements
       // dladdr() for all platforms. Name of the nearest function is copied
    -  // to buf. Distance from its base address is returned as offset.
    +  // to buf. Distance from its base address is optionally returned as offset.
       // If function name is not found, buf[0] is set to '\0' and offset is
    -  // set to -1.
    +  // set to -1 (if offset is non-NULL).
       static bool dll_address_to_function_name(address addr, char* buf,
                                                int buflen, int* offset);
     
       // Locate DLL/DSO. On success, full path of the library is copied to
    -  // buf, and offset is set to be the distance between addr and the
    -  // library's base address. On failure, buf[0] is set to '\0' and
    -  // offset is set to -1.
    +  // buf, and offset is optionally set to be the distance between addr
    +  // and the library's base address. On failure, buf[0] is set to '\0'
    +  // and offset is set to -1 (if offset is non-NULL).
       static bool dll_address_to_library_name(address addr, char* buf,
                                               int buflen, int* offset);
     
    diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp
    index 1062b525fd5..31d13f794b8 100644
    --- a/hotspot/src/share/vm/utilities/debug.cpp
    +++ b/hotspot/src/share/vm/utilities/debug.cpp
    @@ -314,8 +314,8 @@ bool is_error_reported() {
     #ifndef PRODUCT
     #include 
     
    -void test_error_handler(size_t test_num)
    -{
    +void test_error_handler() {
    +  uintx test_num = ErrorHandlerTest;
       if (test_num == 0) return;
     
       // If asserts are disabled, use the corresponding guarantee instead.
    @@ -327,6 +327,8 @@ void test_error_handler(size_t test_num)
     
       const char* const eol = os::line_separator();
       const char* const msg = "this message should be truncated during formatting";
    +  char * const dataPtr = NULL;  // bad data pointer
    +  const void (*funcPtr)(void) = (const void(*)()) 0xF;  // bad function pointer
     
       // Keep this in sync with test/runtime/6888954/vmerrors.sh.
       switch (n) {
    @@ -348,11 +350,16 @@ void test_error_handler(size_t test_num)
         case  9: ShouldNotCallThis();
         case 10: ShouldNotReachHere();
         case 11: Unimplemented();
    -    // This is last because it does not generate an hs_err* file on Windows.
    -    case 12: os::signal_raise(SIGSEGV);
    +    // There's no guarantee the bad data pointer will crash us
    +    // so "break" out to the ShouldNotReachHere().
    +    case 12: *dataPtr = '\0'; break;
    +    // There's no guarantee the bad function pointer will crash us
    +    // so "break" out to the ShouldNotReachHere().
    +    case 13: (*funcPtr)(); break;
     
    -    default: ShouldNotReachHere();
    +    default: tty->print_cr("ERROR: %d: unexpected test_num value.", n);
       }
    +  ShouldNotReachHere();
     }
     #endif // !PRODUCT
     
    diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp
    index 9a8332febe0..2450c8fe113 100644
    --- a/hotspot/src/share/vm/utilities/debug.hpp
    +++ b/hotspot/src/share/vm/utilities/debug.hpp
    @@ -1,5 +1,5 @@
     /*
    - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
    + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
      * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
      *
      * This code is free software; you can redistribute it and/or modify it
    @@ -243,7 +243,7 @@ bool is_error_reported();
     void set_error_reported();
     
     /* Test assert(), fatal(), guarantee(), etc. */
    -NOT_PRODUCT(void test_error_handler(size_t test_num);)
    +NOT_PRODUCT(void test_error_handler();)
     
     void pd_ps(frame f);
     void pd_obfuscate_location(char *buf, size_t buflen);
    diff --git a/hotspot/test/runtime/6888954/vmerrors.sh b/hotspot/test/runtime/6888954/vmerrors.sh
    index 5a47e2208c0..3e3121e40f5 100644
    --- a/hotspot/test/runtime/6888954/vmerrors.sh
    +++ b/hotspot/test/runtime/6888954/vmerrors.sh
    @@ -1,5 +1,6 @@
     # @test
     # @bug 6888954
    +# @bug 8015884
     # @summary exercise HotSpot error handling code
     # @author John Coomes
     # @run shell vmerrors.sh
    @@ -27,9 +28,24 @@ i=1
     rc=0
     
     assert_re='(assert|guarantee)[(](str|num).*failed: *'
    +# for bad_data_ptr_re:
    +# EXCEPTION_ACCESS_VIOLATION - Win-*
    +# SIGILL - MacOS X
    +# SIGSEGV - Linux-*, Solaris SPARC-*, Solaris X86-*
    +#
    +bad_data_ptr_re='(SIGILL|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc='
    +#
    +# for bad_func_ptr_re:
    +# EXCEPTION_ACCESS_VIOLATION - Win-*
    +# SIGBUS - Solaris SPARC-64
    +# SIGSEGV - Linux-*, Solaris SPARC-32, Solaris X86-*
    +#
    +# Note: would like to use "pc=0x00*0f," in the pattern, but Solaris SPARC-*
    +# gets its signal at a PC in test_error_handler().
    +#
    +bad_func_ptr_re='(SIGBUS|SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc='
     guarantee_re='guarantee[(](str|num).*failed: *'
     fatal_re='fatal error: *'
    -signal_re='(SIGSEGV|EXCEPTION_ACCESS_VIOLATION).* at pc='
     tail_1='.*expected null'
     tail_2='.*num='
     
    @@ -39,8 +55,9 @@ for re in                                                 \
         "${fatal_re}${tail_1}"     "${fatal_re}${tail_2}"     \
         "${fatal_re}.*truncated"   "ChunkPool::allocate"      \
         "ShouldNotCall"            "ShouldNotReachHere"       \
    -    "Unimplemented"            "$signal_re"
    -    
    +    "Unimplemented"            "$bad_data_ptr_re"         \
    +    "$bad_func_ptr_re"
    +
     do
         i2=$i
         [ $i -lt 10 ] && i2=0$i
    
    From f6dc452231895d51301b701e93bae6ce8bd668c9 Mon Sep 17 00:00:00 2001
    From: Frederic Parain 
    Date: Fri, 5 Jul 2013 08:26:49 +0000
    Subject: [PATCH 034/156] 8016465: The hs_err file gets wrong name
    
    Reviewed-by: dcubed, dholmes, rdurbin
    ---
     hotspot/src/share/vm/utilities/vmError.cpp | 5 +++--
     1 file changed, 3 insertions(+), 2 deletions(-)
    
    diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
    index 64f753bc75c..873f479d609 100644
    --- a/hotspot/src/share/vm/utilities/vmError.cpp
    +++ b/hotspot/src/share/vm/utilities/vmError.cpp
    @@ -908,10 +908,11 @@ void VMError::report_and_die() {
         // This is not the first error, see if it happened in a different thread
         // or in the same thread during error reporting.
         if (first_error_tid != mytid) {
    -      jio_snprintf(buffer, sizeof(buffer),
    +      char msgbuf[64];
    +      jio_snprintf(msgbuf, sizeof(msgbuf),
                        "[thread " INT64_FORMAT " also had an error]",
                        mytid);
    -      out.print_raw_cr(buffer);
    +      out.print_raw_cr(msgbuf);
     
           // error reporting is not MT-safe, block current thread
           os::infinite_sleep();
    
    From 1853f28ab3b46feb9e272c27e6f0a2b19e3e791c Mon Sep 17 00:00:00 2001
    From: Athijegannathan Sundararajan 
    Date: Fri, 5 Jul 2013 14:38:04 +0530
    Subject: [PATCH 035/156] 8019947: inherited property invalidation does not
     work with two globals in same context
    
    Reviewed-by: jlaskey, lagergren, hannesw, attila
    ---
     nashorn/make/build-nasgen.xml                 |   7 -
     nashorn/make/build.xml                        |   3 +-
     .../api/scripting/ScriptObjectMirror.java     |   2 +-
     .../internal/codegen/CodeGenerator.java       |  14 +-
     .../objects/AccessorPropertyDescriptor.java   |   8 +-
     .../internal/objects/ArrayBufferView.java     |  11 +-
     .../objects/BoundScriptFunctionImpl.java      |   2 +-
     .../objects/DataPropertyDescriptor.java       |   9 +-
     .../objects/GenericPropertyDescriptor.java    |   8 +-
     .../jdk/nashorn/internal/objects/Global.java  | 236 +++++++++++++++---
     .../internal/objects/NativeArguments.java     |  24 +-
     .../nashorn/internal/objects/NativeArray.java |  10 +-
     .../internal/objects/NativeArrayBuffer.java   |  12 +-
     .../internal/objects/NativeBoolean.java       |  28 +--
     .../nashorn/internal/objects/NativeDate.java  |  26 +-
     .../nashorn/internal/objects/NativeDebug.java |   5 +-
     .../nashorn/internal/objects/NativeError.java |  22 +-
     .../internal/objects/NativeEvalError.java     |  17 +-
     .../internal/objects/NativeFloat32Array.java  |   4 +-
     .../internal/objects/NativeFloat64Array.java  |   4 +-
     .../internal/objects/NativeFunction.java      |   1 +
     .../internal/objects/NativeInt16Array.java    |   4 +-
     .../internal/objects/NativeInt32Array.java    |   4 +-
     .../internal/objects/NativeInt8Array.java     |   4 +-
     .../internal/objects/NativeJSAdapter.java     |  24 +-
     .../nashorn/internal/objects/NativeJSON.java  |   5 +-
     .../nashorn/internal/objects/NativeJava.java  |   2 +
     .../internal/objects/NativeJavaImporter.java  |  16 +-
     .../nashorn/internal/objects/NativeMath.java  |   5 +-
     .../internal/objects/NativeNumber.java        |  34 ++-
     .../internal/objects/NativeObject.java        |   2 +
     .../internal/objects/NativeRangeError.java    |  16 +-
     .../objects/NativeReferenceError.java         |  16 +-
     .../internal/objects/NativeRegExp.java        |  33 ++-
     .../objects/NativeRegExpExecResult.java       |   8 +-
     .../objects/NativeStrictArguments.java        |  14 +-
     .../internal/objects/NativeString.java        |  33 +--
     .../internal/objects/NativeSyntaxError.java   |  12 +-
     .../internal/objects/NativeTypeError.java     |  12 +-
     .../internal/objects/NativeURIError.java      |  12 +-
     .../internal/objects/NativeUint16Array.java   |   4 +-
     .../internal/objects/NativeUint32Array.java   |   4 +-
     .../internal/objects/NativeUint8Array.java    |   4 +-
     .../objects/NativeUint8ClampedArray.java      |   4 +-
     .../internal/objects/PrototypeObject.java     |  22 +-
     .../internal/objects/ScriptFunctionImpl.java  |  59 +++--
     .../jdk/nashorn/internal/runtime/Context.java |  26 +-
     .../internal/runtime/GlobalFunctions.java     |   3 -
     .../internal/runtime/GlobalObject.java        |   9 +-
     .../internal/runtime/ScriptObject.java        |   9 +
     .../internal/runtime/StructureLoader.java     |  49 +---
     .../src/jdk/nashorn/internal/scripts/JO.java  |  16 +-
     nashorn/src/jdk/nashorn/tools/Shell.java      |   3 +-
     nashorn/test/script/basic/JDK-8019947.js      |  68 +++++
     .../test/script/basic/JDK-8019947.js.EXPECTED |   3 +
     55 files changed, 668 insertions(+), 324 deletions(-)
     create mode 100644 nashorn/test/script/basic/JDK-8019947.js
     create mode 100644 nashorn/test/script/basic/JDK-8019947.js.EXPECTED
    
    diff --git a/nashorn/make/build-nasgen.xml b/nashorn/make/build-nasgen.xml
    index a50d41e02c3..9dca5505316 100644
    --- a/nashorn/make/build-nasgen.xml
    +++ b/nashorn/make/build-nasgen.xml
    @@ -42,11 +42,6 @@
                 
                 
             
    -
    -        
    -            
    -            
    -        
         
     
         
    @@ -66,7 +61,6 @@
                 
                     
                 
    -            
             
     
             
    @@ -75,7 +69,6 @@
                 
                     
                 
    -            
             
         
     
    diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
    index 58a1d116be1..da2ded1ea1d 100644
    --- a/nashorn/make/build.xml
    +++ b/nashorn/make/build.xml
    @@ -100,7 +100,8 @@
                target="${javac.target}"
                debug="${javac.debug}"
                encoding="${javac.encoding}"
    -           includeantruntime="false">
    +           includeantruntime="false" fork="true">
    +      
           
           
           
    diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
    index c7dbab5a184..52684cfe0c8 100644
    --- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
    +++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
    @@ -308,9 +308,9 @@ public final class ScriptObjectMirror extends JSObject implements Bindings {
         public void putAll(final Map map) {
             final ScriptObject oldGlobal = NashornScriptEngine.getNashornGlobal();
             final boolean globalChanged = (oldGlobal != global);
    -        final boolean strict = sobj.isStrictContext();
             inGlobal(new Callable() {
                 @Override public Object call() {
    +                final boolean strict = global.isStrictContext();
                     for (final Map.Entry entry : map.entrySet()) {
                         final Object value = entry.getValue();
                         final Object modValue = globalChanged? wrap(value, oldGlobal) : value;
    diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    index df6906c6bb7..52241265513 100644
    --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
    @@ -109,6 +109,8 @@ import jdk.nashorn.internal.ir.WithNode;
     import jdk.nashorn.internal.ir.debug.ASTWriter;
     import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
     import jdk.nashorn.internal.ir.visitor.NodeVisitor;
    +import jdk.nashorn.internal.objects.Global;
    +import jdk.nashorn.internal.objects.ScriptFunctionImpl;
     import jdk.nashorn.internal.parser.Lexer.RegexToken;
     import jdk.nashorn.internal.parser.TokenType;
     import jdk.nashorn.internal.runtime.Context;
    @@ -148,11 +150,9 @@ import jdk.nashorn.internal.runtime.linker.LinkerCallSite;
      */
     final class CodeGenerator extends NodeOperatorVisitor {
     
    -    /** Name of the Global object, cannot be referred to as .class, @see CodeGenerator */
    -    private static final String GLOBAL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "Global";
    +    private static final String GLOBAL_OBJECT = Type.getInternalName(Global.class);
     
    -    /** Name of the ScriptFunctionImpl, cannot be referred to as .class @see FunctionObjectCreator */
    -    private static final String SCRIPTFUNCTION_IMPL_OBJECT = Compiler.OBJECTS_PACKAGE + '/' + "ScriptFunctionImpl";
    +    private static final String SCRIPTFUNCTION_IMPL_OBJECT = Type.getInternalName(ScriptFunctionImpl.class);
     
         /** Constant data & installation. The only reason the compiler keeps this is because it is assigned
          *  by reflection in class installation */
    @@ -3203,11 +3203,7 @@ final class CodeGenerator extends NodeOperatorVisitor rtype, final Class... types) {
    -        try {
    -            return MethodHandles.lookup().findStatic(Global.class, name, MH.type(rtype, types));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), Global.class, name, MH.type(rtype, types));
         }
     
         RegExpResult getLastRegExpResult() {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
    index 456284d8cfe..443a8938a2c 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
    @@ -70,14 +70,18 @@ public final class NativeArguments extends ScriptObject {
             map$ = map;
         }
     
    +    static PropertyMap getInitialMap() {
    +        return map$;
    +    }
    +
         private Object length;
         private Object callee;
         private ArrayData namedArgs;
         // This is lazily initialized - only when delete is invoked at all
         private BitSet deleted;
     
    -    NativeArguments(final ScriptObject proto, final Object[] arguments, final Object callee, final int numParams) {
    -        super(proto, map$);
    +    NativeArguments(final Object[] arguments, final Object callee, final int numParams, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             setIsArguments();
     
             setArray(ArrayData.allocate(arguments));
    @@ -550,8 +554,13 @@ public final class NativeArguments extends ScriptObject {
         public static ScriptObject allocate(final Object[] arguments, final ScriptFunction callee, final int numParams) {
             // Strict functions won't always have a callee for arguments, and will pass null instead.
             final boolean isStrict = callee == null || callee.isStrict();
    -        final ScriptObject proto = Global.objectPrototype();
    -        return isStrict ? new NativeStrictArguments(proto, arguments, numParams) : new NativeArguments(proto, arguments, callee, numParams);
    +        final Global global = Global.instance();
    +        final ScriptObject proto = global.getObjectPrototype();
    +        if (isStrict) {
    +            return new NativeStrictArguments(arguments, numParams, proto, global.getStrictArgumentsMap());
    +        } else {
    +            return new NativeArguments(arguments, callee, numParams, proto, global.getArgumentsMap());
    +        }
         }
     
         /**
    @@ -623,11 +632,6 @@ public final class NativeArguments extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeArguments.class, name, MH.type(rtype, types));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeArguments.class, name, MH.type(rtype, types));
         }
    -
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
    index 1af79785d9c..ca02cf63e21 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
    @@ -86,6 +86,10 @@ public final class NativeArray extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
         /*
          * Constructors.
          */
    @@ -130,7 +134,11 @@ public final class NativeArray extends ScriptObject {
         }
     
         NativeArray(final ArrayData arrayData) {
    -        super(Global.instance().getArrayPrototype(), $nasgenmap$);
    +        this(arrayData, Global.instance());
    +    }
    +
    +    NativeArray(final ArrayData arrayData, final Global global) {
    +        super(global.getArrayPrototype(), global.getArrayMap());
             this.setArray(arrayData);
             this.setIsArray();
         }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
    index f122bfca8f5..356e7b6cfec 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArrayBuffer.java
    @@ -43,6 +43,10 @@ final class NativeArrayBuffer extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
         @Constructor(arity = 1)
         public static Object constructor(final boolean newObj, final Object self, final Object... args) {
             if (args.length == 0) {
    @@ -52,11 +56,15 @@ final class NativeArrayBuffer extends ScriptObject {
             return new NativeArrayBuffer(JSType.toInt32(args[0]));
         }
     
    -    protected NativeArrayBuffer(final byte[] byteArray) {
    -        super(Global.instance().getArrayBufferPrototype(), $nasgenmap$);
    +    protected NativeArrayBuffer(final byte[] byteArray, final Global global) {
    +        super(global.getArrayBufferPrototype(), global.getArrayBufferMap());
             this.buffer = byteArray;
         }
     
    +    protected NativeArrayBuffer(final byte[] byteArray) {
    +        this(byteArray, Global.instance());
    +    }
    +
         protected NativeArrayBuffer(final int byteLength) {
             this(new byte[byteLength]);
         }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
    index bfbbb3d73d7..962086c491e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java
    @@ -56,15 +56,23 @@ public final class NativeBoolean extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeBoolean(final boolean value) {
    -        this(value, Global.instance().getBooleanPrototype());
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
         }
     
    -    private NativeBoolean(final boolean value, final ScriptObject proto) {
    -        super(proto, $nasgenmap$);
    +    private NativeBoolean(final boolean value, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             this.value = value;
         }
     
    +    NativeBoolean(final boolean flag, final Global global) {
    +        this(flag, global.getBooleanPrototype(), global.getBooleanMap());
    +    }
    +
    +    NativeBoolean(final boolean flag) {
    +        this(flag, Global.instance());
    +    }
    +
         @Override
         public String safeToString() {
             return "[Boolean " + toString() + "]";
    @@ -131,11 +139,7 @@ public final class NativeBoolean extends ScriptObject {
             final boolean flag = JSType.toBoolean(value);
     
             if (newObj) {
    -            final ScriptObject proto = (self instanceof ScriptObject) ?
    -                ((ScriptObject)self).getProto() :
    -                Global.instance().getBooleanPrototype();
    -
    -            return new NativeBoolean(flag, proto);
    +            return new NativeBoolean(flag);
             }
     
             return flag;
    @@ -176,10 +180,6 @@ public final class NativeBoolean extends ScriptObject {
         }
     
         private static MethodHandle findWrapFilter() {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
    -        } catch (NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeBoolean.class, "wrapFilter", MH.type(NativeBoolean.class, Object.class));
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
    index 3a7d0ef3535..11ab886e467 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
    @@ -104,18 +104,30 @@ public final class NativeDate extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeDate() {
    -        this(System.currentTimeMillis());
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
         }
     
    -    NativeDate(final double time) {
    -        super(Global.instance().getDatePrototype(), $nasgenmap$);
    +    private NativeDate(final double time, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             final ScriptEnvironment env = Global.getEnv();
     
             this.time = time;
             this.timezone = env._timezone;
         }
     
    +    NativeDate(final double time, final Global global) {
    +        this(time, global.getDatePrototype(), global.getDateMap());
    +    }
    +
    +    private NativeDate (final double time) {
    +        this(time, Global.instance());
    +    }
    +
    +    private NativeDate() {
    +        this(System.currentTimeMillis());
    +    }
    +
         @Override
         public String getClassName() {
             return "Date";
    @@ -153,6 +165,10 @@ public final class NativeDate extends ScriptObject {
          */
         @Constructor(arity = 7)
         public static Object construct(final boolean isNew, final Object self, final Object... args) {
    +        if (! isNew) {
    +            return toStringImpl(new NativeDate(), FORMAT_DATE_TIME);
    +        }
    +
             NativeDate result;
             switch (args.length) {
             case 0:
    @@ -182,7 +198,7 @@ public final class NativeDate extends ScriptObject {
                 break;
              }
     
    -         return isNew ? result : toStringImpl(new NativeDate(), FORMAT_DATE_TIME);
    +         return result;
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
    index afcf7b2bfc2..43106eeb7b8 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java
    @@ -51,8 +51,9 @@ public final class NativeDebug extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeDebug() {
    -        super(Global.objectPrototype(), $nasgenmap$);
    +    private NativeDebug() {
    +        // don't create me!
    +        throw new UnsupportedOperationException();
         }
     
         @Override
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    index b8f69c502e4..0f233f18b17 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java
    @@ -87,8 +87,12 @@ public final class NativeError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeError(final Object msg) {
    -        super(Global.instance().getErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    private NativeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -96,6 +100,14 @@ public final class NativeError extends ScriptObject {
             }
         }
     
    +    NativeError(final Object msg, final Global global) {
    +        this(msg, global.getErrorPrototype(), global.getErrorMap());
    +    }
    +
    +    private NativeError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
    @@ -354,11 +366,7 @@ public final class NativeError extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeError.class, name, MH.type(rtype, types));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeError.class, name, MH.type(rtype, types));
         }
     
         private static String getScriptStackString(final ScriptObject sobj, final Throwable exp) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
    index 2b88f7dc90a..89e9485fd9d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeEvalError.java
    @@ -58,8 +58,12 @@ public final class NativeEvalError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeEvalError(final Object msg) {
    -        super(Global.instance().getEvalErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    private NativeEvalError(final Object msg, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -67,12 +71,19 @@ public final class NativeEvalError extends ScriptObject {
             }
         }
     
    +    NativeEvalError(final Object msg, final Global global) {
    +        this(msg, global.getEvalErrorPrototype(), global.getEvalErrorMap());
    +    }
    +
    +    private NativeEvalError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
         }
     
    -
         /**
          * ECMA 15.11.6.1 EvalError
          *
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    index 852f448dd1e..614fd6f54d0 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
    @@ -192,7 +192,7 @@ public final class NativeFloat32Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getFloat32ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getFloat32ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    index 4ea52991243..22467bcc1be 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
    @@ -202,7 +202,7 @@ public final class NativeFloat64Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getFloat64ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getFloat64ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    index 5e5f42f0475..c208a35ce7e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFunction.java
    @@ -61,6 +61,7 @@ public final class NativeFunction {
     
         // do *not* create me!
         private NativeFunction() {
    +        throw new UnsupportedOperationException();
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    index 24b2383756c..904dbce0390 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
    @@ -151,7 +151,7 @@ public final class NativeInt16Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getInt16ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getInt16ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    index a89d8350a50..78aed11f507 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
    @@ -154,7 +154,7 @@ public final class NativeInt32Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getInt32ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getInt32ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    index 316fdab50d8..3ed5688a45f 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
    @@ -144,7 +144,7 @@ public final class NativeInt8Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getInt8ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getInt8ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
    index 5db4a1fddac..8e98f4e1825 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java
    @@ -49,6 +49,7 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
     import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator;
     import jdk.nashorn.internal.lookup.Lookup;
     import jdk.nashorn.internal.lookup.MethodHandleFactory;
    +import jdk.nashorn.internal.scripts.JO;
     
     /**
      * This class is the implementation of the Nashorn-specific global object named {@code JSAdapter}. It can be
    @@ -146,8 +147,12 @@ public final class NativeJSAdapter extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeJSAdapter(final ScriptObject proto, final Object overrides, final ScriptObject adaptee) {
    -        super(proto, $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    NativeJSAdapter(final Object overrides, final ScriptObject adaptee, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             this.adaptee = wrapAdaptee(adaptee);
             if (overrides instanceof ScriptObject) {
                 this.overrides = true;
    @@ -159,9 +164,7 @@ public final class NativeJSAdapter extends ScriptObject {
         }
     
         private static ScriptObject wrapAdaptee(final ScriptObject adaptee) {
    -        final ScriptObject sobj = new jdk.nashorn.internal.scripts.JO();
    -        sobj.setProto(adaptee);
    -        return sobj;
    +        return new JO(adaptee, Global.instance().getObjectMap());
         }
     
         @Override
    @@ -570,11 +573,12 @@ public final class NativeJSAdapter extends ScriptObject {
                 throw typeError("not.an.object", ScriptRuntime.safeToString(adaptee));
             }
     
    +        final Global global = Global.instance();
             if (proto != null && !(proto instanceof ScriptObject)) {
    -            proto = Global.instance().getJSAdapterPrototype();
    +            proto = global.getJSAdapterPrototype();
             }
     
    -        return new NativeJSAdapter((ScriptObject)proto, overrides, (ScriptObject)adaptee);
    +        return new NativeJSAdapter(overrides, (ScriptObject)adaptee, (ScriptObject)proto, global.getJSAdapterMap());
         }
     
         @Override
    @@ -736,10 +740,6 @@ public final class NativeJSAdapter extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeJSAdapter.class, name, MH.type(rtype, types));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeJSAdapter.class, name, MH.type(rtype, types));
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
    index 3270bc84cd6..0fdb170f44b 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java
    @@ -62,8 +62,9 @@ public final class NativeJSON extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeJSON() {
    -        super(Global.objectPrototype(), $nasgenmap$);
    +    private NativeJSON() {
    +        // don't create me!!
    +        throw new UnsupportedOperationException();
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    index 8303c39367a..be63e531984 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
    @@ -60,6 +60,8 @@ public final class NativeJava {
         private static PropertyMap $nasgenmap$;
     
         private NativeJava() {
    +        // don't create me
    +        throw new UnsupportedOperationException();
         }
     
         /**
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
    index 9d4c15ac4d1..c2d2bd10e81 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJavaImporter.java
    @@ -59,11 +59,23 @@ public final class NativeJavaImporter extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeJavaImporter(final Object[] args) {
    -        super(Global.instance().getJavaImporterPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    private NativeJavaImporter(final Object[] args, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             this.args = args;
         }
     
    +    private NativeJavaImporter(final Object[] args, final Global global) {
    +        this(args, global.getJavaImporterPrototype(), global.getJavaImporterMap());
    +    }
    +
    +    private NativeJavaImporter(final Object[] args) {
    +        this(args, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "JavaImporter";
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
    index 2b093548315..c952bd1d295 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
    @@ -45,8 +45,9 @@ public final class NativeMath extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeMath() {
    -        super(Global.objectPrototype(), $nasgenmap$);
    +    private NativeMath() {
    +        // don't create me!
    +        throw new UnsupportedOperationException();
         }
     
         /** ECMA 15.8.1.1 - E, always a double constant. Not writable or configurable */
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
    index 94a7cca1a4d..c69478967f4 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java
    @@ -87,17 +87,26 @@ public final class NativeNumber extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeNumber(final double value) {
    -        this(value, Global.instance().getNumberPrototype());
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
         }
     
    -    private NativeNumber(final double value, final ScriptObject proto) {
    -        super(proto, $nasgenmap$);
    +    private NativeNumber(final double value, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             this.value = value;
             this.isInt  = isRepresentableAsInt(value);
             this.isLong = isRepresentableAsLong(value);
         }
     
    +    NativeNumber(final double value, final Global global) {
    +        this(value, global.getNumberPrototype(), global.getNumberMap());
    +    }
    +
    +    private NativeNumber(final double value) {
    +        this(value, Global.instance());
    +    }
    +
    +
         @Override
         public String safeToString() {
             return "[Number " + toString() + "]";
    @@ -165,16 +174,7 @@ public final class NativeNumber extends ScriptObject {
         public static Object constructor(final boolean newObj, final Object self, final Object... args) {
             final double num = (args.length > 0) ? JSType.toNumber(args[0]) : 0.0;
     
    -        if (newObj) {
    -            final ScriptObject proto =
    -                (self instanceof ScriptObject) ?
    -                    ((ScriptObject)self).getProto() :
    -                    Global.instance().getNumberPrototype();
    -
    -            return new NativeNumber(num, proto);
    -        }
    -
    -        return num;
    +        return newObj? new NativeNumber(num) : num;
         }
     
         /**
    @@ -380,10 +380,6 @@ public final class NativeNumber extends ScriptObject {
         }
     
         private static MethodHandle findWrapFilter() {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeNumber.class, "wrapFilter", MH.type(NativeNumber.class, Object.class));
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    index 7112557e1d0..6e4791bd20c 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
    @@ -58,6 +58,8 @@ public final class NativeObject {
         private static PropertyMap $nasgenmap$;
     
         private NativeObject() {
    +        // don't create me!
    +        throw new UnsupportedOperationException();
         }
     
         private static ECMAException notAnObject(final Object obj) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
    index faf68f871f7..d51a0c09d41 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRangeError.java
    @@ -58,8 +58,12 @@ public final class NativeRangeError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeRangeError(final Object msg) {
    -        super(Global.instance().getRangeErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    private NativeRangeError(final Object msg, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -67,6 +71,14 @@ public final class NativeRangeError extends ScriptObject {
             }
         }
     
    +    NativeRangeError(final Object msg, final Global global) {
    +        this(msg, global.getRangeErrorPrototype(), global.getRangeErrorMap());
    +    }
    +
    +    private NativeRangeError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
    index 954eed641f5..a269b51520a 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeReferenceError.java
    @@ -58,8 +58,12 @@ public final class NativeReferenceError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeReferenceError(final Object msg) {
    -        super(Global.instance().getReferenceErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    private NativeReferenceError(final Object msg, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -67,6 +71,14 @@ public final class NativeReferenceError extends ScriptObject {
             }
         }
     
    +    NativeReferenceError(final Object msg, final Global global) {
    +        this(msg, global.getReferenceErrorPrototype(), global.getReferenceErrorMap());
    +    }
    +
    +    private NativeReferenceError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    index 1ba8b4df01b..e6aa4be4357 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExp.java
    @@ -71,7 +71,17 @@ public final class NativeRegExp extends ScriptObject {
         @SuppressWarnings("unused")
         private static PropertyMap $nasgenmap$;
     
    -    NativeRegExp(final String input, final String flagString) {
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    private NativeRegExp(final Global global) {
    +        super(global.getRegExpPrototype(), global.getRegExpMap());
    +        this.globalObject = global;
    +    }
    +
    +    NativeRegExp(final String input, final String flagString, final Global global) {
    +        this(global);
             try {
                 this.regexp = RegExpFactory.create(input, flagString);
             } catch (final ParserException e) {
    @@ -81,17 +91,24 @@ public final class NativeRegExp extends ScriptObject {
             }
     
             this.setLastIndex(0);
    -        init();
    +    }
    +
    +    NativeRegExp(final String input, final String flagString) {
    +        this(input, flagString, Global.instance());
    +    }
    +
    +    NativeRegExp(final String string, final Global global) {
    +        this(string, "", global);
         }
     
         NativeRegExp(final String string) {
    -        this(string, "");
    +        this(string, Global.instance());
         }
     
         NativeRegExp(final NativeRegExp regExp) {
    +        this(Global.instance());
             this.lastIndex  = regExp.getLastIndexObject();
             this.regexp      = regExp.getRegExp();
    -        init();
         }
     
         @Override
    @@ -615,7 +632,7 @@ public final class NativeRegExp extends ScriptObject {
                 return null;
             }
     
    -        return new NativeRegExpExecResult(match);
    +        return new NativeRegExpExecResult(match, globalObject);
         }
     
         /**
    @@ -886,12 +903,6 @@ public final class NativeRegExp extends ScriptObject {
             this.lastIndex = JSType.toObject(lastIndex);
         }
     
    -    private void init() {
    -        // Keep reference to global object to support "static" properties of RegExp
    -        this.globalObject = Global.instance();
    -        this.setProto(globalObject.getRegExpPrototype());
    -    }
    -
         private static NativeRegExp checkRegExp(final Object self) {
             Global.checkObjectCoercible(self);
             if (self instanceof NativeRegExp) {
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
    index 667205528ed..3508e5f67d1 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeRegExpExecResult.java
    @@ -53,8 +53,12 @@ public final class NativeRegExpExecResult extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeRegExpExecResult(final RegExpResult result) {
    -        super(Global.instance().getArrayPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    NativeRegExpExecResult(final RegExpResult result, final Global global) {
    +        super(global.getArrayPrototype(), global.getRegExpExecResultMap());
             setIsArray();
             this.setArray(ArrayData.allocate(result.getGroups().clone()));
             this.index = result.getIndex();
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
    index cf434f9fce4..ae2ddb01d8d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java
    @@ -64,11 +64,15 @@ public final class NativeStrictArguments extends ScriptObject {
             map$ = map;
         }
     
    +    static PropertyMap getInitialMap() {
    +        return map$;
    +    }
    +
         private Object   length;
         private final Object[] namedArgs;
     
    -    NativeStrictArguments(final ScriptObject proto, final Object[] values, final int numParams) {
    -        super(proto, map$);
    +    NativeStrictArguments(final Object[] values, final int numParams,final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             setIsArguments();
     
             final ScriptFunction func = ScriptFunctionImpl.getTypeErrorThrower();
    @@ -143,10 +147,6 @@ public final class NativeStrictArguments extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeStrictArguments.class, name, MH.type(rtype, types));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeStrictArguments.class, name, MH.type(rtype, types));
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
    index a5b9ea83e54..aa2eec63571 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
    @@ -41,7 +41,7 @@ import java.util.Locale;
     import jdk.internal.dynalink.CallSiteDescriptor;
     import jdk.internal.dynalink.linker.GuardedInvocation;
     import jdk.internal.dynalink.linker.LinkRequest;
    -import jdk.nashorn.internal.lookup.MethodHandleFactory;
    +import jdk.nashorn.internal.lookup.MethodHandleFactory.LookupException;
     import jdk.nashorn.internal.objects.annotations.Attribute;
     import jdk.nashorn.internal.objects.annotations.Constructor;
     import jdk.nashorn.internal.objects.annotations.Function;
    @@ -74,12 +74,20 @@ public final class NativeString extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeString(final CharSequence value) {
    -        this(value, Global.instance().getStringPrototype());
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
         }
     
    -    private NativeString(final CharSequence value, final ScriptObject proto) {
    -        super(proto, $nasgenmap$);
    +    private NativeString(final CharSequence value) {
    +        this(value, Global.instance());
    +    }
    +
    +    NativeString(final CharSequence value, final Global global) {
    +        this(value, global.getStringPrototype(), global.getStringMap());
    +    }
    +
    +    private NativeString(final CharSequence value, final ScriptObject proto, final PropertyMap map) {
    +        super(proto, map);
             assert value instanceof String || value instanceof ConsString;
             this.value = value;
         }
    @@ -147,9 +155,9 @@ public final class NativeString extends ScriptObject {
     
             if (returnType == Object.class && (self instanceof String || self instanceof ConsString)) {
                 try {
    -                MethodHandle mh = MethodHandles.lookup().findStatic(NativeString.class, "get", desc.getMethodType());
    +                MethodHandle mh = MH.findStatic(MethodHandles.lookup(), NativeString.class, "get", desc.getMethodType());
                     return new GuardedInvocation(mh, NashornGuards.getInstanceOf2Guard(String.class, ConsString.class));
    -            } catch (final NoSuchMethodException | IllegalAccessException e) {
    +            } catch (final LookupException e) {
                     // Shouldn't happen. Fall back to super
                 }
             }
    @@ -1065,10 +1073,7 @@ public final class NativeString extends ScriptObject {
         }
     
         private static Object newObj(final Object self, final CharSequence str) {
    -        if (self instanceof ScriptObject) {
    -            return new NativeString(str, ((ScriptObject)self).getProto());
    -        }
    -        return new NativeString(str, Global.instance().getStringPrototype());
    +        return new NativeString(str);
         }
     
         /**
    @@ -1202,10 +1207,6 @@ public final class NativeString extends ScriptObject {
         }
     
         private static MethodHandle findWrapFilter() {
    -        try {
    -            return MethodHandles.lookup().findStatic(NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), NativeString.class, "wrapFilter", MH.type(NativeString.class, Object.class));
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
    index d7d04bbaa6e..45920ba7aec 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeSyntaxError.java
    @@ -58,8 +58,12 @@ public final class NativeSyntaxError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeSyntaxError(final Object msg) {
    -        super(Global.instance().getSyntaxErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    NativeSyntaxError(final Object msg, final Global global) {
    +        super(global.getSyntaxErrorPrototype(), global.getSyntaxErrorMap());
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -67,6 +71,10 @@ public final class NativeSyntaxError extends ScriptObject {
             }
         }
     
    +    private NativeSyntaxError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
    index c811a530569..2b2308b143e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeTypeError.java
    @@ -58,8 +58,12 @@ public final class NativeTypeError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeTypeError(final Object msg) {
    -        super(Global.instance().getTypeErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    NativeTypeError(final Object msg, final Global global) {
    +        super(global.getTypeErrorPrototype(), global.getTypeErrorMap());
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -67,6 +71,10 @@ public final class NativeTypeError extends ScriptObject {
             }
         }
     
    +    private NativeTypeError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
    index 80df6c28529..2caf136954d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeURIError.java
    @@ -57,8 +57,12 @@ public final class NativeURIError extends ScriptObject {
         // initialized by nasgen
         private static PropertyMap $nasgenmap$;
     
    -    NativeURIError(final Object msg) {
    -        super(Global.instance().getURIErrorPrototype(), $nasgenmap$);
    +    static PropertyMap getInitialMap() {
    +        return $nasgenmap$;
    +    }
    +
    +    NativeURIError(final Object msg, final Global global) {
    +        super(global.getURIErrorPrototype(), global.getURIErrorMap());
             if (msg != UNDEFINED) {
                 this.instMessage = JSType.toString(msg);
             } else {
    @@ -66,6 +70,10 @@ public final class NativeURIError extends ScriptObject {
             }
         }
     
    +    private NativeURIError(final Object msg) {
    +        this(msg, Global.instance());
    +    }
    +
         @Override
         public String getClassName() {
             return "Error";
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    index d19e787195d..7c37bac9f6e 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
    @@ -150,7 +150,7 @@ public final class NativeUint16Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getUint16ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getUint16ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    index 87a383cb555..9b51db48d0d 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
    @@ -169,7 +169,7 @@ public final class NativeUint32Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getUint32ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getUint32ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    index 6ae786f3fda..be4e59d368b 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
    @@ -143,7 +143,7 @@ public final class NativeUint8Array extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getUint8ArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getUint8ArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    index 02b7a4edcd0..43b777ba346 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
    @@ -160,7 +160,7 @@ public final class NativeUint8ClampedArray extends ArrayBufferView {
         }
     
         @Override
    -    protected ScriptObject getPrototype() {
    -        return Global.instance().getUint8ClampedArrayPrototype();
    +    protected ScriptObject getPrototype(final Global global) {
    +        return global.getUint8ClampedArrayPrototype();
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
    index 3a7205f9bba..c4cda933dd5 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java
    @@ -57,8 +57,17 @@ public class PrototypeObject extends ScriptObject {
             map$ = map;
         }
     
    +    static PropertyMap getInitialMap() {
    +        return map$;
    +    }
    +
    +    private PrototypeObject(final Global global, final PropertyMap map) {
    +        super(map != map$? map.addAll(global.getPrototypeObjectMap()) : global.getPrototypeObjectMap());
    +        setProto(global.getObjectPrototype());
    +    }
    +
         PrototypeObject() {
    -        this(map$);
    +        this(Global.instance(), map$);
         }
     
         /**
    @@ -67,12 +76,11 @@ public class PrototypeObject extends ScriptObject {
          * @param map property map
          */
         public PrototypeObject(final PropertyMap map) {
    -        super(map != map$ ? map.addAll(map$) : map$);
    -        setProto(Global.objectPrototype());
    +        this(Global.instance(), map);
         }
     
         PrototypeObject(final ScriptFunction func) {
    -        this(map$);
    +        this(Global.instance(), map$);
             this.constructor = func;
         }
     
    @@ -107,10 +115,6 @@ public class PrototypeObject extends ScriptObject {
         }
     
         private static MethodHandle findOwnMH(final String name, final Class rtype, final Class... types) {
    -        try {
    -            return MethodHandles.lookup().findStatic(PrototypeObject.class, name, MH.type(rtype, types));
    -        } catch (final NoSuchMethodException | IllegalAccessException e) {
    -            throw new MethodHandleFactory.LookupException(e);
    -        }
    +        return MH.findStatic(MethodHandles.lookup(), PrototypeObject.class, name, MH.type(rtype, types));
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    index d49f4d3331b..91034c43bdf 100644
    --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java
    @@ -53,9 +53,26 @@ public class ScriptFunctionImpl extends ScriptFunction {
         // property map for non-strict, non-bound functions.
         private static final PropertyMap map$;
     
    +    static PropertyMap getInitialMap() {
    +        return map$;
    +    }
    +
    +    static PropertyMap getInitialStrictMap() {
    +        return strictmodemap$;
    +    }
    +
    +    static PropertyMap getInitialBoundMap() {
    +        return boundfunctionmap$;
    +    }
    +
         // Marker object for lazily initialized prototype object
         private static final Object LAZY_PROTOTYPE = new Object();
     
    +    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs, final Global global) {
    +        super(name, invokeHandle, global.getFunctionMap(), null, specs, false, true, true);
    +        init(global);
    +    }
    +
         /**
          * Constructor called by Nasgen generated code, no membercount, use the default map.
          * Creates builtin functions only.
    @@ -65,8 +82,12 @@ public class ScriptFunctionImpl extends ScriptFunction {
          * @param specs specialized versions of this method, if available, null otherwise
          */
         ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final MethodHandle[] specs) {
    -        super(name, invokeHandle, map$, null, specs, false, true, true);
    -        init();
    +        this(name, invokeHandle, specs, Global.instance());
    +    }
    +
    +    private ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs, final Global global) {
    +        super(name, invokeHandle, map.addAll(global.getFunctionMap()), null, specs, false, true, true);
    +        init(global);
         }
     
         /**
    @@ -79,8 +100,12 @@ public class ScriptFunctionImpl extends ScriptFunction {
          * @param specs specialized versions of this method, if available, null otherwise
          */
         ScriptFunctionImpl(final String name, final MethodHandle invokeHandle, final PropertyMap map, final MethodHandle[] specs) {
    -        super(name, invokeHandle, map.addAll(map$), null, specs, false, true, true);
    -        init();
    +        this(name, invokeHandle, map, specs, Global.instance());
    +    }
    +
    +    private ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor, final Global global) {
    +        super(name, methodHandle, getMap(global, isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
    +        init(global);
         }
     
         /**
    @@ -95,8 +120,12 @@ public class ScriptFunctionImpl extends ScriptFunction {
          * @param isConstructor can the function be used as a constructor (most can; some built-ins are restricted).
          */
         ScriptFunctionImpl(final String name, final MethodHandle methodHandle, final ScriptObject scope, final MethodHandle[] specs, final boolean isStrict, final boolean isBuiltin, final boolean isConstructor) {
    -        super(name, methodHandle, getMap(isStrict), scope, specs, isStrict, isBuiltin, isConstructor);
    -        init();
    +        this(name, methodHandle, scope, specs, isStrict, isBuiltin, isConstructor, Global.instance());
    +    }
    +
    +    private ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope, final Global global) {
    +        super(data, getMap(global, data.isStrict()), scope);
    +        init(global);
         }
     
         /**
    @@ -106,17 +135,17 @@ public class ScriptFunctionImpl extends ScriptFunction {
          * @param scope scope object
          */
         public ScriptFunctionImpl(final RecompilableScriptFunctionData data, final ScriptObject scope) {
    -        super(data, getMap(data.isStrict()), scope);
    -        init();
    +        this(data, scope, Global.instance());
         }
     
         /**
          * Only invoked internally from {@link BoundScriptFunctionImpl} constructor.
          * @param data the script function data for the bound function.
    +     * @param global the global object
          */
    -    ScriptFunctionImpl(final ScriptFunctionData data) {
    -        super(data, boundfunctionmap$, null);
    -        init();
    +    ScriptFunctionImpl(final ScriptFunctionData data, final Global global) {
    +        super(data, global.getBoundFunctionMap(), null);
    +        init(global);
         }
     
         static {
    @@ -159,8 +188,8 @@ public class ScriptFunctionImpl extends ScriptFunction {
         }
     
         // Choose the map based on strict mode!
    -    private static PropertyMap getMap(final boolean strict) {
    -        return strict ? strictmodemap$ : map$;
    +    private static PropertyMap getMap(final Global global, final boolean strict) {
    +        return strict ? global.getStrictFunctionMap() : global.getFunctionMap();
         }
     
         private static PropertyMap createBoundFunctionMap(final PropertyMap strictModeMap) {
    @@ -255,8 +284,8 @@ public class ScriptFunctionImpl extends ScriptFunction {
         }
     
         // Internals below..
    -    private void init() {
    -        this.setProto(Global.instance().getFunctionPrototype());
    +    private void init(final Global global) {
    +        this.setProto(global.getFunctionPrototype());
             this.prototype = LAZY_PROTOTYPE;
     
             // We have to fill user accessor functions late as these are stored
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
    index b39eb44a179..218be74e3bd 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java
    @@ -36,7 +36,6 @@ import java.io.IOException;
     import java.io.PrintWriter;
     import java.lang.invoke.MethodHandle;
     import java.lang.invoke.MethodHandles;
    -import java.lang.reflect.Constructor;
     import java.net.MalformedURLException;
     import java.net.URL;
     import java.security.AccessControlContext;
    @@ -55,6 +54,7 @@ import jdk.nashorn.internal.codegen.ObjectClassGenerator;
     import jdk.nashorn.internal.ir.FunctionNode;
     import jdk.nashorn.internal.ir.debug.ASTWriter;
     import jdk.nashorn.internal.ir.debug.PrintVisitor;
    +import jdk.nashorn.internal.objects.Global;
     import jdk.nashorn.internal.parser.Parser;
     import jdk.nashorn.internal.runtime.options.Options;
     
    @@ -123,8 +123,8 @@ public final class Context {
                 sm.checkPermission(new RuntimePermission("nashorn.setGlobal"));
             }
     
    -        if (global != null && !(global instanceof GlobalObject)) {
    -            throw new IllegalArgumentException("global does not implement GlobalObject!");
    +        if (global != null && !(global instanceof Global)) {
    +            throw new IllegalArgumentException("global is not an instance of Global!");
             }
     
             setGlobalTrusted(global);
    @@ -257,8 +257,7 @@ public final class Context {
                  new PrivilegedAction() {
                     @Override
                     public ClassLoader run() {
    -                    final StructureLoader structureLoader = new StructureLoader(sharedLoader, Context.this);
    -                    return new ScriptLoader(structureLoader, Context.this);
    +                    return new ScriptLoader(sharedLoader, Context.this);
                     }
                  });
             this.errors    = errors;
    @@ -817,25 +816,12 @@ public final class Context {
                  new PrivilegedAction() {
                     @Override
                     public ScriptLoader run() {
    -                    // Generated code won't refer to any class generated by context
    -                    // script loader and so parent loader can be the structure
    -                    // loader -- which is parent of the context script loader.
    -                    return new ScriptLoader((StructureLoader)scriptLoader.getParent(), Context.this);
    +                    return new ScriptLoader(sharedLoader, Context.this);
                     }
                  });
         }
     
         private ScriptObject newGlobalTrusted() {
    -        try {
    -            final Class clazz = Class.forName("jdk.nashorn.internal.objects.Global", true, scriptLoader);
    -            final Constructor cstr = clazz.getConstructor(Context.class);
    -            return (ScriptObject) cstr.newInstance(this);
    -        } catch (final Exception e) {
    -            printStackTrace(e);
    -            if (e instanceof RuntimeException) {
    -                throw (RuntimeException)e;
    -            }
    -            throw new RuntimeException(e);
    -        }
    +        return new Global(this);
         }
     }
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
    index 04211fc6707..c504276f41c 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalFunctions.java
    @@ -34,9 +34,6 @@ import java.util.Locale;
     
     /**
      * Utilities used by Global class.
    - *
    - * These are actual implementation methods for functions exposed by global
    - * scope. The code lives here to share the code across the contexts.
      */
     public final class GlobalFunctions {
     
    diff --git a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
    index b802a1a136f..7a118290c71 100644
    --- a/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
    +++ b/nashorn/src/jdk/nashorn/internal/runtime/GlobalObject.java
    @@ -30,14 +30,7 @@ import jdk.internal.dynalink.linker.GuardedInvocation;
     import jdk.internal.dynalink.linker.LinkRequest;
     
     /**
    - * Runtime interface to the global scope of the current context.
    - * NOTE: never access {@code jdk.nashorn.internal.objects.Global} class directly
    - * from runtime/parser/codegen/ir etc. Always go through this interface.
    - * 

    - * The reason for this is that all objects in the @{code jdk.nashorn.internal.objects.*} package - * are different per Context and loaded separately by each Context class loader. Attempting - * to directly refer to an object in this package from the rest of the runtime - * will lead to {@code ClassNotFoundException} thrown upon link time + * Runtime interface to the global scope objects. */ public interface GlobalObject { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index 1a081a1b2d5..4443d2ed1f5 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -1026,6 +1026,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr return context; } + /** + * Set the current context. + * @param ctx context instance to set + */ + protected final void setContext(final Context ctx) { + ctx.getClass(); + this.context = ctx; + } + /** * Return the map of an object. * @return PropertyMap object. diff --git a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java index ff6973a9fc1..bdc40eddcc9 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/StructureLoader.java @@ -25,30 +25,19 @@ package jdk.nashorn.internal.runtime; -import static jdk.nashorn.internal.codegen.Compiler.OBJECTS_PACKAGE; import static jdk.nashorn.internal.codegen.Compiler.SCRIPTS_PACKAGE; import static jdk.nashorn.internal.codegen.Compiler.binaryName; import static jdk.nashorn.internal.codegen.CompilerConstants.JS_OBJECT_PREFIX; -import java.io.IOException; -import java.io.InputStream; -import java.net.URL; -import java.security.AccessController; -import java.security.CodeSigner; -import java.security.CodeSource; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import jdk.nashorn.internal.codegen.ObjectClassGenerator; /** - * Responsible for on the fly construction of structure classes as well - * as loading jdk.nashorn.internal.objects.* classes. + * Responsible for on the fly construction of structure classes. * */ final class StructureLoader extends NashornLoader { private static final String JS_OBJECT_PREFIX_EXTERNAL = binaryName(SCRIPTS_PACKAGE) + '.' + JS_OBJECT_PREFIX.symbolName(); - private static final String OBJECTS_PACKAGE_EXTERNAL = binaryName(OBJECTS_PACKAGE); /** * Constructor. @@ -68,45 +57,9 @@ final class StructureLoader extends NashornLoader { return loadedClass; } - if (name.startsWith(binaryName(OBJECTS_PACKAGE_EXTERNAL))) { - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction>() { - @Override - public Class run() throws ClassNotFoundException { - final String source = name.replace('.','/') + ".clazz"; - final URL url = getResource(source); - try (final InputStream is = getResourceAsStream(source)) { - if (is == null) { - throw new ClassNotFoundException(name); - } - - byte[] code; - try { - code = Source.readBytes(is); - } catch (final IOException e) { - Context.printStackTrace(e); - throw new ClassNotFoundException(name, e); - } - - final Class cl = defineClass(name, code, 0, code.length, new CodeSource(url, (CodeSigner[])null)); - if (resolve) { - resolveClass(cl); - } - return cl; - } catch (final IOException e) { - throw new RuntimeException(e); - } - } - }); - } catch (final PrivilegedActionException e) { - throw new ClassNotFoundException(name, e); - } - } - return super.loadClassTrusted(name, resolve); } - @Override protected Class findClass(final String name) throws ClassNotFoundException { if (name.startsWith(JS_OBJECT_PREFIX_EXTERNAL)) { diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java index b31df1ae6f1..b4da66e5ef4 100644 --- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java +++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java @@ -36,10 +36,11 @@ public class JO extends ScriptObject { private static final PropertyMap map$ = PropertyMap.newMap(JO.class); /** - * Constructor + * Returns the initial property map to be used. + * @return the initial property map. */ - public JO() { - super(map$); + public static PropertyMap getInitialMap() { + return map$; } /** @@ -52,16 +53,17 @@ public class JO extends ScriptObject { } /** - * Constructor given an initial prototype using the default property map + * Constructor given an initial prototype and an initial property map. * * @param proto the prototype object + * @param map the property map */ - public JO(final ScriptObject proto) { - super(proto, map$); + public JO(final ScriptObject proto, final PropertyMap map) { + super(proto, map); } /** - * Used by FunctionObjectCreator. A method handle of this method is passed to the ScriptFunction constructor. + * A method handle of this method is passed to the ScriptFunction constructor. * * @param map the property map to use for allocatorMap * diff --git a/nashorn/src/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk/nashorn/tools/Shell.java index 708fecc59f1..914c7b6e5cc 100644 --- a/nashorn/src/jdk/nashorn/tools/Shell.java +++ b/nashorn/src/jdk/nashorn/tools/Shell.java @@ -47,6 +47,7 @@ import jdk.nashorn.internal.ir.debug.PrintVisitor; import jdk.nashorn.internal.parser.Parser; import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ErrorManager; +import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.ScriptEnvironment; import jdk.nashorn.internal.runtime.ScriptFunction; @@ -446,7 +447,7 @@ public class Shell { } if (res != null && res != ScriptRuntime.UNDEFINED) { - err.println(ScriptRuntime.safeToString(res)); + err.println(JSType.toString(res)); } } } finally { diff --git a/nashorn/test/script/basic/JDK-8019947.js b/nashorn/test/script/basic/JDK-8019947.js new file mode 100644 index 00000000000..4b64a818b6b --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019947.js @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019947: inherited property invalidation does not work with two globals in same context + * + * @test + * @option -scripting + * @run + */ + +function func(arr) { + try { + print(arr.toString()); + } catch (e) { + print(e.stack); + } +} + +var arr = ["hello", "world"] + +func(arr); + +var global = loadWithNewGlobal({ + name: "t", + script: < Date: Fri, 5 Jul 2013 11:00:19 +0100 Subject: [PATCH 036/156] 8017618: NullPointerException in RichDiagnosticFormatter for bad input program RDF crashes when diagnostic contains type 'void' Reviewed-by: jjg, vromero --- .../sun/tools/javac/util/RichDiagnosticFormatter.java | 5 +++-- .../test/tools/javac/lambda/BadNestedLambda.java | 11 +++++++++++ langtools/test/tools/javac/lambda/BadNestedLambda.out | 3 +++ 3 files changed, 17 insertions(+), 2 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/BadNestedLambda.java create mode 100644 langtools/test/tools/javac/lambda/BadNestedLambda.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java index b142df2ccc8..9650422087c 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/RichDiagnosticFormatter.java @@ -303,8 +303,9 @@ public class RichDiagnosticFormatter extends conflicts.contains(s))) { List l = List.nil(); Symbol s2 = s; - while (s2.type.getEnclosingType().hasTag(CLASS) - && s2.owner.kind == Kinds.TYP) { + while (s2.type.hasTag(CLASS) && + s2.type.getEnclosingType().hasTag(CLASS) && + s2.owner.kind == Kinds.TYP) { l = l.prepend(s2.getSimpleName()); s2 = s2.owner; } diff --git a/langtools/test/tools/javac/lambda/BadNestedLambda.java b/langtools/test/tools/javac/lambda/BadNestedLambda.java new file mode 100644 index 00000000000..616c0868a33 --- /dev/null +++ b/langtools/test/tools/javac/lambda/BadNestedLambda.java @@ -0,0 +1,11 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8017618 + * @summary NullPointerException in RichDiagnosticFormatter for bad input program + * @compile/fail/ref=BadNestedLambda.out -XDrawDiagnostics BadNestedLambda.java + */ +class BadNestedLambda { + void test() { + Runnable add = (int x) -> (int y) -> x + y; + } +} diff --git a/langtools/test/tools/javac/lambda/BadNestedLambda.out b/langtools/test/tools/javac/lambda/BadNestedLambda.out new file mode 100644 index 00000000000..268ad85aa81 --- /dev/null +++ b/langtools/test/tools/javac/lambda/BadNestedLambda.out @@ -0,0 +1,3 @@ +BadNestedLambda.java:9:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.not.a.functional.intf: void)) +BadNestedLambda.java:9:24: compiler.err.prob.found.req: (compiler.misc.incompatible.arg.types.in.lambda) +2 errors From 86f630b63ecf022c304e3b2bf72213a9aadd7c87 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 5 Jul 2013 11:02:17 +0100 Subject: [PATCH 037/156] 8019480: Javac crashes when method is called on a type-variable receiver from lambda expression Logic for shortcircuiting speculative attribution doesn't handle type-variable receivers Reviewed-by: jjg, vromero --- .../sun/tools/javac/comp/DeferredAttr.java | 4 ++++ .../tools/javac/lambda/8019480/T8019480.java | 23 +++++++++++++++++++ .../tools/javac/lambda/8019480/T8019480.out | 3 +++ 3 files changed, 30 insertions(+) create mode 100644 langtools/test/tools/javac/lambda/8019480/T8019480.java create mode 100644 langtools/test/tools/javac/lambda/8019480/T8019480.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index 27b0c606fc2..e2f519f2c07 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -941,6 +941,10 @@ public class DeferredAttr extends JCTree.Visitor { attribSpeculative(rec, env, attr.unknownTypeExprInfo).type : env.enclClass.sym.type; + while (site.hasTag(TYPEVAR)) { + site = site.getUpperBound(); + } + ListBuffer args = ListBuffer.lb(); for (int i = 0; i < tree.args.length(); i ++) { args.append(Type.noType); diff --git a/langtools/test/tools/javac/lambda/8019480/T8019480.java b/langtools/test/tools/javac/lambda/8019480/T8019480.java new file mode 100644 index 00000000000..6d270b12a2b --- /dev/null +++ b/langtools/test/tools/javac/lambda/8019480/T8019480.java @@ -0,0 +1,23 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8019480 + * @summary Javac crashes when method is called on a type-variable receiver from lambda expression + * @author Maurizio Cimadamore + * @compile/fail/ref=T8019480.out -XDrawDiagnostics T8019480.java + */ +import java.util.*; + +class T8019480 { + interface Predicate { + void m(T t); + } + + interface Stream { + void forEach(Predicate pt); + } + + void test(U current, Stream stream) { + List list3 = new ArrayList<>(); + stream.forEach(i -> list3.add(current.clone())); + } +} diff --git a/langtools/test/tools/javac/lambda/8019480/T8019480.out b/langtools/test/tools/javac/lambda/8019480/T8019480.out new file mode 100644 index 00000000000..afc509cb1dd --- /dev/null +++ b/langtools/test/tools/javac/lambda/8019480/T8019480.out @@ -0,0 +1,3 @@ +T8019480.java:21:46: compiler.err.report.access: clone(), protected, java.lang.Object +T8019480.java:21:34: compiler.err.cant.apply.symbols: kindname.method, add, java.lang.Object,{(compiler.misc.inapplicable.method: kindname.method, java.util.Collection, add(U), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, U))),(compiler.misc.inapplicable.method: kindname.method, java.util.List, add(U), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.inconvertible.types: java.lang.Object, U))),(compiler.misc.inapplicable.method: kindname.method, java.util.List, add(int,U), (compiler.misc.arg.length.mismatch))} +2 errors From 28b57590932215c61f1f45d3e9505c88f005cee4 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 5 Jul 2013 11:03:04 +0100 Subject: [PATCH 038/156] 8016059: Cannot compile following lambda 8016060: Lambda isn't compiled with return statement Spurious error triggered during unnecessary recovery round Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/code/Type.java | 3 ++ .../com/sun/tools/javac/comp/Attr.java | 8 +--- .../sun/tools/javac/comp/DeferredAttr.java | 9 +++- .../test/tools/javac/lambda/TargetType75.java | 41 +++++++++++++++++++ 4 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/TargetType75.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index a89f86eed50..b69b421d977 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -78,6 +78,9 @@ public abstract class Type implements TypeMirror { /** Constant type: special type to be used during recovery of deferred expressions. */ public static final JCNoType recoveryType = new JCNoType(); + /** Constant type: special type to be used for marking stuck trees. */ + public static final JCNoType stuckType = new JCNoType(); + /** If this switch is turned on, the names of type variables * and anonymous classes are printed with hashcodes appended. */ diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 91bc4e9b39e..49c10a46517 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -555,11 +555,6 @@ public class Attr extends JCTree.Visitor { } }); } - - @Override - protected Type check(DiagnosticPosition pos, Type found) { - return chk.checkNonVoid(pos, super.check(pos, found)); - } } final ResultInfo statInfo; @@ -1697,7 +1692,8 @@ public class Attr extends JCTree.Visitor { diags.fragment("unexpected.ret.val")); } attribTree(tree.expr, env, env.info.returnResult); - } else if (!env.info.returnResult.pt.hasTag(VOID)) { + } else if (!env.info.returnResult.pt.hasTag(VOID) && + !env.info.returnResult.pt.hasTag(NONE)) { env.info.returnResult.checkContext.report(tree.pos(), diags.fragment("missing.ret.val")); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java index e2f519f2c07..883bcb2d278 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/DeferredAttr.java @@ -95,7 +95,7 @@ public class DeferredAttr extends JCTree.Visitor { make = TreeMaker.instance(context); types = Types.instance(context); Names names = Names.instance(context); - stuckTree = make.Ident(names.empty).setType(Type.noType); + stuckTree = make.Ident(names.empty).setType(Type.stuckType); } /** shared tree for stuck expressions */ @@ -649,7 +649,12 @@ public class DeferredAttr extends JCTree.Visitor { * a default expected type (j.l.Object). */ private Type recover(DeferredType dt) { - dt.check(attr.new RecoveryInfo(deferredAttrContext)); + dt.check(attr.new RecoveryInfo(deferredAttrContext) { + @Override + protected Type check(DiagnosticPosition pos, Type found) { + return chk.checkNonVoid(pos, super.check(pos, found)); + } + }); return super.apply(dt); } } diff --git a/langtools/test/tools/javac/lambda/TargetType75.java b/langtools/test/tools/javac/lambda/TargetType75.java new file mode 100644 index 00000000000..a65b9b95bcb --- /dev/null +++ b/langtools/test/tools/javac/lambda/TargetType75.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8016060 8016059 + * @summary Lambda isn't compiled with return statement + * @compile TargetType75.java + */ +class TargetType75 { + interface P { + void m(X x); + } + + void m(P r, Z z) { } + + void test() { + m(x->{ return; }, ""); + m(x->System.out.println(""), ""); + } +} From 4442f43ea3614fa4764c3afdf476de6aef58e55c Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 5 Jul 2013 11:04:22 +0100 Subject: [PATCH 039/156] 8016702: use of ternary operator in lambda expression gives incorrect results Constant types erroneously creep in during inference Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/comp/Attr.java | 24 ++++++- .../tools/javac/conditional/T8016702.java | 66 +++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 langtools/test/tools/javac/conditional/T8016702.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 49c10a46517..fe404c0b809 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2392,7 +2392,7 @@ public class Attr extends JCTree.Visitor { ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ? recoveryInfo : - new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); + new LambdaResultInfo(lambdaType.getReturnType(), funcContext); localEnv.info.returnResult = bodyResultInfo; Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log); @@ -2584,6 +2584,28 @@ public class Attr extends JCTree.Visitor { } } + class LambdaResultInfo extends ResultInfo { + + LambdaResultInfo(Type pt, CheckContext checkContext) { + super(VAL, pt, checkContext); + } + + @Override + protected Type check(DiagnosticPosition pos, Type found) { + return super.check(pos, found.baseType()); + } + + @Override + protected ResultInfo dup(CheckContext newContext) { + return new LambdaResultInfo(pt, newContext); + } + + @Override + protected ResultInfo dup(Type newPt) { + return new LambdaResultInfo(newPt, checkContext); + } + } + /** * Lambda compatibility. Check that given return types, thrown types, parameter types * are compatible with the expected functional interface descriptor. This means that: diff --git a/langtools/test/tools/javac/conditional/T8016702.java b/langtools/test/tools/javac/conditional/T8016702.java new file mode 100644 index 00000000000..df99fd62465 --- /dev/null +++ b/langtools/test/tools/javac/conditional/T8016702.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8016702 + * @summary use of ternary operator in lambda expression gives incorrect results + */ +import java.util.Arrays; +import java.util.List; + +public class T8016702 { + + static int assertionCount; + + static void assertTrue(boolean b, String msg) { + assertionCount++; + if (!b) { + throw new AssertionError(msg); + } + } + + interface IntFunction { + Y m(int x); + } + + void test(List li) { + map(i -> (i % 2 == 0) ? "" : "i="+i, li); + } + + + @SuppressWarnings("unchecked") + void map(IntFunction mapper, List li) { + for (int i : li) { + String res = (String)mapper.m(i); + assertTrue((i % 2 == 0) ? res.isEmpty() : res.contains("" + i), + "i = " + i + " res = " + res); + } + } + + public static void main(String[] args) { + T8016702 tester = new T8016702(); + tester.test(Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)); + assertTrue(assertionCount == 10, "wrong assertion count: " + assertionCount); + } +} From 7229f89614a7eedb333b9110a409b1c2000b9cc7 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 5 Jul 2013 11:05:02 +0100 Subject: [PATCH 040/156] 8019824: very long error messages on inference error Inference error messages shows several spurious captured variables generated during an inference loop Reviewed-by: jjg, vromero --- .../com/sun/tools/javac/code/Type.java | 11 ++++-- .../com/sun/tools/javac/comp/Infer.java | 34 +++++++++++++------ .../generics/inference/8019824/T8019824.java | 15 ++++++++ .../generics/inference/8019824/T8019824.out | 2 ++ 4 files changed, 48 insertions(+), 14 deletions(-) create mode 100644 langtools/test/tools/javac/generics/inference/8019824/T8019824.java create mode 100644 langtools/test/tools/javac/generics/inference/8019824/T8019824.out diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java index b69b421d977..daa0aa0fc28 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Type.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Type.java @@ -1514,9 +1514,14 @@ public abstract class Type implements TypeMirror { return buf.toList(); } + /** internal method used to override an undetvar bounds */ + public void setBounds(InferenceBound ib, List newBounds) { + bounds.put(ib, newBounds); + } + /** add a bound of a given kind - this might trigger listener notification */ public void addBound(InferenceBound ib, Type bound, Types types) { - Type bound2 = toTypeVarMap.apply(bound); + Type bound2 = boundMap.apply(bound); List prevBounds = bounds.get(ib); for (Type b : prevBounds) { //check for redundancy - use strict version of isSameType on tvars @@ -1527,12 +1532,12 @@ public abstract class Type implements TypeMirror { notifyChange(EnumSet.of(ib)); } //where - Type.Mapping toTypeVarMap = new Mapping("toTypeVarMap") { + Type.Mapping boundMap = new Mapping("boundMap") { @Override public Type apply(Type t) { if (t.hasTag(UNDETVAR)) { UndetVar uv = (UndetVar)t; - return uv.qtype; + return uv.inst != null ? uv.inst : uv.qtype; } else { return t.map(this); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java index c5f4b271f2e..e4242908330 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java @@ -418,6 +418,7 @@ public class Infer { void checkWithinBounds(InferenceContext inferenceContext, Warner warn) throws InferenceException { MultiUndetVarListener mlistener = new MultiUndetVarListener(inferenceContext.undetvars); + List saved_undet = inferenceContext.save(); try { while (true) { mlistener.reset(); @@ -443,6 +444,9 @@ public class Infer { } finally { mlistener.detach(); + if (mlistener.rounds == MAX_INCORPORATION_STEPS) { + inferenceContext.rollback(saved_undet); + } } } //where @@ -645,7 +649,7 @@ public class Infer { UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); //alpha <: beta //0. set beta :> alpha - uv2.addBound(InferenceBound.LOWER, uv.qtype, infer.types); + uv2.addBound(InferenceBound.LOWER, uv, infer.types); //1. copy alpha's lower to beta's for (Type l : uv.getBounds(InferenceBound.LOWER)) { uv2.addBound(InferenceBound.LOWER, inferenceContext.asInstType(l), infer.types); @@ -670,7 +674,7 @@ public class Infer { UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); //alpha :> beta //0. set beta <: alpha - uv2.addBound(InferenceBound.UPPER, uv.qtype, infer.types); + uv2.addBound(InferenceBound.UPPER, uv, infer.types); //1. copy alpha's upper to beta's for (Type u : uv.getBounds(InferenceBound.UPPER)) { uv2.addBound(InferenceBound.UPPER, inferenceContext.asInstType(u), infer.types); @@ -695,7 +699,7 @@ public class Infer { UndetVar uv2 = (UndetVar)inferenceContext.asFree(b); //alpha == beta //0. set beta == alpha - uv2.addBound(InferenceBound.EQ, uv.qtype, infer.types); + uv2.addBound(InferenceBound.EQ, uv, infer.types); //1. copy all alpha's bounds to beta's for (InferenceBound ib : InferenceBound.values()) { for (Type b2 : uv.getBounds(ib)) { @@ -1090,7 +1094,7 @@ public class Infer { while (!sstrategy.done()) { InferenceGraph.Node nodeToSolve = sstrategy.pickNode(inferenceGraph); List varsToSolve = List.from(nodeToSolve.data); - inferenceContext.save(); + List saved_undet = inferenceContext.save(); try { //repeat until all variables are solved outer: while (Type.containsAny(inferenceContext.restvars(), varsToSolve)) { @@ -1107,7 +1111,7 @@ public class Infer { } catch (InferenceException ex) { //did we fail because of interdependent ivars? - inferenceContext.rollback(); + inferenceContext.rollback(saved_undet); instantiateAsUninferredVars(varsToSolve, inferenceContext); checkWithinBounds(inferenceContext, warn); } @@ -1502,7 +1506,7 @@ public class Infer { /** * Save the state of this inference context */ - void save() { + List save() { ListBuffer buf = ListBuffer.lb(); for (Type t : undetvars) { UndetVar uv = (UndetVar)t; @@ -1515,16 +1519,24 @@ public class Infer { uv2.inst = uv.inst; buf.add(uv2); } - saved_undet = buf.toList(); + return buf.toList(); } /** * Restore the state of this inference context to the previous known checkpoint */ - void rollback() { - Assert.check(saved_undet != null && saved_undet.length() == undetvars.length()); - undetvars = saved_undet; - saved_undet = null; + void rollback(List saved_undet) { + Assert.check(saved_undet != null && saved_undet.length() == undetvars.length()); + //restore bounds (note: we need to preserve the old instances) + for (Type t : undetvars) { + UndetVar uv = (UndetVar)t; + UndetVar uv_saved = (UndetVar)saved_undet.head; + for (InferenceBound ib : InferenceBound.values()) { + uv.setBounds(ib, uv_saved.getBounds(ib)); + } + uv.inst = uv_saved.inst; + saved_undet = saved_undet.tail; + } } /** diff --git a/langtools/test/tools/javac/generics/inference/8019824/T8019824.java b/langtools/test/tools/javac/generics/inference/8019824/T8019824.java new file mode 100644 index 00000000000..30f0effd87a --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/8019824/T8019824.java @@ -0,0 +1,15 @@ +/** + * @test /nodynamiccopyright/ + * @bug 8019824 + * @summary very long error messages on inference error + * @compile/fail/ref=T8019824.out -XDrawDiagnostics T8019824.java + */ +class T8019824 { + void test(Class> cls) { + Foo foo = make(cls); + } + + > Foo make(Class cls) { return null; } + + interface Foo {} +} diff --git a/langtools/test/tools/javac/generics/inference/8019824/T8019824.out b/langtools/test/tools/javac/generics/inference/8019824/T8019824.out new file mode 100644 index 00000000000..28a2584d116 --- /dev/null +++ b/langtools/test/tools/javac/generics/inference/8019824/T8019824.out @@ -0,0 +1,2 @@ +T8019824.java:9:25: compiler.err.cant.apply.symbol: kindname.method, make, java.lang.Class, java.lang.Class>, kindname.class, T8019824, (compiler.misc.incompatible.eq.upper.bounds: C, compiler.misc.type.captureof: 1, ? extends T8019824.Foo, T8019824.Foo) +1 error From 8f092c733aa69fa48501b85ba17eb89d95103d88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Fri, 5 Jul 2013 14:36:54 +0200 Subject: [PATCH 041/156] 8017084: Use spill properties for large object literals Reviewed-by: lagergren, sundar --- .../internal/tools/nasgen/ClassGenerator.java | 4 +- .../tools/nasgen/StringConstants.java | 4 +- .../internal/codegen/CodeGenerator.java | 143 +- .../internal/codegen/FieldObjectCreator.java | 69 +- .../internal/codegen/FinalizeTypes.java | 8 + .../nashorn/internal/codegen/MapCreator.java | 38 +- .../codegen/ObjectClassGenerator.java | 15 +- .../internal/codegen/ObjectCreator.java | 74 +- .../internal/codegen/SpillObjectCreator.java | 134 + .../jdk/nashorn/internal/ir/FunctionNode.java | 24 + .../jdk/nashorn/internal/ir/LiteralNode.java | 50 +- .../nashorn/internal/ir/debug/JSONWriter.java | 2 +- .../internal/objects/NativeArguments.java | 2 +- .../objects/NativeStrictArguments.java | 2 +- .../internal/objects/PrototypeObject.java | 2 +- .../internal/objects/ScriptFunctionImpl.java | 4 +- .../jdk/nashorn/internal/parser/Parser.java | 2 +- .../internal/runtime/AccessorProperty.java | 26 +- .../nashorn/internal/runtime/PropertyMap.java | 41 +- .../internal/runtime/ScriptObject.java | 4 +- .../src/jdk/nashorn/internal/scripts/JO.java | 2 +- nashorn/test/script/basic/JDK-8017084.js | 17625 ++++++++++++++++ .../test/script/basic/JDK-8017084.js.EXPECTED | 13 + 23 files changed, 18053 insertions(+), 235 deletions(-) create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java create mode 100644 nashorn/test/script/basic/JDK-8017084.js create mode 100644 nashorn/test/script/basic/JDK-8017084.js.EXPECTED diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java index bc6bb4b2db2..ed0eee61e60 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java @@ -25,6 +25,7 @@ package jdk.nashorn.internal.tools.nasgen; +import static jdk.internal.org.objectweb.asm.Opcodes.ACC_FINAL; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PRIVATE; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC; import static jdk.internal.org.objectweb.asm.Opcodes.ACC_STATIC; @@ -164,7 +165,6 @@ public class ClassGenerator { mi.visitCode(); mi.pushNull(); mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); - mi.loadClass(className); mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC); // stack: PropertyMap } @@ -236,7 +236,7 @@ public class ClassGenerator { static void addMapField(final ClassVisitor cv) { // add a MAP static field - final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC, + final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, MAP_FIELD_NAME, MAP_DESC, null, null); if (fv != null) { fv.visitEnd(); diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java index 5a5032f93a9..d0e3168b31f 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java @@ -96,12 +96,10 @@ public interface StringConstants { static final String MAP_TYPE = TYPE_PROPERTYMAP.getInternalName(); static final String MAP_DESC = TYPE_PROPERTYMAP.getDescriptor(); static final String MAP_NEWMAP = "newMap"; - static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_CLASS); + static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); static final String MAP_DUPLICATE = "duplicate"; static final String MAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); - static final String MAP_SETFLAGS = "setFlags"; static final String LOOKUP_TYPE = TYPE_LOOKUP.getInternalName(); - static final String LOOKUP_GETMETHOD = "getMethod"; static final String LOOKUP_NEWPROPERTY = "newProperty"; static final String LOOKUP_NEWPROPERTY_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_PROPERTYMAP, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 52241265513..fe4e3676e19 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -179,6 +179,8 @@ final class CodeGenerator extends NodeOperatorVisitor foc = new FieldObjectCreator(this, nameList, newSymbols, values, true, hasArguments) { + new FieldObjectCreator(this, nameList, newSymbols, values, true, hasArguments) { @Override protected void loadValue(final Symbol value) { method.load(value); @@ -956,8 +958,7 @@ final class CodeGenerator extends NodeOperatorVisitor(this, keys, symbols, values) { - @Override - protected void loadValue(final Node node) { - load(node); - } + if (elements.size() > OBJECT_SPILL_THRESHOLD) { + new SpillObjectCreator(this, keys, symbols, values).makeObject(method); + } else { + new FieldObjectCreator(this, keys, symbols, values) { + @Override + protected void loadValue(final Node node) { + load(node); + } - /** - * Ensure that the properties start out as object types so that - * we can do putfield initializations instead of dynamicSetIndex - * which would be the case to determine initial property type - * otherwise. - * - * Use case, it's very expensive to do a million var x = {a:obj, b:obj} - * just to have to invalidate them immediately on initialization - * - * see NASHORN-594 - */ - @Override - protected MapCreator newMapCreator(final Class fieldObjectClass) { - return new MapCreator(fieldObjectClass, keys, symbols) { - @Override - protected int getPropertyFlags(final Symbol symbol, final boolean isVarArg) { - return super.getPropertyFlags(symbol, isVarArg) | Property.IS_ALWAYS_OBJECT; - } - }; - } + /** + * Ensure that the properties start out as object types so that + * we can do putfield initializations instead of dynamicSetIndex + * which would be the case to determine initial property type + * otherwise. + * + * Use case, it's very expensive to do a million var x = {a:obj, b:obj} + * just to have to invalidate them immediately on initialization + * + * see NASHORN-594 + */ + @Override + protected MapCreator newMapCreator(final Class fieldObjectClass) { + return new MapCreator(fieldObjectClass, keys, symbols) { + @Override + protected int getPropertyFlags(final Symbol symbol, final boolean hasArguments) { + return super.getPropertyFlags(symbol, hasArguments) | Property.IS_ALWAYS_OBJECT; + } + }; + } - }.makeObject(method); + }.makeObject(method); + } method.dup(); globalObjectPrototype(); method.invoke(ScriptObject.SET_PROTO); - if (!hasGettersSetters) { - method.store(objectNode.getSymbol()); - return false; - } + if (hasGettersSetters) { + for (final PropertyNode propertyNode : elements) { + final FunctionNode getter = propertyNode.getGetter(); + final FunctionNode setter = propertyNode.getSetter(); - for (final Node element : elements) { - final PropertyNode propertyNode = (PropertyNode)element; - final Object key = propertyNode.getKey(); - final FunctionNode getter = propertyNode.getGetter(); - final FunctionNode setter = propertyNode.getSetter(); + if (getter == null && setter == null) { + continue; + } - if (getter == null && setter == null) { - continue; + method.dup().loadKey(propertyNode.getKey()); + + if (getter == null) { + method.loadNull(); + } else { + getter.accept(this); + } + + if (setter == null) { + method.loadNull(); + } else { + setter.accept(this); + } + + method.invoke(ScriptObject.SET_USER_ACCESSORS); } - - method.dup().loadKey(key); - - if (getter == null) { - method.loadNull(); - } else { - getter.accept(this); - } - - if (setter == null) { - method.loadNull(); - } else { - setter.accept(this); - } - - method.invoke(ScriptObject.SET_USER_ACCESSORS); } method.store(objectNode.getSymbol()); - return false; } @@ -3183,24 +3181,21 @@ final class CodeGenerator extends NodeOperatorVisitor(), new ArrayList(), false, false) { - @Override - protected void makeObject(final MethodEmitter m) { - final String className = SCRIPTFUNCTION_IMPL_OBJECT; + method._new(className).dup(); + loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), allocatorClassName, allocatorMap)); - m._new(className).dup(); - loadConstant(new RecompilableScriptFunctionData(functionNode, compiler.getCodeInstaller(), Compiler.binaryName(getClassName()), makeMap())); - - if (isLazy || functionNode.needsParentScope()) { - m.loadCompilerConstant(SCOPE); - } else { - m.loadNull(); - } - m.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class)); - } - }.makeObject(method); + if (functionNode.isLazy() || functionNode.needsParentScope()) { + method.loadCompilerConstant(SCOPE); + } else { + method.loadNull(); + } + method.invoke(constructorNoLookup(className, RecompilableScriptFunctionData.class, ScriptObject.class)); } // calls on Global class. diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java index 974b5ba81a7..9e15b4978a4 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FieldObjectCreator.java @@ -26,15 +26,16 @@ package jdk.nashorn.internal.codegen; import static jdk.nashorn.internal.codegen.CompilerConstants.ARGUMENTS; -import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; import static jdk.nashorn.internal.codegen.CompilerConstants.typeDescriptor; +import static jdk.nashorn.internal.codegen.ObjectClassGenerator.getPaddedFieldCount; import static jdk.nashorn.internal.codegen.types.Type.OBJECT; import java.util.Iterator; import java.util.List; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.Symbol; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.arrays.ArrayIndex; @@ -48,6 +49,13 @@ import jdk.nashorn.internal.runtime.arrays.ArrayIndex; * @see jdk.nashorn.internal.ir.Node */ public abstract class FieldObjectCreator extends ObjectCreator { + + private String fieldObjectClassName; + private Class fieldObjectClass; + private int fieldCount; + private int paddedFieldCount; + private int paramCount; + /** array of corresponding values to symbols (null for no values) */ private final List values; @@ -80,14 +88,9 @@ public abstract class FieldObjectCreator extends ObjectCreator { super(codegen, keys, symbols, isScope, hasArguments); this.values = values; this.callSiteFlags = codegen.getCallSiteFlags(); - } - /** - * Loads the scope on the stack through the passed method emitter. - * @param method the method emitter to use - */ - protected void loadScope(final MethodEmitter method) { - method.loadCompilerConstant(SCOPE); + countFields(); + findClass(); } /** @@ -137,6 +140,13 @@ public abstract class FieldObjectCreator extends ObjectCreator { } } + @Override + protected PropertyMap makeMap() { + assert propertyMap == null : "property map already initialized"; + propertyMap = newMapCreator(fieldObjectClass).makeFieldMap(hasArguments(), fieldCount, paddedFieldCount); + return propertyMap; + } + /** * Technique for loading an initial value. Defined by anonymous subclasses in code gen. * @@ -173,4 +183,47 @@ public abstract class FieldObjectCreator extends ObjectCreator { loadValue(value); method.dynamicSetIndex(callSiteFlags); } + + /** + * Locate (or indirectly create) the object container class. + */ + private void findClass() { + fieldObjectClassName = isScope() ? + ObjectClassGenerator.getClassName(fieldCount, paramCount) : + ObjectClassGenerator.getClassName(paddedFieldCount); + + try { + this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName)); + } catch (final ClassNotFoundException e) { + throw new AssertionError("Nashorn has encountered an internal error. Structure can not be created."); + } + } + + /** + * Get the class name for the object class, + * e.g. {@code com.nashorn.oracle.scripts.JO2P0} + * + * @return script class name + */ + String getClassName() { + return fieldObjectClassName; + } + + /** + * Tally the number of fields and parameters. + */ + private void countFields() { + for (final Symbol symbol : this.symbols) { + if (symbol != null) { + if (hasArguments() && symbol.isParam()) { + symbol.setFieldIndex(paramCount++); + } else { + symbol.setFieldIndex(fieldCount++); + } + } + } + + paddedFieldCount = getPaddedFieldCount(fieldCount); + } + } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java index f9d643228e8..14bec19d8ba 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FinalizeTypes.java @@ -175,6 +175,14 @@ final class FinalizeTypes extends NodeOperatorVisitor { if (destType == null) { destType = specBinaryNode.getType(); } + // Register assignments to this object in case this is used as constructor + if (binaryNode.lhs() instanceof AccessNode) { + AccessNode accessNode = (AccessNode) binaryNode.lhs(); + + if (accessNode.getBase().getSymbol().isThis()) { + lc.getCurrentFunction().addThisProperty(accessNode.getProperty().getName()); + } + } return specBinaryNode.setRHS(convert(specBinaryNode.rhs(), destType)); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java index 609fac9b3ff..6ad03c73691 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java @@ -41,10 +41,10 @@ public class MapCreator { private final Class structure; /** key set for object map */ - private final String[] keys; + final List keys; /** corresponding symbol set for object map */ - private final Symbol[] symbols; + final List symbols; /** * Constructor @@ -54,11 +54,9 @@ public class MapCreator { * @param symbols list of symbols for map */ MapCreator(final Class structure, final List keys, final List symbols) { - final int size = keys.size(); - this.structure = structure; - this.keys = keys.toArray(new String[size]); - this.symbols = symbols.toArray(new Symbol[size]); + this.keys = keys; + this.symbols = symbols; } /** @@ -70,21 +68,37 @@ public class MapCreator { * * @return New map populated with accessor properties. */ - PropertyMap makeMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum) { + PropertyMap makeFieldMap(final boolean hasArguments, final int fieldCount, final int fieldMaximum) { final List properties = new ArrayList<>(); - assert keys != null; - for (int i = 0; i < keys.length; i++) { - final String key = keys[i]; - final Symbol symbol = symbols[i]; + for (int i = 0, length = keys.size(); i < length; i++) { + final String key = keys.get(i); + final Symbol symbol = symbols.get(i); if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) { properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), structure, symbol.getFieldIndex())); } } - return PropertyMap.newMap(structure, properties, fieldCount, fieldMaximum); + return PropertyMap.newMap(properties, fieldCount, fieldMaximum, 0); + } + + PropertyMap makeSpillMap(final boolean hasArguments) { + final List properties = new ArrayList<>(); + int spillIndex = 0; + assert keys != null; + + for (int i = 0, length = keys.size(); i < length; i++) { + final String key = keys.get(i); + final Symbol symbol = symbols.get(i); + + if (symbol != null && !ArrayIndex.isIntArrayIndex(key)) { + properties.add(new AccessorProperty(key, getPropertyFlags(symbol, hasArguments), spillIndex++)); + } + } + + return PropertyMap.newMap(properties, 0, 0, spillIndex); } /** diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java index 934df7a6820..7d61db1f691 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java @@ -73,11 +73,6 @@ public final class ObjectClassGenerator { */ static final int FIELD_PADDING = 4; - /** - * Rounding when calculating the number of fields. - */ - static final int FIELD_ROUNDING = 4; - /** * Debug field logger * Should we print debugging information for fields when they are generated and getters/setters are called? @@ -325,7 +320,6 @@ public final class ObjectClassGenerator { final List initFields = addFields(classEmitter, fieldCount); final MethodEmitter init = newInitMethod(classEmitter); - initializeToUndefined(init, className, initFields); init.returnVoid(); init.end(); @@ -709,6 +703,15 @@ public final class ObjectClassGenerator { } } + /** + * Add padding to field count to avoid creating too many classes and have some spare fields + * @param count the field count + * @return the padded field count + */ + static int getPaddedFieldCount(final int count) { + return count / FIELD_PADDING * FIELD_PADDING + FIELD_PADDING; + } + // // Provide generic getters and setters for undefined types. If a type is undefined, all // and marshals the set to the correct setter depending on the type of the value being set. diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java index b0e5a7730e9..2a8ebba71b4 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectCreator.java @@ -25,10 +25,10 @@ package jdk.nashorn.internal.codegen; +import static jdk.nashorn.internal.codegen.CompilerConstants.SCOPE; + import java.util.List; -import static jdk.nashorn.internal.codegen.ObjectClassGenerator.FIELD_PADDING; import jdk.nashorn.internal.ir.Symbol; -import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.PropertyMap; /** @@ -36,9 +36,6 @@ import jdk.nashorn.internal.runtime.PropertyMap; */ public abstract class ObjectCreator { - /** Compile unit for this ObjectCreator, see CompileUnit */ - //protected final CompileUnit compileUnit; - /** List of keys to initiate in this ObjectCreator */ protected final List keys; @@ -50,12 +47,7 @@ public abstract class ObjectCreator { private final boolean isScope; private final boolean hasArguments; - private int fieldCount; - private int paddedFieldCount; - private int paramCount; - private String fieldObjectClassName; - private Class fieldObjectClass; - private PropertyMap propertyMap; + protected PropertyMap propertyMap; /** * Constructor @@ -72,41 +64,6 @@ public abstract class ObjectCreator { this.symbols = symbols; this.isScope = isScope; this.hasArguments = hasArguments; - - countFields(); - findClass(); - } - - /** - * Tally the number of fields and parameters. - */ - private void countFields() { - for (final Symbol symbol : this.symbols) { - if (symbol != null) { - if (hasArguments() && symbol.isParam()) { - symbol.setFieldIndex(paramCount++); - } else { - symbol.setFieldIndex(fieldCount++); - } - } - } - - paddedFieldCount = fieldCount + FIELD_PADDING; - } - - /** - * Locate (or indirectly create) the object container class. - */ - private void findClass() { - fieldObjectClassName = isScope() ? - ObjectClassGenerator.getClassName(fieldCount, paramCount) : - ObjectClassGenerator.getClassName(paddedFieldCount); - - try { - this.fieldObjectClass = Context.forStructureClass(Compiler.binaryName(fieldObjectClassName)); - } catch (final ClassNotFoundException e) { - throw new AssertionError("Nashorn has encountered an internal error. Structure can not be created."); - } } /** @@ -115,6 +72,12 @@ public abstract class ObjectCreator { */ protected abstract void makeObject(final MethodEmitter method); + /** + * Construct the property map appropriate for the object. + * @return the newly created property map + */ + protected abstract PropertyMap makeMap(); + /** * Create a new MapCreator * @param clazz type of MapCreator @@ -125,12 +88,11 @@ public abstract class ObjectCreator { } /** - * Construct the property map appropriate for the object. - * @return the newly created property map + * Loads the scope on the stack through the passed method emitter. + * @param method the method emitter to use */ - protected PropertyMap makeMap() { - propertyMap = newMapCreator(fieldObjectClass).makeMap(hasArguments(), fieldCount, paddedFieldCount); - return propertyMap; + protected void loadScope(final MethodEmitter method) { + method.loadCompilerConstant(SCOPE); } /** @@ -143,16 +105,6 @@ public abstract class ObjectCreator { return method; } - /** - * Get the class name for the object class, - * e.g. {@code com.nashorn.oracle.scripts.JO2P0} - * - * @return script class name - */ - String getClassName() { - return fieldObjectClassName; - } - /** * Is this a scope object * @return true if scope diff --git a/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java new file mode 100644 index 00000000000..33e1d432ac3 --- /dev/null +++ b/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2010-2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.nashorn.internal.codegen; + +import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.LiteralNode; +import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.Symbol; +import jdk.nashorn.internal.runtime.Property; +import jdk.nashorn.internal.runtime.PropertyMap; +import jdk.nashorn.internal.runtime.ScriptObject; +import jdk.nashorn.internal.scripts.JO; + +import java.util.List; + +import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; +import static jdk.nashorn.internal.codegen.types.Type.OBJECT; + +/** + * An object creator that uses spill properties. + */ +public class SpillObjectCreator extends ObjectCreator { + + private final List values; + + /** + * Constructor + * + * @param codegen code generator + * @param keys keys for fields in object + * @param symbols symbols for fields in object + * @param values list of values corresponding to keys + */ + protected SpillObjectCreator(final CodeGenerator codegen, final List keys, final List symbols, final List values) { + super(codegen, keys, symbols, false, false); + this.values = values; + makeMap(); + } + + @Override + protected void makeObject(final MethodEmitter method) { + assert !isScope() : "spill scope objects are not currently supported"; + + final int length = keys.size(); + final Object[] presetValues = new Object[propertyMap.size()]; + final Class clazz = JO.class; + + // Compute constant values + for (int i = 0; i < length; i++) { + final String key = keys.get(i); + final Property property = propertyMap.findProperty(key); + + if (property != null) { + presetValues[property.getSlot()] = LiteralNode.objectAsConstant(values.get(i)); + } + } + + method._new(clazz).dup(); + codegen.loadConstant(propertyMap); + + method.invoke(constructorNoLookup(JO.class, PropertyMap.class)); + + method.dup(); + codegen.loadConstant(presetValues); + + // Create properties with non-constant values + for (int i = 0; i < length; i++) { + final String key = keys.get(i); + final Property property = propertyMap.findProperty(key); + + if (property != null && presetValues[property.getSlot()] == LiteralNode.POSTSET_MARKER) { + method.dup(); + method.load(property.getSlot()); + codegen.load(values.get(i)).convert(OBJECT); + method.arraystore(); + presetValues[property.getSlot()] = null; + } + } + + method.putField(Type.typeFor(ScriptObject.class).getInternalName(), "spill", Type.OBJECT_ARRAY.getDescriptor()); + final int callSiteFlags = codegen.getCallSiteFlags(); + + // Assign properties with valid array index keys + for (int i = 0; i < length; i++) { + final String key = keys.get(i); + final Property property = propertyMap.findProperty(key); + final Node value = values.get(i); + + if (property == null && value != null) { + method.dup(); + method.load(keys.get(i)); + codegen.load(value); + method.dynamicSetIndex(callSiteFlags); + } + } + } + + @Override + protected PropertyMap makeMap() { + assert propertyMap == null : "property map already initialized"; + + propertyMap = new MapCreator(JO.class, keys, symbols) { + @Override + protected int getPropertyFlags(Symbol symbol, boolean hasArguments) { + return super.getPropertyFlags(symbol, hasArguments) | Property.IS_SPILL | Property.IS_ALWAYS_OBJECT; + } + }.makeSpillMap(false); + + return propertyMap; + } +} diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java index 3640db30e87..8caff9d28fd 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java @@ -131,6 +131,10 @@ public final class FunctionNode extends LexicalContextNode implements Flags thisProperties; + /** Function flags. */ private final int flags; @@ -277,6 +281,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags(); + } + thisProperties.add(key); + } + + /** + * Get the number of properties assigned to the this object in this function. + * @return number of properties + */ + public int countThisProperties() { + return thisProperties == null ? 0 : thisProperties.size(); + } + /** * Return the kind of this function * @see FunctionNode.Kind diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java index a7cea66a256..2c812dbbea5 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java @@ -49,6 +49,9 @@ public abstract class LiteralNode extends Node implements PropertyKey { /** Literal value */ protected final T value; + /** Marker for values that must be computed at runtime */ + public static final Object POSTSET_MARKER = new Object(); + /** * Constructor * @@ -495,6 +498,30 @@ public abstract class LiteralNode extends Node implements PropertyKey { return new LexerTokenLiteralNode(parent.getToken(), parent.getFinish(), value); } + /** + * Get the constant value for an object, or {@link #POSTSET_MARKER} if the value can't be statically computed. + * + * @param object a node or value object + * @return the constant value or {@code POSTSET_MARKER} + */ + public static Object objectAsConstant(final Object object) { + if (object == null) { + return null; + } else if (object instanceof Number || object instanceof String || object instanceof Boolean) { + return object; + } else if (object instanceof LiteralNode) { + return objectAsConstant(((LiteralNode)object).getValue()); + } else if (object instanceof UnaryNode) { + final UnaryNode unaryNode = (UnaryNode)object; + + if (unaryNode.isTokenType(TokenType.CONVERT) && unaryNode.getType().isObject()) { + return objectAsConstant(unaryNode.rhs()); + } + } + + return POSTSET_MARKER; + } + private static final class NullLiteralNode extends LiteralNode { private NullLiteralNode(final long token, final int finish) { @@ -525,11 +552,6 @@ public abstract class LiteralNode extends Node implements PropertyKey { * Array literal node class. */ public static final class ArrayLiteralNode extends LiteralNode { - private static class PostsetMarker { - //empty - } - - private static PostsetMarker POSTSET_MARKER = new PostsetMarker(); /** Array element type. */ private Type elementType; @@ -740,24 +762,6 @@ public abstract class LiteralNode extends Node implements PropertyKey { } } - private Object objectAsConstant(final Object object) { - if (object == null) { - return null; - } else if (object instanceof Number || object instanceof String || object instanceof Boolean) { - return object; - } else if (object instanceof LiteralNode) { - return objectAsConstant(((LiteralNode)object).getValue()); - } else if (object instanceof UnaryNode) { - final UnaryNode unaryNode = (UnaryNode)object; - - if (unaryNode.isTokenType(TokenType.CONVERT) && unaryNode.getType().isObject()) { - return objectAsConstant(unaryNode.rhs()); - } - } - - return POSTSET_MARKER; - } - @Override public Node[] getArray() { return value; diff --git a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java index 4415ebd7689..9ac46dc6000 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java +++ b/nashorn/src/jdk/nashorn/internal/ir/debug/JSONWriter.java @@ -514,7 +514,7 @@ public final class JSONWriter extends NodeVisitor { type("ArrayExpression"); comma(); - final Node[] value = (Node[])literalNode.getValue(); + final Node[] value = literalNode.getArray(); array("elements", Arrays.asList(value)); } else { type("Literal"); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java index 443a8938a2c..4a5b5986197 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java @@ -64,7 +64,7 @@ public final class NativeArguments extends ScriptObject { private static final PropertyMap map$; static { - PropertyMap map = PropertyMap.newMap(NativeArguments.class); + PropertyMap map = PropertyMap.newMap(); map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH); map = Lookup.newProperty(map, "callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE); map$ = map; diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java index ae2ddb01d8d..df2d17dd054 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java @@ -54,7 +54,7 @@ public final class NativeStrictArguments extends ScriptObject { private static final PropertyMap map$; static { - PropertyMap map = PropertyMap.newMap(NativeStrictArguments.class); + PropertyMap map = PropertyMap.newMap(); map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH); // In strict mode, the caller and callee properties should throw TypeError // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors. diff --git a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java index c4cda933dd5..64af421598f 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java +++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java @@ -52,7 +52,7 @@ public class PrototypeObject extends ScriptObject { private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class); static { - PropertyMap map = PropertyMap.newMap(PrototypeObject.class); + PropertyMap map = PropertyMap.newMap(); map = Lookup.newProperty(map, "constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR); map$ = map; } diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java index 91034c43bdf..921073d4484 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java @@ -149,7 +149,7 @@ public class ScriptFunctionImpl extends ScriptFunction { } static { - PropertyMap map = PropertyMap.newMap(ScriptFunctionImpl.class); + PropertyMap map = PropertyMap.newMap(); map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE); map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null); map = Lookup.newProperty(map, "name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null); @@ -201,7 +201,7 @@ public class ScriptFunctionImpl extends ScriptFunction { // Instance of this class is used as global anonymous function which // serves as Function.prototype object. private static class AnonymousFunction extends ScriptFunctionImpl { - private static final PropertyMap nasgenmap$$ = PropertyMap.newMap(AnonymousFunction.class); + private static final PropertyMap nasgenmap$$ = PropertyMap.newMap(); AnonymousFunction() { super("", GlobalFunctions.ANONYMOUS, nasgenmap$$, null); diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index efd6eda6435..4c6107d570e 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -2009,7 +2009,7 @@ loop: } if (!redefinitionOk) { - throw error(AbstractParser.message("property.redefinition", key.toString()), property.getToken()); + throw error(AbstractParser.message("property.redefinition", key), property.getToken()); } PropertyNode newProperty = existingProperty; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java index 1144eb630bd..6840d458c4e 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java @@ -140,8 +140,8 @@ public class AccessorProperty extends Property { this.primitiveGetter = bindTo(property.primitiveGetter, delegate); this.primitiveSetter = bindTo(property.primitiveSetter, delegate); - this.objectGetter = bindTo(property.objectGetter, delegate); - this.objectSetter = bindTo(property.objectSetter, delegate); + this.objectGetter = bindTo(property.ensureObjectGetter(), delegate); + this.objectSetter = bindTo(property.ensureObjectSetter(), delegate); setCurrentType(property.getCurrentType()); } @@ -331,12 +331,26 @@ public class AccessorProperty extends Property { } } - @Override - public MethodHandle getGetter(final Class type) { + // Spill getters and setters are lazily initialized, see JDK-8011630 + private MethodHandle ensureObjectGetter() { if (isSpill() && objectGetter == null) { objectGetter = getSpillGetter(); } + return objectGetter; + } + + private MethodHandle ensureObjectSetter() { + if (isSpill() && objectSetter == null) { + objectSetter = getSpillSetter(); + } + return objectSetter; + } + + @Override + public MethodHandle getGetter(final Class type) { final int i = getAccessorTypeIndex(type); + ensureObjectGetter(); + if (getters[i] == null) { getters[i] = debug( createGetter(currentType, type, primitiveGetter, objectGetter), @@ -372,9 +386,7 @@ public class AccessorProperty extends Property { } private MethodHandle generateSetter(final Class forType, final Class type) { - if (isSpill() && objectSetter == null) { - objectSetter = getSpillSetter(); - } + ensureObjectSetter(); MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter); mh = debug(mh, currentType, type, "set"); return mh; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java index e03a3ef836e..f8d9b437c07 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java @@ -91,14 +91,16 @@ public final class PropertyMap implements Iterable, PropertyListener { /** * Constructor. * - * @param properties A {@link PropertyHashMap} with initial contents. - * @param fieldCount Number of fields in use. + * @param properties A {@link PropertyHashMap} with initial contents. + * @param fieldCount Number of fields in use. * @param fieldMaximum Number of fields available. + * @param spillLength Number of spill slots used. */ - private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum) { + private PropertyMap(final PropertyHashMap properties, final int fieldCount, final int fieldMaximum, final int spillLength) { this.properties = properties; this.fieldCount = fieldCount; this.fieldMaximum = fieldMaximum; + this.spillLength = spillLength; if (Context.DEBUG) { count++; @@ -111,7 +113,7 @@ public final class PropertyMap implements Iterable, PropertyListener { * @param properties A {@link PropertyHashMap} with initial contents. */ private PropertyMap(final PropertyHashMap properties) { - this(properties, 0, 0); + this(properties, 0, 0, 0); } /** @@ -159,42 +161,23 @@ public final class PropertyMap implements Iterable, PropertyListener { /** * Public property map allocator. * - * @param structure Class the map's {@link AccessorProperty}s apply to. - * @param properties Collection of initial properties. - * @param fieldCount Number of fields in use. + * @param properties Collection of initial properties. + * @param fieldCount Number of fields in use. * @param fieldMaximum Number of fields available. - * + * @param spillLength Number of used spill slots. * @return New {@link PropertyMap}. */ - public static PropertyMap newMap(final Class structure, final Collection properties, final int fieldCount, final int fieldMaximum) { - // Reduce the number of empty maps in the context. - if (structure == JO.class) { - return EMPTY_MAP; - } - + public static PropertyMap newMap(final Collection properties, final int fieldCount, final int fieldMaximum, final int spillLength) { PropertyHashMap newProperties = EMPTY_HASHMAP.immutableAdd(properties); - - return new PropertyMap(newProperties, fieldCount, fieldMaximum); - } - - /** - * Public property map factory allocator - * - * @param structure Class the map's {@link AccessorProperty}s apply to. - * - * @return New {@link PropertyMap}. - */ - public static PropertyMap newMap(final Class structure) { - return newMap(structure, null, 0, 0); + return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength); } /** * Return a sharable empty map. * - * @param context the context * @return New empty {@link PropertyMap}. */ - public static PropertyMap newEmptyMap(final Context context) { + public static PropertyMap newMap() { return new PropertyMap(EMPTY_HASHMAP); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index 4443d2ed1f5..e4eaf77e581 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -170,7 +170,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } this.arrayData = ArrayData.EMPTY_ARRAY; - this.setMap(map == null ? PropertyMap.newMap(getClass()) : map); + this.setMap(map == null ? PropertyMap.newMap() : map); } /** @@ -188,7 +188,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr } this.arrayData = ArrayData.EMPTY_ARRAY; - this.setMap(map == null ? PropertyMap.newMap(getClass()) : map); + this.setMap(map == null ? PropertyMap.newMap() : map); this.proto = proto; if (proto != null) { diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java index b4da66e5ef4..d6173918933 100644 --- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java +++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java @@ -33,7 +33,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; */ public class JO extends ScriptObject { - private static final PropertyMap map$ = PropertyMap.newMap(JO.class); + private static final PropertyMap map$ = PropertyMap.newMap(); /** * Returns the initial property map to be used. diff --git a/nashorn/test/script/basic/JDK-8017084.js b/nashorn/test/script/basic/JDK-8017084.js new file mode 100644 index 00000000000..ceac68ee58c --- /dev/null +++ b/nashorn/test/script/basic/JDK-8017084.js @@ -0,0 +1,17625 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8017084: Use spill properties for large object literals + * + * @test + * @run + */ + +var x = { + a: 1, + b: 2, + c: 3, + d: 4, + e: 5, + f: 6, + g: 7, + h: 8, + i: 9, + j: 10, + k: 11, + l: 12, + m: 13, + n: 14, + o: 15, + p: 16, + q: 17, + r: 18, + s: 19, + t: 20, + u: 21, + v: 22, + w: 23, + x: 24, + y: 25, + az: 26, + aa: 27, + ab: 28, + ac: 29, + ad: 30, + ae: 31, + af: 32, + ag: 33, + ah: 34, + ai: 35, + aj: 36, + ak: 37, + al: 38, + am: 39, + an: 40, + ao: 41, + ap: 42, + aq: 43, + ar: 44, + as: 45, + at: 46, + au: 47, + av: 48, + aw: 49, + ax: 50, + ay: 51, + bz: 52, + ba: 53, + bb: 54, + bc: 55, + bd: 56, + be: 57, + bf: 58, + bg: 59, + bh: 60, + bi: 61, + bj: 62, + bk: 63, + bl: 64, + bm: 65, + bn: 66, + bo: 67, + bp: 68, + bq: 69, + br: 70, + bs: 71, + bt: 72, + bu: 73, + bv: 74, + bw: 75, + bx: 76, + by: 77, + cz: 78, + ca: 79, + cb: 80, + cc: 81, + cd: 82, + ce: 83, + cf: 84, + cg: 85, + ch: 86, + ci: 87, + cj: 88, + ck: 89, + cl: 90, + cm: 91, + cn: 92, + co: 93, + cp: 94, + cq: 95, + cr: 96, + cs: 97, + ct: 98, + cu: 99, + cv: 100, + cw: 101, + cx: 102, + cy: 103, + dz: 104, + da: 105, + db: 106, + dc: 107, + dd: 108, + de: 109, + df: 110, + dg: 111, + dh: 112, + di: 113, + dj: 114, + dk: 115, + dl: 116, + dm: 117, + dn: 118, + do: 119, + dp: 120, + dq: 121, + dr: 122, + ds: 123, + dt: 124, + du: 125, + dv: 126, + dw: 127, + dx: 128, + dy: 129, + ez: 130, + ea: 131, + eb: 132, + ec: 133, + ed: 134, + ee: 135, + ef: 136, + eg: 137, + eh: 138, + ei: 139, + ej: 140, + ek: 141, + el: 142, + em: 143, + en: 144, + eo: 145, + ep: 146, + eq: 147, + er: 148, + es: 149, + et: 150, + eu: 151, + ev: 152, + ew: 153, + ex: 154, + ey: 155, + fz: 156, + fa: 157, + fb: 158, + fc: 159, + fd: 160, + fe: 161, + ff: 162, + fg: 163, + fh: 164, + fi: 165, + fj: 166, + fk: 167, + fl: 168, + fm: 169, + fn: 170, + fo: 171, + fp: 172, + fq: 173, + fr: 174, + fs: 175, + ft: 176, + fu: 177, + fv: 178, + fw: 179, + fx: 180, + fy: 181, + gz: 182, + ga: 183, + gb: 184, + gc: 185, + gd: 186, + ge: 187, + gf: 188, + gg: 189, + gh: 190, + gi: 191, + gj: 192, + gk: 193, + gl: 194, + gm: 195, + gn: 196, + go: 197, + gp: 198, + gq: 199, + gr: 200, + gs: 201, + gt: 202, + gu: 203, + gv: 204, + gw: 205, + gx: 206, + gy: 207, + hz: 208, + ha: 209, + hb: 210, + hc: 211, + hd: 212, + he: 213, + hf: 214, + hg: 215, + hh: 216, + hi: 217, + hj: 218, + hk: 219, + hl: 220, + hm: 221, + hn: 222, + ho: 223, + hp: 224, + hq: 225, + hr: 226, + hs: 227, + ht: 228, + hu: 229, + hv: 230, + hw: 231, + hx: 232, + hy: 233, + iz: 234, + ia: 235, + ib: 236, + ic: 237, + id: 238, + ie: 239, + if: 240, + ig: 241, + ih: 242, + ii: 243, + ij: 244, + ik: 245, + il: 246, + im: 247, + in: 248, + io: 249, + ip: 250, + iq: 251, + ir: 252, + is: 253, + it: 254, + iu: 255, + iv: 256, + iw: 257, + ix: 258, + iy: 259, + jz: 260, + ja: 261, + jb: 262, + jc: 263, + jd: 264, + je: 265, + jf: 266, + jg: 267, + jh: 268, + ji: 269, + jj: 270, + jk: 271, + jl: 272, + jm: 273, + jn: 274, + jo: 275, + jp: 276, + jq: 277, + jr: 278, + js: 279, + jt: 280, + ju: 281, + jv: 282, + jw: 283, + jx: 284, + jy: 285, + kz: 286, + ka: 287, + kb: 288, + kc: 289, + kd: 290, + ke: 291, + kf: 292, + kg: 293, + kh: 294, + ki: 295, + kj: 296, + kk: 297, + kl: 298, + km: 299, + kn: 300, + ko: 301, + kp: 302, + kq: 303, + kr: 304, + ks: 305, + kt: 306, + ku: 307, + kv: 308, + kw: 309, + kx: 310, + ky: 311, + lz: 312, + la: 313, + lb: 314, + lc: 315, + ld: 316, + le: 317, + lf: 318, + lg: 319, + lh: 320, + li: 321, + lj: 322, + lk: 323, + ll: 324, + lm: 325, + ln: 326, + lo: 327, + lp: 328, + lq: 329, + lr: 330, + ls: 331, + lt: 332, + lu: 333, + lv: 334, + lw: 335, + lx: 336, + ly: 337, + mz: 338, + ma: 339, + mb: 340, + mc: 341, + md: 342, + me: 343, + mf: 344, + mg: 345, + mh: 346, + mi: 347, + mj: 348, + mk: 349, + ml: 350, + mm: 351, + mn: 352, + mo: 353, + mp: 354, + mq: 355, + mr: 356, + ms: 357, + mt: 358, + mu: 359, + mv: 360, + mw: 361, + mx: 362, + my: 363, + nz: 364, + na: 365, + nb: 366, + nc: 367, + nd: 368, + ne: 369, + nf: 370, + ng: 371, + nh: 372, + ni: 373, + nj: 374, + nk: 375, + nl: 376, + nm: 377, + nn: 378, + no: 379, + np: 380, + nq: 381, + nr: 382, + ns: 383, + nt: 384, + nu: 385, + nv: 386, + nw: 387, + nx: 388, + ny: 389, + oz: 390, + oa: 391, + ob: 392, + oc: 393, + od: 394, + oe: 395, + of: 396, + og: 397, + oh: 398, + oi: 399, + oj: 400, + ok: 401, + ol: 402, + om: 403, + on: 404, + oo: 405, + op: 406, + oq: 407, + or: 408, + os: 409, + ot: 410, + ou: 411, + ov: 412, + ow: 413, + ox: 414, + oy: 415, + pz: 416, + pa: 417, + pb: 418, + pc: 419, + pd: 420, + pe: 421, + pf: 422, + pg: 423, + ph: 424, + pi: 425, + pj: 426, + pk: 427, + pl: 428, + pm: 429, + pn: 430, + po: 431, + pp: 432, + pq: 433, + pr: 434, + ps: 435, + pt: 436, + pu: 437, + pv: 438, + pw: 439, + px: 440, + py: 441, + qz: 442, + qa: 443, + qb: 444, + qc: 445, + qd: 446, + qe: 447, + qf: 448, + qg: 449, + qh: 450, + qi: 451, + qj: 452, + qk: 453, + ql: 454, + qm: 455, + qn: 456, + qo: 457, + qp: 458, + qq: 459, + qr: 460, + qs: 461, + qt: 462, + qu: 463, + qv: 464, + qw: 465, + qx: 466, + qy: 467, + rz: 468, + ra: 469, + rb: 470, + rc: 471, + rd: 472, + re: 473, + rf: 474, + rg: 475, + rh: 476, + ri: 477, + rj: 478, + rk: 479, + rl: 480, + rm: 481, + rn: 482, + ro: 483, + rp: 484, + rq: 485, + rr: 486, + rs: 487, + rt: 488, + ru: 489, + rv: 490, + rw: 491, + rx: 492, + ry: 493, + sz: 494, + sa: 495, + sb: 496, + sc: 497, + sd: 498, + se: 499, + sf: 500, + sg: 501, + sh: 502, + si: 503, + sj: 504, + sk: 505, + sl: 506, + sm: 507, + sn: 508, + so: 509, + sp: 510, + sq: 511, + sr: 512, + ss: 513, + st: 514, + su: 515, + sv: 516, + sw: 517, + sx: 518, + sy: 519, + tz: 520, + ta: 521, + tb: 522, + tc: 523, + td: 524, + te: 525, + tf: 526, + tg: 527, + th: 528, + ti: 529, + tj: 530, + tk: 531, + tl: 532, + tm: 533, + tn: 534, + to: 535, + tp: 536, + tq: 537, + tr: 538, + ts: 539, + tt: 540, + tu: 541, + tv: 542, + tw: 543, + tx: 544, + ty: 545, + uz: 546, + ua: 547, + ub: 548, + uc: 549, + ud: 550, + ue: 551, + uf: 552, + ug: 553, + uh: 554, + ui: 555, + uj: 556, + uk: 557, + ul: 558, + um: 559, + un: 560, + uo: 561, + up: 562, + uq: 563, + ur: 564, + us: 565, + ut: 566, + uu: 567, + uv: 568, + uw: 569, + ux: 570, + uy: 571, + vz: 572, + va: 573, + vb: 574, + vc: 575, + vd: 576, + ve: 577, + vf: 578, + vg: 579, + vh: 580, + vi: 581, + vj: 582, + vk: 583, + vl: 584, + vm: 585, + vn: 586, + vo: 587, + vp: 588, + vq: 589, + vr: 590, + vs: 591, + vt: 592, + vu: 593, + vv: 594, + vw: 595, + vx: 596, + vy: 597, + wz: 598, + wa: 599, + wb: 600, + wc: 601, + wd: 602, + we: 603, + wf: 604, + wg: 605, + wh: 606, + wi: 607, + wj: 608, + wk: 609, + wl: 610, + wm: 611, + wn: 612, + wo: 613, + wp: 614, + wq: 615, + wr: 616, + ws: 617, + wt: 618, + wu: 619, + wv: 620, + ww: 621, + wx: 622, + wy: 623, + xz: 624, + xa: 625, + xb: 626, + xc: 627, + xd: 628, + xe: 629, + xf: 630, + xg: 631, + xh: 632, + xi: 633, + xj: 634, + xk: 635, + xl: 636, + xm: 637, + xn: 638, + xo: 639, + xp: 640, + xq: 641, + xr: 642, + xs: 643, + xt: 644, + xu: 645, + xv: 646, + xw: 647, + xx: 648, + xy: 649, + yz: 650, + ya: 651, + yb: 652, + yc: 653, + yd: 654, + ye: 655, + yf: 656, + yg: 657, + yh: 658, + yi: 659, + yj: 660, + yk: 661, + yl: 662, + ym: 663, + yn: 664, + yo: 665, + yp: 666, + yq: 667, + yr: 668, + ys: 669, + yt: 670, + yu: 671, + yv: 672, + yw: 673, + yx: 674, + yy: 675, + azz: 676, + aza: 677, + azb: 678, + azc: 679, + azd: 680, + aze: 681, + azf: 682, + azg: 683, + azh: 684, + azi: 685, + azj: 686, + azk: 687, + azl: 688, + azm: 689, + azn: 690, + azo: 691, + azp: 692, + azq: 693, + azr: 694, + azs: 695, + azt: 696, + azu: 697, + azv: 698, + azw: 699, + azx: 700, + azy: 701, + aaz: 702, + aaa: 703, + aab: 704, + aac: 705, + aad: 706, + aae: 707, + aaf: 708, + aag: 709, + aah: 710, + aai: 711, + aaj: 712, + aak: 713, + aal: 714, + aam: 715, + aan: 716, + aao: 717, + aap: 718, + aaq: 719, + aar: 720, + aas: 721, + aat: 722, + aau: 723, + aav: 724, + aaw: 725, + aax: 726, + aay: 727, + abz: 728, + aba: 729, + abb: 730, + abc: 731, + abd: 732, + abe: 733, + abf: 734, + abg: 735, + abh: 736, + abi: 737, + abj: 738, + abk: 739, + abl: 740, + abm: 741, + abn: 742, + abo: 743, + abp: 744, + abq: 745, + abr: 746, + abs: 747, + abt: 748, + abu: 749, + abv: 750, + abw: 751, + abx: 752, + aby: 753, + acz: 754, + aca: 755, + acb: 756, + acc: 757, + acd: 758, + ace: 759, + acf: 760, + acg: 761, + ach: 762, + aci: 763, + acj: 764, + ack: 765, + acl: 766, + acm: 767, + acn: 768, + aco: 769, + acp: 770, + acq: 771, + acr: 772, + acs: 773, + act: 774, + acu: 775, + acv: 776, + acw: 777, + acx: 778, + acy: 779, + adz: 780, + ada: 781, + adb: 782, + adc: 783, + add: 784, + ade: 785, + adf: 786, + adg: 787, + adh: 788, + adi: 789, + adj: 790, + adk: 791, + adl: 792, + adm: 793, + adn: 794, + ado: 795, + adp: 796, + adq: 797, + adr: 798, + ads: 799, + adt: 800, + adu: 801, + adv: 802, + adw: 803, + adx: 804, + ady: 805, + aez: 806, + aea: 807, + aeb: 808, + aec: 809, + aed: 810, + aee: 811, + aef: 812, + aeg: 813, + aeh: 814, + aei: 815, + aej: 816, + aek: 817, + ael: 818, + aem: 819, + aen: 820, + aeo: 821, + aep: 822, + aeq: 823, + aer: 824, + aes: 825, + aet: 826, + aeu: 827, + aev: 828, + aew: 829, + aex: 830, + aey: 831, + afz: 832, + afa: 833, + afb: 834, + afc: 835, + afd: 836, + afe: 837, + aff: 838, + afg: 839, + afh: 840, + afi: 841, + afj: 842, + afk: 843, + afl: 844, + afm: 845, + afn: 846, + afo: 847, + afp: 848, + afq: 849, + afr: 850, + afs: 851, + aft: 852, + afu: 853, + afv: 854, + afw: 855, + afx: 856, + afy: 857, + agz: 858, + aga: 859, + agb: 860, + agc: 861, + agd: 862, + age: 863, + agf: 864, + agg: 865, + agh: 866, + agi: 867, + agj: 868, + agk: 869, + agl: 870, + agm: 871, + agn: 872, + ago: 873, + agp: 874, + agq: 875, + agr: 876, + ags: 877, + agt: 878, + agu: 879, + agv: 880, + agw: 881, + agx: 882, + agy: 883, + ahz: 884, + aha: 885, + ahb: 886, + ahc: 887, + ahd: 888, + ahe: 889, + ahf: 890, + ahg: 891, + ahh: 892, + ahi: 893, + ahj: 894, + ahk: 895, + ahl: 896, + ahm: 897, + ahn: 898, + aho: 899, + ahp: 900, + ahq: 901, + ahr: 902, + ahs: 903, + aht: 904, + ahu: 905, + ahv: 906, + ahw: 907, + ahx: 908, + ahy: 909, + aiz: 910, + aia: 911, + aib: 912, + aic: 913, + aid: 914, + aie: 915, + aif: 916, + aig: 917, + aih: 918, + aii: 919, + aij: 920, + aik: 921, + ail: 922, + aim: 923, + ain: 924, + aio: 925, + aip: 926, + aiq: 927, + air: 928, + ais: 929, + ait: 930, + aiu: 931, + aiv: 932, + aiw: 933, + aix: 934, + aiy: 935, + ajz: 936, + aja: 937, + ajb: 938, + ajc: 939, + ajd: 940, + aje: 941, + ajf: 942, + ajg: 943, + ajh: 944, + aji: 945, + ajj: 946, + ajk: 947, + ajl: 948, + ajm: 949, + ajn: 950, + ajo: 951, + ajp: 952, + ajq: 953, + ajr: 954, + ajs: 955, + ajt: 956, + aju: 957, + ajv: 958, + ajw: 959, + ajx: 960, + ajy: 961, + akz: 962, + aka: 963, + akb: 964, + akc: 965, + akd: 966, + ake: 967, + akf: 968, + akg: 969, + akh: 970, + aki: 971, + akj: 972, + akk: 973, + akl: 974, + akm: 975, + akn: 976, + ako: 977, + akp: 978, + akq: 979, + akr: 980, + aks: 981, + akt: 982, + aku: 983, + akv: 984, + akw: 985, + akx: 986, + aky: 987, + alz: 988, + ala: 989, + alb: 990, + alc: 991, + ald: 992, + ale: 993, + alf: 994, + alg: 995, + alh: 996, + ali: 997, + alj: 998, + alk: 999, + all: 1000, + alm: 1001, + aln: 1002, + alo: 1003, + alp: 1004, + alq: 1005, + alr: 1006, + als: 1007, + alt: 1008, + alu: 1009, + alv: 1010, + alw: 1011, + alx: 1012, + aly: 1013, + amz: 1014, + ama: 1015, + amb: 1016, + amc: 1017, + amd: 1018, + ame: 1019, + amf: 1020, + amg: 1021, + amh: 1022, + ami: 1023, + amj: 1024, + amk: 1025, + aml: 1026, + amm: 1027, + amn: 1028, + amo: 1029, + amp: 1030, + amq: 1031, + amr: 1032, + ams: 1033, + amt: 1034, + amu: 1035, + amv: 1036, + amw: 1037, + amx: 1038, + amy: 1039, + anz: 1040, + ana: 1041, + anb: 1042, + anc: 1043, + and: 1044, + ane: 1045, + anf: 1046, + ang: 1047, + anh: 1048, + ani: 1049, + anj: 1050, + ank: 1051, + anl: 1052, + anm: 1053, + ann: 1054, + ano: 1055, + anp: 1056, + anq: 1057, + anr: 1058, + ans: 1059, + ant: 1060, + anu: 1061, + anv: 1062, + anw: 1063, + anx: 1064, + any: 1065, + aoz: 1066, + aoa: 1067, + aob: 1068, + aoc: 1069, + aod: 1070, + aoe: 1071, + aof: 1072, + aog: 1073, + aoh: 1074, + aoi: 1075, + aoj: 1076, + aok: 1077, + aol: 1078, + aom: 1079, + aon: 1080, + aoo: 1081, + aop: 1082, + aoq: 1083, + aor: 1084, + aos: 1085, + aot: 1086, + aou: 1087, + aov: 1088, + aow: 1089, + aox: 1090, + aoy: 1091, + apz: 1092, + apa: 1093, + apb: 1094, + apc: 1095, + apd: 1096, + ape: 1097, + apf: 1098, + apg: 1099, + aph: 1100, + api: 1101, + apj: 1102, + apk: 1103, + apl: 1104, + apm: 1105, + apn: 1106, + apo: 1107, + app: 1108, + apq: 1109, + apr: 1110, + aps: 1111, + apt: 1112, + apu: 1113, + apv: 1114, + apw: 1115, + apx: 1116, + apy: 1117, + aqz: 1118, + aqa: 1119, + aqb: 1120, + aqc: 1121, + aqd: 1122, + aqe: 1123, + aqf: 1124, + aqg: 1125, + aqh: 1126, + aqi: 1127, + aqj: 1128, + aqk: 1129, + aql: 1130, + aqm: 1131, + aqn: 1132, + aqo: 1133, + aqp: 1134, + aqq: 1135, + aqr: 1136, + aqs: 1137, + aqt: 1138, + aqu: 1139, + aqv: 1140, + aqw: 1141, + aqx: 1142, + aqy: 1143, + arz: 1144, + ara: 1145, + arb: 1146, + arc: 1147, + ard: 1148, + are: 1149, + arf: 1150, + arg: 1151, + arh: 1152, + ari: 1153, + arj: 1154, + ark: 1155, + arl: 1156, + arm: 1157, + arn: 1158, + aro: 1159, + arp: 1160, + arq: 1161, + arr: 1162, + ars: 1163, + art: 1164, + aru: 1165, + arv: 1166, + arw: 1167, + arx: 1168, + ary: 1169, + asz: 1170, + asa: 1171, + asb: 1172, + asc: 1173, + asd: 1174, + ase: 1175, + asf: 1176, + asg: 1177, + ash: 1178, + asi: 1179, + asj: 1180, + ask: 1181, + asl: 1182, + asm: 1183, + asn: 1184, + aso: 1185, + asp: 1186, + asq: 1187, + asr: 1188, + ass: 1189, + ast: 1190, + asu: 1191, + asv: 1192, + asw: 1193, + asx: 1194, + asy: 1195, + atz: 1196, + ata: 1197, + atb: 1198, + atc: 1199, + atd: 1200, + ate: 1201, + atf: 1202, + atg: 1203, + ath: 1204, + ati: 1205, + atj: 1206, + atk: 1207, + atl: 1208, + atm: 1209, + atn: 1210, + ato: 1211, + atp: 1212, + atq: 1213, + atr: 1214, + ats: 1215, + att: 1216, + atu: 1217, + atv: 1218, + atw: 1219, + atx: 1220, + aty: 1221, + auz: 1222, + aua: 1223, + aub: 1224, + auc: 1225, + aud: 1226, + aue: 1227, + auf: 1228, + aug: 1229, + auh: 1230, + aui: 1231, + auj: 1232, + auk: 1233, + aul: 1234, + aum: 1235, + aun: 1236, + auo: 1237, + aup: 1238, + auq: 1239, + aur: 1240, + aus: 1241, + aut: 1242, + auu: 1243, + auv: 1244, + auw: 1245, + aux: 1246, + auy: 1247, + avz: 1248, + ava: 1249, + avb: 1250, + avc: 1251, + avd: 1252, + ave: 1253, + avf: 1254, + avg: 1255, + avh: 1256, + avi: 1257, + avj: 1258, + avk: 1259, + avl: 1260, + avm: 1261, + avn: 1262, + avo: 1263, + avp: 1264, + avq: 1265, + avr: 1266, + avs: 1267, + avt: 1268, + avu: 1269, + avv: 1270, + avw: 1271, + avx: 1272, + avy: 1273, + awz: 1274, + awa: 1275, + awb: 1276, + awc: 1277, + awd: 1278, + awe: 1279, + awf: 1280, + awg: 1281, + awh: 1282, + awi: 1283, + awj: 1284, + awk: 1285, + awl: 1286, + awm: 1287, + awn: 1288, + awo: 1289, + awp: 1290, + awq: 1291, + awr: 1292, + aws: 1293, + awt: 1294, + awu: 1295, + awv: 1296, + aww: 1297, + awx: 1298, + awy: 1299, + axz: 1300, + axa: 1301, + axb: 1302, + axc: 1303, + axd: 1304, + axe: 1305, + axf: 1306, + axg: 1307, + axh: 1308, + axi: 1309, + axj: 1310, + axk: 1311, + axl: 1312, + axm: 1313, + axn: 1314, + axo: 1315, + axp: 1316, + axq: 1317, + axr: 1318, + axs: 1319, + axt: 1320, + axu: 1321, + axv: 1322, + axw: 1323, + axx: 1324, + axy: 1325, + ayz: 1326, + aya: 1327, + ayb: 1328, + ayc: 1329, + ayd: 1330, + aye: 1331, + ayf: 1332, + ayg: 1333, + ayh: 1334, + ayi: 1335, + ayj: 1336, + ayk: 1337, + ayl: 1338, + aym: 1339, + ayn: 1340, + ayo: 1341, + ayp: 1342, + ayq: 1343, + ayr: 1344, + ays: 1345, + ayt: 1346, + ayu: 1347, + ayv: 1348, + ayw: 1349, + ayx: 1350, + ayy: 1351, + bzz: 1352, + bza: 1353, + bzb: 1354, + bzc: 1355, + bzd: 1356, + bze: 1357, + bzf: 1358, + bzg: 1359, + bzh: 1360, + bzi: 1361, + bzj: 1362, + bzk: 1363, + bzl: 1364, + bzm: 1365, + bzn: 1366, + bzo: 1367, + bzp: 1368, + bzq: 1369, + bzr: 1370, + bzs: 1371, + bzt: 1372, + bzu: 1373, + bzv: 1374, + bzw: 1375, + bzx: 1376, + bzy: 1377, + baz: 1378, + baa: 1379, + bab: 1380, + bac: 1381, + bad: 1382, + bae: 1383, + baf: 1384, + bag: 1385, + bah: 1386, + bai: 1387, + baj: 1388, + bak: 1389, + bal: 1390, + bam: 1391, + ban: 1392, + bao: 1393, + bap: 1394, + baq: 1395, + bar: 1396, + bas: 1397, + bat: 1398, + bau: 1399, + bav: 1400, + baw: 1401, + bax: 1402, + bay: 1403, + bbz: 1404, + bba: 1405, + bbb: 1406, + bbc: 1407, + bbd: 1408, + bbe: 1409, + bbf: 1410, + bbg: 1411, + bbh: 1412, + bbi: 1413, + bbj: 1414, + bbk: 1415, + bbl: 1416, + bbm: 1417, + bbn: 1418, + bbo: 1419, + bbp: 1420, + bbq: 1421, + bbr: 1422, + bbs: 1423, + bbt: 1424, + bbu: 1425, + bbv: 1426, + bbw: 1427, + bbx: 1428, + bby: 1429, + bcz: 1430, + bca: 1431, + bcb: 1432, + bcc: 1433, + bcd: 1434, + bce: 1435, + bcf: 1436, + bcg: 1437, + bch: 1438, + bci: 1439, + bcj: 1440, + bck: 1441, + bcl: 1442, + bcm: 1443, + bcn: 1444, + bco: 1445, + bcp: 1446, + bcq: 1447, + bcr: 1448, + bcs: 1449, + bct: 1450, + bcu: 1451, + bcv: 1452, + bcw: 1453, + bcx: 1454, + bcy: 1455, + bdz: 1456, + bda: 1457, + bdb: 1458, + bdc: 1459, + bdd: 1460, + bde: 1461, + bdf: 1462, + bdg: 1463, + bdh: 1464, + bdi: 1465, + bdj: 1466, + bdk: 1467, + bdl: 1468, + bdm: 1469, + bdn: 1470, + bdo: 1471, + bdp: 1472, + bdq: 1473, + bdr: 1474, + bds: 1475, + bdt: 1476, + bdu: 1477, + bdv: 1478, + bdw: 1479, + bdx: 1480, + bdy: 1481, + bez: 1482, + bea: 1483, + beb: 1484, + bec: 1485, + bed: 1486, + bee: 1487, + bef: 1488, + beg: 1489, + beh: 1490, + bei: 1491, + bej: 1492, + bek: 1493, + bel: 1494, + bem: 1495, + ben: 1496, + beo: 1497, + bep: 1498, + beq: 1499, + ber: 1500, + bes: 1501, + bet: 1502, + beu: 1503, + bev: 1504, + bew: 1505, + bex: 1506, + bey: 1507, + bfz: 1508, + bfa: 1509, + bfb: 1510, + bfc: 1511, + bfd: 1512, + bfe: 1513, + bff: 1514, + bfg: 1515, + bfh: 1516, + bfi: 1517, + bfj: 1518, + bfk: 1519, + bfl: 1520, + bfm: 1521, + bfn: 1522, + bfo: 1523, + bfp: 1524, + bfq: 1525, + bfr: 1526, + bfs: 1527, + bft: 1528, + bfu: 1529, + bfv: 1530, + bfw: 1531, + bfx: 1532, + bfy: 1533, + bgz: 1534, + bga: 1535, + bgb: 1536, + bgc: 1537, + bgd: 1538, + bge: 1539, + bgf: 1540, + bgg: 1541, + bgh: 1542, + bgi: 1543, + bgj: 1544, + bgk: 1545, + bgl: 1546, + bgm: 1547, + bgn: 1548, + bgo: 1549, + bgp: 1550, + bgq: 1551, + bgr: 1552, + bgs: 1553, + bgt: 1554, + bgu: 1555, + bgv: 1556, + bgw: 1557, + bgx: 1558, + bgy: 1559, + bhz: 1560, + bha: 1561, + bhb: 1562, + bhc: 1563, + bhd: 1564, + bhe: 1565, + bhf: 1566, + bhg: 1567, + bhh: 1568, + bhi: 1569, + bhj: 1570, + bhk: 1571, + bhl: 1572, + bhm: 1573, + bhn: 1574, + bho: 1575, + bhp: 1576, + bhq: 1577, + bhr: 1578, + bhs: 1579, + bht: 1580, + bhu: 1581, + bhv: 1582, + bhw: 1583, + bhx: 1584, + bhy: 1585, + biz: 1586, + bia: 1587, + bib: 1588, + bic: 1589, + bid: 1590, + bie: 1591, + bif: 1592, + big: 1593, + bih: 1594, + bii: 1595, + bij: 1596, + bik: 1597, + bil: 1598, + bim: 1599, + bin: 1600, + bio: 1601, + bip: 1602, + biq: 1603, + bir: 1604, + bis: 1605, + bit: 1606, + biu: 1607, + biv: 1608, + biw: 1609, + bix: 1610, + biy: 1611, + bjz: 1612, + bja: 1613, + bjb: 1614, + bjc: 1615, + bjd: 1616, + bje: 1617, + bjf: 1618, + bjg: 1619, + bjh: 1620, + bji: 1621, + bjj: 1622, + bjk: 1623, + bjl: 1624, + bjm: 1625, + bjn: 1626, + bjo: 1627, + bjp: 1628, + bjq: 1629, + bjr: 1630, + bjs: 1631, + bjt: 1632, + bju: 1633, + bjv: 1634, + bjw: 1635, + bjx: 1636, + bjy: 1637, + bkz: 1638, + bka: 1639, + bkb: 1640, + bkc: 1641, + bkd: 1642, + bke: 1643, + bkf: 1644, + bkg: 1645, + bkh: 1646, + bki: 1647, + bkj: 1648, + bkk: 1649, + bkl: 1650, + bkm: 1651, + bkn: 1652, + bko: 1653, + bkp: 1654, + bkq: 1655, + bkr: 1656, + bks: 1657, + bkt: 1658, + bku: 1659, + bkv: 1660, + bkw: 1661, + bkx: 1662, + bky: 1663, + blz: 1664, + bla: 1665, + blb: 1666, + blc: 1667, + bld: 1668, + ble: 1669, + blf: 1670, + blg: 1671, + blh: 1672, + bli: 1673, + blj: 1674, + blk: 1675, + bll: 1676, + blm: 1677, + bln: 1678, + blo: 1679, + blp: 1680, + blq: 1681, + blr: 1682, + bls: 1683, + blt: 1684, + blu: 1685, + blv: 1686, + blw: 1687, + blx: 1688, + bly: 1689, + bmz: 1690, + bma: 1691, + bmb: 1692, + bmc: 1693, + bmd: 1694, + bme: 1695, + bmf: 1696, + bmg: 1697, + bmh: 1698, + bmi: 1699, + bmj: 1700, + bmk: 1701, + bml: 1702, + bmm: 1703, + bmn: 1704, + bmo: 1705, + bmp: 1706, + bmq: 1707, + bmr: 1708, + bms: 1709, + bmt: 1710, + bmu: 1711, + bmv: 1712, + bmw: 1713, + bmx: 1714, + bmy: 1715, + bnz: 1716, + bna: 1717, + bnb: 1718, + bnc: 1719, + bnd: 1720, + bne: 1721, + bnf: 1722, + bng: 1723, + bnh: 1724, + bni: 1725, + bnj: 1726, + bnk: 1727, + bnl: 1728, + bnm: 1729, + bnn: 1730, + bno: 1731, + bnp: 1732, + bnq: 1733, + bnr: 1734, + bns: 1735, + bnt: 1736, + bnu: 1737, + bnv: 1738, + bnw: 1739, + bnx: 1740, + bny: 1741, + boz: 1742, + boa: 1743, + bob: 1744, + boc: 1745, + bod: 1746, + boe: 1747, + bof: 1748, + bog: 1749, + boh: 1750, + boi: 1751, + boj: 1752, + bok: 1753, + bol: 1754, + bom: 1755, + bon: 1756, + boo: 1757, + bop: 1758, + boq: 1759, + bor: 1760, + bos: 1761, + bot: 1762, + bou: 1763, + bov: 1764, + bow: 1765, + box: 1766, + boy: 1767, + bpz: 1768, + bpa: 1769, + bpb: 1770, + bpc: 1771, + bpd: 1772, + bpe: 1773, + bpf: 1774, + bpg: 1775, + bph: 1776, + bpi: 1777, + bpj: 1778, + bpk: 1779, + bpl: 1780, + bpm: 1781, + bpn: 1782, + bpo: 1783, + bpp: 1784, + bpq: 1785, + bpr: 1786, + bps: 1787, + bpt: 1788, + bpu: 1789, + bpv: 1790, + bpw: 1791, + bpx: 1792, + bpy: 1793, + bqz: 1794, + bqa: 1795, + bqb: 1796, + bqc: 1797, + bqd: 1798, + bqe: 1799, + bqf: 1800, + bqg: 1801, + bqh: 1802, + bqi: 1803, + bqj: 1804, + bqk: 1805, + bql: 1806, + bqm: 1807, + bqn: 1808, + bqo: 1809, + bqp: 1810, + bqq: 1811, + bqr: 1812, + bqs: 1813, + bqt: 1814, + bqu: 1815, + bqv: 1816, + bqw: 1817, + bqx: 1818, + bqy: 1819, + brz: 1820, + bra: 1821, + brb: 1822, + brc: 1823, + brd: 1824, + bre: 1825, + brf: 1826, + brg: 1827, + brh: 1828, + bri: 1829, + brj: 1830, + brk: 1831, + brl: 1832, + brm: 1833, + brn: 1834, + bro: 1835, + brp: 1836, + brq: 1837, + brr: 1838, + brs: 1839, + brt: 1840, + bru: 1841, + brv: 1842, + brw: 1843, + brx: 1844, + bry: 1845, + bsz: 1846, + bsa: 1847, + bsb: 1848, + bsc: 1849, + bsd: 1850, + bse: 1851, + bsf: 1852, + bsg: 1853, + bsh: 1854, + bsi: 1855, + bsj: 1856, + bsk: 1857, + bsl: 1858, + bsm: 1859, + bsn: 1860, + bso: 1861, + bsp: 1862, + bsq: 1863, + bsr: 1864, + bss: 1865, + bst: 1866, + bsu: 1867, + bsv: 1868, + bsw: 1869, + bsx: 1870, + bsy: 1871, + btz: 1872, + bta: 1873, + btb: 1874, + btc: 1875, + btd: 1876, + bte: 1877, + btf: 1878, + btg: 1879, + bth: 1880, + bti: 1881, + btj: 1882, + btk: 1883, + btl: 1884, + btm: 1885, + btn: 1886, + bto: 1887, + btp: 1888, + btq: 1889, + btr: 1890, + bts: 1891, + btt: 1892, + btu: 1893, + btv: 1894, + btw: 1895, + btx: 1896, + bty: 1897, + buz: 1898, + bua: 1899, + bub: 1900, + buc: 1901, + bud: 1902, + bue: 1903, + buf: 1904, + bug: 1905, + buh: 1906, + bui: 1907, + buj: 1908, + buk: 1909, + bul: 1910, + bum: 1911, + bun: 1912, + buo: 1913, + bup: 1914, + buq: 1915, + bur: 1916, + bus: 1917, + but: 1918, + buu: 1919, + buv: 1920, + buw: 1921, + bux: 1922, + buy: 1923, + bvz: 1924, + bva: 1925, + bvb: 1926, + bvc: 1927, + bvd: 1928, + bve: 1929, + bvf: 1930, + bvg: 1931, + bvh: 1932, + bvi: 1933, + bvj: 1934, + bvk: 1935, + bvl: 1936, + bvm: 1937, + bvn: 1938, + bvo: 1939, + bvp: 1940, + bvq: 1941, + bvr: 1942, + bvs: 1943, + bvt: 1944, + bvu: 1945, + bvv: 1946, + bvw: 1947, + bvx: 1948, + bvy: 1949, + bwz: 1950, + bwa: 1951, + bwb: 1952, + bwc: 1953, + bwd: 1954, + bwe: 1955, + bwf: 1956, + bwg: 1957, + bwh: 1958, + bwi: 1959, + bwj: 1960, + bwk: 1961, + bwl: 1962, + bwm: 1963, + bwn: 1964, + bwo: 1965, + bwp: 1966, + bwq: 1967, + bwr: 1968, + bws: 1969, + bwt: 1970, + bwu: 1971, + bwv: 1972, + bww: 1973, + bwx: 1974, + bwy: 1975, + bxz: 1976, + bxa: 1977, + bxb: 1978, + bxc: 1979, + bxd: 1980, + bxe: 1981, + bxf: 1982, + bxg: 1983, + bxh: 1984, + bxi: 1985, + bxj: 1986, + bxk: 1987, + bxl: 1988, + bxm: 1989, + bxn: 1990, + bxo: 1991, + bxp: 1992, + bxq: 1993, + bxr: 1994, + bxs: 1995, + bxt: 1996, + bxu: 1997, + bxv: 1998, + bxw: 1999, + bxx: 2000, + bxy: 2001, + byz: 2002, + bya: 2003, + byb: 2004, + byc: 2005, + byd: 2006, + bye: 2007, + byf: 2008, + byg: 2009, + byh: 2010, + byi: 2011, + byj: 2012, + byk: 2013, + byl: 2014, + bym: 2015, + byn: 2016, + byo: 2017, + byp: 2018, + byq: 2019, + byr: 2020, + bys: 2021, + byt: 2022, + byu: 2023, + byv: 2024, + byw: 2025, + byx: 2026, + byy: 2027, + czz: 2028, + cza: 2029, + czb: 2030, + czc: 2031, + czd: 2032, + cze: 2033, + czf: 2034, + czg: 2035, + czh: 2036, + czi: 2037, + czj: 2038, + czk: 2039, + czl: 2040, + czm: 2041, + czn: 2042, + czo: 2043, + czp: 2044, + czq: 2045, + czr: 2046, + czs: 2047, + czt: 2048, + czu: 2049, + czv: 2050, + czw: 2051, + czx: 2052, + czy: 2053, + caz: 2054, + caa: 2055, + cab: 2056, + cac: 2057, + cad: 2058, + cae: 2059, + caf: 2060, + cag: 2061, + cah: 2062, + cai: 2063, + caj: 2064, + cak: 2065, + cal: 2066, + cam: 2067, + can: 2068, + cao: 2069, + cap: 2070, + caq: 2071, + car: 2072, + cas: 2073, + cat: 2074, + cau: 2075, + cav: 2076, + caw: 2077, + cax: 2078, + cay: 2079, + cbz: 2080, + cba: 2081, + cbb: 2082, + cbc: 2083, + cbd: 2084, + cbe: 2085, + cbf: 2086, + cbg: 2087, + cbh: 2088, + cbi: 2089, + cbj: 2090, + cbk: 2091, + cbl: 2092, + cbm: 2093, + cbn: 2094, + cbo: 2095, + cbp: 2096, + cbq: 2097, + cbr: 2098, + cbs: 2099, + cbt: 2100, + cbu: 2101, + cbv: 2102, + cbw: 2103, + cbx: 2104, + cby: 2105, + ccz: 2106, + cca: 2107, + ccb: 2108, + ccc: 2109, + ccd: 2110, + cce: 2111, + ccf: 2112, + ccg: 2113, + cch: 2114, + cci: 2115, + ccj: 2116, + cck: 2117, + ccl: 2118, + ccm: 2119, + ccn: 2120, + cco: 2121, + ccp: 2122, + ccq: 2123, + ccr: 2124, + ccs: 2125, + cct: 2126, + ccu: 2127, + ccv: 2128, + ccw: 2129, + ccx: 2130, + ccy: 2131, + cdz: 2132, + cda: 2133, + cdb: 2134, + cdc: 2135, + cdd: 2136, + cde: 2137, + cdf: 2138, + cdg: 2139, + cdh: 2140, + cdi: 2141, + cdj: 2142, + cdk: 2143, + cdl: 2144, + cdm: 2145, + cdn: 2146, + cdo: 2147, + cdp: 2148, + cdq: 2149, + cdr: 2150, + cds: 2151, + cdt: 2152, + cdu: 2153, + cdv: 2154, + cdw: 2155, + cdx: 2156, + cdy: 2157, + cez: 2158, + cea: 2159, + ceb: 2160, + cec: 2161, + ced: 2162, + cee: 2163, + cef: 2164, + ceg: 2165, + ceh: 2166, + cei: 2167, + cej: 2168, + cek: 2169, + cel: 2170, + cem: 2171, + cen: 2172, + ceo: 2173, + cep: 2174, + ceq: 2175, + cer: 2176, + ces: 2177, + cet: 2178, + ceu: 2179, + cev: 2180, + cew: 2181, + cex: 2182, + cey: 2183, + cfz: 2184, + cfa: 2185, + cfb: 2186, + cfc: 2187, + cfd: 2188, + cfe: 2189, + cff: 2190, + cfg: 2191, + cfh: 2192, + cfi: 2193, + cfj: 2194, + cfk: 2195, + cfl: 2196, + cfm: 2197, + cfn: 2198, + cfo: 2199, + cfp: 2200, + cfq: 2201, + cfr: 2202, + cfs: 2203, + cft: 2204, + cfu: 2205, + cfv: 2206, + cfw: 2207, + cfx: 2208, + cfy: 2209, + cgz: 2210, + cga: 2211, + cgb: 2212, + cgc: 2213, + cgd: 2214, + cge: 2215, + cgf: 2216, + cgg: 2217, + cgh: 2218, + cgi: 2219, + cgj: 2220, + cgk: 2221, + cgl: 2222, + cgm: 2223, + cgn: 2224, + cgo: 2225, + cgp: 2226, + cgq: 2227, + cgr: 2228, + cgs: 2229, + cgt: 2230, + cgu: 2231, + cgv: 2232, + cgw: 2233, + cgx: 2234, + cgy: 2235, + chz: 2236, + cha: 2237, + chb: 2238, + chc: 2239, + chd: 2240, + che: 2241, + chf: 2242, + chg: 2243, + chh: 2244, + chi: 2245, + chj: 2246, + chk: 2247, + chl: 2248, + chm: 2249, + chn: 2250, + cho: 2251, + chp: 2252, + chq: 2253, + chr: 2254, + chs: 2255, + cht: 2256, + chu: 2257, + chv: 2258, + chw: 2259, + chx: 2260, + chy: 2261, + ciz: 2262, + cia: 2263, + cib: 2264, + cic: 2265, + cid: 2266, + cie: 2267, + cif: 2268, + cig: 2269, + cih: 2270, + cii: 2271, + cij: 2272, + cik: 2273, + cil: 2274, + cim: 2275, + cin: 2276, + cio: 2277, + cip: 2278, + ciq: 2279, + cir: 2280, + cis: 2281, + cit: 2282, + ciu: 2283, + civ: 2284, + ciw: 2285, + cix: 2286, + ciy: 2287, + cjz: 2288, + cja: 2289, + cjb: 2290, + cjc: 2291, + cjd: 2292, + cje: 2293, + cjf: 2294, + cjg: 2295, + cjh: 2296, + cji: 2297, + cjj: 2298, + cjk: 2299, + cjl: 2300, + cjm: 2301, + cjn: 2302, + cjo: 2303, + cjp: 2304, + cjq: 2305, + cjr: 2306, + cjs: 2307, + cjt: 2308, + cju: 2309, + cjv: 2310, + cjw: 2311, + cjx: 2312, + cjy: 2313, + ckz: 2314, + cka: 2315, + ckb: 2316, + ckc: 2317, + ckd: 2318, + cke: 2319, + ckf: 2320, + ckg: 2321, + ckh: 2322, + cki: 2323, + ckj: 2324, + ckk: 2325, + ckl: 2326, + ckm: 2327, + ckn: 2328, + cko: 2329, + ckp: 2330, + ckq: 2331, + ckr: 2332, + cks: 2333, + ckt: 2334, + cku: 2335, + ckv: 2336, + ckw: 2337, + ckx: 2338, + cky: 2339, + clz: 2340, + cla: 2341, + clb: 2342, + clc: 2343, + cld: 2344, + cle: 2345, + clf: 2346, + clg: 2347, + clh: 2348, + cli: 2349, + clj: 2350, + clk: 2351, + cll: 2352, + clm: 2353, + cln: 2354, + clo: 2355, + clp: 2356, + clq: 2357, + clr: 2358, + cls: 2359, + clt: 2360, + clu: 2361, + clv: 2362, + clw: 2363, + clx: 2364, + cly: 2365, + cmz: 2366, + cma: 2367, + cmb: 2368, + cmc: 2369, + cmd: 2370, + cme: 2371, + cmf: 2372, + cmg: 2373, + cmh: 2374, + cmi: 2375, + cmj: 2376, + cmk: 2377, + cml: 2378, + cmm: 2379, + cmn: 2380, + cmo: 2381, + cmp: 2382, + cmq: 2383, + cmr: 2384, + cms: 2385, + cmt: 2386, + cmu: 2387, + cmv: 2388, + cmw: 2389, + cmx: 2390, + cmy: 2391, + cnz: 2392, + cna: 2393, + cnb: 2394, + cnc: 2395, + cnd: 2396, + cne: 2397, + cnf: 2398, + cng: 2399, + cnh: 2400, + cni: 2401, + cnj: 2402, + cnk: 2403, + cnl: 2404, + cnm: 2405, + cnn: 2406, + cno: 2407, + cnp: 2408, + cnq: 2409, + cnr: 2410, + cns: 2411, + cnt: 2412, + cnu: 2413, + cnv: 2414, + cnw: 2415, + cnx: 2416, + cny: 2417, + coz: 2418, + coa: 2419, + cob: 2420, + coc: 2421, + cod: 2422, + coe: 2423, + cof: 2424, + cog: 2425, + coh: 2426, + coi: 2427, + coj: 2428, + cok: 2429, + col: 2430, + com: 2431, + con: 2432, + coo: 2433, + cop: 2434, + coq: 2435, + cor: 2436, + cos: 2437, + cot: 2438, + cou: 2439, + cov: 2440, + cow: 2441, + cox: 2442, + coy: 2443, + cpz: 2444, + cpa: 2445, + cpb: 2446, + cpc: 2447, + cpd: 2448, + cpe: 2449, + cpf: 2450, + cpg: 2451, + cph: 2452, + cpi: 2453, + cpj: 2454, + cpk: 2455, + cpl: 2456, + cpm: 2457, + cpn: 2458, + cpo: 2459, + cpp: 2460, + cpq: 2461, + cpr: 2462, + cps: 2463, + cpt: 2464, + cpu: 2465, + cpv: 2466, + cpw: 2467, + cpx: 2468, + cpy: 2469, + cqz: 2470, + cqa: 2471, + cqb: 2472, + cqc: 2473, + cqd: 2474, + cqe: 2475, + cqf: 2476, + cqg: 2477, + cqh: 2478, + cqi: 2479, + cqj: 2480, + cqk: 2481, + cql: 2482, + cqm: 2483, + cqn: 2484, + cqo: 2485, + cqp: 2486, + cqq: 2487, + cqr: 2488, + cqs: 2489, + cqt: 2490, + cqu: 2491, + cqv: 2492, + cqw: 2493, + cqx: 2494, + cqy: 2495, + crz: 2496, + cra: 2497, + crb: 2498, + crc: 2499, + crd: 2500, + cre: 2501, + crf: 2502, + crg: 2503, + crh: 2504, + cri: 2505, + crj: 2506, + crk: 2507, + crl: 2508, + crm: 2509, + crn: 2510, + cro: 2511, + crp: 2512, + crq: 2513, + crr: 2514, + crs: 2515, + crt: 2516, + cru: 2517, + crv: 2518, + crw: 2519, + crx: 2520, + cry: 2521, + csz: 2522, + csa: 2523, + csb: 2524, + csc: 2525, + csd: 2526, + cse: 2527, + csf: 2528, + csg: 2529, + csh: 2530, + csi: 2531, + csj: 2532, + csk: 2533, + csl: 2534, + csm: 2535, + csn: 2536, + cso: 2537, + csp: 2538, + csq: 2539, + csr: 2540, + css: 2541, + cst: 2542, + csu: 2543, + csv: 2544, + csw: 2545, + csx: 2546, + csy: 2547, + ctz: 2548, + cta: 2549, + ctb: 2550, + ctc: 2551, + ctd: 2552, + cte: 2553, + ctf: 2554, + ctg: 2555, + cth: 2556, + cti: 2557, + ctj: 2558, + ctk: 2559, + ctl: 2560, + ctm: 2561, + ctn: 2562, + cto: 2563, + ctp: 2564, + ctq: 2565, + ctr: 2566, + cts: 2567, + ctt: 2568, + ctu: 2569, + ctv: 2570, + ctw: 2571, + ctx: 2572, + cty: 2573, + cuz: 2574, + cua: 2575, + cub: 2576, + cuc: 2577, + cud: 2578, + cue: 2579, + cuf: 2580, + cug: 2581, + cuh: 2582, + cui: 2583, + cuj: 2584, + cuk: 2585, + cul: 2586, + cum: 2587, + cun: 2588, + cuo: 2589, + cup: 2590, + cuq: 2591, + cur: 2592, + cus: 2593, + cut: 2594, + cuu: 2595, + cuv: 2596, + cuw: 2597, + cux: 2598, + cuy: 2599, + cvz: 2600, + cva: 2601, + cvb: 2602, + cvc: 2603, + cvd: 2604, + cve: 2605, + cvf: 2606, + cvg: 2607, + cvh: 2608, + cvi: 2609, + cvj: 2610, + cvk: 2611, + cvl: 2612, + cvm: 2613, + cvn: 2614, + cvo: 2615, + cvp: 2616, + cvq: 2617, + cvr: 2618, + cvs: 2619, + cvt: 2620, + cvu: 2621, + cvv: 2622, + cvw: 2623, + cvx: 2624, + cvy: 2625, + cwz: 2626, + cwa: 2627, + cwb: 2628, + cwc: 2629, + cwd: 2630, + cwe: 2631, + cwf: 2632, + cwg: 2633, + cwh: 2634, + cwi: 2635, + cwj: 2636, + cwk: 2637, + cwl: 2638, + cwm: 2639, + cwn: 2640, + cwo: 2641, + cwp: 2642, + cwq: 2643, + cwr: 2644, + cws: 2645, + cwt: 2646, + cwu: 2647, + cwv: 2648, + cww: 2649, + cwx: 2650, + cwy: 2651, + cxz: 2652, + cxa: 2653, + cxb: 2654, + cxc: 2655, + cxd: 2656, + cxe: 2657, + cxf: 2658, + cxg: 2659, + cxh: 2660, + cxi: 2661, + cxj: 2662, + cxk: 2663, + cxl: 2664, + cxm: 2665, + cxn: 2666, + cxo: 2667, + cxp: 2668, + cxq: 2669, + cxr: 2670, + cxs: 2671, + cxt: 2672, + cxu: 2673, + cxv: 2674, + cxw: 2675, + cxx: 2676, + cxy: 2677, + cyz: 2678, + cya: 2679, + cyb: 2680, + cyc: 2681, + cyd: 2682, + cye: 2683, + cyf: 2684, + cyg: 2685, + cyh: 2686, + cyi: 2687, + cyj: 2688, + cyk: 2689, + cyl: 2690, + cym: 2691, + cyn: 2692, + cyo: 2693, + cyp: 2694, + cyq: 2695, + cyr: 2696, + cys: 2697, + cyt: 2698, + cyu: 2699, + cyv: 2700, + cyw: 2701, + cyx: 2702, + cyy: 2703, + dzz: 2704, + dza: 2705, + dzb: 2706, + dzc: 2707, + dzd: 2708, + dze: 2709, + dzf: 2710, + dzg: 2711, + dzh: 2712, + dzi: 2713, + dzj: 2714, + dzk: 2715, + dzl: 2716, + dzm: 2717, + dzn: 2718, + dzo: 2719, + dzp: 2720, + dzq: 2721, + dzr: 2722, + dzs: 2723, + dzt: 2724, + dzu: 2725, + dzv: 2726, + dzw: 2727, + dzx: 2728, + dzy: 2729, + daz: 2730, + daa: 2731, + dab: 2732, + dac: 2733, + dad: 2734, + dae: 2735, + daf: 2736, + dag: 2737, + dah: 2738, + dai: 2739, + daj: 2740, + dak: 2741, + dal: 2742, + dam: 2743, + dan: 2744, + dao: 2745, + dap: 2746, + daq: 2747, + dar: 2748, + das: 2749, + dat: 2750, + dau: 2751, + dav: 2752, + daw: 2753, + dax: 2754, + day: 2755, + dbz: 2756, + dba: 2757, + dbb: 2758, + dbc: 2759, + dbd: 2760, + dbe: 2761, + dbf: 2762, + dbg: 2763, + dbh: 2764, + dbi: 2765, + dbj: 2766, + dbk: 2767, + dbl: 2768, + dbm: 2769, + dbn: 2770, + dbo: 2771, + dbp: 2772, + dbq: 2773, + dbr: 2774, + dbs: 2775, + dbt: 2776, + dbu: 2777, + dbv: 2778, + dbw: 2779, + dbx: 2780, + dby: 2781, + dcz: 2782, + dca: 2783, + dcb: 2784, + dcc: 2785, + dcd: 2786, + dce: 2787, + dcf: 2788, + dcg: 2789, + dch: 2790, + dci: 2791, + dcj: 2792, + dck: 2793, + dcl: 2794, + dcm: 2795, + dcn: 2796, + dco: 2797, + dcp: 2798, + dcq: 2799, + dcr: 2800, + dcs: 2801, + dct: 2802, + dcu: 2803, + dcv: 2804, + dcw: 2805, + dcx: 2806, + dcy: 2807, + ddz: 2808, + dda: 2809, + ddb: 2810, + ddc: 2811, + ddd: 2812, + dde: 2813, + ddf: 2814, + ddg: 2815, + ddh: 2816, + ddi: 2817, + ddj: 2818, + ddk: 2819, + ddl: 2820, + ddm: 2821, + ddn: 2822, + ddo: 2823, + ddp: 2824, + ddq: 2825, + ddr: 2826, + dds: 2827, + ddt: 2828, + ddu: 2829, + ddv: 2830, + ddw: 2831, + ddx: 2832, + ddy: 2833, + dez: 2834, + dea: 2835, + deb: 2836, + dec: 2837, + ded: 2838, + dee: 2839, + def: 2840, + deg: 2841, + deh: 2842, + dei: 2843, + dej: 2844, + dek: 2845, + del: 2846, + dem: 2847, + den: 2848, + deo: 2849, + dep: 2850, + deq: 2851, + der: 2852, + des: 2853, + det: 2854, + deu: 2855, + dev: 2856, + dew: 2857, + dex: 2858, + dey: 2859, + dfz: 2860, + dfa: 2861, + dfb: 2862, + dfc: 2863, + dfd: 2864, + dfe: 2865, + dff: 2866, + dfg: 2867, + dfh: 2868, + dfi: 2869, + dfj: 2870, + dfk: 2871, + dfl: 2872, + dfm: 2873, + dfn: 2874, + dfo: 2875, + dfp: 2876, + dfq: 2877, + dfr: 2878, + dfs: 2879, + dft: 2880, + dfu: 2881, + dfv: 2882, + dfw: 2883, + dfx: 2884, + dfy: 2885, + dgz: 2886, + dga: 2887, + dgb: 2888, + dgc: 2889, + dgd: 2890, + dge: 2891, + dgf: 2892, + dgg: 2893, + dgh: 2894, + dgi: 2895, + dgj: 2896, + dgk: 2897, + dgl: 2898, + dgm: 2899, + dgn: 2900, + dgo: 2901, + dgp: 2902, + dgq: 2903, + dgr: 2904, + dgs: 2905, + dgt: 2906, + dgu: 2907, + dgv: 2908, + dgw: 2909, + dgx: 2910, + dgy: 2911, + dhz: 2912, + dha: 2913, + dhb: 2914, + dhc: 2915, + dhd: 2916, + dhe: 2917, + dhf: 2918, + dhg: 2919, + dhh: 2920, + dhi: 2921, + dhj: 2922, + dhk: 2923, + dhl: 2924, + dhm: 2925, + dhn: 2926, + dho: 2927, + dhp: 2928, + dhq: 2929, + dhr: 2930, + dhs: 2931, + dht: 2932, + dhu: 2933, + dhv: 2934, + dhw: 2935, + dhx: 2936, + dhy: 2937, + diz: 2938, + dia: 2939, + dib: 2940, + dic: 2941, + did: 2942, + die: 2943, + dif: 2944, + dig: 2945, + dih: 2946, + dii: 2947, + dij: 2948, + dik: 2949, + dil: 2950, + dim: 2951, + din: 2952, + dio: 2953, + dip: 2954, + diq: 2955, + dir: 2956, + dis: 2957, + dit: 2958, + diu: 2959, + div: 2960, + diw: 2961, + dix: 2962, + diy: 2963, + djz: 2964, + dja: 2965, + djb: 2966, + djc: 2967, + djd: 2968, + dje: 2969, + djf: 2970, + djg: 2971, + djh: 2972, + dji: 2973, + djj: 2974, + djk: 2975, + djl: 2976, + djm: 2977, + djn: 2978, + djo: 2979, + djp: 2980, + djq: 2981, + djr: 2982, + djs: 2983, + djt: 2984, + dju: 2985, + djv: 2986, + djw: 2987, + djx: 2988, + djy: 2989, + dkz: 2990, + dka: 2991, + dkb: 2992, + dkc: 2993, + dkd: 2994, + dke: 2995, + dkf: 2996, + dkg: 2997, + dkh: 2998, + dki: 2999, + dkj: 3000, + dkk: 3001, + dkl: 3002, + dkm: 3003, + dkn: 3004, + dko: 3005, + dkp: 3006, + dkq: 3007, + dkr: 3008, + dks: 3009, + dkt: 3010, + dku: 3011, + dkv: 3012, + dkw: 3013, + dkx: 3014, + dky: 3015, + dlz: 3016, + dla: 3017, + dlb: 3018, + dlc: 3019, + dld: 3020, + dle: 3021, + dlf: 3022, + dlg: 3023, + dlh: 3024, + dli: 3025, + dlj: 3026, + dlk: 3027, + dll: 3028, + dlm: 3029, + dln: 3030, + dlo: 3031, + dlp: 3032, + dlq: 3033, + dlr: 3034, + dls: 3035, + dlt: 3036, + dlu: 3037, + dlv: 3038, + dlw: 3039, + dlx: 3040, + dly: 3041, + dmz: 3042, + dma: 3043, + dmb: 3044, + dmc: 3045, + dmd: 3046, + dme: 3047, + dmf: 3048, + dmg: 3049, + dmh: 3050, + dmi: 3051, + dmj: 3052, + dmk: 3053, + dml: 3054, + dmm: 3055, + dmn: 3056, + dmo: 3057, + dmp: 3058, + dmq: 3059, + dmr: 3060, + dms: 3061, + dmt: 3062, + dmu: 3063, + dmv: 3064, + dmw: 3065, + dmx: 3066, + dmy: 3067, + dnz: 3068, + dna: 3069, + dnb: 3070, + dnc: 3071, + dnd: 3072, + dne: 3073, + dnf: 3074, + dng: 3075, + dnh: 3076, + dni: 3077, + dnj: 3078, + dnk: 3079, + dnl: 3080, + dnm: 3081, + dnn: 3082, + dno: 3083, + dnp: 3084, + dnq: 3085, + dnr: 3086, + dns: 3087, + dnt: 3088, + dnu: 3089, + dnv: 3090, + dnw: 3091, + dnx: 3092, + dny: 3093, + doz: 3094, + doa: 3095, + dob: 3096, + doc: 3097, + dod: 3098, + doe: 3099, + dof: 3100, + dog: 3101, + doh: 3102, + doi: 3103, + doj: 3104, + dok: 3105, + dol: 3106, + dom: 3107, + don: 3108, + doo: 3109, + dop: 3110, + doq: 3111, + dor: 3112, + dos: 3113, + dot: 3114, + dou: 3115, + dov: 3116, + dow: 3117, + dox: 3118, + doy: 3119, + dpz: 3120, + dpa: 3121, + dpb: 3122, + dpc: 3123, + dpd: 3124, + dpe: 3125, + dpf: 3126, + dpg: 3127, + dph: 3128, + dpi: 3129, + dpj: 3130, + dpk: 3131, + dpl: 3132, + dpm: 3133, + dpn: 3134, + dpo: 3135, + dpp: 3136, + dpq: 3137, + dpr: 3138, + dps: 3139, + dpt: 3140, + dpu: 3141, + dpv: 3142, + dpw: 3143, + dpx: 3144, + dpy: 3145, + dqz: 3146, + dqa: 3147, + dqb: 3148, + dqc: 3149, + dqd: 3150, + dqe: 3151, + dqf: 3152, + dqg: 3153, + dqh: 3154, + dqi: 3155, + dqj: 3156, + dqk: 3157, + dql: 3158, + dqm: 3159, + dqn: 3160, + dqo: 3161, + dqp: 3162, + dqq: 3163, + dqr: 3164, + dqs: 3165, + dqt: 3166, + dqu: 3167, + dqv: 3168, + dqw: 3169, + dqx: 3170, + dqy: 3171, + drz: 3172, + dra: 3173, + drb: 3174, + drc: 3175, + drd: 3176, + dre: 3177, + drf: 3178, + drg: 3179, + drh: 3180, + dri: 3181, + drj: 3182, + drk: 3183, + drl: 3184, + drm: 3185, + drn: 3186, + dro: 3187, + drp: 3188, + drq: 3189, + drr: 3190, + drs: 3191, + drt: 3192, + dru: 3193, + drv: 3194, + drw: 3195, + drx: 3196, + dry: 3197, + dsz: 3198, + dsa: 3199, + dsb: 3200, + dsc: 3201, + dsd: 3202, + dse: 3203, + dsf: 3204, + dsg: 3205, + dsh: 3206, + dsi: 3207, + dsj: 3208, + dsk: 3209, + dsl: 3210, + dsm: 3211, + dsn: 3212, + dso: 3213, + dsp: 3214, + dsq: 3215, + dsr: 3216, + dss: 3217, + dst: 3218, + dsu: 3219, + dsv: 3220, + dsw: 3221, + dsx: 3222, + dsy: 3223, + dtz: 3224, + dta: 3225, + dtb: 3226, + dtc: 3227, + dtd: 3228, + dte: 3229, + dtf: 3230, + dtg: 3231, + dth: 3232, + dti: 3233, + dtj: 3234, + dtk: 3235, + dtl: 3236, + dtm: 3237, + dtn: 3238, + dto: 3239, + dtp: 3240, + dtq: 3241, + dtr: 3242, + dts: 3243, + dtt: 3244, + dtu: 3245, + dtv: 3246, + dtw: 3247, + dtx: 3248, + dty: 3249, + duz: 3250, + dua: 3251, + dub: 3252, + duc: 3253, + dud: 3254, + due: 3255, + duf: 3256, + dug: 3257, + duh: 3258, + dui: 3259, + duj: 3260, + duk: 3261, + dul: 3262, + dum: 3263, + dun: 3264, + duo: 3265, + dup: 3266, + duq: 3267, + dur: 3268, + dus: 3269, + dut: 3270, + duu: 3271, + duv: 3272, + duw: 3273, + dux: 3274, + duy: 3275, + dvz: 3276, + dva: 3277, + dvb: 3278, + dvc: 3279, + dvd: 3280, + dve: 3281, + dvf: 3282, + dvg: 3283, + dvh: 3284, + dvi: 3285, + dvj: 3286, + dvk: 3287, + dvl: 3288, + dvm: 3289, + dvn: 3290, + dvo: 3291, + dvp: 3292, + dvq: 3293, + dvr: 3294, + dvs: 3295, + dvt: 3296, + dvu: 3297, + dvv: 3298, + dvw: 3299, + dvx: 3300, + dvy: 3301, + dwz: 3302, + dwa: 3303, + dwb: 3304, + dwc: 3305, + dwd: 3306, + dwe: 3307, + dwf: 3308, + dwg: 3309, + dwh: 3310, + dwi: 3311, + dwj: 3312, + dwk: 3313, + dwl: 3314, + dwm: 3315, + dwn: 3316, + dwo: 3317, + dwp: 3318, + dwq: 3319, + dwr: 3320, + dws: 3321, + dwt: 3322, + dwu: 3323, + dwv: 3324, + dww: 3325, + dwx: 3326, + dwy: 3327, + dxz: 3328, + dxa: 3329, + dxb: 3330, + dxc: 3331, + dxd: 3332, + dxe: 3333, + dxf: 3334, + dxg: 3335, + dxh: 3336, + dxi: 3337, + dxj: 3338, + dxk: 3339, + dxl: 3340, + dxm: 3341, + dxn: 3342, + dxo: 3343, + dxp: 3344, + dxq: 3345, + dxr: 3346, + dxs: 3347, + dxt: 3348, + dxu: 3349, + dxv: 3350, + dxw: 3351, + dxx: 3352, + dxy: 3353, + dyz: 3354, + dya: 3355, + dyb: 3356, + dyc: 3357, + dyd: 3358, + dye: 3359, + dyf: 3360, + dyg: 3361, + dyh: 3362, + dyi: 3363, + dyj: 3364, + dyk: 3365, + dyl: 3366, + dym: 3367, + dyn: 3368, + dyo: 3369, + dyp: 3370, + dyq: 3371, + dyr: 3372, + dys: 3373, + dyt: 3374, + dyu: 3375, + dyv: 3376, + dyw: 3377, + dyx: 3378, + dyy: 3379, + ezz: 3380, + eza: 3381, + ezb: 3382, + ezc: 3383, + ezd: 3384, + eze: 3385, + ezf: 3386, + ezg: 3387, + ezh: 3388, + ezi: 3389, + ezj: 3390, + ezk: 3391, + ezl: 3392, + ezm: 3393, + ezn: 3394, + ezo: 3395, + ezp: 3396, + ezq: 3397, + ezr: 3398, + ezs: 3399, + ezt: 3400, + ezu: 3401, + ezv: 3402, + ezw: 3403, + ezx: 3404, + ezy: 3405, + eaz: 3406, + eaa: 3407, + eab: 3408, + eac: 3409, + ead: 3410, + eae: 3411, + eaf: 3412, + eag: 3413, + eah: 3414, + eai: 3415, + eaj: 3416, + eak: 3417, + eal: 3418, + eam: 3419, + ean: 3420, + eao: 3421, + eap: 3422, + eaq: 3423, + ear: 3424, + eas: 3425, + eat: 3426, + eau: 3427, + eav: 3428, + eaw: 3429, + eax: 3430, + eay: 3431, + ebz: 3432, + eba: 3433, + ebb: 3434, + ebc: 3435, + ebd: 3436, + ebe: 3437, + ebf: 3438, + ebg: 3439, + ebh: 3440, + ebi: 3441, + ebj: 3442, + ebk: 3443, + ebl: 3444, + ebm: 3445, + ebn: 3446, + ebo: 3447, + ebp: 3448, + ebq: 3449, + ebr: 3450, + ebs: 3451, + ebt: 3452, + ebu: 3453, + ebv: 3454, + ebw: 3455, + ebx: 3456, + eby: 3457, + ecz: 3458, + eca: 3459, + ecb: 3460, + ecc: 3461, + ecd: 3462, + ece: 3463, + ecf: 3464, + ecg: 3465, + ech: 3466, + eci: 3467, + ecj: 3468, + eck: 3469, + ecl: 3470, + ecm: 3471, + ecn: 3472, + eco: 3473, + ecp: 3474, + ecq: 3475, + ecr: 3476, + ecs: 3477, + ect: 3478, + ecu: 3479, + ecv: 3480, + ecw: 3481, + ecx: 3482, + ecy: 3483, + edz: 3484, + eda: 3485, + edb: 3486, + edc: 3487, + edd: 3488, + ede: 3489, + edf: 3490, + edg: 3491, + edh: 3492, + edi: 3493, + edj: 3494, + edk: 3495, + edl: 3496, + edm: 3497, + edn: 3498, + edo: 3499, + edp: 3500, + edq: 3501, + edr: 3502, + eds: 3503, + edt: 3504, + edu: 3505, + edv: 3506, + edw: 3507, + edx: 3508, + edy: 3509, + eez: 3510, + eea: 3511, + eeb: 3512, + eec: 3513, + eed: 3514, + eee: 3515, + eef: 3516, + eeg: 3517, + eeh: 3518, + eei: 3519, + eej: 3520, + eek: 3521, + eel: 3522, + eem: 3523, + een: 3524, + eeo: 3525, + eep: 3526, + eeq: 3527, + eer: 3528, + ees: 3529, + eet: 3530, + eeu: 3531, + eev: 3532, + eew: 3533, + eex: 3534, + eey: 3535, + efz: 3536, + efa: 3537, + efb: 3538, + efc: 3539, + efd: 3540, + efe: 3541, + eff: 3542, + efg: 3543, + efh: 3544, + efi: 3545, + efj: 3546, + efk: 3547, + efl: 3548, + efm: 3549, + efn: 3550, + efo: 3551, + efp: 3552, + efq: 3553, + efr: 3554, + efs: 3555, + eft: 3556, + efu: 3557, + efv: 3558, + efw: 3559, + efx: 3560, + efy: 3561, + egz: 3562, + ega: 3563, + egb: 3564, + egc: 3565, + egd: 3566, + ege: 3567, + egf: 3568, + egg: 3569, + egh: 3570, + egi: 3571, + egj: 3572, + egk: 3573, + egl: 3574, + egm: 3575, + egn: 3576, + ego: 3577, + egp: 3578, + egq: 3579, + egr: 3580, + egs: 3581, + egt: 3582, + egu: 3583, + egv: 3584, + egw: 3585, + egx: 3586, + egy: 3587, + ehz: 3588, + eha: 3589, + ehb: 3590, + ehc: 3591, + ehd: 3592, + ehe: 3593, + ehf: 3594, + ehg: 3595, + ehh: 3596, + ehi: 3597, + ehj: 3598, + ehk: 3599, + ehl: 3600, + ehm: 3601, + ehn: 3602, + eho: 3603, + ehp: 3604, + ehq: 3605, + ehr: 3606, + ehs: 3607, + eht: 3608, + ehu: 3609, + ehv: 3610, + ehw: 3611, + ehx: 3612, + ehy: 3613, + eiz: 3614, + eia: 3615, + eib: 3616, + eic: 3617, + eid: 3618, + eie: 3619, + eif: 3620, + eig: 3621, + eih: 3622, + eii: 3623, + eij: 3624, + eik: 3625, + eil: 3626, + eim: 3627, + ein: 3628, + eio: 3629, + eip: 3630, + eiq: 3631, + eir: 3632, + eis: 3633, + eit: 3634, + eiu: 3635, + eiv: 3636, + eiw: 3637, + eix: 3638, + eiy: 3639, + ejz: 3640, + eja: 3641, + ejb: 3642, + ejc: 3643, + ejd: 3644, + eje: 3645, + ejf: 3646, + ejg: 3647, + ejh: 3648, + eji: 3649, + ejj: 3650, + ejk: 3651, + ejl: 3652, + ejm: 3653, + ejn: 3654, + ejo: 3655, + ejp: 3656, + ejq: 3657, + ejr: 3658, + ejs: 3659, + ejt: 3660, + eju: 3661, + ejv: 3662, + ejw: 3663, + ejx: 3664, + ejy: 3665, + ekz: 3666, + eka: 3667, + ekb: 3668, + ekc: 3669, + ekd: 3670, + eke: 3671, + ekf: 3672, + ekg: 3673, + ekh: 3674, + eki: 3675, + ekj: 3676, + ekk: 3677, + ekl: 3678, + ekm: 3679, + ekn: 3680, + eko: 3681, + ekp: 3682, + ekq: 3683, + ekr: 3684, + eks: 3685, + ekt: 3686, + eku: 3687, + ekv: 3688, + ekw: 3689, + ekx: 3690, + eky: 3691, + elz: 3692, + ela: 3693, + elb: 3694, + elc: 3695, + eld: 3696, + ele: 3697, + elf: 3698, + elg: 3699, + elh: 3700, + eli: 3701, + elj: 3702, + elk: 3703, + ell: 3704, + elm: 3705, + eln: 3706, + elo: 3707, + elp: 3708, + elq: 3709, + elr: 3710, + els: 3711, + elt: 3712, + elu: 3713, + elv: 3714, + elw: 3715, + elx: 3716, + ely: 3717, + emz: 3718, + ema: 3719, + emb: 3720, + emc: 3721, + emd: 3722, + eme: 3723, + emf: 3724, + emg: 3725, + emh: 3726, + emi: 3727, + emj: 3728, + emk: 3729, + eml: 3730, + emm: 3731, + emn: 3732, + emo: 3733, + emp: 3734, + emq: 3735, + emr: 3736, + ems: 3737, + emt: 3738, + emu: 3739, + emv: 3740, + emw: 3741, + emx: 3742, + emy: 3743, + enz: 3744, + ena: 3745, + enb: 3746, + enc: 3747, + end: 3748, + ene: 3749, + enf: 3750, + eng: 3751, + enh: 3752, + eni: 3753, + enj: 3754, + enk: 3755, + enl: 3756, + enm: 3757, + enn: 3758, + eno: 3759, + enp: 3760, + enq: 3761, + enr: 3762, + ens: 3763, + ent: 3764, + enu: 3765, + env: 3766, + enw: 3767, + enx: 3768, + eny: 3769, + eoz: 3770, + eoa: 3771, + eob: 3772, + eoc: 3773, + eod: 3774, + eoe: 3775, + eof: 3776, + eog: 3777, + eoh: 3778, + eoi: 3779, + eoj: 3780, + eok: 3781, + eol: 3782, + eom: 3783, + eon: 3784, + eoo: 3785, + eop: 3786, + eoq: 3787, + eor: 3788, + eos: 3789, + eot: 3790, + eou: 3791, + eov: 3792, + eow: 3793, + eox: 3794, + eoy: 3795, + epz: 3796, + epa: 3797, + epb: 3798, + epc: 3799, + epd: 3800, + epe: 3801, + epf: 3802, + epg: 3803, + eph: 3804, + epi: 3805, + epj: 3806, + epk: 3807, + epl: 3808, + epm: 3809, + epn: 3810, + epo: 3811, + epp: 3812, + epq: 3813, + epr: 3814, + eps: 3815, + ept: 3816, + epu: 3817, + epv: 3818, + epw: 3819, + epx: 3820, + epy: 3821, + eqz: 3822, + eqa: 3823, + eqb: 3824, + eqc: 3825, + eqd: 3826, + eqe: 3827, + eqf: 3828, + eqg: 3829, + eqh: 3830, + eqi: 3831, + eqj: 3832, + eqk: 3833, + eql: 3834, + eqm: 3835, + eqn: 3836, + eqo: 3837, + eqp: 3838, + eqq: 3839, + eqr: 3840, + eqs: 3841, + eqt: 3842, + equ: 3843, + eqv: 3844, + eqw: 3845, + eqx: 3846, + eqy: 3847, + erz: 3848, + era: 3849, + erb: 3850, + erc: 3851, + erd: 3852, + ere: 3853, + erf: 3854, + erg: 3855, + erh: 3856, + eri: 3857, + erj: 3858, + erk: 3859, + erl: 3860, + erm: 3861, + ern: 3862, + ero: 3863, + erp: 3864, + erq: 3865, + err: 3866, + ers: 3867, + ert: 3868, + eru: 3869, + erv: 3870, + erw: 3871, + erx: 3872, + ery: 3873, + esz: 3874, + esa: 3875, + esb: 3876, + esc: 3877, + esd: 3878, + ese: 3879, + esf: 3880, + esg: 3881, + esh: 3882, + esi: 3883, + esj: 3884, + esk: 3885, + esl: 3886, + esm: 3887, + esn: 3888, + eso: 3889, + esp: 3890, + esq: 3891, + esr: 3892, + ess: 3893, + est: 3894, + esu: 3895, + esv: 3896, + esw: 3897, + esx: 3898, + esy: 3899, + etz: 3900, + eta: 3901, + etb: 3902, + etc: 3903, + etd: 3904, + ete: 3905, + etf: 3906, + etg: 3907, + eth: 3908, + eti: 3909, + etj: 3910, + etk: 3911, + etl: 3912, + etm: 3913, + etn: 3914, + eto: 3915, + etp: 3916, + etq: 3917, + etr: 3918, + ets: 3919, + ett: 3920, + etu: 3921, + etv: 3922, + etw: 3923, + etx: 3924, + ety: 3925, + euz: 3926, + eua: 3927, + eub: 3928, + euc: 3929, + eud: 3930, + eue: 3931, + euf: 3932, + eug: 3933, + euh: 3934, + eui: 3935, + euj: 3936, + euk: 3937, + eul: 3938, + eum: 3939, + eun: 3940, + euo: 3941, + eup: 3942, + euq: 3943, + eur: 3944, + eus: 3945, + eut: 3946, + euu: 3947, + euv: 3948, + euw: 3949, + eux: 3950, + euy: 3951, + evz: 3952, + eva: 3953, + evb: 3954, + evc: 3955, + evd: 3956, + eve: 3957, + evf: 3958, + evg: 3959, + evh: 3960, + evi: 3961, + evj: 3962, + evk: 3963, + evl: 3964, + evm: 3965, + evn: 3966, + evo: 3967, + evp: 3968, + evq: 3969, + evr: 3970, + evs: 3971, + evt: 3972, + evu: 3973, + evv: 3974, + evw: 3975, + evx: 3976, + evy: 3977, + ewz: 3978, + ewa: 3979, + ewb: 3980, + ewc: 3981, + ewd: 3982, + ewe: 3983, + ewf: 3984, + ewg: 3985, + ewh: 3986, + ewi: 3987, + ewj: 3988, + ewk: 3989, + ewl: 3990, + ewm: 3991, + ewn: 3992, + ewo: 3993, + ewp: 3994, + ewq: 3995, + ewr: 3996, + ews: 3997, + ewt: 3998, + ewu: 3999, + ewv: 4000, + eww: 4001, + ewx: 4002, + ewy: 4003, + exz: 4004, + exa: 4005, + exb: 4006, + exc: 4007, + exd: 4008, + exe: 4009, + exf: 4010, + exg: 4011, + exh: 4012, + exi: 4013, + exj: 4014, + exk: 4015, + exl: 4016, + exm: 4017, + exn: 4018, + exo: 4019, + exp: 4020, + exq: 4021, + exr: 4022, + exs: 4023, + ext: 4024, + exu: 4025, + exv: 4026, + exw: 4027, + exx: 4028, + exy: 4029, + eyz: 4030, + eya: 4031, + eyb: 4032, + eyc: 4033, + eyd: 4034, + eye: 4035, + eyf: 4036, + eyg: 4037, + eyh: 4038, + eyi: 4039, + eyj: 4040, + eyk: 4041, + eyl: 4042, + eym: 4043, + eyn: 4044, + eyo: 4045, + eyp: 4046, + eyq: 4047, + eyr: 4048, + eys: 4049, + eyt: 4050, + eyu: 4051, + eyv: 4052, + eyw: 4053, + eyx: 4054, + eyy: 4055, + fzz: 4056, + fza: 4057, + fzb: 4058, + fzc: 4059, + fzd: 4060, + fze: 4061, + fzf: 4062, + fzg: 4063, + fzh: 4064, + fzi: 4065, + fzj: 4066, + fzk: 4067, + fzl: 4068, + fzm: 4069, + fzn: 4070, + fzo: 4071, + fzp: 4072, + fzq: 4073, + fzr: 4074, + fzs: 4075, + fzt: 4076, + fzu: 4077, + fzv: 4078, + fzw: 4079, + fzx: 4080, + fzy: 4081, + faz: 4082, + faa: 4083, + fab: 4084, + fac: 4085, + fad: 4086, + fae: 4087, + faf: 4088, + fag: 4089, + fah: 4090, + fai: 4091, + faj: 4092, + fak: 4093, + fal: 4094, + fam: 4095, + fan: 4096, + fao: 4097, + fap: 4098, + faq: 4099, + far: 4100, + fas: 4101, + fat: 4102, + fau: 4103, + fav: 4104, + faw: 4105, + fax: 4106, + fay: 4107, + fbz: 4108, + fba: 4109, + fbb: 4110, + fbc: 4111, + fbd: 4112, + fbe: 4113, + fbf: 4114, + fbg: 4115, + fbh: 4116, + fbi: 4117, + fbj: 4118, + fbk: 4119, + fbl: 4120, + fbm: 4121, + fbn: 4122, + fbo: 4123, + fbp: 4124, + fbq: 4125, + fbr: 4126, + fbs: 4127, + fbt: 4128, + fbu: 4129, + fbv: 4130, + fbw: 4131, + fbx: 4132, + fby: 4133, + fcz: 4134, + fca: 4135, + fcb: 4136, + fcc: 4137, + fcd: 4138, + fce: 4139, + fcf: 4140, + fcg: 4141, + fch: 4142, + fci: 4143, + fcj: 4144, + fck: 4145, + fcl: 4146, + fcm: 4147, + fcn: 4148, + fco: 4149, + fcp: 4150, + fcq: 4151, + fcr: 4152, + fcs: 4153, + fct: 4154, + fcu: 4155, + fcv: 4156, + fcw: 4157, + fcx: 4158, + fcy: 4159, + fdz: 4160, + fda: 4161, + fdb: 4162, + fdc: 4163, + fdd: 4164, + fde: 4165, + fdf: 4166, + fdg: 4167, + fdh: 4168, + fdi: 4169, + fdj: 4170, + fdk: 4171, + fdl: 4172, + fdm: 4173, + fdn: 4174, + fdo: 4175, + fdp: 4176, + fdq: 4177, + fdr: 4178, + fds: 4179, + fdt: 4180, + fdu: 4181, + fdv: 4182, + fdw: 4183, + fdx: 4184, + fdy: 4185, + fez: 4186, + fea: 4187, + feb: 4188, + fec: 4189, + fed: 4190, + fee: 4191, + fef: 4192, + feg: 4193, + feh: 4194, + fei: 4195, + fej: 4196, + fek: 4197, + fel: 4198, + fem: 4199, + fen: 4200, + feo: 4201, + fep: 4202, + feq: 4203, + fer: 4204, + fes: 4205, + fet: 4206, + feu: 4207, + fev: 4208, + few: 4209, + fex: 4210, + fey: 4211, + ffz: 4212, + ffa: 4213, + ffb: 4214, + ffc: 4215, + ffd: 4216, + ffe: 4217, + fff: 4218, + ffg: 4219, + ffh: 4220, + ffi: 4221, + ffj: 4222, + ffk: 4223, + ffl: 4224, + ffm: 4225, + ffn: 4226, + ffo: 4227, + ffp: 4228, + ffq: 4229, + ffr: 4230, + ffs: 4231, + fft: 4232, + ffu: 4233, + ffv: 4234, + ffw: 4235, + ffx: 4236, + ffy: 4237, + fgz: 4238, + fga: 4239, + fgb: 4240, + fgc: 4241, + fgd: 4242, + fge: 4243, + fgf: 4244, + fgg: 4245, + fgh: 4246, + fgi: 4247, + fgj: 4248, + fgk: 4249, + fgl: 4250, + fgm: 4251, + fgn: 4252, + fgo: 4253, + fgp: 4254, + fgq: 4255, + fgr: 4256, + fgs: 4257, + fgt: 4258, + fgu: 4259, + fgv: 4260, + fgw: 4261, + fgx: 4262, + fgy: 4263, + fhz: 4264, + fha: 4265, + fhb: 4266, + fhc: 4267, + fhd: 4268, + fhe: 4269, + fhf: 4270, + fhg: 4271, + fhh: 4272, + fhi: 4273, + fhj: 4274, + fhk: 4275, + fhl: 4276, + fhm: 4277, + fhn: 4278, + fho: 4279, + fhp: 4280, + fhq: 4281, + fhr: 4282, + fhs: 4283, + fht: 4284, + fhu: 4285, + fhv: 4286, + fhw: 4287, + fhx: 4288, + fhy: 4289, + fiz: 4290, + fia: 4291, + fib: 4292, + fic: 4293, + fid: 4294, + fie: 4295, + fif: 4296, + fig: 4297, + fih: 4298, + fii: 4299, + fij: 4300, + fik: 4301, + fil: 4302, + fim: 4303, + fin: 4304, + fio: 4305, + fip: 4306, + fiq: 4307, + fir: 4308, + fis: 4309, + fit: 4310, + fiu: 4311, + fiv: 4312, + fiw: 4313, + fix: 4314, + fiy: 4315, + fjz: 4316, + fja: 4317, + fjb: 4318, + fjc: 4319, + fjd: 4320, + fje: 4321, + fjf: 4322, + fjg: 4323, + fjh: 4324, + fji: 4325, + fjj: 4326, + fjk: 4327, + fjl: 4328, + fjm: 4329, + fjn: 4330, + fjo: 4331, + fjp: 4332, + fjq: 4333, + fjr: 4334, + fjs: 4335, + fjt: 4336, + fju: 4337, + fjv: 4338, + fjw: 4339, + fjx: 4340, + fjy: 4341, + fkz: 4342, + fka: 4343, + fkb: 4344, + fkc: 4345, + fkd: 4346, + fke: 4347, + fkf: 4348, + fkg: 4349, + fkh: 4350, + fki: 4351, + fkj: 4352, + fkk: 4353, + fkl: 4354, + fkm: 4355, + fkn: 4356, + fko: 4357, + fkp: 4358, + fkq: 4359, + fkr: 4360, + fks: 4361, + fkt: 4362, + fku: 4363, + fkv: 4364, + fkw: 4365, + fkx: 4366, + fky: 4367, + flz: 4368, + fla: 4369, + flb: 4370, + flc: 4371, + fld: 4372, + fle: 4373, + flf: 4374, + flg: 4375, + flh: 4376, + fli: 4377, + flj: 4378, + flk: 4379, + fll: 4380, + flm: 4381, + fln: 4382, + flo: 4383, + flp: 4384, + flq: 4385, + flr: 4386, + fls: 4387, + flt: 4388, + flu: 4389, + flv: 4390, + flw: 4391, + flx: 4392, + fly: 4393, + fmz: 4394, + fma: 4395, + fmb: 4396, + fmc: 4397, + fmd: 4398, + fme: 4399, + fmf: 4400, + fmg: 4401, + fmh: 4402, + fmi: 4403, + fmj: 4404, + fmk: 4405, + fml: 4406, + fmm: 4407, + fmn: 4408, + fmo: 4409, + fmp: 4410, + fmq: 4411, + fmr: 4412, + fms: 4413, + fmt: 4414, + fmu: 4415, + fmv: 4416, + fmw: 4417, + fmx: 4418, + fmy: 4419, + fnz: 4420, + fna: 4421, + fnb: 4422, + fnc: 4423, + fnd: 4424, + fne: 4425, + fnf: 4426, + fng: 4427, + fnh: 4428, + fni: 4429, + fnj: 4430, + fnk: 4431, + fnl: 4432, + fnm: 4433, + fnn: 4434, + fno: 4435, + fnp: 4436, + fnq: 4437, + fnr: 4438, + fns: 4439, + fnt: 4440, + fnu: 4441, + fnv: 4442, + fnw: 4443, + fnx: 4444, + fny: 4445, + foz: 4446, + foa: 4447, + fob: 4448, + foc: 4449, + fod: 4450, + foe: 4451, + fof: 4452, + fog: 4453, + foh: 4454, + foi: 4455, + foj: 4456, + fok: 4457, + fol: 4458, + fom: 4459, + fon: 4460, + foo: 4461, + fop: 4462, + foq: 4463, + for: 4464, + fos: 4465, + fot: 4466, + fou: 4467, + fov: 4468, + fow: 4469, + fox: 4470, + foy: 4471, + fpz: 4472, + fpa: 4473, + fpb: 4474, + fpc: 4475, + fpd: 4476, + fpe: 4477, + fpf: 4478, + fpg: 4479, + fph: 4480, + fpi: 4481, + fpj: 4482, + fpk: 4483, + fpl: 4484, + fpm: 4485, + fpn: 4486, + fpo: 4487, + fpp: 4488, + fpq: 4489, + fpr: 4490, + fps: 4491, + fpt: 4492, + fpu: 4493, + fpv: 4494, + fpw: 4495, + fpx: 4496, + fpy: 4497, + fqz: 4498, + fqa: 4499, + fqb: 4500, + fqc: 4501, + fqd: 4502, + fqe: 4503, + fqf: 4504, + fqg: 4505, + fqh: 4506, + fqi: 4507, + fqj: 4508, + fqk: 4509, + fql: 4510, + fqm: 4511, + fqn: 4512, + fqo: 4513, + fqp: 4514, + fqq: 4515, + fqr: 4516, + fqs: 4517, + fqt: 4518, + fqu: 4519, + fqv: 4520, + fqw: 4521, + fqx: 4522, + fqy: 4523, + frz: 4524, + fra: 4525, + frb: 4526, + frc: 4527, + frd: 4528, + fre: 4529, + frf: 4530, + frg: 4531, + frh: 4532, + fri: 4533, + frj: 4534, + frk: 4535, + frl: 4536, + frm: 4537, + frn: 4538, + fro: 4539, + frp: 4540, + frq: 4541, + frr: 4542, + frs: 4543, + frt: 4544, + fru: 4545, + frv: 4546, + frw: 4547, + frx: 4548, + fry: 4549, + fsz: 4550, + fsa: 4551, + fsb: 4552, + fsc: 4553, + fsd: 4554, + fse: 4555, + fsf: 4556, + fsg: 4557, + fsh: 4558, + fsi: 4559, + fsj: 4560, + fsk: 4561, + fsl: 4562, + fsm: 4563, + fsn: 4564, + fso: 4565, + fsp: 4566, + fsq: 4567, + fsr: 4568, + fss: 4569, + fst: 4570, + fsu: 4571, + fsv: 4572, + fsw: 4573, + fsx: 4574, + fsy: 4575, + ftz: 4576, + fta: 4577, + ftb: 4578, + ftc: 4579, + ftd: 4580, + fte: 4581, + ftf: 4582, + ftg: 4583, + fth: 4584, + fti: 4585, + ftj: 4586, + ftk: 4587, + ftl: 4588, + ftm: 4589, + ftn: 4590, + fto: 4591, + ftp: 4592, + ftq: 4593, + ftr: 4594, + fts: 4595, + ftt: 4596, + ftu: 4597, + ftv: 4598, + ftw: 4599, + ftx: 4600, + fty: 4601, + fuz: 4602, + fua: 4603, + fub: 4604, + fuc: 4605, + fud: 4606, + fue: 4607, + fuf: 4608, + fug: 4609, + fuh: 4610, + fui: 4611, + fuj: 4612, + fuk: 4613, + ful: 4614, + fum: 4615, + fun: 4616, + fuo: 4617, + fup: 4618, + fuq: 4619, + fur: 4620, + fus: 4621, + fut: 4622, + fuu: 4623, + fuv: 4624, + fuw: 4625, + fux: 4626, + fuy: 4627, + fvz: 4628, + fva: 4629, + fvb: 4630, + fvc: 4631, + fvd: 4632, + fve: 4633, + fvf: 4634, + fvg: 4635, + fvh: 4636, + fvi: 4637, + fvj: 4638, + fvk: 4639, + fvl: 4640, + fvm: 4641, + fvn: 4642, + fvo: 4643, + fvp: 4644, + fvq: 4645, + fvr: 4646, + fvs: 4647, + fvt: 4648, + fvu: 4649, + fvv: 4650, + fvw: 4651, + fvx: 4652, + fvy: 4653, + fwz: 4654, + fwa: 4655, + fwb: 4656, + fwc: 4657, + fwd: 4658, + fwe: 4659, + fwf: 4660, + fwg: 4661, + fwh: 4662, + fwi: 4663, + fwj: 4664, + fwk: 4665, + fwl: 4666, + fwm: 4667, + fwn: 4668, + fwo: 4669, + fwp: 4670, + fwq: 4671, + fwr: 4672, + fws: 4673, + fwt: 4674, + fwu: 4675, + fwv: 4676, + fww: 4677, + fwx: 4678, + fwy: 4679, + fxz: 4680, + fxa: 4681, + fxb: 4682, + fxc: 4683, + fxd: 4684, + fxe: 4685, + fxf: 4686, + fxg: 4687, + fxh: 4688, + fxi: 4689, + fxj: 4690, + fxk: 4691, + fxl: 4692, + fxm: 4693, + fxn: 4694, + fxo: 4695, + fxp: 4696, + fxq: 4697, + fxr: 4698, + fxs: 4699, + fxt: 4700, + fxu: 4701, + fxv: 4702, + fxw: 4703, + fxx: 4704, + fxy: 4705, + fyz: 4706, + fya: 4707, + fyb: 4708, + fyc: 4709, + fyd: 4710, + fye: 4711, + fyf: 4712, + fyg: 4713, + fyh: 4714, + fyi: 4715, + fyj: 4716, + fyk: 4717, + fyl: 4718, + fym: 4719, + fyn: 4720, + fyo: 4721, + fyp: 4722, + fyq: 4723, + fyr: 4724, + fys: 4725, + fyt: 4726, + fyu: 4727, + fyv: 4728, + fyw: 4729, + fyx: 4730, + fyy: 4731, + gzz: 4732, + gza: 4733, + gzb: 4734, + gzc: 4735, + gzd: 4736, + gze: 4737, + gzf: 4738, + gzg: 4739, + gzh: 4740, + gzi: 4741, + gzj: 4742, + gzk: 4743, + gzl: 4744, + gzm: 4745, + gzn: 4746, + gzo: 4747, + gzp: 4748, + gzq: 4749, + gzr: 4750, + gzs: 4751, + gzt: 4752, + gzu: 4753, + gzv: 4754, + gzw: 4755, + gzx: 4756, + gzy: 4757, + gaz: 4758, + gaa: 4759, + gab: 4760, + gac: 4761, + gad: 4762, + gae: 4763, + gaf: 4764, + gag: 4765, + gah: 4766, + gai: 4767, + gaj: 4768, + gak: 4769, + gal: 4770, + gam: 4771, + gan: 4772, + gao: 4773, + gap: 4774, + gaq: 4775, + gar: 4776, + gas: 4777, + gat: 4778, + gau: 4779, + gav: 4780, + gaw: 4781, + gax: 4782, + gay: 4783, + gbz: 4784, + gba: 4785, + gbb: 4786, + gbc: 4787, + gbd: 4788, + gbe: 4789, + gbf: 4790, + gbg: 4791, + gbh: 4792, + gbi: 4793, + gbj: 4794, + gbk: 4795, + gbl: 4796, + gbm: 4797, + gbn: 4798, + gbo: 4799, + gbp: 4800, + gbq: 4801, + gbr: 4802, + gbs: 4803, + gbt: 4804, + gbu: 4805, + gbv: 4806, + gbw: 4807, + gbx: 4808, + gby: 4809, + gcz: 4810, + gca: 4811, + gcb: 4812, + gcc: 4813, + gcd: 4814, + gce: 4815, + gcf: 4816, + gcg: 4817, + gch: 4818, + gci: 4819, + gcj: 4820, + gck: 4821, + gcl: 4822, + gcm: 4823, + gcn: 4824, + gco: 4825, + gcp: 4826, + gcq: 4827, + gcr: 4828, + gcs: 4829, + gct: 4830, + gcu: 4831, + gcv: 4832, + gcw: 4833, + gcx: 4834, + gcy: 4835, + gdz: 4836, + gda: 4837, + gdb: 4838, + gdc: 4839, + gdd: 4840, + gde: 4841, + gdf: 4842, + gdg: 4843, + gdh: 4844, + gdi: 4845, + gdj: 4846, + gdk: 4847, + gdl: 4848, + gdm: 4849, + gdn: 4850, + gdo: 4851, + gdp: 4852, + gdq: 4853, + gdr: 4854, + gds: 4855, + gdt: 4856, + gdu: 4857, + gdv: 4858, + gdw: 4859, + gdx: 4860, + gdy: 4861, + gez: 4862, + gea: 4863, + geb: 4864, + gec: 4865, + ged: 4866, + gee: 4867, + gef: 4868, + geg: 4869, + geh: 4870, + gei: 4871, + gej: 4872, + gek: 4873, + gel: 4874, + gem: 4875, + gen: 4876, + geo: 4877, + gep: 4878, + geq: 4879, + ger: 4880, + ges: 4881, + get: 4882, + geu: 4883, + gev: 4884, + gew: 4885, + gex: 4886, + gey: 4887, + gfz: 4888, + gfa: 4889, + gfb: 4890, + gfc: 4891, + gfd: 4892, + gfe: 4893, + gff: 4894, + gfg: 4895, + gfh: 4896, + gfi: 4897, + gfj: 4898, + gfk: 4899, + gfl: 4900, + gfm: 4901, + gfn: 4902, + gfo: 4903, + gfp: 4904, + gfq: 4905, + gfr: 4906, + gfs: 4907, + gft: 4908, + gfu: 4909, + gfv: 4910, + gfw: 4911, + gfx: 4912, + gfy: 4913, + ggz: 4914, + gga: 4915, + ggb: 4916, + ggc: 4917, + ggd: 4918, + gge: 4919, + ggf: 4920, + ggg: 4921, + ggh: 4922, + ggi: 4923, + ggj: 4924, + ggk: 4925, + ggl: 4926, + ggm: 4927, + ggn: 4928, + ggo: 4929, + ggp: 4930, + ggq: 4931, + ggr: 4932, + ggs: 4933, + ggt: 4934, + ggu: 4935, + ggv: 4936, + ggw: 4937, + ggx: 4938, + ggy: 4939, + ghz: 4940, + gha: 4941, + ghb: 4942, + ghc: 4943, + ghd: 4944, + ghe: 4945, + ghf: 4946, + ghg: 4947, + ghh: 4948, + ghi: 4949, + ghj: 4950, + ghk: 4951, + ghl: 4952, + ghm: 4953, + ghn: 4954, + gho: 4955, + ghp: 4956, + ghq: 4957, + ghr: 4958, + ghs: 4959, + ght: 4960, + ghu: 4961, + ghv: 4962, + ghw: 4963, + ghx: 4964, + ghy: 4965, + giz: 4966, + gia: 4967, + gib: 4968, + gic: 4969, + gid: 4970, + gie: 4971, + gif: 4972, + gig: 4973, + gih: 4974, + gii: 4975, + gij: 4976, + gik: 4977, + gil: 4978, + gim: 4979, + gin: 4980, + gio: 4981, + gip: 4982, + giq: 4983, + gir: 4984, + gis: 4985, + git: 4986, + giu: 4987, + giv: 4988, + giw: 4989, + gix: 4990, + giy: 4991, + gjz: 4992, + gja: 4993, + gjb: 4994, + gjc: 4995, + gjd: 4996, + gje: 4997, + gjf: 4998, + gjg: 4999, + gjh: 5000, + gji: 5001, + gjj: 5002, + gjk: 5003, + gjl: 5004, + gjm: 5005, + gjn: 5006, + gjo: 5007, + gjp: 5008, + gjq: 5009, + gjr: 5010, + gjs: 5011, + gjt: 5012, + gju: 5013, + gjv: 5014, + gjw: 5015, + gjx: 5016, + gjy: 5017, + gkz: 5018, + gka: 5019, + gkb: 5020, + gkc: 5021, + gkd: 5022, + gke: 5023, + gkf: 5024, + gkg: 5025, + gkh: 5026, + gki: 5027, + gkj: 5028, + gkk: 5029, + gkl: 5030, + gkm: 5031, + gkn: 5032, + gko: 5033, + gkp: 5034, + gkq: 5035, + gkr: 5036, + gks: 5037, + gkt: 5038, + gku: 5039, + gkv: 5040, + gkw: 5041, + gkx: 5042, + gky: 5043, + glz: 5044, + gla: 5045, + glb: 5046, + glc: 5047, + gld: 5048, + gle: 5049, + glf: 5050, + glg: 5051, + glh: 5052, + gli: 5053, + glj: 5054, + glk: 5055, + gll: 5056, + glm: 5057, + gln: 5058, + glo: 5059, + glp: 5060, + glq: 5061, + glr: 5062, + gls: 5063, + glt: 5064, + glu: 5065, + glv: 5066, + glw: 5067, + glx: 5068, + gly: 5069, + gmz: 5070, + gma: 5071, + gmb: 5072, + gmc: 5073, + gmd: 5074, + gme: 5075, + gmf: 5076, + gmg: 5077, + gmh: 5078, + gmi: 5079, + gmj: 5080, + gmk: 5081, + gml: 5082, + gmm: 5083, + gmn: 5084, + gmo: 5085, + gmp: 5086, + gmq: 5087, + gmr: 5088, + gms: 5089, + gmt: 5090, + gmu: 5091, + gmv: 5092, + gmw: 5093, + gmx: 5094, + gmy: 5095, + gnz: 5096, + gna: 5097, + gnb: 5098, + gnc: 5099, + gnd: 5100, + gne: 5101, + gnf: 5102, + gng: 5103, + gnh: 5104, + gni: 5105, + gnj: 5106, + gnk: 5107, + gnl: 5108, + gnm: 5109, + gnn: 5110, + gno: 5111, + gnp: 5112, + gnq: 5113, + gnr: 5114, + gns: 5115, + gnt: 5116, + gnu: 5117, + gnv: 5118, + gnw: 5119, + gnx: 5120, + gny: 5121, + goz: 5122, + goa: 5123, + gob: 5124, + goc: 5125, + god: 5126, + goe: 5127, + gof: 5128, + gog: 5129, + goh: 5130, + goi: 5131, + goj: 5132, + gok: 5133, + gol: 5134, + gom: 5135, + gon: 5136, + goo: 5137, + gop: 5138, + goq: 5139, + gor: 5140, + gos: 5141, + got: 5142, + gou: 5143, + gov: 5144, + gow: 5145, + gox: 5146, + goy: 5147, + gpz: 5148, + gpa: 5149, + gpb: 5150, + gpc: 5151, + gpd: 5152, + gpe: 5153, + gpf: 5154, + gpg: 5155, + gph: 5156, + gpi: 5157, + gpj: 5158, + gpk: 5159, + gpl: 5160, + gpm: 5161, + gpn: 5162, + gpo: 5163, + gpp: 5164, + gpq: 5165, + gpr: 5166, + gps: 5167, + gpt: 5168, + gpu: 5169, + gpv: 5170, + gpw: 5171, + gpx: 5172, + gpy: 5173, + gqz: 5174, + gqa: 5175, + gqb: 5176, + gqc: 5177, + gqd: 5178, + gqe: 5179, + gqf: 5180, + gqg: 5181, + gqh: 5182, + gqi: 5183, + gqj: 5184, + gqk: 5185, + gql: 5186, + gqm: 5187, + gqn: 5188, + gqo: 5189, + gqp: 5190, + gqq: 5191, + gqr: 5192, + gqs: 5193, + gqt: 5194, + gqu: 5195, + gqv: 5196, + gqw: 5197, + gqx: 5198, + gqy: 5199, + grz: 5200, + gra: 5201, + grb: 5202, + grc: 5203, + grd: 5204, + gre: 5205, + grf: 5206, + grg: 5207, + grh: 5208, + gri: 5209, + grj: 5210, + grk: 5211, + grl: 5212, + grm: 5213, + grn: 5214, + gro: 5215, + grp: 5216, + grq: 5217, + grr: 5218, + grs: 5219, + grt: 5220, + gru: 5221, + grv: 5222, + grw: 5223, + grx: 5224, + gry: 5225, + gsz: 5226, + gsa: 5227, + gsb: 5228, + gsc: 5229, + gsd: 5230, + gse: 5231, + gsf: 5232, + gsg: 5233, + gsh: 5234, + gsi: 5235, + gsj: 5236, + gsk: 5237, + gsl: 5238, + gsm: 5239, + gsn: 5240, + gso: 5241, + gsp: 5242, + gsq: 5243, + gsr: 5244, + gss: 5245, + gst: 5246, + gsu: 5247, + gsv: 5248, + gsw: 5249, + gsx: 5250, + gsy: 5251, + gtz: 5252, + gta: 5253, + gtb: 5254, + gtc: 5255, + gtd: 5256, + gte: 5257, + gtf: 5258, + gtg: 5259, + gth: 5260, + gti: 5261, + gtj: 5262, + gtk: 5263, + gtl: 5264, + gtm: 5265, + gtn: 5266, + gto: 5267, + gtp: 5268, + gtq: 5269, + gtr: 5270, + gts: 5271, + gtt: 5272, + gtu: 5273, + gtv: 5274, + gtw: 5275, + gtx: 5276, + gty: 5277, + guz: 5278, + gua: 5279, + gub: 5280, + guc: 5281, + gud: 5282, + gue: 5283, + guf: 5284, + gug: 5285, + guh: 5286, + gui: 5287, + guj: 5288, + guk: 5289, + gul: 5290, + gum: 5291, + gun: 5292, + guo: 5293, + gup: 5294, + guq: 5295, + gur: 5296, + gus: 5297, + gut: 5298, + guu: 5299, + guv: 5300, + guw: 5301, + gux: 5302, + guy: 5303, + gvz: 5304, + gva: 5305, + gvb: 5306, + gvc: 5307, + gvd: 5308, + gve: 5309, + gvf: 5310, + gvg: 5311, + gvh: 5312, + gvi: 5313, + gvj: 5314, + gvk: 5315, + gvl: 5316, + gvm: 5317, + gvn: 5318, + gvo: 5319, + gvp: 5320, + gvq: 5321, + gvr: 5322, + gvs: 5323, + gvt: 5324, + gvu: 5325, + gvv: 5326, + gvw: 5327, + gvx: 5328, + gvy: 5329, + gwz: 5330, + gwa: 5331, + gwb: 5332, + gwc: 5333, + gwd: 5334, + gwe: 5335, + gwf: 5336, + gwg: 5337, + gwh: 5338, + gwi: 5339, + gwj: 5340, + gwk: 5341, + gwl: 5342, + gwm: 5343, + gwn: 5344, + gwo: 5345, + gwp: 5346, + gwq: 5347, + gwr: 5348, + gws: 5349, + gwt: 5350, + gwu: 5351, + gwv: 5352, + gww: 5353, + gwx: 5354, + gwy: 5355, + gxz: 5356, + gxa: 5357, + gxb: 5358, + gxc: 5359, + gxd: 5360, + gxe: 5361, + gxf: 5362, + gxg: 5363, + gxh: 5364, + gxi: 5365, + gxj: 5366, + gxk: 5367, + gxl: 5368, + gxm: 5369, + gxn: 5370, + gxo: 5371, + gxp: 5372, + gxq: 5373, + gxr: 5374, + gxs: 5375, + gxt: 5376, + gxu: 5377, + gxv: 5378, + gxw: 5379, + gxx: 5380, + gxy: 5381, + gyz: 5382, + gya: 5383, + gyb: 5384, + gyc: 5385, + gyd: 5386, + gye: 5387, + gyf: 5388, + gyg: 5389, + gyh: 5390, + gyi: 5391, + gyj: 5392, + gyk: 5393, + gyl: 5394, + gym: 5395, + gyn: 5396, + gyo: 5397, + gyp: 5398, + gyq: 5399, + gyr: 5400, + gys: 5401, + gyt: 5402, + gyu: 5403, + gyv: 5404, + gyw: 5405, + gyx: 5406, + gyy: 5407, + hzz: 5408, + hza: 5409, + hzb: 5410, + hzc: 5411, + hzd: 5412, + hze: 5413, + hzf: 5414, + hzg: 5415, + hzh: 5416, + hzi: 5417, + hzj: 5418, + hzk: 5419, + hzl: 5420, + hzm: 5421, + hzn: 5422, + hzo: 5423, + hzp: 5424, + hzq: 5425, + hzr: 5426, + hzs: 5427, + hzt: 5428, + hzu: 5429, + hzv: 5430, + hzw: 5431, + hzx: 5432, + hzy: 5433, + haz: 5434, + haa: 5435, + hab: 5436, + hac: 5437, + had: 5438, + hae: 5439, + haf: 5440, + hag: 5441, + hah: 5442, + hai: 5443, + haj: 5444, + hak: 5445, + hal: 5446, + ham: 5447, + han: 5448, + hao: 5449, + hap: 5450, + haq: 5451, + har: 5452, + has: 5453, + hat: 5454, + hau: 5455, + hav: 5456, + haw: 5457, + hax: 5458, + hay: 5459, + hbz: 5460, + hba: 5461, + hbb: 5462, + hbc: 5463, + hbd: 5464, + hbe: 5465, + hbf: 5466, + hbg: 5467, + hbh: 5468, + hbi: 5469, + hbj: 5470, + hbk: 5471, + hbl: 5472, + hbm: 5473, + hbn: 5474, + hbo: 5475, + hbp: 5476, + hbq: 5477, + hbr: 5478, + hbs: 5479, + hbt: 5480, + hbu: 5481, + hbv: 5482, + hbw: 5483, + hbx: 5484, + hby: 5485, + hcz: 5486, + hca: 5487, + hcb: 5488, + hcc: 5489, + hcd: 5490, + hce: 5491, + hcf: 5492, + hcg: 5493, + hch: 5494, + hci: 5495, + hcj: 5496, + hck: 5497, + hcl: 5498, + hcm: 5499, + hcn: 5500, + hco: 5501, + hcp: 5502, + hcq: 5503, + hcr: 5504, + hcs: 5505, + hct: 5506, + hcu: 5507, + hcv: 5508, + hcw: 5509, + hcx: 5510, + hcy: 5511, + hdz: 5512, + hda: 5513, + hdb: 5514, + hdc: 5515, + hdd: 5516, + hde: 5517, + hdf: 5518, + hdg: 5519, + hdh: 5520, + hdi: 5521, + hdj: 5522, + hdk: 5523, + hdl: 5524, + hdm: 5525, + hdn: 5526, + hdo: 5527, + hdp: 5528, + hdq: 5529, + hdr: 5530, + hds: 5531, + hdt: 5532, + hdu: 5533, + hdv: 5534, + hdw: 5535, + hdx: 5536, + hdy: 5537, + hez: 5538, + hea: 5539, + heb: 5540, + hec: 5541, + hed: 5542, + hee: 5543, + hef: 5544, + heg: 5545, + heh: 5546, + hei: 5547, + hej: 5548, + hek: 5549, + hel: 5550, + hem: 5551, + hen: 5552, + heo: 5553, + hep: 5554, + heq: 5555, + her: 5556, + hes: 5557, + het: 5558, + heu: 5559, + hev: 5560, + hew: 5561, + hex: 5562, + hey: 5563, + hfz: 5564, + hfa: 5565, + hfb: 5566, + hfc: 5567, + hfd: 5568, + hfe: 5569, + hff: 5570, + hfg: 5571, + hfh: 5572, + hfi: 5573, + hfj: 5574, + hfk: 5575, + hfl: 5576, + hfm: 5577, + hfn: 5578, + hfo: 5579, + hfp: 5580, + hfq: 5581, + hfr: 5582, + hfs: 5583, + hft: 5584, + hfu: 5585, + hfv: 5586, + hfw: 5587, + hfx: 5588, + hfy: 5589, + hgz: 5590, + hga: 5591, + hgb: 5592, + hgc: 5593, + hgd: 5594, + hge: 5595, + hgf: 5596, + hgg: 5597, + hgh: 5598, + hgi: 5599, + hgj: 5600, + hgk: 5601, + hgl: 5602, + hgm: 5603, + hgn: 5604, + hgo: 5605, + hgp: 5606, + hgq: 5607, + hgr: 5608, + hgs: 5609, + hgt: 5610, + hgu: 5611, + hgv: 5612, + hgw: 5613, + hgx: 5614, + hgy: 5615, + hhz: 5616, + hha: 5617, + hhb: 5618, + hhc: 5619, + hhd: 5620, + hhe: 5621, + hhf: 5622, + hhg: 5623, + hhh: 5624, + hhi: 5625, + hhj: 5626, + hhk: 5627, + hhl: 5628, + hhm: 5629, + hhn: 5630, + hho: 5631, + hhp: 5632, + hhq: 5633, + hhr: 5634, + hhs: 5635, + hht: 5636, + hhu: 5637, + hhv: 5638, + hhw: 5639, + hhx: 5640, + hhy: 5641, + hiz: 5642, + hia: 5643, + hib: 5644, + hic: 5645, + hid: 5646, + hie: 5647, + hif: 5648, + hig: 5649, + hih: 5650, + hii: 5651, + hij: 5652, + hik: 5653, + hil: 5654, + him: 5655, + hin: 5656, + hio: 5657, + hip: 5658, + hiq: 5659, + hir: 5660, + his: 5661, + hit: 5662, + hiu: 5663, + hiv: 5664, + hiw: 5665, + hix: 5666, + hiy: 5667, + hjz: 5668, + hja: 5669, + hjb: 5670, + hjc: 5671, + hjd: 5672, + hje: 5673, + hjf: 5674, + hjg: 5675, + hjh: 5676, + hji: 5677, + hjj: 5678, + hjk: 5679, + hjl: 5680, + hjm: 5681, + hjn: 5682, + hjo: 5683, + hjp: 5684, + hjq: 5685, + hjr: 5686, + hjs: 5687, + hjt: 5688, + hju: 5689, + hjv: 5690, + hjw: 5691, + hjx: 5692, + hjy: 5693, + hkz: 5694, + hka: 5695, + hkb: 5696, + hkc: 5697, + hkd: 5698, + hke: 5699, + hkf: 5700, + hkg: 5701, + hkh: 5702, + hki: 5703, + hkj: 5704, + hkk: 5705, + hkl: 5706, + hkm: 5707, + hkn: 5708, + hko: 5709, + hkp: 5710, + hkq: 5711, + hkr: 5712, + hks: 5713, + hkt: 5714, + hku: 5715, + hkv: 5716, + hkw: 5717, + hkx: 5718, + hky: 5719, + hlz: 5720, + hla: 5721, + hlb: 5722, + hlc: 5723, + hld: 5724, + hle: 5725, + hlf: 5726, + hlg: 5727, + hlh: 5728, + hli: 5729, + hlj: 5730, + hlk: 5731, + hll: 5732, + hlm: 5733, + hln: 5734, + hlo: 5735, + hlp: 5736, + hlq: 5737, + hlr: 5738, + hls: 5739, + hlt: 5740, + hlu: 5741, + hlv: 5742, + hlw: 5743, + hlx: 5744, + hly: 5745, + hmz: 5746, + hma: 5747, + hmb: 5748, + hmc: 5749, + hmd: 5750, + hme: 5751, + hmf: 5752, + hmg: 5753, + hmh: 5754, + hmi: 5755, + hmj: 5756, + hmk: 5757, + hml: 5758, + hmm: 5759, + hmn: 5760, + hmo: 5761, + hmp: 5762, + hmq: 5763, + hmr: 5764, + hms: 5765, + hmt: 5766, + hmu: 5767, + hmv: 5768, + hmw: 5769, + hmx: 5770, + hmy: 5771, + hnz: 5772, + hna: 5773, + hnb: 5774, + hnc: 5775, + hnd: 5776, + hne: 5777, + hnf: 5778, + hng: 5779, + hnh: 5780, + hni: 5781, + hnj: 5782, + hnk: 5783, + hnl: 5784, + hnm: 5785, + hnn: 5786, + hno: 5787, + hnp: 5788, + hnq: 5789, + hnr: 5790, + hns: 5791, + hnt: 5792, + hnu: 5793, + hnv: 5794, + hnw: 5795, + hnx: 5796, + hny: 5797, + hoz: 5798, + hoa: 5799, + hob: 5800, + hoc: 5801, + hod: 5802, + hoe: 5803, + hof: 5804, + hog: 5805, + hoh: 5806, + hoi: 5807, + hoj: 5808, + hok: 5809, + hol: 5810, + hom: 5811, + hon: 5812, + hoo: 5813, + hop: 5814, + hoq: 5815, + hor: 5816, + hos: 5817, + hot: 5818, + hou: 5819, + hov: 5820, + how: 5821, + hox: 5822, + hoy: 5823, + hpz: 5824, + hpa: 5825, + hpb: 5826, + hpc: 5827, + hpd: 5828, + hpe: 5829, + hpf: 5830, + hpg: 5831, + hph: 5832, + hpi: 5833, + hpj: 5834, + hpk: 5835, + hpl: 5836, + hpm: 5837, + hpn: 5838, + hpo: 5839, + hpp: 5840, + hpq: 5841, + hpr: 5842, + hps: 5843, + hpt: 5844, + hpu: 5845, + hpv: 5846, + hpw: 5847, + hpx: 5848, + hpy: 5849, + hqz: 5850, + hqa: 5851, + hqb: 5852, + hqc: 5853, + hqd: 5854, + hqe: 5855, + hqf: 5856, + hqg: 5857, + hqh: 5858, + hqi: 5859, + hqj: 5860, + hqk: 5861, + hql: 5862, + hqm: 5863, + hqn: 5864, + hqo: 5865, + hqp: 5866, + hqq: 5867, + hqr: 5868, + hqs: 5869, + hqt: 5870, + hqu: 5871, + hqv: 5872, + hqw: 5873, + hqx: 5874, + hqy: 5875, + hrz: 5876, + hra: 5877, + hrb: 5878, + hrc: 5879, + hrd: 5880, + hre: 5881, + hrf: 5882, + hrg: 5883, + hrh: 5884, + hri: 5885, + hrj: 5886, + hrk: 5887, + hrl: 5888, + hrm: 5889, + hrn: 5890, + hro: 5891, + hrp: 5892, + hrq: 5893, + hrr: 5894, + hrs: 5895, + hrt: 5896, + hru: 5897, + hrv: 5898, + hrw: 5899, + hrx: 5900, + hry: 5901, + hsz: 5902, + hsa: 5903, + hsb: 5904, + hsc: 5905, + hsd: 5906, + hse: 5907, + hsf: 5908, + hsg: 5909, + hsh: 5910, + hsi: 5911, + hsj: 5912, + hsk: 5913, + hsl: 5914, + hsm: 5915, + hsn: 5916, + hso: 5917, + hsp: 5918, + hsq: 5919, + hsr: 5920, + hss: 5921, + hst: 5922, + hsu: 5923, + hsv: 5924, + hsw: 5925, + hsx: 5926, + hsy: 5927, + htz: 5928, + hta: 5929, + htb: 5930, + htc: 5931, + htd: 5932, + hte: 5933, + htf: 5934, + htg: 5935, + hth: 5936, + hti: 5937, + htj: 5938, + htk: 5939, + htl: 5940, + htm: 5941, + htn: 5942, + hto: 5943, + htp: 5944, + htq: 5945, + htr: 5946, + hts: 5947, + htt: 5948, + htu: 5949, + htv: 5950, + htw: 5951, + htx: 5952, + hty: 5953, + huz: 5954, + hua: 5955, + hub: 5956, + huc: 5957, + hud: 5958, + hue: 5959, + huf: 5960, + hug: 5961, + huh: 5962, + hui: 5963, + huj: 5964, + huk: 5965, + hul: 5966, + hum: 5967, + hun: 5968, + huo: 5969, + hup: 5970, + huq: 5971, + hur: 5972, + hus: 5973, + hut: 5974, + huu: 5975, + huv: 5976, + huw: 5977, + hux: 5978, + huy: 5979, + hvz: 5980, + hva: 5981, + hvb: 5982, + hvc: 5983, + hvd: 5984, + hve: 5985, + hvf: 5986, + hvg: 5987, + hvh: 5988, + hvi: 5989, + hvj: 5990, + hvk: 5991, + hvl: 5992, + hvm: 5993, + hvn: 5994, + hvo: 5995, + hvp: 5996, + hvq: 5997, + hvr: 5998, + hvs: 5999, + hvt: 6000, + hvu: 6001, + hvv: 6002, + hvw: 6003, + hvx: 6004, + hvy: 6005, + hwz: 6006, + hwa: 6007, + hwb: 6008, + hwc: 6009, + hwd: 6010, + hwe: 6011, + hwf: 6012, + hwg: 6013, + hwh: 6014, + hwi: 6015, + hwj: 6016, + hwk: 6017, + hwl: 6018, + hwm: 6019, + hwn: 6020, + hwo: 6021, + hwp: 6022, + hwq: 6023, + hwr: 6024, + hws: 6025, + hwt: 6026, + hwu: 6027, + hwv: 6028, + hww: 6029, + hwx: 6030, + hwy: 6031, + hxz: 6032, + hxa: 6033, + hxb: 6034, + hxc: 6035, + hxd: 6036, + hxe: 6037, + hxf: 6038, + hxg: 6039, + hxh: 6040, + hxi: 6041, + hxj: 6042, + hxk: 6043, + hxl: 6044, + hxm: 6045, + hxn: 6046, + hxo: 6047, + hxp: 6048, + hxq: 6049, + hxr: 6050, + hxs: 6051, + hxt: 6052, + hxu: 6053, + hxv: 6054, + hxw: 6055, + hxx: 6056, + hxy: 6057, + hyz: 6058, + hya: 6059, + hyb: 6060, + hyc: 6061, + hyd: 6062, + hye: 6063, + hyf: 6064, + hyg: 6065, + hyh: 6066, + hyi: 6067, + hyj: 6068, + hyk: 6069, + hyl: 6070, + hym: 6071, + hyn: 6072, + hyo: 6073, + hyp: 6074, + hyq: 6075, + hyr: 6076, + hys: 6077, + hyt: 6078, + hyu: 6079, + hyv: 6080, + hyw: 6081, + hyx: 6082, + hyy: 6083, + izz: 6084, + iza: 6085, + izb: 6086, + izc: 6087, + izd: 6088, + ize: 6089, + izf: 6090, + izg: 6091, + izh: 6092, + izi: 6093, + izj: 6094, + izk: 6095, + izl: 6096, + izm: 6097, + izn: 6098, + izo: 6099, + izp: 6100, + izq: 6101, + izr: 6102, + izs: 6103, + izt: 6104, + izu: 6105, + izv: 6106, + izw: 6107, + izx: 6108, + izy: 6109, + iaz: 6110, + iaa: 6111, + iab: 6112, + iac: 6113, + iad: 6114, + iae: 6115, + iaf: 6116, + iag: 6117, + iah: 6118, + iai: 6119, + iaj: 6120, + iak: 6121, + ial: 6122, + iam: 6123, + ian: 6124, + iao: 6125, + iap: 6126, + iaq: 6127, + iar: 6128, + ias: 6129, + iat: 6130, + iau: 6131, + iav: 6132, + iaw: 6133, + iax: 6134, + iay: 6135, + ibz: 6136, + iba: 6137, + ibb: 6138, + ibc: 6139, + ibd: 6140, + ibe: 6141, + ibf: 6142, + ibg: 6143, + ibh: 6144, + ibi: 6145, + ibj: 6146, + ibk: 6147, + ibl: 6148, + ibm: 6149, + ibn: 6150, + ibo: 6151, + ibp: 6152, + ibq: 6153, + ibr: 6154, + ibs: 6155, + ibt: 6156, + ibu: 6157, + ibv: 6158, + ibw: 6159, + ibx: 6160, + iby: 6161, + icz: 6162, + ica: 6163, + icb: 6164, + icc: 6165, + icd: 6166, + ice: 6167, + icf: 6168, + icg: 6169, + ich: 6170, + ici: 6171, + icj: 6172, + ick: 6173, + icl: 6174, + icm: 6175, + icn: 6176, + ico: 6177, + icp: 6178, + icq: 6179, + icr: 6180, + ics: 6181, + ict: 6182, + icu: 6183, + icv: 6184, + icw: 6185, + icx: 6186, + icy: 6187, + idz: 6188, + ida: 6189, + idb: 6190, + idc: 6191, + idd: 6192, + ide: 6193, + idf: 6194, + idg: 6195, + idh: 6196, + idi: 6197, + idj: 6198, + idk: 6199, + idl: 6200, + idm: 6201, + idn: 6202, + ido: 6203, + idp: 6204, + idq: 6205, + idr: 6206, + ids: 6207, + idt: 6208, + idu: 6209, + idv: 6210, + idw: 6211, + idx: 6212, + idy: 6213, + iez: 6214, + iea: 6215, + ieb: 6216, + iec: 6217, + ied: 6218, + iee: 6219, + ief: 6220, + ieg: 6221, + ieh: 6222, + iei: 6223, + iej: 6224, + iek: 6225, + iel: 6226, + iem: 6227, + ien: 6228, + ieo: 6229, + iep: 6230, + ieq: 6231, + ier: 6232, + ies: 6233, + iet: 6234, + ieu: 6235, + iev: 6236, + iew: 6237, + iex: 6238, + iey: 6239, + ifz: 6240, + ifa: 6241, + ifb: 6242, + ifc: 6243, + ifd: 6244, + ife: 6245, + iff: 6246, + ifg: 6247, + ifh: 6248, + ifi: 6249, + ifj: 6250, + ifk: 6251, + ifl: 6252, + ifm: 6253, + ifn: 6254, + ifo: 6255, + ifp: 6256, + ifq: 6257, + ifr: 6258, + ifs: 6259, + ift: 6260, + ifu: 6261, + ifv: 6262, + ifw: 6263, + ifx: 6264, + ify: 6265, + igz: 6266, + iga: 6267, + igb: 6268, + igc: 6269, + igd: 6270, + ige: 6271, + igf: 6272, + igg: 6273, + igh: 6274, + igi: 6275, + igj: 6276, + igk: 6277, + igl: 6278, + igm: 6279, + ign: 6280, + igo: 6281, + igp: 6282, + igq: 6283, + igr: 6284, + igs: 6285, + igt: 6286, + igu: 6287, + igv: 6288, + igw: 6289, + igx: 6290, + igy: 6291, + ihz: 6292, + iha: 6293, + ihb: 6294, + ihc: 6295, + ihd: 6296, + ihe: 6297, + ihf: 6298, + ihg: 6299, + ihh: 6300, + ihi: 6301, + ihj: 6302, + ihk: 6303, + ihl: 6304, + ihm: 6305, + ihn: 6306, + iho: 6307, + ihp: 6308, + ihq: 6309, + ihr: 6310, + ihs: 6311, + iht: 6312, + ihu: 6313, + ihv: 6314, + ihw: 6315, + ihx: 6316, + ihy: 6317, + iiz: 6318, + iia: 6319, + iib: 6320, + iic: 6321, + iid: 6322, + iie: 6323, + iif: 6324, + iig: 6325, + iih: 6326, + iii: 6327, + iij: 6328, + iik: 6329, + iil: 6330, + iim: 6331, + iin: 6332, + iio: 6333, + iip: 6334, + iiq: 6335, + iir: 6336, + iis: 6337, + iit: 6338, + iiu: 6339, + iiv: 6340, + iiw: 6341, + iix: 6342, + iiy: 6343, + ijz: 6344, + ija: 6345, + ijb: 6346, + ijc: 6347, + ijd: 6348, + ije: 6349, + ijf: 6350, + ijg: 6351, + ijh: 6352, + iji: 6353, + ijj: 6354, + ijk: 6355, + ijl: 6356, + ijm: 6357, + ijn: 6358, + ijo: 6359, + ijp: 6360, + ijq: 6361, + ijr: 6362, + ijs: 6363, + ijt: 6364, + iju: 6365, + ijv: 6366, + ijw: 6367, + ijx: 6368, + ijy: 6369, + ikz: 6370, + ika: 6371, + ikb: 6372, + ikc: 6373, + ikd: 6374, + ike: 6375, + ikf: 6376, + ikg: 6377, + ikh: 6378, + iki: 6379, + ikj: 6380, + ikk: 6381, + ikl: 6382, + ikm: 6383, + ikn: 6384, + iko: 6385, + ikp: 6386, + ikq: 6387, + ikr: 6388, + iks: 6389, + ikt: 6390, + iku: 6391, + ikv: 6392, + ikw: 6393, + ikx: 6394, + iky: 6395, + ilz: 6396, + ila: 6397, + ilb: 6398, + ilc: 6399, + ild: 6400, + ile: 6401, + ilf: 6402, + ilg: 6403, + ilh: 6404, + ili: 6405, + ilj: 6406, + ilk: 6407, + ill: 6408, + ilm: 6409, + iln: 6410, + ilo: 6411, + ilp: 6412, + ilq: 6413, + ilr: 6414, + ils: 6415, + ilt: 6416, + ilu: 6417, + ilv: 6418, + ilw: 6419, + ilx: 6420, + ily: 6421, + imz: 6422, + ima: 6423, + imb: 6424, + imc: 6425, + imd: 6426, + ime: 6427, + imf: 6428, + img: 6429, + imh: 6430, + imi: 6431, + imj: 6432, + imk: 6433, + iml: 6434, + imm: 6435, + imn: 6436, + imo: 6437, + imp: 6438, + imq: 6439, + imr: 6440, + ims: 6441, + imt: 6442, + imu: 6443, + imv: 6444, + imw: 6445, + imx: 6446, + imy: 6447, + inz: 6448, + ina: 6449, + inb: 6450, + inc: 6451, + ind: 6452, + ine: 6453, + inf: 6454, + ing: 6455, + inh: 6456, + ini: 6457, + inj: 6458, + ink: 6459, + inl: 6460, + inm: 6461, + inn: 6462, + ino: 6463, + inp: 6464, + inq: 6465, + inr: 6466, + ins: 6467, + int: 6468, + inu: 6469, + inv: 6470, + inw: 6471, + inx: 6472, + iny: 6473, + ioz: 6474, + ioa: 6475, + iob: 6476, + ioc: 6477, + iod: 6478, + ioe: 6479, + iof: 6480, + iog: 6481, + ioh: 6482, + ioi: 6483, + ioj: 6484, + iok: 6485, + iol: 6486, + iom: 6487, + ion: 6488, + ioo: 6489, + iop: 6490, + ioq: 6491, + ior: 6492, + ios: 6493, + iot: 6494, + iou: 6495, + iov: 6496, + iow: 6497, + iox: 6498, + ioy: 6499, + ipz: 6500, + ipa: 6501, + ipb: 6502, + ipc: 6503, + ipd: 6504, + ipe: 6505, + ipf: 6506, + ipg: 6507, + iph: 6508, + ipi: 6509, + ipj: 6510, + ipk: 6511, + ipl: 6512, + ipm: 6513, + ipn: 6514, + ipo: 6515, + ipp: 6516, + ipq: 6517, + ipr: 6518, + ips: 6519, + ipt: 6520, + ipu: 6521, + ipv: 6522, + ipw: 6523, + ipx: 6524, + ipy: 6525, + iqz: 6526, + iqa: 6527, + iqb: 6528, + iqc: 6529, + iqd: 6530, + iqe: 6531, + iqf: 6532, + iqg: 6533, + iqh: 6534, + iqi: 6535, + iqj: 6536, + iqk: 6537, + iql: 6538, + iqm: 6539, + iqn: 6540, + iqo: 6541, + iqp: 6542, + iqq: 6543, + iqr: 6544, + iqs: 6545, + iqt: 6546, + iqu: 6547, + iqv: 6548, + iqw: 6549, + iqx: 6550, + iqy: 6551, + irz: 6552, + ira: 6553, + irb: 6554, + irc: 6555, + ird: 6556, + ire: 6557, + irf: 6558, + irg: 6559, + irh: 6560, + iri: 6561, + irj: 6562, + irk: 6563, + irl: 6564, + irm: 6565, + irn: 6566, + iro: 6567, + irp: 6568, + irq: 6569, + irr: 6570, + irs: 6571, + irt: 6572, + iru: 6573, + irv: 6574, + irw: 6575, + irx: 6576, + iry: 6577, + isz: 6578, + isa: 6579, + isb: 6580, + isc: 6581, + isd: 6582, + ise: 6583, + isf: 6584, + isg: 6585, + ish: 6586, + isi: 6587, + isj: 6588, + isk: 6589, + isl: 6590, + ism: 6591, + isn: 6592, + iso: 6593, + isp: 6594, + isq: 6595, + isr: 6596, + iss: 6597, + ist: 6598, + isu: 6599, + isv: 6600, + isw: 6601, + isx: 6602, + isy: 6603, + itz: 6604, + ita: 6605, + itb: 6606, + itc: 6607, + itd: 6608, + ite: 6609, + itf: 6610, + itg: 6611, + ith: 6612, + iti: 6613, + itj: 6614, + itk: 6615, + itl: 6616, + itm: 6617, + itn: 6618, + ito: 6619, + itp: 6620, + itq: 6621, + itr: 6622, + its: 6623, + itt: 6624, + itu: 6625, + itv: 6626, + itw: 6627, + itx: 6628, + ity: 6629, + iuz: 6630, + iua: 6631, + iub: 6632, + iuc: 6633, + iud: 6634, + iue: 6635, + iuf: 6636, + iug: 6637, + iuh: 6638, + iui: 6639, + iuj: 6640, + iuk: 6641, + iul: 6642, + ium: 6643, + iun: 6644, + iuo: 6645, + iup: 6646, + iuq: 6647, + iur: 6648, + ius: 6649, + iut: 6650, + iuu: 6651, + iuv: 6652, + iuw: 6653, + iux: 6654, + iuy: 6655, + ivz: 6656, + iva: 6657, + ivb: 6658, + ivc: 6659, + ivd: 6660, + ive: 6661, + ivf: 6662, + ivg: 6663, + ivh: 6664, + ivi: 6665, + ivj: 6666, + ivk: 6667, + ivl: 6668, + ivm: 6669, + ivn: 6670, + ivo: 6671, + ivp: 6672, + ivq: 6673, + ivr: 6674, + ivs: 6675, + ivt: 6676, + ivu: 6677, + ivv: 6678, + ivw: 6679, + ivx: 6680, + ivy: 6681, + iwz: 6682, + iwa: 6683, + iwb: 6684, + iwc: 6685, + iwd: 6686, + iwe: 6687, + iwf: 6688, + iwg: 6689, + iwh: 6690, + iwi: 6691, + iwj: 6692, + iwk: 6693, + iwl: 6694, + iwm: 6695, + iwn: 6696, + iwo: 6697, + iwp: 6698, + iwq: 6699, + iwr: 6700, + iws: 6701, + iwt: 6702, + iwu: 6703, + iwv: 6704, + iww: 6705, + iwx: 6706, + iwy: 6707, + ixz: 6708, + ixa: 6709, + ixb: 6710, + ixc: 6711, + ixd: 6712, + ixe: 6713, + ixf: 6714, + ixg: 6715, + ixh: 6716, + ixi: 6717, + ixj: 6718, + ixk: 6719, + ixl: 6720, + ixm: 6721, + ixn: 6722, + ixo: 6723, + ixp: 6724, + ixq: 6725, + ixr: 6726, + ixs: 6727, + ixt: 6728, + ixu: 6729, + ixv: 6730, + ixw: 6731, + ixx: 6732, + ixy: 6733, + iyz: 6734, + iya: 6735, + iyb: 6736, + iyc: 6737, + iyd: 6738, + iye: 6739, + iyf: 6740, + iyg: 6741, + iyh: 6742, + iyi: 6743, + iyj: 6744, + iyk: 6745, + iyl: 6746, + iym: 6747, + iyn: 6748, + iyo: 6749, + iyp: 6750, + iyq: 6751, + iyr: 6752, + iys: 6753, + iyt: 6754, + iyu: 6755, + iyv: 6756, + iyw: 6757, + iyx: 6758, + iyy: 6759, + jzz: 6760, + jza: 6761, + jzb: 6762, + jzc: 6763, + jzd: 6764, + jze: 6765, + jzf: 6766, + jzg: 6767, + jzh: 6768, + jzi: 6769, + jzj: 6770, + jzk: 6771, + jzl: 6772, + jzm: 6773, + jzn: 6774, + jzo: 6775, + jzp: 6776, + jzq: 6777, + jzr: 6778, + jzs: 6779, + jzt: 6780, + jzu: 6781, + jzv: 6782, + jzw: 6783, + jzx: 6784, + jzy: 6785, + jaz: 6786, + jaa: 6787, + jab: 6788, + jac: 6789, + jad: 6790, + jae: 6791, + jaf: 6792, + jag: 6793, + jah: 6794, + jai: 6795, + jaj: 6796, + jak: 6797, + jal: 6798, + jam: 6799, + jan: 6800, + jao: 6801, + jap: 6802, + jaq: 6803, + jar: 6804, + jas: 6805, + jat: 6806, + jau: 6807, + jav: 6808, + jaw: 6809, + jax: 6810, + jay: 6811, + jbz: 6812, + jba: 6813, + jbb: 6814, + jbc: 6815, + jbd: 6816, + jbe: 6817, + jbf: 6818, + jbg: 6819, + jbh: 6820, + jbi: 6821, + jbj: 6822, + jbk: 6823, + jbl: 6824, + jbm: 6825, + jbn: 6826, + jbo: 6827, + jbp: 6828, + jbq: 6829, + jbr: 6830, + jbs: 6831, + jbt: 6832, + jbu: 6833, + jbv: 6834, + jbw: 6835, + jbx: 6836, + jby: 6837, + jcz: 6838, + jca: 6839, + jcb: 6840, + jcc: 6841, + jcd: 6842, + jce: 6843, + jcf: 6844, + jcg: 6845, + jch: 6846, + jci: 6847, + jcj: 6848, + jck: 6849, + jcl: 6850, + jcm: 6851, + jcn: 6852, + jco: 6853, + jcp: 6854, + jcq: 6855, + jcr: 6856, + jcs: 6857, + jct: 6858, + jcu: 6859, + jcv: 6860, + jcw: 6861, + jcx: 6862, + jcy: 6863, + jdz: 6864, + jda: 6865, + jdb: 6866, + jdc: 6867, + jdd: 6868, + jde: 6869, + jdf: 6870, + jdg: 6871, + jdh: 6872, + jdi: 6873, + jdj: 6874, + jdk: 6875, + jdl: 6876, + jdm: 6877, + jdn: 6878, + jdo: 6879, + jdp: 6880, + jdq: 6881, + jdr: 6882, + jds: 6883, + jdt: 6884, + jdu: 6885, + jdv: 6886, + jdw: 6887, + jdx: 6888, + jdy: 6889, + jez: 6890, + jea: 6891, + jeb: 6892, + jec: 6893, + jed: 6894, + jee: 6895, + jef: 6896, + jeg: 6897, + jeh: 6898, + jei: 6899, + jej: 6900, + jek: 6901, + jel: 6902, + jem: 6903, + jen: 6904, + jeo: 6905, + jep: 6906, + jeq: 6907, + jer: 6908, + jes: 6909, + jet: 6910, + jeu: 6911, + jev: 6912, + jew: 6913, + jex: 6914, + jey: 6915, + jfz: 6916, + jfa: 6917, + jfb: 6918, + jfc: 6919, + jfd: 6920, + jfe: 6921, + jff: 6922, + jfg: 6923, + jfh: 6924, + jfi: 6925, + jfj: 6926, + jfk: 6927, + jfl: 6928, + jfm: 6929, + jfn: 6930, + jfo: 6931, + jfp: 6932, + jfq: 6933, + jfr: 6934, + jfs: 6935, + jft: 6936, + jfu: 6937, + jfv: 6938, + jfw: 6939, + jfx: 6940, + jfy: 6941, + jgz: 6942, + jga: 6943, + jgb: 6944, + jgc: 6945, + jgd: 6946, + jge: 6947, + jgf: 6948, + jgg: 6949, + jgh: 6950, + jgi: 6951, + jgj: 6952, + jgk: 6953, + jgl: 6954, + jgm: 6955, + jgn: 6956, + jgo: 6957, + jgp: 6958, + jgq: 6959, + jgr: 6960, + jgs: 6961, + jgt: 6962, + jgu: 6963, + jgv: 6964, + jgw: 6965, + jgx: 6966, + jgy: 6967, + jhz: 6968, + jha: 6969, + jhb: 6970, + jhc: 6971, + jhd: 6972, + jhe: 6973, + jhf: 6974, + jhg: 6975, + jhh: 6976, + jhi: 6977, + jhj: 6978, + jhk: 6979, + jhl: 6980, + jhm: 6981, + jhn: 6982, + jho: 6983, + jhp: 6984, + jhq: 6985, + jhr: 6986, + jhs: 6987, + jht: 6988, + jhu: 6989, + jhv: 6990, + jhw: 6991, + jhx: 6992, + jhy: 6993, + jiz: 6994, + jia: 6995, + jib: 6996, + jic: 6997, + jid: 6998, + jie: 6999, + jif: 7000, + jig: 7001, + jih: 7002, + jii: 7003, + jij: 7004, + jik: 7005, + jil: 7006, + jim: 7007, + jin: 7008, + jio: 7009, + jip: 7010, + jiq: 7011, + jir: 7012, + jis: 7013, + jit: 7014, + jiu: 7015, + jiv: 7016, + jiw: 7017, + jix: 7018, + jiy: 7019, + jjz: 7020, + jja: 7021, + jjb: 7022, + jjc: 7023, + jjd: 7024, + jje: 7025, + jjf: 7026, + jjg: 7027, + jjh: 7028, + jji: 7029, + jjj: 7030, + jjk: 7031, + jjl: 7032, + jjm: 7033, + jjn: 7034, + jjo: 7035, + jjp: 7036, + jjq: 7037, + jjr: 7038, + jjs: 7039, + jjt: 7040, + jju: 7041, + jjv: 7042, + jjw: 7043, + jjx: 7044, + jjy: 7045, + jkz: 7046, + jka: 7047, + jkb: 7048, + jkc: 7049, + jkd: 7050, + jke: 7051, + jkf: 7052, + jkg: 7053, + jkh: 7054, + jki: 7055, + jkj: 7056, + jkk: 7057, + jkl: 7058, + jkm: 7059, + jkn: 7060, + jko: 7061, + jkp: 7062, + jkq: 7063, + jkr: 7064, + jks: 7065, + jkt: 7066, + jku: 7067, + jkv: 7068, + jkw: 7069, + jkx: 7070, + jky: 7071, + jlz: 7072, + jla: 7073, + jlb: 7074, + jlc: 7075, + jld: 7076, + jle: 7077, + jlf: 7078, + jlg: 7079, + jlh: 7080, + jli: 7081, + jlj: 7082, + jlk: 7083, + jll: 7084, + jlm: 7085, + jln: 7086, + jlo: 7087, + jlp: 7088, + jlq: 7089, + jlr: 7090, + jls: 7091, + jlt: 7092, + jlu: 7093, + jlv: 7094, + jlw: 7095, + jlx: 7096, + jly: 7097, + jmz: 7098, + jma: 7099, + jmb: 7100, + jmc: 7101, + jmd: 7102, + jme: 7103, + jmf: 7104, + jmg: 7105, + jmh: 7106, + jmi: 7107, + jmj: 7108, + jmk: 7109, + jml: 7110, + jmm: 7111, + jmn: 7112, + jmo: 7113, + jmp: 7114, + jmq: 7115, + jmr: 7116, + jms: 7117, + jmt: 7118, + jmu: 7119, + jmv: 7120, + jmw: 7121, + jmx: 7122, + jmy: 7123, + jnz: 7124, + jna: 7125, + jnb: 7126, + jnc: 7127, + jnd: 7128, + jne: 7129, + jnf: 7130, + jng: 7131, + jnh: 7132, + jni: 7133, + jnj: 7134, + jnk: 7135, + jnl: 7136, + jnm: 7137, + jnn: 7138, + jno: 7139, + jnp: 7140, + jnq: 7141, + jnr: 7142, + jns: 7143, + jnt: 7144, + jnu: 7145, + jnv: 7146, + jnw: 7147, + jnx: 7148, + jny: 7149, + joz: 7150, + joa: 7151, + job: 7152, + joc: 7153, + jod: 7154, + joe: 7155, + jof: 7156, + jog: 7157, + joh: 7158, + joi: 7159, + joj: 7160, + jok: 7161, + jol: 7162, + jom: 7163, + jon: 7164, + joo: 7165, + jop: 7166, + joq: 7167, + jor: 7168, + jos: 7169, + jot: 7170, + jou: 7171, + jov: 7172, + jow: 7173, + jox: 7174, + joy: 7175, + jpz: 7176, + jpa: 7177, + jpb: 7178, + jpc: 7179, + jpd: 7180, + jpe: 7181, + jpf: 7182, + jpg: 7183, + jph: 7184, + jpi: 7185, + jpj: 7186, + jpk: 7187, + jpl: 7188, + jpm: 7189, + jpn: 7190, + jpo: 7191, + jpp: 7192, + jpq: 7193, + jpr: 7194, + jps: 7195, + jpt: 7196, + jpu: 7197, + jpv: 7198, + jpw: 7199, + jpx: 7200, + jpy: 7201, + jqz: 7202, + jqa: 7203, + jqb: 7204, + jqc: 7205, + jqd: 7206, + jqe: 7207, + jqf: 7208, + jqg: 7209, + jqh: 7210, + jqi: 7211, + jqj: 7212, + jqk: 7213, + jql: 7214, + jqm: 7215, + jqn: 7216, + jqo: 7217, + jqp: 7218, + jqq: 7219, + jqr: 7220, + jqs: 7221, + jqt: 7222, + jqu: 7223, + jqv: 7224, + jqw: 7225, + jqx: 7226, + jqy: 7227, + jrz: 7228, + jra: 7229, + jrb: 7230, + jrc: 7231, + jrd: 7232, + jre: 7233, + jrf: 7234, + jrg: 7235, + jrh: 7236, + jri: 7237, + jrj: 7238, + jrk: 7239, + jrl: 7240, + jrm: 7241, + jrn: 7242, + jro: 7243, + jrp: 7244, + jrq: 7245, + jrr: 7246, + jrs: 7247, + jrt: 7248, + jru: 7249, + jrv: 7250, + jrw: 7251, + jrx: 7252, + jry: 7253, + jsz: 7254, + jsa: 7255, + jsb: 7256, + jsc: 7257, + jsd: 7258, + jse: 7259, + jsf: 7260, + jsg: 7261, + jsh: 7262, + jsi: 7263, + jsj: 7264, + jsk: 7265, + jsl: 7266, + jsm: 7267, + jsn: 7268, + jso: 7269, + jsp: 7270, + jsq: 7271, + jsr: 7272, + jss: 7273, + jst: 7274, + jsu: 7275, + jsv: 7276, + jsw: 7277, + jsx: 7278, + jsy: 7279, + jtz: 7280, + jta: 7281, + jtb: 7282, + jtc: 7283, + jtd: 7284, + jte: 7285, + jtf: 7286, + jtg: 7287, + jth: 7288, + jti: 7289, + jtj: 7290, + jtk: 7291, + jtl: 7292, + jtm: 7293, + jtn: 7294, + jto: 7295, + jtp: 7296, + jtq: 7297, + jtr: 7298, + jts: 7299, + jtt: 7300, + jtu: 7301, + jtv: 7302, + jtw: 7303, + jtx: 7304, + jty: 7305, + juz: 7306, + jua: 7307, + jub: 7308, + juc: 7309, + jud: 7310, + jue: 7311, + juf: 7312, + jug: 7313, + juh: 7314, + jui: 7315, + juj: 7316, + juk: 7317, + jul: 7318, + jum: 7319, + jun: 7320, + juo: 7321, + jup: 7322, + juq: 7323, + jur: 7324, + jus: 7325, + jut: 7326, + juu: 7327, + juv: 7328, + juw: 7329, + jux: 7330, + juy: 7331, + jvz: 7332, + jva: 7333, + jvb: 7334, + jvc: 7335, + jvd: 7336, + jve: 7337, + jvf: 7338, + jvg: 7339, + jvh: 7340, + jvi: 7341, + jvj: 7342, + jvk: 7343, + jvl: 7344, + jvm: 7345, + jvn: 7346, + jvo: 7347, + jvp: 7348, + jvq: 7349, + jvr: 7350, + jvs: 7351, + jvt: 7352, + jvu: 7353, + jvv: 7354, + jvw: 7355, + jvx: 7356, + jvy: 7357, + jwz: 7358, + jwa: 7359, + jwb: 7360, + jwc: 7361, + jwd: 7362, + jwe: 7363, + jwf: 7364, + jwg: 7365, + jwh: 7366, + jwi: 7367, + jwj: 7368, + jwk: 7369, + jwl: 7370, + jwm: 7371, + jwn: 7372, + jwo: 7373, + jwp: 7374, + jwq: 7375, + jwr: 7376, + jws: 7377, + jwt: 7378, + jwu: 7379, + jwv: 7380, + jww: 7381, + jwx: 7382, + jwy: 7383, + jxz: 7384, + jxa: 7385, + jxb: 7386, + jxc: 7387, + jxd: 7388, + jxe: 7389, + jxf: 7390, + jxg: 7391, + jxh: 7392, + jxi: 7393, + jxj: 7394, + jxk: 7395, + jxl: 7396, + jxm: 7397, + jxn: 7398, + jxo: 7399, + jxp: 7400, + jxq: 7401, + jxr: 7402, + jxs: 7403, + jxt: 7404, + jxu: 7405, + jxv: 7406, + jxw: 7407, + jxx: 7408, + jxy: 7409, + jyz: 7410, + jya: 7411, + jyb: 7412, + jyc: 7413, + jyd: 7414, + jye: 7415, + jyf: 7416, + jyg: 7417, + jyh: 7418, + jyi: 7419, + jyj: 7420, + jyk: 7421, + jyl: 7422, + jym: 7423, + jyn: 7424, + jyo: 7425, + jyp: 7426, + jyq: 7427, + jyr: 7428, + jys: 7429, + jyt: 7430, + jyu: 7431, + jyv: 7432, + jyw: 7433, + jyx: 7434, + jyy: 7435, + kzz: 7436, + kza: 7437, + kzb: 7438, + kzc: 7439, + kzd: 7440, + kze: 7441, + kzf: 7442, + kzg: 7443, + kzh: 7444, + kzi: 7445, + kzj: 7446, + kzk: 7447, + kzl: 7448, + kzm: 7449, + kzn: 7450, + kzo: 7451, + kzp: 7452, + kzq: 7453, + kzr: 7454, + kzs: 7455, + kzt: 7456, + kzu: 7457, + kzv: 7458, + kzw: 7459, + kzx: 7460, + kzy: 7461, + kaz: 7462, + kaa: 7463, + kab: 7464, + kac: 7465, + kad: 7466, + kae: 7467, + kaf: 7468, + kag: 7469, + kah: 7470, + kai: 7471, + kaj: 7472, + kak: 7473, + kal: 7474, + kam: 7475, + kan: 7476, + kao: 7477, + kap: 7478, + kaq: 7479, + kar: 7480, + kas: 7481, + kat: 7482, + kau: 7483, + kav: 7484, + kaw: 7485, + kax: 7486, + kay: 7487, + kbz: 7488, + kba: 7489, + kbb: 7490, + kbc: 7491, + kbd: 7492, + kbe: 7493, + kbf: 7494, + kbg: 7495, + kbh: 7496, + kbi: 7497, + kbj: 7498, + kbk: 7499, + kbl: 7500, + kbm: 7501, + kbn: 7502, + kbo: 7503, + kbp: 7504, + kbq: 7505, + kbr: 7506, + kbs: 7507, + kbt: 7508, + kbu: 7509, + kbv: 7510, + kbw: 7511, + kbx: 7512, + kby: 7513, + kcz: 7514, + kca: 7515, + kcb: 7516, + kcc: 7517, + kcd: 7518, + kce: 7519, + kcf: 7520, + kcg: 7521, + kch: 7522, + kci: 7523, + kcj: 7524, + kck: 7525, + kcl: 7526, + kcm: 7527, + kcn: 7528, + kco: 7529, + kcp: 7530, + kcq: 7531, + kcr: 7532, + kcs: 7533, + kct: 7534, + kcu: 7535, + kcv: 7536, + kcw: 7537, + kcx: 7538, + kcy: 7539, + kdz: 7540, + kda: 7541, + kdb: 7542, + kdc: 7543, + kdd: 7544, + kde: 7545, + kdf: 7546, + kdg: 7547, + kdh: 7548, + kdi: 7549, + kdj: 7550, + kdk: 7551, + kdl: 7552, + kdm: 7553, + kdn: 7554, + kdo: 7555, + kdp: 7556, + kdq: 7557, + kdr: 7558, + kds: 7559, + kdt: 7560, + kdu: 7561, + kdv: 7562, + kdw: 7563, + kdx: 7564, + kdy: 7565, + kez: 7566, + kea: 7567, + keb: 7568, + kec: 7569, + ked: 7570, + kee: 7571, + kef: 7572, + keg: 7573, + keh: 7574, + kei: 7575, + kej: 7576, + kek: 7577, + kel: 7578, + kem: 7579, + ken: 7580, + keo: 7581, + kep: 7582, + keq: 7583, + ker: 7584, + kes: 7585, + ket: 7586, + keu: 7587, + kev: 7588, + kew: 7589, + kex: 7590, + key: 7591, + kfz: 7592, + kfa: 7593, + kfb: 7594, + kfc: 7595, + kfd: 7596, + kfe: 7597, + kff: 7598, + kfg: 7599, + kfh: 7600, + kfi: 7601, + kfj: 7602, + kfk: 7603, + kfl: 7604, + kfm: 7605, + kfn: 7606, + kfo: 7607, + kfp: 7608, + kfq: 7609, + kfr: 7610, + kfs: 7611, + kft: 7612, + kfu: 7613, + kfv: 7614, + kfw: 7615, + kfx: 7616, + kfy: 7617, + kgz: 7618, + kga: 7619, + kgb: 7620, + kgc: 7621, + kgd: 7622, + kge: 7623, + kgf: 7624, + kgg: 7625, + kgh: 7626, + kgi: 7627, + kgj: 7628, + kgk: 7629, + kgl: 7630, + kgm: 7631, + kgn: 7632, + kgo: 7633, + kgp: 7634, + kgq: 7635, + kgr: 7636, + kgs: 7637, + kgt: 7638, + kgu: 7639, + kgv: 7640, + kgw: 7641, + kgx: 7642, + kgy: 7643, + khz: 7644, + kha: 7645, + khb: 7646, + khc: 7647, + khd: 7648, + khe: 7649, + khf: 7650, + khg: 7651, + khh: 7652, + khi: 7653, + khj: 7654, + khk: 7655, + khl: 7656, + khm: 7657, + khn: 7658, + kho: 7659, + khp: 7660, + khq: 7661, + khr: 7662, + khs: 7663, + kht: 7664, + khu: 7665, + khv: 7666, + khw: 7667, + khx: 7668, + khy: 7669, + kiz: 7670, + kia: 7671, + kib: 7672, + kic: 7673, + kid: 7674, + kie: 7675, + kif: 7676, + kig: 7677, + kih: 7678, + kii: 7679, + kij: 7680, + kik: 7681, + kil: 7682, + kim: 7683, + kin: 7684, + kio: 7685, + kip: 7686, + kiq: 7687, + kir: 7688, + kis: 7689, + kit: 7690, + kiu: 7691, + kiv: 7692, + kiw: 7693, + kix: 7694, + kiy: 7695, + kjz: 7696, + kja: 7697, + kjb: 7698, + kjc: 7699, + kjd: 7700, + kje: 7701, + kjf: 7702, + kjg: 7703, + kjh: 7704, + kji: 7705, + kjj: 7706, + kjk: 7707, + kjl: 7708, + kjm: 7709, + kjn: 7710, + kjo: 7711, + kjp: 7712, + kjq: 7713, + kjr: 7714, + kjs: 7715, + kjt: 7716, + kju: 7717, + kjv: 7718, + kjw: 7719, + kjx: 7720, + kjy: 7721, + kkz: 7722, + kka: 7723, + kkb: 7724, + kkc: 7725, + kkd: 7726, + kke: 7727, + kkf: 7728, + kkg: 7729, + kkh: 7730, + kki: 7731, + kkj: 7732, + kkk: 7733, + kkl: 7734, + kkm: 7735, + kkn: 7736, + kko: 7737, + kkp: 7738, + kkq: 7739, + kkr: 7740, + kks: 7741, + kkt: 7742, + kku: 7743, + kkv: 7744, + kkw: 7745, + kkx: 7746, + kky: 7747, + klz: 7748, + kla: 7749, + klb: 7750, + klc: 7751, + kld: 7752, + kle: 7753, + klf: 7754, + klg: 7755, + klh: 7756, + kli: 7757, + klj: 7758, + klk: 7759, + kll: 7760, + klm: 7761, + kln: 7762, + klo: 7763, + klp: 7764, + klq: 7765, + klr: 7766, + kls: 7767, + klt: 7768, + klu: 7769, + klv: 7770, + klw: 7771, + klx: 7772, + kly: 7773, + kmz: 7774, + kma: 7775, + kmb: 7776, + kmc: 7777, + kmd: 7778, + kme: 7779, + kmf: 7780, + kmg: 7781, + kmh: 7782, + kmi: 7783, + kmj: 7784, + kmk: 7785, + kml: 7786, + kmm: 7787, + kmn: 7788, + kmo: 7789, + kmp: 7790, + kmq: 7791, + kmr: 7792, + kms: 7793, + kmt: 7794, + kmu: 7795, + kmv: 7796, + kmw: 7797, + kmx: 7798, + kmy: 7799, + knz: 7800, + kna: 7801, + knb: 7802, + knc: 7803, + knd: 7804, + kne: 7805, + knf: 7806, + kng: 7807, + knh: 7808, + kni: 7809, + knj: 7810, + knk: 7811, + knl: 7812, + knm: 7813, + knn: 7814, + kno: 7815, + knp: 7816, + knq: 7817, + knr: 7818, + kns: 7819, + knt: 7820, + knu: 7821, + knv: 7822, + knw: 7823, + knx: 7824, + kny: 7825, + koz: 7826, + koa: 7827, + kob: 7828, + koc: 7829, + kod: 7830, + koe: 7831, + kof: 7832, + kog: 7833, + koh: 7834, + koi: 7835, + koj: 7836, + kok: 7837, + kol: 7838, + kom: 7839, + kon: 7840, + koo: 7841, + kop: 7842, + koq: 7843, + kor: 7844, + kos: 7845, + kot: 7846, + kou: 7847, + kov: 7848, + kow: 7849, + kox: 7850, + koy: 7851, + kpz: 7852, + kpa: 7853, + kpb: 7854, + kpc: 7855, + kpd: 7856, + kpe: 7857, + kpf: 7858, + kpg: 7859, + kph: 7860, + kpi: 7861, + kpj: 7862, + kpk: 7863, + kpl: 7864, + kpm: 7865, + kpn: 7866, + kpo: 7867, + kpp: 7868, + kpq: 7869, + kpr: 7870, + kps: 7871, + kpt: 7872, + kpu: 7873, + kpv: 7874, + kpw: 7875, + kpx: 7876, + kpy: 7877, + kqz: 7878, + kqa: 7879, + kqb: 7880, + kqc: 7881, + kqd: 7882, + kqe: 7883, + kqf: 7884, + kqg: 7885, + kqh: 7886, + kqi: 7887, + kqj: 7888, + kqk: 7889, + kql: 7890, + kqm: 7891, + kqn: 7892, + kqo: 7893, + kqp: 7894, + kqq: 7895, + kqr: 7896, + kqs: 7897, + kqt: 7898, + kqu: 7899, + kqv: 7900, + kqw: 7901, + kqx: 7902, + kqy: 7903, + krz: 7904, + kra: 7905, + krb: 7906, + krc: 7907, + krd: 7908, + kre: 7909, + krf: 7910, + krg: 7911, + krh: 7912, + kri: 7913, + krj: 7914, + krk: 7915, + krl: 7916, + krm: 7917, + krn: 7918, + kro: 7919, + krp: 7920, + krq: 7921, + krr: 7922, + krs: 7923, + krt: 7924, + kru: 7925, + krv: 7926, + krw: 7927, + krx: 7928, + kry: 7929, + ksz: 7930, + ksa: 7931, + ksb: 7932, + ksc: 7933, + ksd: 7934, + kse: 7935, + ksf: 7936, + ksg: 7937, + ksh: 7938, + ksi: 7939, + ksj: 7940, + ksk: 7941, + ksl: 7942, + ksm: 7943, + ksn: 7944, + kso: 7945, + ksp: 7946, + ksq: 7947, + ksr: 7948, + kss: 7949, + kst: 7950, + ksu: 7951, + ksv: 7952, + ksw: 7953, + ksx: 7954, + ksy: 7955, + ktz: 7956, + kta: 7957, + ktb: 7958, + ktc: 7959, + ktd: 7960, + kte: 7961, + ktf: 7962, + ktg: 7963, + kth: 7964, + kti: 7965, + ktj: 7966, + ktk: 7967, + ktl: 7968, + ktm: 7969, + ktn: 7970, + kto: 7971, + ktp: 7972, + ktq: 7973, + ktr: 7974, + kts: 7975, + ktt: 7976, + ktu: 7977, + ktv: 7978, + ktw: 7979, + ktx: 7980, + kty: 7981, + kuz: 7982, + kua: 7983, + kub: 7984, + kuc: 7985, + kud: 7986, + kue: 7987, + kuf: 7988, + kug: 7989, + kuh: 7990, + kui: 7991, + kuj: 7992, + kuk: 7993, + kul: 7994, + kum: 7995, + kun: 7996, + kuo: 7997, + kup: 7998, + kuq: 7999, + kur: 8000, + kus: 8001, + kut: 8002, + kuu: 8003, + kuv: 8004, + kuw: 8005, + kux: 8006, + kuy: 8007, + kvz: 8008, + kva: 8009, + kvb: 8010, + kvc: 8011, + kvd: 8012, + kve: 8013, + kvf: 8014, + kvg: 8015, + kvh: 8016, + kvi: 8017, + kvj: 8018, + kvk: 8019, + kvl: 8020, + kvm: 8021, + kvn: 8022, + kvo: 8023, + kvp: 8024, + kvq: 8025, + kvr: 8026, + kvs: 8027, + kvt: 8028, + kvu: 8029, + kvv: 8030, + kvw: 8031, + kvx: 8032, + kvy: 8033, + kwz: 8034, + kwa: 8035, + kwb: 8036, + kwc: 8037, + kwd: 8038, + kwe: 8039, + kwf: 8040, + kwg: 8041, + kwh: 8042, + kwi: 8043, + kwj: 8044, + kwk: 8045, + kwl: 8046, + kwm: 8047, + kwn: 8048, + kwo: 8049, + kwp: 8050, + kwq: 8051, + kwr: 8052, + kws: 8053, + kwt: 8054, + kwu: 8055, + kwv: 8056, + kww: 8057, + kwx: 8058, + kwy: 8059, + kxz: 8060, + kxa: 8061, + kxb: 8062, + kxc: 8063, + kxd: 8064, + kxe: 8065, + kxf: 8066, + kxg: 8067, + kxh: 8068, + kxi: 8069, + kxj: 8070, + kxk: 8071, + kxl: 8072, + kxm: 8073, + kxn: 8074, + kxo: 8075, + kxp: 8076, + kxq: 8077, + kxr: 8078, + kxs: 8079, + kxt: 8080, + kxu: 8081, + kxv: 8082, + kxw: 8083, + kxx: 8084, + kxy: 8085, + kyz: 8086, + kya: 8087, + kyb: 8088, + kyc: 8089, + kyd: 8090, + kye: 8091, + kyf: 8092, + kyg: 8093, + kyh: 8094, + kyi: 8095, + kyj: 8096, + kyk: 8097, + kyl: 8098, + kym: 8099, + kyn: 8100, + kyo: 8101, + kyp: 8102, + kyq: 8103, + kyr: 8104, + kys: 8105, + kyt: 8106, + kyu: 8107, + kyv: 8108, + kyw: 8109, + kyx: 8110, + kyy: 8111, + lzz: 8112, + lza: 8113, + lzb: 8114, + lzc: 8115, + lzd: 8116, + lze: 8117, + lzf: 8118, + lzg: 8119, + lzh: 8120, + lzi: 8121, + lzj: 8122, + lzk: 8123, + lzl: 8124, + lzm: 8125, + lzn: 8126, + lzo: 8127, + lzp: 8128, + lzq: 8129, + lzr: 8130, + lzs: 8131, + lzt: 8132, + lzu: 8133, + lzv: 8134, + lzw: 8135, + lzx: 8136, + lzy: 8137, + laz: 8138, + laa: 8139, + lab: 8140, + lac: 8141, + lad: 8142, + lae: 8143, + laf: 8144, + lag: 8145, + lah: 8146, + lai: 8147, + laj: 8148, + lak: 8149, + lal: 8150, + lam: 8151, + lan: 8152, + lao: 8153, + lap: 8154, + laq: 8155, + lar: 8156, + las: 8157, + lat: 8158, + lau: 8159, + lav: 8160, + law: 8161, + lax: 8162, + lay: 8163, + lbz: 8164, + lba: 8165, + lbb: 8166, + lbc: 8167, + lbd: 8168, + lbe: 8169, + lbf: 8170, + lbg: 8171, + lbh: 8172, + lbi: 8173, + lbj: 8174, + lbk: 8175, + lbl: 8176, + lbm: 8177, + lbn: 8178, + lbo: 8179, + lbp: 8180, + lbq: 8181, + lbr: 8182, + lbs: 8183, + lbt: 8184, + lbu: 8185, + lbv: 8186, + lbw: 8187, + lbx: 8188, + lby: 8189, + lcz: 8190, + lca: 8191, + lcb: 8192, + lcc: 8193, + lcd: 8194, + lce: 8195, + lcf: 8196, + lcg: 8197, + lch: 8198, + lci: 8199, + lcj: 8200, + lck: 8201, + lcl: 8202, + lcm: 8203, + lcn: 8204, + lco: 8205, + lcp: 8206, + lcq: 8207, + lcr: 8208, + lcs: 8209, + lct: 8210, + lcu: 8211, + lcv: 8212, + lcw: 8213, + lcx: 8214, + lcy: 8215, + ldz: 8216, + lda: 8217, + ldb: 8218, + ldc: 8219, + ldd: 8220, + lde: 8221, + ldf: 8222, + ldg: 8223, + ldh: 8224, + ldi: 8225, + ldj: 8226, + ldk: 8227, + ldl: 8228, + ldm: 8229, + ldn: 8230, + ldo: 8231, + ldp: 8232, + ldq: 8233, + ldr: 8234, + lds: 8235, + ldt: 8236, + ldu: 8237, + ldv: 8238, + ldw: 8239, + ldx: 8240, + ldy: 8241, + lez: 8242, + lea: 8243, + leb: 8244, + lec: 8245, + led: 8246, + lee: 8247, + lef: 8248, + leg: 8249, + leh: 8250, + lei: 8251, + lej: 8252, + lek: 8253, + lel: 8254, + lem: 8255, + len: 8256, + leo: 8257, + lep: 8258, + leq: 8259, + ler: 8260, + les: 8261, + let: 8262, + leu: 8263, + lev: 8264, + lew: 8265, + lex: 8266, + ley: 8267, + lfz: 8268, + lfa: 8269, + lfb: 8270, + lfc: 8271, + lfd: 8272, + lfe: 8273, + lff: 8274, + lfg: 8275, + lfh: 8276, + lfi: 8277, + lfj: 8278, + lfk: 8279, + lfl: 8280, + lfm: 8281, + lfn: 8282, + lfo: 8283, + lfp: 8284, + lfq: 8285, + lfr: 8286, + lfs: 8287, + lft: 8288, + lfu: 8289, + lfv: 8290, + lfw: 8291, + lfx: 8292, + lfy: 8293, + lgz: 8294, + lga: 8295, + lgb: 8296, + lgc: 8297, + lgd: 8298, + lge: 8299, + lgf: 8300, + lgg: 8301, + lgh: 8302, + lgi: 8303, + lgj: 8304, + lgk: 8305, + lgl: 8306, + lgm: 8307, + lgn: 8308, + lgo: 8309, + lgp: 8310, + lgq: 8311, + lgr: 8312, + lgs: 8313, + lgt: 8314, + lgu: 8315, + lgv: 8316, + lgw: 8317, + lgx: 8318, + lgy: 8319, + lhz: 8320, + lha: 8321, + lhb: 8322, + lhc: 8323, + lhd: 8324, + lhe: 8325, + lhf: 8326, + lhg: 8327, + lhh: 8328, + lhi: 8329, + lhj: 8330, + lhk: 8331, + lhl: 8332, + lhm: 8333, + lhn: 8334, + lho: 8335, + lhp: 8336, + lhq: 8337, + lhr: 8338, + lhs: 8339, + lht: 8340, + lhu: 8341, + lhv: 8342, + lhw: 8343, + lhx: 8344, + lhy: 8345, + liz: 8346, + lia: 8347, + lib: 8348, + lic: 8349, + lid: 8350, + lie: 8351, + lif: 8352, + lig: 8353, + lih: 8354, + lii: 8355, + lij: 8356, + lik: 8357, + lil: 8358, + lim: 8359, + lin: 8360, + lio: 8361, + lip: 8362, + liq: 8363, + lir: 8364, + lis: 8365, + lit: 8366, + liu: 8367, + liv: 8368, + liw: 8369, + lix: 8370, + liy: 8371, + ljz: 8372, + lja: 8373, + ljb: 8374, + ljc: 8375, + ljd: 8376, + lje: 8377, + ljf: 8378, + ljg: 8379, + ljh: 8380, + lji: 8381, + ljj: 8382, + ljk: 8383, + ljl: 8384, + ljm: 8385, + ljn: 8386, + ljo: 8387, + ljp: 8388, + ljq: 8389, + ljr: 8390, + ljs: 8391, + ljt: 8392, + lju: 8393, + ljv: 8394, + ljw: 8395, + ljx: 8396, + ljy: 8397, + lkz: 8398, + lka: 8399, + lkb: 8400, + lkc: 8401, + lkd: 8402, + lke: 8403, + lkf: 8404, + lkg: 8405, + lkh: 8406, + lki: 8407, + lkj: 8408, + lkk: 8409, + lkl: 8410, + lkm: 8411, + lkn: 8412, + lko: 8413, + lkp: 8414, + lkq: 8415, + lkr: 8416, + lks: 8417, + lkt: 8418, + lku: 8419, + lkv: 8420, + lkw: 8421, + lkx: 8422, + lky: 8423, + llz: 8424, + lla: 8425, + llb: 8426, + llc: 8427, + lld: 8428, + lle: 8429, + llf: 8430, + llg: 8431, + llh: 8432, + lli: 8433, + llj: 8434, + llk: 8435, + lll: 8436, + llm: 8437, + lln: 8438, + llo: 8439, + llp: 8440, + llq: 8441, + llr: 8442, + lls: 8443, + llt: 8444, + llu: 8445, + llv: 8446, + llw: 8447, + llx: 8448, + lly: 8449, + lmz: 8450, + lma: 8451, + lmb: 8452, + lmc: 8453, + lmd: 8454, + lme: 8455, + lmf: 8456, + lmg: 8457, + lmh: 8458, + lmi: 8459, + lmj: 8460, + lmk: 8461, + lml: 8462, + lmm: 8463, + lmn: 8464, + lmo: 8465, + lmp: 8466, + lmq: 8467, + lmr: 8468, + lms: 8469, + lmt: 8470, + lmu: 8471, + lmv: 8472, + lmw: 8473, + lmx: 8474, + lmy: 8475, + lnz: 8476, + lna: 8477, + lnb: 8478, + lnc: 8479, + lnd: 8480, + lne: 8481, + lnf: 8482, + lng: 8483, + lnh: 8484, + lni: 8485, + lnj: 8486, + lnk: 8487, + lnl: 8488, + lnm: 8489, + lnn: 8490, + lno: 8491, + lnp: 8492, + lnq: 8493, + lnr: 8494, + lns: 8495, + lnt: 8496, + lnu: 8497, + lnv: 8498, + lnw: 8499, + lnx: 8500, + lny: 8501, + loz: 8502, + loa: 8503, + lob: 8504, + loc: 8505, + lod: 8506, + loe: 8507, + lof: 8508, + log: 8509, + loh: 8510, + loi: 8511, + loj: 8512, + lok: 8513, + lol: 8514, + lom: 8515, + lon: 8516, + loo: 8517, + lop: 8518, + loq: 8519, + lor: 8520, + los: 8521, + lot: 8522, + lou: 8523, + lov: 8524, + low: 8525, + lox: 8526, + loy: 8527, + lpz: 8528, + lpa: 8529, + lpb: 8530, + lpc: 8531, + lpd: 8532, + lpe: 8533, + lpf: 8534, + lpg: 8535, + lph: 8536, + lpi: 8537, + lpj: 8538, + lpk: 8539, + lpl: 8540, + lpm: 8541, + lpn: 8542, + lpo: 8543, + lpp: 8544, + lpq: 8545, + lpr: 8546, + lps: 8547, + lpt: 8548, + lpu: 8549, + lpv: 8550, + lpw: 8551, + lpx: 8552, + lpy: 8553, + lqz: 8554, + lqa: 8555, + lqb: 8556, + lqc: 8557, + lqd: 8558, + lqe: 8559, + lqf: 8560, + lqg: 8561, + lqh: 8562, + lqi: 8563, + lqj: 8564, + lqk: 8565, + lql: 8566, + lqm: 8567, + lqn: 8568, + lqo: 8569, + lqp: 8570, + lqq: 8571, + lqr: 8572, + lqs: 8573, + lqt: 8574, + lqu: 8575, + lqv: 8576, + lqw: 8577, + lqx: 8578, + lqy: 8579, + lrz: 8580, + lra: 8581, + lrb: 8582, + lrc: 8583, + lrd: 8584, + lre: 8585, + lrf: 8586, + lrg: 8587, + lrh: 8588, + lri: 8589, + lrj: 8590, + lrk: 8591, + lrl: 8592, + lrm: 8593, + lrn: 8594, + lro: 8595, + lrp: 8596, + lrq: 8597, + lrr: 8598, + lrs: 8599, + lrt: 8600, + lru: 8601, + lrv: 8602, + lrw: 8603, + lrx: 8604, + lry: 8605, + lsz: 8606, + lsa: 8607, + lsb: 8608, + lsc: 8609, + lsd: 8610, + lse: 8611, + lsf: 8612, + lsg: 8613, + lsh: 8614, + lsi: 8615, + lsj: 8616, + lsk: 8617, + lsl: 8618, + lsm: 8619, + lsn: 8620, + lso: 8621, + lsp: 8622, + lsq: 8623, + lsr: 8624, + lss: 8625, + lst: 8626, + lsu: 8627, + lsv: 8628, + lsw: 8629, + lsx: 8630, + lsy: 8631, + ltz: 8632, + lta: 8633, + ltb: 8634, + ltc: 8635, + ltd: 8636, + lte: 8637, + ltf: 8638, + ltg: 8639, + lth: 8640, + lti: 8641, + ltj: 8642, + ltk: 8643, + ltl: 8644, + ltm: 8645, + ltn: 8646, + lto: 8647, + ltp: 8648, + ltq: 8649, + ltr: 8650, + lts: 8651, + ltt: 8652, + ltu: 8653, + ltv: 8654, + ltw: 8655, + ltx: 8656, + lty: 8657, + luz: 8658, + lua: 8659, + lub: 8660, + luc: 8661, + lud: 8662, + lue: 8663, + luf: 8664, + lug: 8665, + luh: 8666, + lui: 8667, + luj: 8668, + luk: 8669, + lul: 8670, + lum: 8671, + lun: 8672, + luo: 8673, + lup: 8674, + luq: 8675, + lur: 8676, + lus: 8677, + lut: 8678, + luu: 8679, + luv: 8680, + luw: 8681, + lux: 8682, + luy: 8683, + lvz: 8684, + lva: 8685, + lvb: 8686, + lvc: 8687, + lvd: 8688, + lve: 8689, + lvf: 8690, + lvg: 8691, + lvh: 8692, + lvi: 8693, + lvj: 8694, + lvk: 8695, + lvl: 8696, + lvm: 8697, + lvn: 8698, + lvo: 8699, + lvp: 8700, + lvq: 8701, + lvr: 8702, + lvs: 8703, + lvt: 8704, + lvu: 8705, + lvv: 8706, + lvw: 8707, + lvx: 8708, + lvy: 8709, + lwz: 8710, + lwa: 8711, + lwb: 8712, + lwc: 8713, + lwd: 8714, + lwe: 8715, + lwf: 8716, + lwg: 8717, + lwh: 8718, + lwi: 8719, + lwj: 8720, + lwk: 8721, + lwl: 8722, + lwm: 8723, + lwn: 8724, + lwo: 8725, + lwp: 8726, + lwq: 8727, + lwr: 8728, + lws: 8729, + lwt: 8730, + lwu: 8731, + lwv: 8732, + lww: 8733, + lwx: 8734, + lwy: 8735, + lxz: 8736, + lxa: 8737, + lxb: 8738, + lxc: 8739, + lxd: 8740, + lxe: 8741, + lxf: 8742, + lxg: 8743, + lxh: 8744, + lxi: 8745, + lxj: 8746, + lxk: 8747, + lxl: 8748, + lxm: 8749, + lxn: 8750, + lxo: 8751, + lxp: 8752, + lxq: 8753, + lxr: 8754, + lxs: 8755, + lxt: 8756, + lxu: 8757, + lxv: 8758, + lxw: 8759, + lxx: 8760, + lxy: 8761, + lyz: 8762, + lya: 8763, + lyb: 8764, + lyc: 8765, + lyd: 8766, + lye: 8767, + lyf: 8768, + lyg: 8769, + lyh: 8770, + lyi: 8771, + lyj: 8772, + lyk: 8773, + lyl: 8774, + lym: 8775, + lyn: 8776, + lyo: 8777, + lyp: 8778, + lyq: 8779, + lyr: 8780, + lys: 8781, + lyt: 8782, + lyu: 8783, + lyv: 8784, + lyw: 8785, + lyx: 8786, + lyy: 8787, + mzz: 8788, + mza: 8789, + mzb: 8790, + mzc: 8791, + mzd: 8792, + mze: 8793, + mzf: 8794, + mzg: 8795, + mzh: 8796, + mzi: 8797, + mzj: 8798, + mzk: 8799, + mzl: 8800, + mzm: 8801, + mzn: 8802, + mzo: 8803, + mzp: 8804, + mzq: 8805, + mzr: 8806, + mzs: 8807, + mzt: 8808, + mzu: 8809, + mzv: 8810, + mzw: 8811, + mzx: 8812, + mzy: 8813, + maz: 8814, + maa: 8815, + mab: 8816, + mac: 8817, + mad: 8818, + mae: 8819, + maf: 8820, + mag: 8821, + mah: 8822, + mai: 8823, + maj: 8824, + mak: 8825, + mal: 8826, + mam: 8827, + man: 8828, + mao: 8829, + map: 8830, + maq: 8831, + mar: 8832, + mas: 8833, + mat: 8834, + mau: 8835, + mav: 8836, + maw: 8837, + max: 8838, + may: 8839, + mbz: 8840, + mba: 8841, + mbb: 8842, + mbc: 8843, + mbd: 8844, + mbe: 8845, + mbf: 8846, + mbg: 8847, + mbh: 8848, + mbi: 8849, + mbj: 8850, + mbk: 8851, + mbl: 8852, + mbm: 8853, + mbn: 8854, + mbo: 8855, + mbp: 8856, + mbq: 8857, + mbr: 8858, + mbs: 8859, + mbt: 8860, + mbu: 8861, + mbv: 8862, + mbw: 8863, + mbx: 8864, + mby: 8865, + mcz: 8866, + mca: 8867, + mcb: 8868, + mcc: 8869, + mcd: 8870, + mce: 8871, + mcf: 8872, + mcg: 8873, + mch: 8874, + mci: 8875, + mcj: 8876, + mck: 8877, + mcl: 8878, + mcm: 8879, + mcn: 8880, + mco: 8881, + mcp: 8882, + mcq: 8883, + mcr: 8884, + mcs: 8885, + mct: 8886, + mcu: 8887, + mcv: 8888, + mcw: 8889, + mcx: 8890, + mcy: 8891, + mdz: 8892, + mda: 8893, + mdb: 8894, + mdc: 8895, + mdd: 8896, + mde: 8897, + mdf: 8898, + mdg: 8899, + mdh: 8900, + mdi: 8901, + mdj: 8902, + mdk: 8903, + mdl: 8904, + mdm: 8905, + mdn: 8906, + mdo: 8907, + mdp: 8908, + mdq: 8909, + mdr: 8910, + mds: 8911, + mdt: 8912, + mdu: 8913, + mdv: 8914, + mdw: 8915, + mdx: 8916, + mdy: 8917, + mez: 8918, + mea: 8919, + meb: 8920, + mec: 8921, + med: 8922, + mee: 8923, + mef: 8924, + meg: 8925, + meh: 8926, + mei: 8927, + mej: 8928, + mek: 8929, + mel: 8930, + mem: 8931, + men: 8932, + meo: 8933, + mep: 8934, + meq: 8935, + mer: 8936, + mes: 8937, + met: 8938, + meu: 8939, + mev: 8940, + mew: 8941, + mex: 8942, + mey: 8943, + mfz: 8944, + mfa: 8945, + mfb: 8946, + mfc: 8947, + mfd: 8948, + mfe: 8949, + mff: 8950, + mfg: 8951, + mfh: 8952, + mfi: 8953, + mfj: 8954, + mfk: 8955, + mfl: 8956, + mfm: 8957, + mfn: 8958, + mfo: 8959, + mfp: 8960, + mfq: 8961, + mfr: 8962, + mfs: 8963, + mft: 8964, + mfu: 8965, + mfv: 8966, + mfw: 8967, + mfx: 8968, + mfy: 8969, + mgz: 8970, + mga: 8971, + mgb: 8972, + mgc: 8973, + mgd: 8974, + mge: 8975, + mgf: 8976, + mgg: 8977, + mgh: 8978, + mgi: 8979, + mgj: 8980, + mgk: 8981, + mgl: 8982, + mgm: 8983, + mgn: 8984, + mgo: 8985, + mgp: 8986, + mgq: 8987, + mgr: 8988, + mgs: 8989, + mgt: 8990, + mgu: 8991, + mgv: 8992, + mgw: 8993, + mgx: 8994, + mgy: 8995, + mhz: 8996, + mha: 8997, + mhb: 8998, + mhc: 8999, + mhd: 9000, + mhe: 9001, + mhf: 9002, + mhg: 9003, + mhh: 9004, + mhi: 9005, + mhj: 9006, + mhk: 9007, + mhl: 9008, + mhm: 9009, + mhn: 9010, + mho: 9011, + mhp: 9012, + mhq: 9013, + mhr: 9014, + mhs: 9015, + mht: 9016, + mhu: 9017, + mhv: 9018, + mhw: 9019, + mhx: 9020, + mhy: 9021, + miz: 9022, + mia: 9023, + mib: 9024, + mic: 9025, + mid: 9026, + mie: 9027, + mif: 9028, + mig: 9029, + mih: 9030, + mii: 9031, + mij: 9032, + mik: 9033, + mil: 9034, + mim: 9035, + min: 9036, + mio: 9037, + mip: 9038, + miq: 9039, + mir: 9040, + mis: 9041, + mit: 9042, + miu: 9043, + miv: 9044, + miw: 9045, + mix: 9046, + miy: 9047, + mjz: 9048, + mja: 9049, + mjb: 9050, + mjc: 9051, + mjd: 9052, + mje: 9053, + mjf: 9054, + mjg: 9055, + mjh: 9056, + mji: 9057, + mjj: 9058, + mjk: 9059, + mjl: 9060, + mjm: 9061, + mjn: 9062, + mjo: 9063, + mjp: 9064, + mjq: 9065, + mjr: 9066, + mjs: 9067, + mjt: 9068, + mju: 9069, + mjv: 9070, + mjw: 9071, + mjx: 9072, + mjy: 9073, + mkz: 9074, + mka: 9075, + mkb: 9076, + mkc: 9077, + mkd: 9078, + mke: 9079, + mkf: 9080, + mkg: 9081, + mkh: 9082, + mki: 9083, + mkj: 9084, + mkk: 9085, + mkl: 9086, + mkm: 9087, + mkn: 9088, + mko: 9089, + mkp: 9090, + mkq: 9091, + mkr: 9092, + mks: 9093, + mkt: 9094, + mku: 9095, + mkv: 9096, + mkw: 9097, + mkx: 9098, + mky: 9099, + mlz: 9100, + mla: 9101, + mlb: 9102, + mlc: 9103, + mld: 9104, + mle: 9105, + mlf: 9106, + mlg: 9107, + mlh: 9108, + mli: 9109, + mlj: 9110, + mlk: 9111, + mll: 9112, + mlm: 9113, + mln: 9114, + mlo: 9115, + mlp: 9116, + mlq: 9117, + mlr: 9118, + mls: 9119, + mlt: 9120, + mlu: 9121, + mlv: 9122, + mlw: 9123, + mlx: 9124, + mly: 9125, + mmz: 9126, + mma: 9127, + mmb: 9128, + mmc: 9129, + mmd: 9130, + mme: 9131, + mmf: 9132, + mmg: 9133, + mmh: 9134, + mmi: 9135, + mmj: 9136, + mmk: 9137, + mml: 9138, + mmm: 9139, + mmn: 9140, + mmo: 9141, + mmp: 9142, + mmq: 9143, + mmr: 9144, + mms: 9145, + mmt: 9146, + mmu: 9147, + mmv: 9148, + mmw: 9149, + mmx: 9150, + mmy: 9151, + mnz: 9152, + mna: 9153, + mnb: 9154, + mnc: 9155, + mnd: 9156, + mne: 9157, + mnf: 9158, + mng: 9159, + mnh: 9160, + mni: 9161, + mnj: 9162, + mnk: 9163, + mnl: 9164, + mnm: 9165, + mnn: 9166, + mno: 9167, + mnp: 9168, + mnq: 9169, + mnr: 9170, + mns: 9171, + mnt: 9172, + mnu: 9173, + mnv: 9174, + mnw: 9175, + mnx: 9176, + mny: 9177, + moz: 9178, + moa: 9179, + mob: 9180, + moc: 9181, + mod: 9182, + moe: 9183, + mof: 9184, + mog: 9185, + moh: 9186, + moi: 9187, + moj: 9188, + mok: 9189, + mol: 9190, + mom: 9191, + mon: 9192, + moo: 9193, + mop: 9194, + moq: 9195, + mor: 9196, + mos: 9197, + mot: 9198, + mou: 9199, + mov: 9200, + mow: 9201, + mox: 9202, + moy: 9203, + mpz: 9204, + mpa: 9205, + mpb: 9206, + mpc: 9207, + mpd: 9208, + mpe: 9209, + mpf: 9210, + mpg: 9211, + mph: 9212, + mpi: 9213, + mpj: 9214, + mpk: 9215, + mpl: 9216, + mpm: 9217, + mpn: 9218, + mpo: 9219, + mpp: 9220, + mpq: 9221, + mpr: 9222, + mps: 9223, + mpt: 9224, + mpu: 9225, + mpv: 9226, + mpw: 9227, + mpx: 9228, + mpy: 9229, + mqz: 9230, + mqa: 9231, + mqb: 9232, + mqc: 9233, + mqd: 9234, + mqe: 9235, + mqf: 9236, + mqg: 9237, + mqh: 9238, + mqi: 9239, + mqj: 9240, + mqk: 9241, + mql: 9242, + mqm: 9243, + mqn: 9244, + mqo: 9245, + mqp: 9246, + mqq: 9247, + mqr: 9248, + mqs: 9249, + mqt: 9250, + mqu: 9251, + mqv: 9252, + mqw: 9253, + mqx: 9254, + mqy: 9255, + mrz: 9256, + mra: 9257, + mrb: 9258, + mrc: 9259, + mrd: 9260, + mre: 9261, + mrf: 9262, + mrg: 9263, + mrh: 9264, + mri: 9265, + mrj: 9266, + mrk: 9267, + mrl: 9268, + mrm: 9269, + mrn: 9270, + mro: 9271, + mrp: 9272, + mrq: 9273, + mrr: 9274, + mrs: 9275, + mrt: 9276, + mru: 9277, + mrv: 9278, + mrw: 9279, + mrx: 9280, + mry: 9281, + msz: 9282, + msa: 9283, + msb: 9284, + msc: 9285, + msd: 9286, + mse: 9287, + msf: 9288, + msg: 9289, + msh: 9290, + msi: 9291, + msj: 9292, + msk: 9293, + msl: 9294, + msm: 9295, + msn: 9296, + mso: 9297, + msp: 9298, + msq: 9299, + msr: 9300, + mss: 9301, + mst: 9302, + msu: 9303, + msv: 9304, + msw: 9305, + msx: 9306, + msy: 9307, + mtz: 9308, + mta: 9309, + mtb: 9310, + mtc: 9311, + mtd: 9312, + mte: 9313, + mtf: 9314, + mtg: 9315, + mth: 9316, + mti: 9317, + mtj: 9318, + mtk: 9319, + mtl: 9320, + mtm: 9321, + mtn: 9322, + mto: 9323, + mtp: 9324, + mtq: 9325, + mtr: 9326, + mts: 9327, + mtt: 9328, + mtu: 9329, + mtv: 9330, + mtw: 9331, + mtx: 9332, + mty: 9333, + muz: 9334, + mua: 9335, + mub: 9336, + muc: 9337, + mud: 9338, + mue: 9339, + muf: 9340, + mug: 9341, + muh: 9342, + mui: 9343, + muj: 9344, + muk: 9345, + mul: 9346, + mum: 9347, + mun: 9348, + muo: 9349, + mup: 9350, + muq: 9351, + mur: 9352, + mus: 9353, + mut: 9354, + muu: 9355, + muv: 9356, + muw: 9357, + mux: 9358, + muy: 9359, + mvz: 9360, + mva: 9361, + mvb: 9362, + mvc: 9363, + mvd: 9364, + mve: 9365, + mvf: 9366, + mvg: 9367, + mvh: 9368, + mvi: 9369, + mvj: 9370, + mvk: 9371, + mvl: 9372, + mvm: 9373, + mvn: 9374, + mvo: 9375, + mvp: 9376, + mvq: 9377, + mvr: 9378, + mvs: 9379, + mvt: 9380, + mvu: 9381, + mvv: 9382, + mvw: 9383, + mvx: 9384, + mvy: 9385, + mwz: 9386, + mwa: 9387, + mwb: 9388, + mwc: 9389, + mwd: 9390, + mwe: 9391, + mwf: 9392, + mwg: 9393, + mwh: 9394, + mwi: 9395, + mwj: 9396, + mwk: 9397, + mwl: 9398, + mwm: 9399, + mwn: 9400, + mwo: 9401, + mwp: 9402, + mwq: 9403, + mwr: 9404, + mws: 9405, + mwt: 9406, + mwu: 9407, + mwv: 9408, + mww: 9409, + mwx: 9410, + mwy: 9411, + mxz: 9412, + mxa: 9413, + mxb: 9414, + mxc: 9415, + mxd: 9416, + mxe: 9417, + mxf: 9418, + mxg: 9419, + mxh: 9420, + mxi: 9421, + mxj: 9422, + mxk: 9423, + mxl: 9424, + mxm: 9425, + mxn: 9426, + mxo: 9427, + mxp: 9428, + mxq: 9429, + mxr: 9430, + mxs: 9431, + mxt: 9432, + mxu: 9433, + mxv: 9434, + mxw: 9435, + mxx: 9436, + mxy: 9437, + myz: 9438, + mya: 9439, + myb: 9440, + myc: 9441, + myd: 9442, + mye: 9443, + myf: 9444, + myg: 9445, + myh: 9446, + myi: 9447, + myj: 9448, + myk: 9449, + myl: 9450, + mym: 9451, + myn: 9452, + myo: 9453, + myp: 9454, + myq: 9455, + myr: 9456, + mys: 9457, + myt: 9458, + myu: 9459, + myv: 9460, + myw: 9461, + myx: 9462, + myy: 9463, + nzz: 9464, + nza: 9465, + nzb: 9466, + nzc: 9467, + nzd: 9468, + nze: 9469, + nzf: 9470, + nzg: 9471, + nzh: 9472, + nzi: 9473, + nzj: 9474, + nzk: 9475, + nzl: 9476, + nzm: 9477, + nzn: 9478, + nzo: 9479, + nzp: 9480, + nzq: 9481, + nzr: 9482, + nzs: 9483, + nzt: 9484, + nzu: 9485, + nzv: 9486, + nzw: 9487, + nzx: 9488, + nzy: 9489, + naz: 9490, + naa: 9491, + nab: 9492, + nac: 9493, + nad: 9494, + nae: 9495, + naf: 9496, + nag: 9497, + nah: 9498, + nai: 9499, + naj: 9500, + nak: 9501, + nal: 9502, + nam: 9503, + nan: 9504, + nao: 9505, + nap: 9506, + naq: 9507, + nar: 9508, + nas: 9509, + nat: 9510, + nau: 9511, + nav: 9512, + naw: 9513, + nax: 9514, + nay: 9515, + nbz: 9516, + nba: 9517, + nbb: 9518, + nbc: 9519, + nbd: 9520, + nbe: 9521, + nbf: 9522, + nbg: 9523, + nbh: 9524, + nbi: 9525, + nbj: 9526, + nbk: 9527, + nbl: 9528, + nbm: 9529, + nbn: 9530, + nbo: 9531, + nbp: 9532, + nbq: 9533, + nbr: 9534, + nbs: 9535, + nbt: 9536, + nbu: 9537, + nbv: 9538, + nbw: 9539, + nbx: 9540, + nby: 9541, + ncz: 9542, + nca: 9543, + ncb: 9544, + ncc: 9545, + ncd: 9546, + nce: 9547, + ncf: 9548, + ncg: 9549, + nch: 9550, + nci: 9551, + ncj: 9552, + nck: 9553, + ncl: 9554, + ncm: 9555, + ncn: 9556, + nco: 9557, + ncp: 9558, + ncq: 9559, + ncr: 9560, + ncs: 9561, + nct: 9562, + ncu: 9563, + ncv: 9564, + ncw: 9565, + ncx: 9566, + ncy: 9567, + ndz: 9568, + nda: 9569, + ndb: 9570, + ndc: 9571, + ndd: 9572, + nde: 9573, + ndf: 9574, + ndg: 9575, + ndh: 9576, + ndi: 9577, + ndj: 9578, + ndk: 9579, + ndl: 9580, + ndm: 9581, + ndn: 9582, + ndo: 9583, + ndp: 9584, + ndq: 9585, + ndr: 9586, + nds: 9587, + ndt: 9588, + ndu: 9589, + ndv: 9590, + ndw: 9591, + ndx: 9592, + ndy: 9593, + nez: 9594, + nea: 9595, + neb: 9596, + nec: 9597, + ned: 9598, + nee: 9599, + nef: 9600, + neg: 9601, + neh: 9602, + nei: 9603, + nej: 9604, + nek: 9605, + nel: 9606, + nem: 9607, + nen: 9608, + neo: 9609, + nep: 9610, + neq: 9611, + ner: 9612, + nes: 9613, + net: 9614, + neu: 9615, + nev: 9616, + new: 9617, + nex: 9618, + ney: 9619, + nfz: 9620, + nfa: 9621, + nfb: 9622, + nfc: 9623, + nfd: 9624, + nfe: 9625, + nff: 9626, + nfg: 9627, + nfh: 9628, + nfi: 9629, + nfj: 9630, + nfk: 9631, + nfl: 9632, + nfm: 9633, + nfn: 9634, + nfo: 9635, + nfp: 9636, + nfq: 9637, + nfr: 9638, + nfs: 9639, + nft: 9640, + nfu: 9641, + nfv: 9642, + nfw: 9643, + nfx: 9644, + nfy: 9645, + ngz: 9646, + nga: 9647, + ngb: 9648, + ngc: 9649, + ngd: 9650, + nge: 9651, + ngf: 9652, + ngg: 9653, + ngh: 9654, + ngi: 9655, + ngj: 9656, + ngk: 9657, + ngl: 9658, + ngm: 9659, + ngn: 9660, + ngo: 9661, + ngp: 9662, + ngq: 9663, + ngr: 9664, + ngs: 9665, + ngt: 9666, + ngu: 9667, + ngv: 9668, + ngw: 9669, + ngx: 9670, + ngy: 9671, + nhz: 9672, + nha: 9673, + nhb: 9674, + nhc: 9675, + nhd: 9676, + nhe: 9677, + nhf: 9678, + nhg: 9679, + nhh: 9680, + nhi: 9681, + nhj: 9682, + nhk: 9683, + nhl: 9684, + nhm: 9685, + nhn: 9686, + nho: 9687, + nhp: 9688, + nhq: 9689, + nhr: 9690, + nhs: 9691, + nht: 9692, + nhu: 9693, + nhv: 9694, + nhw: 9695, + nhx: 9696, + nhy: 9697, + niz: 9698, + nia: 9699, + nib: 9700, + nic: 9701, + nid: 9702, + nie: 9703, + nif: 9704, + nig: 9705, + nih: 9706, + nii: 9707, + nij: 9708, + nik: 9709, + nil: 9710, + nim: 9711, + nin: 9712, + nio: 9713, + nip: 9714, + niq: 9715, + nir: 9716, + nis: 9717, + nit: 9718, + niu: 9719, + niv: 9720, + niw: 9721, + nix: 9722, + niy: 9723, + njz: 9724, + nja: 9725, + njb: 9726, + njc: 9727, + njd: 9728, + nje: 9729, + njf: 9730, + njg: 9731, + njh: 9732, + nji: 9733, + njj: 9734, + njk: 9735, + njl: 9736, + njm: 9737, + njn: 9738, + njo: 9739, + njp: 9740, + njq: 9741, + njr: 9742, + njs: 9743, + njt: 9744, + nju: 9745, + njv: 9746, + njw: 9747, + njx: 9748, + njy: 9749, + nkz: 9750, + nka: 9751, + nkb: 9752, + nkc: 9753, + nkd: 9754, + nke: 9755, + nkf: 9756, + nkg: 9757, + nkh: 9758, + nki: 9759, + nkj: 9760, + nkk: 9761, + nkl: 9762, + nkm: 9763, + nkn: 9764, + nko: 9765, + nkp: 9766, + nkq: 9767, + nkr: 9768, + nks: 9769, + nkt: 9770, + nku: 9771, + nkv: 9772, + nkw: 9773, + nkx: 9774, + nky: 9775, + nlz: 9776, + nla: 9777, + nlb: 9778, + nlc: 9779, + nld: 9780, + nle: 9781, + nlf: 9782, + nlg: 9783, + nlh: 9784, + nli: 9785, + nlj: 9786, + nlk: 9787, + nll: 9788, + nlm: 9789, + nln: 9790, + nlo: 9791, + nlp: 9792, + nlq: 9793, + nlr: 9794, + nls: 9795, + nlt: 9796, + nlu: 9797, + nlv: 9798, + nlw: 9799, + nlx: 9800, + nly: 9801, + nmz: 9802, + nma: 9803, + nmb: 9804, + nmc: 9805, + nmd: 9806, + nme: 9807, + nmf: 9808, + nmg: 9809, + nmh: 9810, + nmi: 9811, + nmj: 9812, + nmk: 9813, + nml: 9814, + nmm: 9815, + nmn: 9816, + nmo: 9817, + nmp: 9818, + nmq: 9819, + nmr: 9820, + nms: 9821, + nmt: 9822, + nmu: 9823, + nmv: 9824, + nmw: 9825, + nmx: 9826, + nmy: 9827, + nnz: 9828, + nna: 9829, + nnb: 9830, + nnc: 9831, + nnd: 9832, + nne: 9833, + nnf: 9834, + nng: 9835, + nnh: 9836, + nni: 9837, + nnj: 9838, + nnk: 9839, + nnl: 9840, + nnm: 9841, + nnn: 9842, + nno: 9843, + nnp: 9844, + nnq: 9845, + nnr: 9846, + nns: 9847, + nnt: 9848, + nnu: 9849, + nnv: 9850, + nnw: 9851, + nnx: 9852, + nny: 9853, + noz: 9854, + noa: 9855, + nob: 9856, + noc: 9857, + nod: 9858, + noe: 9859, + nof: 9860, + nog: 9861, + noh: 9862, + noi: 9863, + noj: 9864, + nok: 9865, + nol: 9866, + nom: 9867, + non: 9868, + noo: 9869, + nop: 9870, + noq: 9871, + nor: 9872, + nos: 9873, + not: 9874, + nou: 9875, + nov: 9876, + now: 9877, + nox: 9878, + noy: 9879, + npz: 9880, + npa: 9881, + npb: 9882, + npc: 9883, + npd: 9884, + npe: 9885, + npf: 9886, + npg: 9887, + nph: 9888, + npi: 9889, + npj: 9890, + npk: 9891, + npl: 9892, + npm: 9893, + npn: 9894, + npo: 9895, + npp: 9896, + npq: 9897, + npr: 9898, + nps: 9899, + npt: 9900, + npu: 9901, + npv: 9902, + npw: 9903, + npx: 9904, + npy: 9905, + nqz: 9906, + nqa: 9907, + nqb: 9908, + nqc: 9909, + nqd: 9910, + nqe: 9911, + nqf: 9912, + nqg: 9913, + nqh: 9914, + nqi: 9915, + nqj: 9916, + nqk: 9917, + nql: 9918, + nqm: 9919, + nqn: 9920, + nqo: 9921, + nqp: 9922, + nqq: 9923, + nqr: 9924, + nqs: 9925, + nqt: 9926, + nqu: 9927, + nqv: 9928, + nqw: 9929, + nqx: 9930, + nqy: 9931, + nrz: 9932, + nra: 9933, + nrb: 9934, + nrc: 9935, + nrd: 9936, + nre: 9937, + nrf: 9938, + nrg: 9939, + nrh: 9940, + nri: 9941, + nrj: 9942, + nrk: 9943, + nrl: 9944, + nrm: 9945, + nrn: 9946, + nro: 9947, + nrp: 9948, + nrq: 9949, + nrr: 9950, + nrs: 9951, + nrt: 9952, + nru: 9953, + nrv: 9954, + nrw: 9955, + nrx: 9956, + nry: 9957, + nsz: 9958, + nsa: 9959, + nsb: 9960, + nsc: 9961, + nsd: 9962, + nse: 9963, + nsf: 9964, + nsg: 9965, + nsh: 9966, + nsi: 9967, + nsj: 9968, + nsk: 9969, + nsl: 9970, + nsm: 9971, + nsn: 9972, + nso: 9973, + nsp: 9974, + nsq: 9975, + nsr: 9976, + nss: 9977, + nst: 9978, + nsu: 9979, + nsv: 9980, + nsw: 9981, + nsx: 9982, + nsy: 9983, + ntz: 9984, + nta: 9985, + ntb: 9986, + ntc: 9987, + ntd: 9988, + nte: 9989, + ntf: 9990, + ntg: 9991, + nth: 9992, + nti: 9993, + ntj: 9994, + ntk: 9995, + ntl: 9996, + ntm: 9997, + ntn: 9998, + nto: 9999, + ntp: 10000, + ntq: 10001, + ntr: 10002, + nts: 10003, + ntt: 10004, + ntu: 10005, + ntv: 10006, + ntw: 10007, + ntx: 10008, + nty: 10009, + nuz: 10010, + nua: 10011, + nub: 10012, + nuc: 10013, + nud: 10014, + nue: 10015, + nuf: 10016, + nug: 10017, + nuh: 10018, + nui: 10019, + nuj: 10020, + nuk: 10021, + nul: 10022, + num: 10023, + nun: 10024, + nuo: 10025, + nup: 10026, + nuq: 10027, + nur: 10028, + nus: 10029, + nut: 10030, + nuu: 10031, + nuv: 10032, + nuw: 10033, + nux: 10034, + nuy: 10035, + nvz: 10036, + nva: 10037, + nvb: 10038, + nvc: 10039, + nvd: 10040, + nve: 10041, + nvf: 10042, + nvg: 10043, + nvh: 10044, + nvi: 10045, + nvj: 10046, + nvk: 10047, + nvl: 10048, + nvm: 10049, + nvn: 10050, + nvo: 10051, + nvp: 10052, + nvq: 10053, + nvr: 10054, + nvs: 10055, + nvt: 10056, + nvu: 10057, + nvv: 10058, + nvw: 10059, + nvx: 10060, + nvy: 10061, + nwz: 10062, + nwa: 10063, + nwb: 10064, + nwc: 10065, + nwd: 10066, + nwe: 10067, + nwf: 10068, + nwg: 10069, + nwh: 10070, + nwi: 10071, + nwj: 10072, + nwk: 10073, + nwl: 10074, + nwm: 10075, + nwn: 10076, + nwo: 10077, + nwp: 10078, + nwq: 10079, + nwr: 10080, + nws: 10081, + nwt: 10082, + nwu: 10083, + nwv: 10084, + nww: 10085, + nwx: 10086, + nwy: 10087, + nxz: 10088, + nxa: 10089, + nxb: 10090, + nxc: 10091, + nxd: 10092, + nxe: 10093, + nxf: 10094, + nxg: 10095, + nxh: 10096, + nxi: 10097, + nxj: 10098, + nxk: 10099, + nxl: 10100, + nxm: 10101, + nxn: 10102, + nxo: 10103, + nxp: 10104, + nxq: 10105, + nxr: 10106, + nxs: 10107, + nxt: 10108, + nxu: 10109, + nxv: 10110, + nxw: 10111, + nxx: 10112, + nxy: 10113, + nyz: 10114, + nya: 10115, + nyb: 10116, + nyc: 10117, + nyd: 10118, + nye: 10119, + nyf: 10120, + nyg: 10121, + nyh: 10122, + nyi: 10123, + nyj: 10124, + nyk: 10125, + nyl: 10126, + nym: 10127, + nyn: 10128, + nyo: 10129, + nyp: 10130, + nyq: 10131, + nyr: 10132, + nys: 10133, + nyt: 10134, + nyu: 10135, + nyv: 10136, + nyw: 10137, + nyx: 10138, + nyy: 10139, + ozz: 10140, + oza: 10141, + ozb: 10142, + ozc: 10143, + ozd: 10144, + oze: 10145, + ozf: 10146, + ozg: 10147, + ozh: 10148, + ozi: 10149, + ozj: 10150, + ozk: 10151, + ozl: 10152, + ozm: 10153, + ozn: 10154, + ozo: 10155, + ozp: 10156, + ozq: 10157, + ozr: 10158, + ozs: 10159, + ozt: 10160, + ozu: 10161, + ozv: 10162, + ozw: 10163, + ozx: 10164, + ozy: 10165, + oaz: 10166, + oaa: 10167, + oab: 10168, + oac: 10169, + oad: 10170, + oae: 10171, + oaf: 10172, + oag: 10173, + oah: 10174, + oai: 10175, + oaj: 10176, + oak: 10177, + oal: 10178, + oam: 10179, + oan: 10180, + oao: 10181, + oap: 10182, + oaq: 10183, + oar: 10184, + oas: 10185, + oat: 10186, + oau: 10187, + oav: 10188, + oaw: 10189, + oax: 10190, + oay: 10191, + obz: 10192, + oba: 10193, + obb: 10194, + obc: 10195, + obd: 10196, + obe: 10197, + obf: 10198, + obg: 10199, + obh: 10200, + obi: 10201, + obj: 10202, + obk: 10203, + obl: 10204, + obm: 10205, + obn: 10206, + obo: 10207, + obp: 10208, + obq: 10209, + obr: 10210, + obs: 10211, + obt: 10212, + obu: 10213, + obv: 10214, + obw: 10215, + obx: 10216, + oby: 10217, + ocz: 10218, + oca: 10219, + ocb: 10220, + occ: 10221, + ocd: 10222, + oce: 10223, + ocf: 10224, + ocg: 10225, + och: 10226, + oci: 10227, + ocj: 10228, + ock: 10229, + ocl: 10230, + ocm: 10231, + ocn: 10232, + oco: 10233, + ocp: 10234, + ocq: 10235, + ocr: 10236, + ocs: 10237, + oct: 10238, + ocu: 10239, + ocv: 10240, + ocw: 10241, + ocx: 10242, + ocy: 10243, + odz: 10244, + oda: 10245, + odb: 10246, + odc: 10247, + odd: 10248, + ode: 10249, + odf: 10250, + odg: 10251, + odh: 10252, + odi: 10253, + odj: 10254, + odk: 10255, + odl: 10256, + odm: 10257, + odn: 10258, + odo: 10259, + odp: 10260, + odq: 10261, + odr: 10262, + ods: 10263, + odt: 10264, + odu: 10265, + odv: 10266, + odw: 10267, + odx: 10268, + ody: 10269, + oez: 10270, + oea: 10271, + oeb: 10272, + oec: 10273, + oed: 10274, + oee: 10275, + oef: 10276, + oeg: 10277, + oeh: 10278, + oei: 10279, + oej: 10280, + oek: 10281, + oel: 10282, + oem: 10283, + oen: 10284, + oeo: 10285, + oep: 10286, + oeq: 10287, + oer: 10288, + oes: 10289, + oet: 10290, + oeu: 10291, + oev: 10292, + oew: 10293, + oex: 10294, + oey: 10295, + ofz: 10296, + ofa: 10297, + ofb: 10298, + ofc: 10299, + ofd: 10300, + ofe: 10301, + off: 10302, + ofg: 10303, + ofh: 10304, + ofi: 10305, + ofj: 10306, + ofk: 10307, + ofl: 10308, + ofm: 10309, + ofn: 10310, + ofo: 10311, + ofp: 10312, + ofq: 10313, + ofr: 10314, + ofs: 10315, + oft: 10316, + ofu: 10317, + ofv: 10318, + ofw: 10319, + ofx: 10320, + ofy: 10321, + ogz: 10322, + oga: 10323, + ogb: 10324, + ogc: 10325, + ogd: 10326, + oge: 10327, + ogf: 10328, + ogg: 10329, + ogh: 10330, + ogi: 10331, + ogj: 10332, + ogk: 10333, + ogl: 10334, + ogm: 10335, + ogn: 10336, + ogo: 10337, + ogp: 10338, + ogq: 10339, + ogr: 10340, + ogs: 10341, + ogt: 10342, + ogu: 10343, + ogv: 10344, + ogw: 10345, + ogx: 10346, + ogy: 10347, + ohz: 10348, + oha: 10349, + ohb: 10350, + ohc: 10351, + ohd: 10352, + ohe: 10353, + ohf: 10354, + ohg: 10355, + ohh: 10356, + ohi: 10357, + ohj: 10358, + ohk: 10359, + ohl: 10360, + ohm: 10361, + ohn: 10362, + oho: 10363, + ohp: 10364, + ohq: 10365, + ohr: 10366, + ohs: 10367, + oht: 10368, + ohu: 10369, + ohv: 10370, + ohw: 10371, + ohx: 10372, + ohy: 10373, + oiz: 10374, + oia: 10375, + oib: 10376, + oic: 10377, + oid: 10378, + oie: 10379, + oif: 10380, + oig: 10381, + oih: 10382, + oii: 10383, + oij: 10384, + oik: 10385, + oil: 10386, + oim: 10387, + oin: 10388, + oio: 10389, + oip: 10390, + oiq: 10391, + oir: 10392, + ois: 10393, + oit: 10394, + oiu: 10395, + oiv: 10396, + oiw: 10397, + oix: 10398, + oiy: 10399, + ojz: 10400, + oja: 10401, + ojb: 10402, + ojc: 10403, + ojd: 10404, + oje: 10405, + ojf: 10406, + ojg: 10407, + ojh: 10408, + oji: 10409, + ojj: 10410, + ojk: 10411, + ojl: 10412, + ojm: 10413, + ojn: 10414, + ojo: 10415, + ojp: 10416, + ojq: 10417, + ojr: 10418, + ojs: 10419, + ojt: 10420, + oju: 10421, + ojv: 10422, + ojw: 10423, + ojx: 10424, + ojy: 10425, + okz: 10426, + oka: 10427, + okb: 10428, + okc: 10429, + okd: 10430, + oke: 10431, + okf: 10432, + okg: 10433, + okh: 10434, + oki: 10435, + okj: 10436, + okk: 10437, + okl: 10438, + okm: 10439, + okn: 10440, + oko: 10441, + okp: 10442, + okq: 10443, + okr: 10444, + oks: 10445, + okt: 10446, + oku: 10447, + okv: 10448, + okw: 10449, + okx: 10450, + oky: 10451, + olz: 10452, + ola: 10453, + olb: 10454, + olc: 10455, + old: 10456, + ole: 10457, + olf: 10458, + olg: 10459, + olh: 10460, + oli: 10461, + olj: 10462, + olk: 10463, + oll: 10464, + olm: 10465, + oln: 10466, + olo: 10467, + olp: 10468, + olq: 10469, + olr: 10470, + ols: 10471, + olt: 10472, + olu: 10473, + olv: 10474, + olw: 10475, + olx: 10476, + oly: 10477, + omz: 10478, + oma: 10479, + omb: 10480, + omc: 10481, + omd: 10482, + ome: 10483, + omf: 10484, + omg: 10485, + omh: 10486, + omi: 10487, + omj: 10488, + omk: 10489, + oml: 10490, + omm: 10491, + omn: 10492, + omo: 10493, + omp: 10494, + omq: 10495, + omr: 10496, + oms: 10497, + omt: 10498, + omu: 10499, + omv: 10500, + omw: 10501, + omx: 10502, + omy: 10503, + onz: 10504, + ona: 10505, + onb: 10506, + onc: 10507, + ond: 10508, + one: 10509, + onf: 10510, + ong: 10511, + onh: 10512, + oni: 10513, + onj: 10514, + onk: 10515, + onl: 10516, + onm: 10517, + onn: 10518, + ono: 10519, + onp: 10520, + onq: 10521, + onr: 10522, + ons: 10523, + ont: 10524, + onu: 10525, + onv: 10526, + onw: 10527, + onx: 10528, + ony: 10529, + ooz: 10530, + ooa: 10531, + oob: 10532, + ooc: 10533, + ood: 10534, + ooe: 10535, + oof: 10536, + oog: 10537, + ooh: 10538, + ooi: 10539, + ooj: 10540, + ook: 10541, + ool: 10542, + oom: 10543, + oon: 10544, + ooo: 10545, + oop: 10546, + ooq: 10547, + oor: 10548, + oos: 10549, + oot: 10550, + oou: 10551, + oov: 10552, + oow: 10553, + oox: 10554, + ooy: 10555, + opz: 10556, + opa: 10557, + opb: 10558, + opc: 10559, + opd: 10560, + ope: 10561, + opf: 10562, + opg: 10563, + oph: 10564, + opi: 10565, + opj: 10566, + opk: 10567, + opl: 10568, + opm: 10569, + opn: 10570, + opo: 10571, + opp: 10572, + opq: 10573, + opr: 10574, + ops: 10575, + opt: 10576, + opu: 10577, + opv: 10578, + opw: 10579, + opx: 10580, + opy: 10581, + oqz: 10582, + oqa: 10583, + oqb: 10584, + oqc: 10585, + oqd: 10586, + oqe: 10587, + oqf: 10588, + oqg: 10589, + oqh: 10590, + oqi: 10591, + oqj: 10592, + oqk: 10593, + oql: 10594, + oqm: 10595, + oqn: 10596, + oqo: 10597, + oqp: 10598, + oqq: 10599, + oqr: 10600, + oqs: 10601, + oqt: 10602, + oqu: 10603, + oqv: 10604, + oqw: 10605, + oqx: 10606, + oqy: 10607, + orz: 10608, + ora: 10609, + orb: 10610, + orc: 10611, + ord: 10612, + ore: 10613, + orf: 10614, + org: 10615, + orh: 10616, + ori: 10617, + orj: 10618, + ork: 10619, + orl: 10620, + orm: 10621, + orn: 10622, + oro: 10623, + orp: 10624, + orq: 10625, + orr: 10626, + ors: 10627, + ort: 10628, + oru: 10629, + orv: 10630, + orw: 10631, + orx: 10632, + ory: 10633, + osz: 10634, + osa: 10635, + osb: 10636, + osc: 10637, + osd: 10638, + ose: 10639, + osf: 10640, + osg: 10641, + osh: 10642, + osi: 10643, + osj: 10644, + osk: 10645, + osl: 10646, + osm: 10647, + osn: 10648, + oso: 10649, + osp: 10650, + osq: 10651, + osr: 10652, + oss: 10653, + ost: 10654, + osu: 10655, + osv: 10656, + osw: 10657, + osx: 10658, + osy: 10659, + otz: 10660, + ota: 10661, + otb: 10662, + otc: 10663, + otd: 10664, + ote: 10665, + otf: 10666, + otg: 10667, + oth: 10668, + oti: 10669, + otj: 10670, + otk: 10671, + otl: 10672, + otm: 10673, + otn: 10674, + oto: 10675, + otp: 10676, + otq: 10677, + otr: 10678, + ots: 10679, + ott: 10680, + otu: 10681, + otv: 10682, + otw: 10683, + otx: 10684, + oty: 10685, + ouz: 10686, + oua: 10687, + oub: 10688, + ouc: 10689, + oud: 10690, + oue: 10691, + ouf: 10692, + oug: 10693, + ouh: 10694, + oui: 10695, + ouj: 10696, + ouk: 10697, + oul: 10698, + oum: 10699, + oun: 10700, + ouo: 10701, + oup: 10702, + ouq: 10703, + our: 10704, + ous: 10705, + out: 10706, + ouu: 10707, + ouv: 10708, + ouw: 10709, + oux: 10710, + ouy: 10711, + ovz: 10712, + ova: 10713, + ovb: 10714, + ovc: 10715, + ovd: 10716, + ove: 10717, + ovf: 10718, + ovg: 10719, + ovh: 10720, + ovi: 10721, + ovj: 10722, + ovk: 10723, + ovl: 10724, + ovm: 10725, + ovn: 10726, + ovo: 10727, + ovp: 10728, + ovq: 10729, + ovr: 10730, + ovs: 10731, + ovt: 10732, + ovu: 10733, + ovv: 10734, + ovw: 10735, + ovx: 10736, + ovy: 10737, + owz: 10738, + owa: 10739, + owb: 10740, + owc: 10741, + owd: 10742, + owe: 10743, + owf: 10744, + owg: 10745, + owh: 10746, + owi: 10747, + owj: 10748, + owk: 10749, + owl: 10750, + owm: 10751, + own: 10752, + owo: 10753, + owp: 10754, + owq: 10755, + owr: 10756, + ows: 10757, + owt: 10758, + owu: 10759, + owv: 10760, + oww: 10761, + owx: 10762, + owy: 10763, + oxz: 10764, + oxa: 10765, + oxb: 10766, + oxc: 10767, + oxd: 10768, + oxe: 10769, + oxf: 10770, + oxg: 10771, + oxh: 10772, + oxi: 10773, + oxj: 10774, + oxk: 10775, + oxl: 10776, + oxm: 10777, + oxn: 10778, + oxo: 10779, + oxp: 10780, + oxq: 10781, + oxr: 10782, + oxs: 10783, + oxt: 10784, + oxu: 10785, + oxv: 10786, + oxw: 10787, + oxx: 10788, + oxy: 10789, + oyz: 10790, + oya: 10791, + oyb: 10792, + oyc: 10793, + oyd: 10794, + oye: 10795, + oyf: 10796, + oyg: 10797, + oyh: 10798, + oyi: 10799, + oyj: 10800, + oyk: 10801, + oyl: 10802, + oym: 10803, + oyn: 10804, + oyo: 10805, + oyp: 10806, + oyq: 10807, + oyr: 10808, + oys: 10809, + oyt: 10810, + oyu: 10811, + oyv: 10812, + oyw: 10813, + oyx: 10814, + oyy: 10815, + pzz: 10816, + pza: 10817, + pzb: 10818, + pzc: 10819, + pzd: 10820, + pze: 10821, + pzf: 10822, + pzg: 10823, + pzh: 10824, + pzi: 10825, + pzj: 10826, + pzk: 10827, + pzl: 10828, + pzm: 10829, + pzn: 10830, + pzo: 10831, + pzp: 10832, + pzq: 10833, + pzr: 10834, + pzs: 10835, + pzt: 10836, + pzu: 10837, + pzv: 10838, + pzw: 10839, + pzx: 10840, + pzy: 10841, + paz: 10842, + paa: 10843, + pab: 10844, + pac: 10845, + pad: 10846, + pae: 10847, + paf: 10848, + pag: 10849, + pah: 10850, + pai: 10851, + paj: 10852, + pak: 10853, + pal: 10854, + pam: 10855, + pan: 10856, + pao: 10857, + pap: 10858, + paq: 10859, + par: 10860, + pas: 10861, + pat: 10862, + pau: 10863, + pav: 10864, + paw: 10865, + pax: 10866, + pay: 10867, + pbz: 10868, + pba: 10869, + pbb: 10870, + pbc: 10871, + pbd: 10872, + pbe: 10873, + pbf: 10874, + pbg: 10875, + pbh: 10876, + pbi: 10877, + pbj: 10878, + pbk: 10879, + pbl: 10880, + pbm: 10881, + pbn: 10882, + pbo: 10883, + pbp: 10884, + pbq: 10885, + pbr: 10886, + pbs: 10887, + pbt: 10888, + pbu: 10889, + pbv: 10890, + pbw: 10891, + pbx: 10892, + pby: 10893, + pcz: 10894, + pca: 10895, + pcb: 10896, + pcc: 10897, + pcd: 10898, + pce: 10899, + pcf: 10900, + pcg: 10901, + pch: 10902, + pci: 10903, + pcj: 10904, + pck: 10905, + pcl: 10906, + pcm: 10907, + pcn: 10908, + pco: 10909, + pcp: 10910, + pcq: 10911, + pcr: 10912, + pcs: 10913, + pct: 10914, + pcu: 10915, + pcv: 10916, + pcw: 10917, + pcx: 10918, + pcy: 10919, + pdz: 10920, + pda: 10921, + pdb: 10922, + pdc: 10923, + pdd: 10924, + pde: 10925, + pdf: 10926, + pdg: 10927, + pdh: 10928, + pdi: 10929, + pdj: 10930, + pdk: 10931, + pdl: 10932, + pdm: 10933, + pdn: 10934, + pdo: 10935, + pdp: 10936, + pdq: 10937, + pdr: 10938, + pds: 10939, + pdt: 10940, + pdu: 10941, + pdv: 10942, + pdw: 10943, + pdx: 10944, + pdy: 10945, + pez: 10946, + pea: 10947, + peb: 10948, + pec: 10949, + ped: 10950, + pee: 10951, + pef: 10952, + peg: 10953, + peh: 10954, + pei: 10955, + pej: 10956, + pek: 10957, + pel: 10958, + pem: 10959, + pen: 10960, + peo: 10961, + pep: 10962, + peq: 10963, + per: 10964, + pes: 10965, + pet: 10966, + peu: 10967, + pev: 10968, + pew: 10969, + pex: 10970, + pey: 10971, + pfz: 10972, + pfa: 10973, + pfb: 10974, + pfc: 10975, + pfd: 10976, + pfe: 10977, + pff: 10978, + pfg: 10979, + pfh: 10980, + pfi: 10981, + pfj: 10982, + pfk: 10983, + pfl: 10984, + pfm: 10985, + pfn: 10986, + pfo: 10987, + pfp: 10988, + pfq: 10989, + pfr: 10990, + pfs: 10991, + pft: 10992, + pfu: 10993, + pfv: 10994, + pfw: 10995, + pfx: 10996, + pfy: 10997, + pgz: 10998, + pga: 10999, + pgb: 11000, + pgc: 11001, + pgd: 11002, + pge: 11003, + pgf: 11004, + pgg: 11005, + pgh: 11006, + pgi: 11007, + pgj: 11008, + pgk: 11009, + pgl: 11010, + pgm: 11011, + pgn: 11012, + pgo: 11013, + pgp: 11014, + pgq: 11015, + pgr: 11016, + pgs: 11017, + pgt: 11018, + pgu: 11019, + pgv: 11020, + pgw: 11021, + pgx: 11022, + pgy: 11023, + phz: 11024, + pha: 11025, + phb: 11026, + phc: 11027, + phd: 11028, + phe: 11029, + phf: 11030, + phg: 11031, + phh: 11032, + phi: 11033, + phj: 11034, + phk: 11035, + phl: 11036, + phm: 11037, + phn: 11038, + pho: 11039, + php: 11040, + phq: 11041, + phr: 11042, + phs: 11043, + pht: 11044, + phu: 11045, + phv: 11046, + phw: 11047, + phx: 11048, + phy: 11049, + piz: 11050, + pia: 11051, + pib: 11052, + pic: 11053, + pid: 11054, + pie: 11055, + pif: 11056, + pig: 11057, + pih: 11058, + pii: 11059, + pij: 11060, + pik: 11061, + pil: 11062, + pim: 11063, + pin: 11064, + pio: 11065, + pip: 11066, + piq: 11067, + pir: 11068, + pis: 11069, + pit: 11070, + piu: 11071, + piv: 11072, + piw: 11073, + pix: 11074, + piy: 11075, + pjz: 11076, + pja: 11077, + pjb: 11078, + pjc: 11079, + pjd: 11080, + pje: 11081, + pjf: 11082, + pjg: 11083, + pjh: 11084, + pji: 11085, + pjj: 11086, + pjk: 11087, + pjl: 11088, + pjm: 11089, + pjn: 11090, + pjo: 11091, + pjp: 11092, + pjq: 11093, + pjr: 11094, + pjs: 11095, + pjt: 11096, + pju: 11097, + pjv: 11098, + pjw: 11099, + pjx: 11100, + pjy: 11101, + pkz: 11102, + pka: 11103, + pkb: 11104, + pkc: 11105, + pkd: 11106, + pke: 11107, + pkf: 11108, + pkg: 11109, + pkh: 11110, + pki: 11111, + pkj: 11112, + pkk: 11113, + pkl: 11114, + pkm: 11115, + pkn: 11116, + pko: 11117, + pkp: 11118, + pkq: 11119, + pkr: 11120, + pks: 11121, + pkt: 11122, + pku: 11123, + pkv: 11124, + pkw: 11125, + pkx: 11126, + pky: 11127, + plz: 11128, + pla: 11129, + plb: 11130, + plc: 11131, + pld: 11132, + ple: 11133, + plf: 11134, + plg: 11135, + plh: 11136, + pli: 11137, + plj: 11138, + plk: 11139, + pll: 11140, + plm: 11141, + pln: 11142, + plo: 11143, + plp: 11144, + plq: 11145, + plr: 11146, + pls: 11147, + plt: 11148, + plu: 11149, + plv: 11150, + plw: 11151, + plx: 11152, + ply: 11153, + pmz: 11154, + pma: 11155, + pmb: 11156, + pmc: 11157, + pmd: 11158, + pme: 11159, + pmf: 11160, + pmg: 11161, + pmh: 11162, + pmi: 11163, + pmj: 11164, + pmk: 11165, + pml: 11166, + pmm: 11167, + pmn: 11168, + pmo: 11169, + pmp: 11170, + pmq: 11171, + pmr: 11172, + pms: 11173, + pmt: 11174, + pmu: 11175, + pmv: 11176, + pmw: 11177, + pmx: 11178, + pmy: 11179, + pnz: 11180, + pna: 11181, + pnb: 11182, + pnc: 11183, + pnd: 11184, + pne: 11185, + pnf: 11186, + png: 11187, + pnh: 11188, + pni: 11189, + pnj: 11190, + pnk: 11191, + pnl: 11192, + pnm: 11193, + pnn: 11194, + pno: 11195, + pnp: 11196, + pnq: 11197, + pnr: 11198, + pns: 11199, + pnt: 11200, + pnu: 11201, + pnv: 11202, + pnw: 11203, + pnx: 11204, + pny: 11205, + poz: 11206, + poa: 11207, + pob: 11208, + poc: 11209, + pod: 11210, + poe: 11211, + pof: 11212, + pog: 11213, + poh: 11214, + poi: 11215, + poj: 11216, + pok: 11217, + pol: 11218, + pom: 11219, + pon: 11220, + poo: 11221, + pop: 11222, + poq: 11223, + por: 11224, + pos: 11225, + pot: 11226, + pou: 11227, + pov: 11228, + pow: 11229, + pox: 11230, + poy: 11231, + ppz: 11232, + ppa: 11233, + ppb: 11234, + ppc: 11235, + ppd: 11236, + ppe: 11237, + ppf: 11238, + ppg: 11239, + pph: 11240, + ppi: 11241, + ppj: 11242, + ppk: 11243, + ppl: 11244, + ppm: 11245, + ppn: 11246, + ppo: 11247, + ppp: 11248, + ppq: 11249, + ppr: 11250, + pps: 11251, + ppt: 11252, + ppu: 11253, + ppv: 11254, + ppw: 11255, + ppx: 11256, + ppy: 11257, + pqz: 11258, + pqa: 11259, + pqb: 11260, + pqc: 11261, + pqd: 11262, + pqe: 11263, + pqf: 11264, + pqg: 11265, + pqh: 11266, + pqi: 11267, + pqj: 11268, + pqk: 11269, + pql: 11270, + pqm: 11271, + pqn: 11272, + pqo: 11273, + pqp: 11274, + pqq: 11275, + pqr: 11276, + pqs: 11277, + pqt: 11278, + pqu: 11279, + pqv: 11280, + pqw: 11281, + pqx: 11282, + pqy: 11283, + prz: 11284, + pra: 11285, + prb: 11286, + prc: 11287, + prd: 11288, + pre: 11289, + prf: 11290, + prg: 11291, + prh: 11292, + pri: 11293, + prj: 11294, + prk: 11295, + prl: 11296, + prm: 11297, + prn: 11298, + pro: 11299, + prp: 11300, + prq: 11301, + prr: 11302, + prs: 11303, + prt: 11304, + pru: 11305, + prv: 11306, + prw: 11307, + prx: 11308, + pry: 11309, + psz: 11310, + psa: 11311, + psb: 11312, + psc: 11313, + psd: 11314, + pse: 11315, + psf: 11316, + psg: 11317, + psh: 11318, + psi: 11319, + psj: 11320, + psk: 11321, + psl: 11322, + psm: 11323, + psn: 11324, + pso: 11325, + psp: 11326, + psq: 11327, + psr: 11328, + pss: 11329, + pst: 11330, + psu: 11331, + psv: 11332, + psw: 11333, + psx: 11334, + psy: 11335, + ptz: 11336, + pta: 11337, + ptb: 11338, + ptc: 11339, + ptd: 11340, + pte: 11341, + ptf: 11342, + ptg: 11343, + pth: 11344, + pti: 11345, + ptj: 11346, + ptk: 11347, + ptl: 11348, + ptm: 11349, + ptn: 11350, + pto: 11351, + ptp: 11352, + ptq: 11353, + ptr: 11354, + pts: 11355, + ptt: 11356, + ptu: 11357, + ptv: 11358, + ptw: 11359, + ptx: 11360, + pty: 11361, + puz: 11362, + pua: 11363, + pub: 11364, + puc: 11365, + pud: 11366, + pue: 11367, + puf: 11368, + pug: 11369, + puh: 11370, + pui: 11371, + puj: 11372, + puk: 11373, + pul: 11374, + pum: 11375, + pun: 11376, + puo: 11377, + pup: 11378, + puq: 11379, + pur: 11380, + pus: 11381, + put: 11382, + puu: 11383, + puv: 11384, + puw: 11385, + pux: 11386, + puy: 11387, + pvz: 11388, + pva: 11389, + pvb: 11390, + pvc: 11391, + pvd: 11392, + pve: 11393, + pvf: 11394, + pvg: 11395, + pvh: 11396, + pvi: 11397, + pvj: 11398, + pvk: 11399, + pvl: 11400, + pvm: 11401, + pvn: 11402, + pvo: 11403, + pvp: 11404, + pvq: 11405, + pvr: 11406, + pvs: 11407, + pvt: 11408, + pvu: 11409, + pvv: 11410, + pvw: 11411, + pvx: 11412, + pvy: 11413, + pwz: 11414, + pwa: 11415, + pwb: 11416, + pwc: 11417, + pwd: 11418, + pwe: 11419, + pwf: 11420, + pwg: 11421, + pwh: 11422, + pwi: 11423, + pwj: 11424, + pwk: 11425, + pwl: 11426, + pwm: 11427, + pwn: 11428, + pwo: 11429, + pwp: 11430, + pwq: 11431, + pwr: 11432, + pws: 11433, + pwt: 11434, + pwu: 11435, + pwv: 11436, + pww: 11437, + pwx: 11438, + pwy: 11439, + pxz: 11440, + pxa: 11441, + pxb: 11442, + pxc: 11443, + pxd: 11444, + pxe: 11445, + pxf: 11446, + pxg: 11447, + pxh: 11448, + pxi: 11449, + pxj: 11450, + pxk: 11451, + pxl: 11452, + pxm: 11453, + pxn: 11454, + pxo: 11455, + pxp: 11456, + pxq: 11457, + pxr: 11458, + pxs: 11459, + pxt: 11460, + pxu: 11461, + pxv: 11462, + pxw: 11463, + pxx: 11464, + pxy: 11465, + pyz: 11466, + pya: 11467, + pyb: 11468, + pyc: 11469, + pyd: 11470, + pye: 11471, + pyf: 11472, + pyg: 11473, + pyh: 11474, + pyi: 11475, + pyj: 11476, + pyk: 11477, + pyl: 11478, + pym: 11479, + pyn: 11480, + pyo: 11481, + pyp: 11482, + pyq: 11483, + pyr: 11484, + pys: 11485, + pyt: 11486, + pyu: 11487, + pyv: 11488, + pyw: 11489, + pyx: 11490, + pyy: 11491, + qzz: 11492, + qza: 11493, + qzb: 11494, + qzc: 11495, + qzd: 11496, + qze: 11497, + qzf: 11498, + qzg: 11499, + qzh: 11500, + qzi: 11501, + qzj: 11502, + qzk: 11503, + qzl: 11504, + qzm: 11505, + qzn: 11506, + qzo: 11507, + qzp: 11508, + qzq: 11509, + qzr: 11510, + qzs: 11511, + qzt: 11512, + qzu: 11513, + qzv: 11514, + qzw: 11515, + qzx: 11516, + qzy: 11517, + qaz: 11518, + qaa: 11519, + qab: 11520, + qac: 11521, + qad: 11522, + qae: 11523, + qaf: 11524, + qag: 11525, + qah: 11526, + qai: 11527, + qaj: 11528, + qak: 11529, + qal: 11530, + qam: 11531, + qan: 11532, + qao: 11533, + qap: 11534, + qaq: 11535, + qar: 11536, + qas: 11537, + qat: 11538, + qau: 11539, + qav: 11540, + qaw: 11541, + qax: 11542, + qay: 11543, + qbz: 11544, + qba: 11545, + qbb: 11546, + qbc: 11547, + qbd: 11548, + qbe: 11549, + qbf: 11550, + qbg: 11551, + qbh: 11552, + qbi: 11553, + qbj: 11554, + qbk: 11555, + qbl: 11556, + qbm: 11557, + qbn: 11558, + qbo: 11559, + qbp: 11560, + qbq: 11561, + qbr: 11562, + qbs: 11563, + qbt: 11564, + qbu: 11565, + qbv: 11566, + qbw: 11567, + qbx: 11568, + qby: 11569, + qcz: 11570, + qca: 11571, + qcb: 11572, + qcc: 11573, + qcd: 11574, + qce: 11575, + qcf: 11576, + qcg: 11577, + qch: 11578, + qci: 11579, + qcj: 11580, + qck: 11581, + qcl: 11582, + qcm: 11583, + qcn: 11584, + qco: 11585, + qcp: 11586, + qcq: 11587, + qcr: 11588, + qcs: 11589, + qct: 11590, + qcu: 11591, + qcv: 11592, + qcw: 11593, + qcx: 11594, + qcy: 11595, + qdz: 11596, + qda: 11597, + qdb: 11598, + qdc: 11599, + qdd: 11600, + qde: 11601, + qdf: 11602, + qdg: 11603, + qdh: 11604, + qdi: 11605, + qdj: 11606, + qdk: 11607, + qdl: 11608, + qdm: 11609, + qdn: 11610, + qdo: 11611, + qdp: 11612, + qdq: 11613, + qdr: 11614, + qds: 11615, + qdt: 11616, + qdu: 11617, + qdv: 11618, + qdw: 11619, + qdx: 11620, + qdy: 11621, + qez: 11622, + qea: 11623, + qeb: 11624, + qec: 11625, + qed: 11626, + qee: 11627, + qef: 11628, + qeg: 11629, + qeh: 11630, + qei: 11631, + qej: 11632, + qek: 11633, + qel: 11634, + qem: 11635, + qen: 11636, + qeo: 11637, + qep: 11638, + qeq: 11639, + qer: 11640, + qes: 11641, + qet: 11642, + qeu: 11643, + qev: 11644, + qew: 11645, + qex: 11646, + qey: 11647, + qfz: 11648, + qfa: 11649, + qfb: 11650, + qfc: 11651, + qfd: 11652, + qfe: 11653, + qff: 11654, + qfg: 11655, + qfh: 11656, + qfi: 11657, + qfj: 11658, + qfk: 11659, + qfl: 11660, + qfm: 11661, + qfn: 11662, + qfo: 11663, + qfp: 11664, + qfq: 11665, + qfr: 11666, + qfs: 11667, + qft: 11668, + qfu: 11669, + qfv: 11670, + qfw: 11671, + qfx: 11672, + qfy: 11673, + qgz: 11674, + qga: 11675, + qgb: 11676, + qgc: 11677, + qgd: 11678, + qge: 11679, + qgf: 11680, + qgg: 11681, + qgh: 11682, + qgi: 11683, + qgj: 11684, + qgk: 11685, + qgl: 11686, + qgm: 11687, + qgn: 11688, + qgo: 11689, + qgp: 11690, + qgq: 11691, + qgr: 11692, + qgs: 11693, + qgt: 11694, + qgu: 11695, + qgv: 11696, + qgw: 11697, + qgx: 11698, + qgy: 11699, + qhz: 11700, + qha: 11701, + qhb: 11702, + qhc: 11703, + qhd: 11704, + qhe: 11705, + qhf: 11706, + qhg: 11707, + qhh: 11708, + qhi: 11709, + qhj: 11710, + qhk: 11711, + qhl: 11712, + qhm: 11713, + qhn: 11714, + qho: 11715, + qhp: 11716, + qhq: 11717, + qhr: 11718, + qhs: 11719, + qht: 11720, + qhu: 11721, + qhv: 11722, + qhw: 11723, + qhx: 11724, + qhy: 11725, + qiz: 11726, + qia: 11727, + qib: 11728, + qic: 11729, + qid: 11730, + qie: 11731, + qif: 11732, + qig: 11733, + qih: 11734, + qii: 11735, + qij: 11736, + qik: 11737, + qil: 11738, + qim: 11739, + qin: 11740, + qio: 11741, + qip: 11742, + qiq: 11743, + qir: 11744, + qis: 11745, + qit: 11746, + qiu: 11747, + qiv: 11748, + qiw: 11749, + qix: 11750, + qiy: 11751, + qjz: 11752, + qja: 11753, + qjb: 11754, + qjc: 11755, + qjd: 11756, + qje: 11757, + qjf: 11758, + qjg: 11759, + qjh: 11760, + qji: 11761, + qjj: 11762, + qjk: 11763, + qjl: 11764, + qjm: 11765, + qjn: 11766, + qjo: 11767, + qjp: 11768, + qjq: 11769, + qjr: 11770, + qjs: 11771, + qjt: 11772, + qju: 11773, + qjv: 11774, + qjw: 11775, + qjx: 11776, + qjy: 11777, + qkz: 11778, + qka: 11779, + qkb: 11780, + qkc: 11781, + qkd: 11782, + qke: 11783, + qkf: 11784, + qkg: 11785, + qkh: 11786, + qki: 11787, + qkj: 11788, + qkk: 11789, + qkl: 11790, + qkm: 11791, + qkn: 11792, + qko: 11793, + qkp: 11794, + qkq: 11795, + qkr: 11796, + qks: 11797, + qkt: 11798, + qku: 11799, + qkv: 11800, + qkw: 11801, + qkx: 11802, + qky: 11803, + qlz: 11804, + qla: 11805, + qlb: 11806, + qlc: 11807, + qld: 11808, + qle: 11809, + qlf: 11810, + qlg: 11811, + qlh: 11812, + qli: 11813, + qlj: 11814, + qlk: 11815, + qll: 11816, + qlm: 11817, + qln: 11818, + qlo: 11819, + qlp: 11820, + qlq: 11821, + qlr: 11822, + qls: 11823, + qlt: 11824, + qlu: 11825, + qlv: 11826, + qlw: 11827, + qlx: 11828, + qly: 11829, + qmz: 11830, + qma: 11831, + qmb: 11832, + qmc: 11833, + qmd: 11834, + qme: 11835, + qmf: 11836, + qmg: 11837, + qmh: 11838, + qmi: 11839, + qmj: 11840, + qmk: 11841, + qml: 11842, + qmm: 11843, + qmn: 11844, + qmo: 11845, + qmp: 11846, + qmq: 11847, + qmr: 11848, + qms: 11849, + qmt: 11850, + qmu: 11851, + qmv: 11852, + qmw: 11853, + qmx: 11854, + qmy: 11855, + qnz: 11856, + qna: 11857, + qnb: 11858, + qnc: 11859, + qnd: 11860, + qne: 11861, + qnf: 11862, + qng: 11863, + qnh: 11864, + qni: 11865, + qnj: 11866, + qnk: 11867, + qnl: 11868, + qnm: 11869, + qnn: 11870, + qno: 11871, + qnp: 11872, + qnq: 11873, + qnr: 11874, + qns: 11875, + qnt: 11876, + qnu: 11877, + qnv: 11878, + qnw: 11879, + qnx: 11880, + qny: 11881, + qoz: 11882, + qoa: 11883, + qob: 11884, + qoc: 11885, + qod: 11886, + qoe: 11887, + qof: 11888, + qog: 11889, + qoh: 11890, + qoi: 11891, + qoj: 11892, + qok: 11893, + qol: 11894, + qom: 11895, + qon: 11896, + qoo: 11897, + qop: 11898, + qoq: 11899, + qor: 11900, + qos: 11901, + qot: 11902, + qou: 11903, + qov: 11904, + qow: 11905, + qox: 11906, + qoy: 11907, + qpz: 11908, + qpa: 11909, + qpb: 11910, + qpc: 11911, + qpd: 11912, + qpe: 11913, + qpf: 11914, + qpg: 11915, + qph: 11916, + qpi: 11917, + qpj: 11918, + qpk: 11919, + qpl: 11920, + qpm: 11921, + qpn: 11922, + qpo: 11923, + qpp: 11924, + qpq: 11925, + qpr: 11926, + qps: 11927, + qpt: 11928, + qpu: 11929, + qpv: 11930, + qpw: 11931, + qpx: 11932, + qpy: 11933, + qqz: 11934, + qqa: 11935, + qqb: 11936, + qqc: 11937, + qqd: 11938, + qqe: 11939, + qqf: 11940, + qqg: 11941, + qqh: 11942, + qqi: 11943, + qqj: 11944, + qqk: 11945, + qql: 11946, + qqm: 11947, + qqn: 11948, + qqo: 11949, + qqp: 11950, + qqq: 11951, + qqr: 11952, + qqs: 11953, + qqt: 11954, + qqu: 11955, + qqv: 11956, + qqw: 11957, + qqx: 11958, + qqy: 11959, + qrz: 11960, + qra: 11961, + qrb: 11962, + qrc: 11963, + qrd: 11964, + qre: 11965, + qrf: 11966, + qrg: 11967, + qrh: 11968, + qri: 11969, + qrj: 11970, + qrk: 11971, + qrl: 11972, + qrm: 11973, + qrn: 11974, + qro: 11975, + qrp: 11976, + qrq: 11977, + qrr: 11978, + qrs: 11979, + qrt: 11980, + qru: 11981, + qrv: 11982, + qrw: 11983, + qrx: 11984, + qry: 11985, + qsz: 11986, + qsa: 11987, + qsb: 11988, + qsc: 11989, + qsd: 11990, + qse: 11991, + qsf: 11992, + qsg: 11993, + qsh: 11994, + qsi: 11995, + qsj: 11996, + qsk: 11997, + qsl: 11998, + qsm: 11999, + qsn: 12000, + qso: 12001, + qsp: 12002, + qsq: 12003, + qsr: 12004, + qss: 12005, + qst: 12006, + qsu: 12007, + qsv: 12008, + qsw: 12009, + qsx: 12010, + qsy: 12011, + qtz: 12012, + qta: 12013, + qtb: 12014, + qtc: 12015, + qtd: 12016, + qte: 12017, + qtf: 12018, + qtg: 12019, + qth: 12020, + qti: 12021, + qtj: 12022, + qtk: 12023, + qtl: 12024, + qtm: 12025, + qtn: 12026, + qto: 12027, + qtp: 12028, + qtq: 12029, + qtr: 12030, + qts: 12031, + qtt: 12032, + qtu: 12033, + qtv: 12034, + qtw: 12035, + qtx: 12036, + qty: 12037, + quz: 12038, + qua: 12039, + qub: 12040, + quc: 12041, + qud: 12042, + que: 12043, + quf: 12044, + qug: 12045, + quh: 12046, + qui: 12047, + quj: 12048, + quk: 12049, + qul: 12050, + qum: 12051, + qun: 12052, + quo: 12053, + qup: 12054, + quq: 12055, + qur: 12056, + qus: 12057, + qut: 12058, + quu: 12059, + quv: 12060, + quw: 12061, + qux: 12062, + quy: 12063, + qvz: 12064, + qva: 12065, + qvb: 12066, + qvc: 12067, + qvd: 12068, + qve: 12069, + qvf: 12070, + qvg: 12071, + qvh: 12072, + qvi: 12073, + qvj: 12074, + qvk: 12075, + qvl: 12076, + qvm: 12077, + qvn: 12078, + qvo: 12079, + qvp: 12080, + qvq: 12081, + qvr: 12082, + qvs: 12083, + qvt: 12084, + qvu: 12085, + qvv: 12086, + qvw: 12087, + qvx: 12088, + qvy: 12089, + qwz: 12090, + qwa: 12091, + qwb: 12092, + qwc: 12093, + qwd: 12094, + qwe: 12095, + qwf: 12096, + qwg: 12097, + qwh: 12098, + qwi: 12099, + qwj: 12100, + qwk: 12101, + qwl: 12102, + qwm: 12103, + qwn: 12104, + qwo: 12105, + qwp: 12106, + qwq: 12107, + qwr: 12108, + qws: 12109, + qwt: 12110, + qwu: 12111, + qwv: 12112, + qww: 12113, + qwx: 12114, + qwy: 12115, + qxz: 12116, + qxa: 12117, + qxb: 12118, + qxc: 12119, + qxd: 12120, + qxe: 12121, + qxf: 12122, + qxg: 12123, + qxh: 12124, + qxi: 12125, + qxj: 12126, + qxk: 12127, + qxl: 12128, + qxm: 12129, + qxn: 12130, + qxo: 12131, + qxp: 12132, + qxq: 12133, + qxr: 12134, + qxs: 12135, + qxt: 12136, + qxu: 12137, + qxv: 12138, + qxw: 12139, + qxx: 12140, + qxy: 12141, + qyz: 12142, + qya: 12143, + qyb: 12144, + qyc: 12145, + qyd: 12146, + qye: 12147, + qyf: 12148, + qyg: 12149, + qyh: 12150, + qyi: 12151, + qyj: 12152, + qyk: 12153, + qyl: 12154, + qym: 12155, + qyn: 12156, + qyo: 12157, + qyp: 12158, + qyq: 12159, + qyr: 12160, + qys: 12161, + qyt: 12162, + qyu: 12163, + qyv: 12164, + qyw: 12165, + qyx: 12166, + qyy: 12167, + rzz: 12168, + rza: 12169, + rzb: 12170, + rzc: 12171, + rzd: 12172, + rze: 12173, + rzf: 12174, + rzg: 12175, + rzh: 12176, + rzi: 12177, + rzj: 12178, + rzk: 12179, + rzl: 12180, + rzm: 12181, + rzn: 12182, + rzo: 12183, + rzp: 12184, + rzq: 12185, + rzr: 12186, + rzs: 12187, + rzt: 12188, + rzu: 12189, + rzv: 12190, + rzw: 12191, + rzx: 12192, + rzy: 12193, + raz: 12194, + raa: 12195, + rab: 12196, + rac: 12197, + rad: 12198, + rae: 12199, + raf: 12200, + rag: 12201, + rah: 12202, + rai: 12203, + raj: 12204, + rak: 12205, + ral: 12206, + ram: 12207, + ran: 12208, + rao: 12209, + rap: 12210, + raq: 12211, + rar: 12212, + ras: 12213, + rat: 12214, + rau: 12215, + rav: 12216, + raw: 12217, + rax: 12218, + ray: 12219, + rbz: 12220, + rba: 12221, + rbb: 12222, + rbc: 12223, + rbd: 12224, + rbe: 12225, + rbf: 12226, + rbg: 12227, + rbh: 12228, + rbi: 12229, + rbj: 12230, + rbk: 12231, + rbl: 12232, + rbm: 12233, + rbn: 12234, + rbo: 12235, + rbp: 12236, + rbq: 12237, + rbr: 12238, + rbs: 12239, + rbt: 12240, + rbu: 12241, + rbv: 12242, + rbw: 12243, + rbx: 12244, + rby: 12245, + rcz: 12246, + rca: 12247, + rcb: 12248, + rcc: 12249, + rcd: 12250, + rce: 12251, + rcf: 12252, + rcg: 12253, + rch: 12254, + rci: 12255, + rcj: 12256, + rck: 12257, + rcl: 12258, + rcm: 12259, + rcn: 12260, + rco: 12261, + rcp: 12262, + rcq: 12263, + rcr: 12264, + rcs: 12265, + rct: 12266, + rcu: 12267, + rcv: 12268, + rcw: 12269, + rcx: 12270, + rcy: 12271, + rdz: 12272, + rda: 12273, + rdb: 12274, + rdc: 12275, + rdd: 12276, + rde: 12277, + rdf: 12278, + rdg: 12279, + rdh: 12280, + rdi: 12281, + rdj: 12282, + rdk: 12283, + rdl: 12284, + rdm: 12285, + rdn: 12286, + rdo: 12287, + rdp: 12288, + rdq: 12289, + rdr: 12290, + rds: 12291, + rdt: 12292, + rdu: 12293, + rdv: 12294, + rdw: 12295, + rdx: 12296, + rdy: 12297, + rez: 12298, + rea: 12299, + reb: 12300, + rec: 12301, + red: 12302, + ree: 12303, + ref: 12304, + reg: 12305, + reh: 12306, + rei: 12307, + rej: 12308, + rek: 12309, + rel: 12310, + rem: 12311, + ren: 12312, + reo: 12313, + rep: 12314, + req: 12315, + rer: 12316, + res: 12317, + ret: 12318, + reu: 12319, + rev: 12320, + rew: 12321, + rex: 12322, + rey: 12323, + rfz: 12324, + rfa: 12325, + rfb: 12326, + rfc: 12327, + rfd: 12328, + rfe: 12329, + rff: 12330, + rfg: 12331, + rfh: 12332, + rfi: 12333, + rfj: 12334, + rfk: 12335, + rfl: 12336, + rfm: 12337, + rfn: 12338, + rfo: 12339, + rfp: 12340, + rfq: 12341, + rfr: 12342, + rfs: 12343, + rft: 12344, + rfu: 12345, + rfv: 12346, + rfw: 12347, + rfx: 12348, + rfy: 12349, + rgz: 12350, + rga: 12351, + rgb: 12352, + rgc: 12353, + rgd: 12354, + rge: 12355, + rgf: 12356, + rgg: 12357, + rgh: 12358, + rgi: 12359, + rgj: 12360, + rgk: 12361, + rgl: 12362, + rgm: 12363, + rgn: 12364, + rgo: 12365, + rgp: 12366, + rgq: 12367, + rgr: 12368, + rgs: 12369, + rgt: 12370, + rgu: 12371, + rgv: 12372, + rgw: 12373, + rgx: 12374, + rgy: 12375, + rhz: 12376, + rha: 12377, + rhb: 12378, + rhc: 12379, + rhd: 12380, + rhe: 12381, + rhf: 12382, + rhg: 12383, + rhh: 12384, + rhi: 12385, + rhj: 12386, + rhk: 12387, + rhl: 12388, + rhm: 12389, + rhn: 12390, + rho: 12391, + rhp: 12392, + rhq: 12393, + rhr: 12394, + rhs: 12395, + rht: 12396, + rhu: 12397, + rhv: 12398, + rhw: 12399, + rhx: 12400, + rhy: 12401, + riz: 12402, + ria: 12403, + rib: 12404, + ric: 12405, + rid: 12406, + rie: 12407, + rif: 12408, + rig: 12409, + rih: 12410, + rii: 12411, + rij: 12412, + rik: 12413, + ril: 12414, + rim: 12415, + rin: 12416, + rio: 12417, + rip: 12418, + riq: 12419, + rir: 12420, + ris: 12421, + rit: 12422, + riu: 12423, + riv: 12424, + riw: 12425, + rix: 12426, + riy: 12427, + rjz: 12428, + rja: 12429, + rjb: 12430, + rjc: 12431, + rjd: 12432, + rje: 12433, + rjf: 12434, + rjg: 12435, + rjh: 12436, + rji: 12437, + rjj: 12438, + rjk: 12439, + rjl: 12440, + rjm: 12441, + rjn: 12442, + rjo: 12443, + rjp: 12444, + rjq: 12445, + rjr: 12446, + rjs: 12447, + rjt: 12448, + rju: 12449, + rjv: 12450, + rjw: 12451, + rjx: 12452, + rjy: 12453, + rkz: 12454, + rka: 12455, + rkb: 12456, + rkc: 12457, + rkd: 12458, + rke: 12459, + rkf: 12460, + rkg: 12461, + rkh: 12462, + rki: 12463, + rkj: 12464, + rkk: 12465, + rkl: 12466, + rkm: 12467, + rkn: 12468, + rko: 12469, + rkp: 12470, + rkq: 12471, + rkr: 12472, + rks: 12473, + rkt: 12474, + rku: 12475, + rkv: 12476, + rkw: 12477, + rkx: 12478, + rky: 12479, + rlz: 12480, + rla: 12481, + rlb: 12482, + rlc: 12483, + rld: 12484, + rle: 12485, + rlf: 12486, + rlg: 12487, + rlh: 12488, + rli: 12489, + rlj: 12490, + rlk: 12491, + rll: 12492, + rlm: 12493, + rln: 12494, + rlo: 12495, + rlp: 12496, + rlq: 12497, + rlr: 12498, + rls: 12499, + rlt: 12500, + rlu: 12501, + rlv: 12502, + rlw: 12503, + rlx: 12504, + rly: 12505, + rmz: 12506, + rma: 12507, + rmb: 12508, + rmc: 12509, + rmd: 12510, + rme: 12511, + rmf: 12512, + rmg: 12513, + rmh: 12514, + rmi: 12515, + rmj: 12516, + rmk: 12517, + rml: 12518, + rmm: 12519, + rmn: 12520, + rmo: 12521, + rmp: 12522, + rmq: 12523, + rmr: 12524, + rms: 12525, + rmt: 12526, + rmu: 12527, + rmv: 12528, + rmw: 12529, + rmx: 12530, + rmy: 12531, + rnz: 12532, + rna: 12533, + rnb: 12534, + rnc: 12535, + rnd: 12536, + rne: 12537, + rnf: 12538, + rng: 12539, + rnh: 12540, + rni: 12541, + rnj: 12542, + rnk: 12543, + rnl: 12544, + rnm: 12545, + rnn: 12546, + rno: 12547, + rnp: 12548, + rnq: 12549, + rnr: 12550, + rns: 12551, + rnt: 12552, + rnu: 12553, + rnv: 12554, + rnw: 12555, + rnx: 12556, + rny: 12557, + roz: 12558, + roa: 12559, + rob: 12560, + roc: 12561, + rod: 12562, + roe: 12563, + rof: 12564, + rog: 12565, + roh: 12566, + roi: 12567, + roj: 12568, + rok: 12569, + rol: 12570, + rom: 12571, + ron: 12572, + roo: 12573, + rop: 12574, + roq: 12575, + ror: 12576, + ros: 12577, + rot: 12578, + rou: 12579, + rov: 12580, + row: 12581, + rox: 12582, + roy: 12583, + rpz: 12584, + rpa: 12585, + rpb: 12586, + rpc: 12587, + rpd: 12588, + rpe: 12589, + rpf: 12590, + rpg: 12591, + rph: 12592, + rpi: 12593, + rpj: 12594, + rpk: 12595, + rpl: 12596, + rpm: 12597, + rpn: 12598, + rpo: 12599, + rpp: 12600, + rpq: 12601, + rpr: 12602, + rps: 12603, + rpt: 12604, + rpu: 12605, + rpv: 12606, + rpw: 12607, + rpx: 12608, + rpy: 12609, + rqz: 12610, + rqa: 12611, + rqb: 12612, + rqc: 12613, + rqd: 12614, + rqe: 12615, + rqf: 12616, + rqg: 12617, + rqh: 12618, + rqi: 12619, + rqj: 12620, + rqk: 12621, + rql: 12622, + rqm: 12623, + rqn: 12624, + rqo: 12625, + rqp: 12626, + rqq: 12627, + rqr: 12628, + rqs: 12629, + rqt: 12630, + rqu: 12631, + rqv: 12632, + rqw: 12633, + rqx: 12634, + rqy: 12635, + rrz: 12636, + rra: 12637, + rrb: 12638, + rrc: 12639, + rrd: 12640, + rre: 12641, + rrf: 12642, + rrg: 12643, + rrh: 12644, + rri: 12645, + rrj: 12646, + rrk: 12647, + rrl: 12648, + rrm: 12649, + rrn: 12650, + rro: 12651, + rrp: 12652, + rrq: 12653, + rrr: 12654, + rrs: 12655, + rrt: 12656, + rru: 12657, + rrv: 12658, + rrw: 12659, + rrx: 12660, + rry: 12661, + rsz: 12662, + rsa: 12663, + rsb: 12664, + rsc: 12665, + rsd: 12666, + rse: 12667, + rsf: 12668, + rsg: 12669, + rsh: 12670, + rsi: 12671, + rsj: 12672, + rsk: 12673, + rsl: 12674, + rsm: 12675, + rsn: 12676, + rso: 12677, + rsp: 12678, + rsq: 12679, + rsr: 12680, + rss: 12681, + rst: 12682, + rsu: 12683, + rsv: 12684, + rsw: 12685, + rsx: 12686, + rsy: 12687, + rtz: 12688, + rta: 12689, + rtb: 12690, + rtc: 12691, + rtd: 12692, + rte: 12693, + rtf: 12694, + rtg: 12695, + rth: 12696, + rti: 12697, + rtj: 12698, + rtk: 12699, + rtl: 12700, + rtm: 12701, + rtn: 12702, + rto: 12703, + rtp: 12704, + rtq: 12705, + rtr: 12706, + rts: 12707, + rtt: 12708, + rtu: 12709, + rtv: 12710, + rtw: 12711, + rtx: 12712, + rty: 12713, + ruz: 12714, + rua: 12715, + rub: 12716, + ruc: 12717, + rud: 12718, + rue: 12719, + ruf: 12720, + rug: 12721, + ruh: 12722, + rui: 12723, + ruj: 12724, + ruk: 12725, + rul: 12726, + rum: 12727, + run: 12728, + ruo: 12729, + rup: 12730, + ruq: 12731, + rur: 12732, + rus: 12733, + rut: 12734, + ruu: 12735, + ruv: 12736, + ruw: 12737, + rux: 12738, + ruy: 12739, + rvz: 12740, + rva: 12741, + rvb: 12742, + rvc: 12743, + rvd: 12744, + rve: 12745, + rvf: 12746, + rvg: 12747, + rvh: 12748, + rvi: 12749, + rvj: 12750, + rvk: 12751, + rvl: 12752, + rvm: 12753, + rvn: 12754, + rvo: 12755, + rvp: 12756, + rvq: 12757, + rvr: 12758, + rvs: 12759, + rvt: 12760, + rvu: 12761, + rvv: 12762, + rvw: 12763, + rvx: 12764, + rvy: 12765, + rwz: 12766, + rwa: 12767, + rwb: 12768, + rwc: 12769, + rwd: 12770, + rwe: 12771, + rwf: 12772, + rwg: 12773, + rwh: 12774, + rwi: 12775, + rwj: 12776, + rwk: 12777, + rwl: 12778, + rwm: 12779, + rwn: 12780, + rwo: 12781, + rwp: 12782, + rwq: 12783, + rwr: 12784, + rws: 12785, + rwt: 12786, + rwu: 12787, + rwv: 12788, + rww: 12789, + rwx: 12790, + rwy: 12791, + rxz: 12792, + rxa: 12793, + rxb: 12794, + rxc: 12795, + rxd: 12796, + rxe: 12797, + rxf: 12798, + rxg: 12799, + rxh: 12800, + rxi: 12801, + rxj: 12802, + rxk: 12803, + rxl: 12804, + rxm: 12805, + rxn: 12806, + rxo: 12807, + rxp: 12808, + rxq: 12809, + rxr: 12810, + rxs: 12811, + rxt: 12812, + rxu: 12813, + rxv: 12814, + rxw: 12815, + rxx: 12816, + rxy: 12817, + ryz: 12818, + rya: 12819, + ryb: 12820, + ryc: 12821, + ryd: 12822, + rye: 12823, + ryf: 12824, + ryg: 12825, + ryh: 12826, + ryi: 12827, + ryj: 12828, + ryk: 12829, + ryl: 12830, + rym: 12831, + ryn: 12832, + ryo: 12833, + ryp: 12834, + ryq: 12835, + ryr: 12836, + rys: 12837, + ryt: 12838, + ryu: 12839, + ryv: 12840, + ryw: 12841, + ryx: 12842, + ryy: 12843, + szz: 12844, + sza: 12845, + szb: 12846, + szc: 12847, + szd: 12848, + sze: 12849, + szf: 12850, + szg: 12851, + szh: 12852, + szi: 12853, + szj: 12854, + szk: 12855, + szl: 12856, + szm: 12857, + szn: 12858, + szo: 12859, + szp: 12860, + szq: 12861, + szr: 12862, + szs: 12863, + szt: 12864, + szu: 12865, + szv: 12866, + szw: 12867, + szx: 12868, + szy: 12869, + saz: 12870, + saa: 12871, + sab: 12872, + sac: 12873, + sad: 12874, + sae: 12875, + saf: 12876, + sag: 12877, + sah: 12878, + sai: 12879, + saj: 12880, + sak: 12881, + sal: 12882, + sam: 12883, + san: 12884, + sao: 12885, + sap: 12886, + saq: 12887, + sar: 12888, + sas: 12889, + sat: 12890, + sau: 12891, + sav: 12892, + saw: 12893, + sax: 12894, + say: 12895, + sbz: 12896, + sba: 12897, + sbb: 12898, + sbc: 12899, + sbd: 12900, + sbe: 12901, + sbf: 12902, + sbg: 12903, + sbh: 12904, + sbi: 12905, + sbj: 12906, + sbk: 12907, + sbl: 12908, + sbm: 12909, + sbn: 12910, + sbo: 12911, + sbp: 12912, + sbq: 12913, + sbr: 12914, + sbs: 12915, + sbt: 12916, + sbu: 12917, + sbv: 12918, + sbw: 12919, + sbx: 12920, + sby: 12921, + scz: 12922, + sca: 12923, + scb: 12924, + scc: 12925, + scd: 12926, + sce: 12927, + scf: 12928, + scg: 12929, + sch: 12930, + sci: 12931, + scj: 12932, + sck: 12933, + scl: 12934, + scm: 12935, + scn: 12936, + sco: 12937, + scp: 12938, + scq: 12939, + scr: 12940, + scs: 12941, + sct: 12942, + scu: 12943, + scv: 12944, + scw: 12945, + scx: 12946, + scy: 12947, + sdz: 12948, + sda: 12949, + sdb: 12950, + sdc: 12951, + sdd: 12952, + sde: 12953, + sdf: 12954, + sdg: 12955, + sdh: 12956, + sdi: 12957, + sdj: 12958, + sdk: 12959, + sdl: 12960, + sdm: 12961, + sdn: 12962, + sdo: 12963, + sdp: 12964, + sdq: 12965, + sdr: 12966, + sds: 12967, + sdt: 12968, + sdu: 12969, + sdv: 12970, + sdw: 12971, + sdx: 12972, + sdy: 12973, + sez: 12974, + sea: 12975, + seb: 12976, + sec: 12977, + sed: 12978, + see: 12979, + sef: 12980, + seg: 12981, + seh: 12982, + sei: 12983, + sej: 12984, + sek: 12985, + sel: 12986, + sem: 12987, + sen: 12988, + seo: 12989, + sep: 12990, + seq: 12991, + ser: 12992, + ses: 12993, + set: 12994, + seu: 12995, + sev: 12996, + sew: 12997, + sex: 12998, + sey: 12999, + sfz: 13000, + sfa: 13001, + sfb: 13002, + sfc: 13003, + sfd: 13004, + sfe: 13005, + sff: 13006, + sfg: 13007, + sfh: 13008, + sfi: 13009, + sfj: 13010, + sfk: 13011, + sfl: 13012, + sfm: 13013, + sfn: 13014, + sfo: 13015, + sfp: 13016, + sfq: 13017, + sfr: 13018, + sfs: 13019, + sft: 13020, + sfu: 13021, + sfv: 13022, + sfw: 13023, + sfx: 13024, + sfy: 13025, + sgz: 13026, + sga: 13027, + sgb: 13028, + sgc: 13029, + sgd: 13030, + sge: 13031, + sgf: 13032, + sgg: 13033, + sgh: 13034, + sgi: 13035, + sgj: 13036, + sgk: 13037, + sgl: 13038, + sgm: 13039, + sgn: 13040, + sgo: 13041, + sgp: 13042, + sgq: 13043, + sgr: 13044, + sgs: 13045, + sgt: 13046, + sgu: 13047, + sgv: 13048, + sgw: 13049, + sgx: 13050, + sgy: 13051, + shz: 13052, + sha: 13053, + shb: 13054, + shc: 13055, + shd: 13056, + she: 13057, + shf: 13058, + shg: 13059, + shh: 13060, + shi: 13061, + shj: 13062, + shk: 13063, + shl: 13064, + shm: 13065, + shn: 13066, + sho: 13067, + shp: 13068, + shq: 13069, + shr: 13070, + shs: 13071, + sht: 13072, + shu: 13073, + shv: 13074, + shw: 13075, + shx: 13076, + shy: 13077, + siz: 13078, + sia: 13079, + sib: 13080, + sic: 13081, + sid: 13082, + sie: 13083, + sif: 13084, + sig: 13085, + sih: 13086, + sii: 13087, + sij: 13088, + sik: 13089, + sil: 13090, + sim: 13091, + sin: 13092, + sio: 13093, + sip: 13094, + siq: 13095, + sir: 13096, + sis: 13097, + sit: 13098, + siu: 13099, + siv: 13100, + siw: 13101, + six: 13102, + siy: 13103, + sjz: 13104, + sja: 13105, + sjb: 13106, + sjc: 13107, + sjd: 13108, + sje: 13109, + sjf: 13110, + sjg: 13111, + sjh: 13112, + sji: 13113, + sjj: 13114, + sjk: 13115, + sjl: 13116, + sjm: 13117, + sjn: 13118, + sjo: 13119, + sjp: 13120, + sjq: 13121, + sjr: 13122, + sjs: 13123, + sjt: 13124, + sju: 13125, + sjv: 13126, + sjw: 13127, + sjx: 13128, + sjy: 13129, + skz: 13130, + ska: 13131, + skb: 13132, + skc: 13133, + skd: 13134, + ske: 13135, + skf: 13136, + skg: 13137, + skh: 13138, + ski: 13139, + skj: 13140, + skk: 13141, + skl: 13142, + skm: 13143, + skn: 13144, + sko: 13145, + skp: 13146, + skq: 13147, + skr: 13148, + sks: 13149, + skt: 13150, + sku: 13151, + skv: 13152, + skw: 13153, + skx: 13154, + sky: 13155, + slz: 13156, + sla: 13157, + slb: 13158, + slc: 13159, + sld: 13160, + sle: 13161, + slf: 13162, + slg: 13163, + slh: 13164, + sli: 13165, + slj: 13166, + slk: 13167, + sll: 13168, + slm: 13169, + sln: 13170, + slo: 13171, + slp: 13172, + slq: 13173, + slr: 13174, + sls: 13175, + slt: 13176, + slu: 13177, + slv: 13178, + slw: 13179, + slx: 13180, + sly: 13181, + smz: 13182, + sma: 13183, + smb: 13184, + smc: 13185, + smd: 13186, + sme: 13187, + smf: 13188, + smg: 13189, + smh: 13190, + smi: 13191, + smj: 13192, + smk: 13193, + sml: 13194, + smm: 13195, + smn: 13196, + smo: 13197, + smp: 13198, + smq: 13199, + smr: 13200, + sms: 13201, + smt: 13202, + smu: 13203, + smv: 13204, + smw: 13205, + smx: 13206, + smy: 13207, + snz: 13208, + sna: 13209, + snb: 13210, + snc: 13211, + snd: 13212, + sne: 13213, + snf: 13214, + sng: 13215, + snh: 13216, + sni: 13217, + snj: 13218, + snk: 13219, + snl: 13220, + snm: 13221, + snn: 13222, + sno: 13223, + snp: 13224, + snq: 13225, + snr: 13226, + sns: 13227, + snt: 13228, + snu: 13229, + snv: 13230, + snw: 13231, + snx: 13232, + sny: 13233, + soz: 13234, + soa: 13235, + sob: 13236, + soc: 13237, + sod: 13238, + soe: 13239, + sof: 13240, + sog: 13241, + soh: 13242, + soi: 13243, + soj: 13244, + sok: 13245, + sol: 13246, + som: 13247, + son: 13248, + soo: 13249, + sop: 13250, + soq: 13251, + sor: 13252, + sos: 13253, + sot: 13254, + sou: 13255, + sov: 13256, + sow: 13257, + sox: 13258, + soy: 13259, + spz: 13260, + spa: 13261, + spb: 13262, + spc: 13263, + spd: 13264, + spe: 13265, + spf: 13266, + spg: 13267, + sph: 13268, + spi: 13269, + spj: 13270, + spk: 13271, + spl: 13272, + spm: 13273, + spn: 13274, + spo: 13275, + spp: 13276, + spq: 13277, + spr: 13278, + sps: 13279, + spt: 13280, + spu: 13281, + spv: 13282, + spw: 13283, + spx: 13284, + spy: 13285, + sqz: 13286, + sqa: 13287, + sqb: 13288, + sqc: 13289, + sqd: 13290, + sqe: 13291, + sqf: 13292, + sqg: 13293, + sqh: 13294, + sqi: 13295, + sqj: 13296, + sqk: 13297, + sql: 13298, + sqm: 13299, + sqn: 13300, + sqo: 13301, + sqp: 13302, + sqq: 13303, + sqr: 13304, + sqs: 13305, + sqt: 13306, + squ: 13307, + sqv: 13308, + sqw: 13309, + sqx: 13310, + sqy: 13311, + srz: 13312, + sra: 13313, + srb: 13314, + src: 13315, + srd: 13316, + sre: 13317, + srf: 13318, + srg: 13319, + srh: 13320, + sri: 13321, + srj: 13322, + srk: 13323, + srl: 13324, + srm: 13325, + srn: 13326, + sro: 13327, + srp: 13328, + srq: 13329, + srr: 13330, + srs: 13331, + srt: 13332, + sru: 13333, + srv: 13334, + srw: 13335, + srx: 13336, + sry: 13337, + ssz: 13338, + ssa: 13339, + ssb: 13340, + ssc: 13341, + ssd: 13342, + sse: 13343, + ssf: 13344, + ssg: 13345, + ssh: 13346, + ssi: 13347, + ssj: 13348, + ssk: 13349, + ssl: 13350, + ssm: 13351, + ssn: 13352, + sso: 13353, + ssp: 13354, + ssq: 13355, + ssr: 13356, + sss: 13357, + sst: 13358, + ssu: 13359, + ssv: 13360, + ssw: 13361, + ssx: 13362, + ssy: 13363, + stz: 13364, + sta: 13365, + stb: 13366, + stc: 13367, + std: 13368, + ste: 13369, + stf: 13370, + stg: 13371, + sth: 13372, + sti: 13373, + stj: 13374, + stk: 13375, + stl: 13376, + stm: 13377, + stn: 13378, + sto: 13379, + stp: 13380, + stq: 13381, + str: 13382, + sts: 13383, + stt: 13384, + stu: 13385, + stv: 13386, + stw: 13387, + stx: 13388, + sty: 13389, + suz: 13390, + sua: 13391, + sub: 13392, + suc: 13393, + sud: 13394, + sue: 13395, + suf: 13396, + sug: 13397, + suh: 13398, + sui: 13399, + suj: 13400, + suk: 13401, + sul: 13402, + sum: 13403, + sun: 13404, + suo: 13405, + sup: 13406, + suq: 13407, + sur: 13408, + sus: 13409, + sut: 13410, + suu: 13411, + suv: 13412, + suw: 13413, + sux: 13414, + suy: 13415, + svz: 13416, + sva: 13417, + svb: 13418, + svc: 13419, + svd: 13420, + sve: 13421, + svf: 13422, + svg: 13423, + svh: 13424, + svi: 13425, + svj: 13426, + svk: 13427, + svl: 13428, + svm: 13429, + svn: 13430, + svo: 13431, + svp: 13432, + svq: 13433, + svr: 13434, + svs: 13435, + svt: 13436, + svu: 13437, + svv: 13438, + svw: 13439, + svx: 13440, + svy: 13441, + swz: 13442, + swa: 13443, + swb: 13444, + swc: 13445, + swd: 13446, + swe: 13447, + swf: 13448, + swg: 13449, + swh: 13450, + swi: 13451, + swj: 13452, + swk: 13453, + swl: 13454, + swm: 13455, + swn: 13456, + swo: 13457, + swp: 13458, + swq: 13459, + swr: 13460, + sws: 13461, + swt: 13462, + swu: 13463, + swv: 13464, + sww: 13465, + swx: 13466, + swy: 13467, + sxz: 13468, + sxa: 13469, + sxb: 13470, + sxc: 13471, + sxd: 13472, + sxe: 13473, + sxf: 13474, + sxg: 13475, + sxh: 13476, + sxi: 13477, + sxj: 13478, + sxk: 13479, + sxl: 13480, + sxm: 13481, + sxn: 13482, + sxo: 13483, + sxp: 13484, + sxq: 13485, + sxr: 13486, + sxs: 13487, + sxt: 13488, + sxu: 13489, + sxv: 13490, + sxw: 13491, + sxx: 13492, + sxy: 13493, + syz: 13494, + sya: 13495, + syb: 13496, + syc: 13497, + syd: 13498, + sye: 13499, + syf: 13500, + syg: 13501, + syh: 13502, + syi: 13503, + syj: 13504, + syk: 13505, + syl: 13506, + sym: 13507, + syn: 13508, + syo: 13509, + syp: 13510, + syq: 13511, + syr: 13512, + sys: 13513, + syt: 13514, + syu: 13515, + syv: 13516, + syw: 13517, + syx: 13518, + syy: 13519, + tzz: 13520, + tza: 13521, + tzb: 13522, + tzc: 13523, + tzd: 13524, + tze: 13525, + tzf: 13526, + tzg: 13527, + tzh: 13528, + tzi: 13529, + tzj: 13530, + tzk: 13531, + tzl: 13532, + tzm: 13533, + tzn: 13534, + tzo: 13535, + tzp: 13536, + tzq: 13537, + tzr: 13538, + tzs: 13539, + tzt: 13540, + tzu: 13541, + tzv: 13542, + tzw: 13543, + tzx: 13544, + tzy: 13545, + taz: 13546, + taa: 13547, + tab: 13548, + tac: 13549, + tad: 13550, + tae: 13551, + taf: 13552, + tag: 13553, + tah: 13554, + tai: 13555, + taj: 13556, + tak: 13557, + tal: 13558, + tam: 13559, + tan: 13560, + tao: 13561, + tap: 13562, + taq: 13563, + tar: 13564, + tas: 13565, + tat: 13566, + tau: 13567, + tav: 13568, + taw: 13569, + tax: 13570, + tay: 13571, + tbz: 13572, + tba: 13573, + tbb: 13574, + tbc: 13575, + tbd: 13576, + tbe: 13577, + tbf: 13578, + tbg: 13579, + tbh: 13580, + tbi: 13581, + tbj: 13582, + tbk: 13583, + tbl: 13584, + tbm: 13585, + tbn: 13586, + tbo: 13587, + tbp: 13588, + tbq: 13589, + tbr: 13590, + tbs: 13591, + tbt: 13592, + tbu: 13593, + tbv: 13594, + tbw: 13595, + tbx: 13596, + tby: 13597, + tcz: 13598, + tca: 13599, + tcb: 13600, + tcc: 13601, + tcd: 13602, + tce: 13603, + tcf: 13604, + tcg: 13605, + tch: 13606, + tci: 13607, + tcj: 13608, + tck: 13609, + tcl: 13610, + tcm: 13611, + tcn: 13612, + tco: 13613, + tcp: 13614, + tcq: 13615, + tcr: 13616, + tcs: 13617, + tct: 13618, + tcu: 13619, + tcv: 13620, + tcw: 13621, + tcx: 13622, + tcy: 13623, + tdz: 13624, + tda: 13625, + tdb: 13626, + tdc: 13627, + tdd: 13628, + tde: 13629, + tdf: 13630, + tdg: 13631, + tdh: 13632, + tdi: 13633, + tdj: 13634, + tdk: 13635, + tdl: 13636, + tdm: 13637, + tdn: 13638, + tdo: 13639, + tdp: 13640, + tdq: 13641, + tdr: 13642, + tds: 13643, + tdt: 13644, + tdu: 13645, + tdv: 13646, + tdw: 13647, + tdx: 13648, + tdy: 13649, + tez: 13650, + tea: 13651, + teb: 13652, + tec: 13653, + ted: 13654, + tee: 13655, + tef: 13656, + teg: 13657, + teh: 13658, + tei: 13659, + tej: 13660, + tek: 13661, + tel: 13662, + tem: 13663, + ten: 13664, + teo: 13665, + tep: 13666, + teq: 13667, + ter: 13668, + tes: 13669, + tet: 13670, + teu: 13671, + tev: 13672, + tew: 13673, + tex: 13674, + tey: 13675, + tfz: 13676, + tfa: 13677, + tfb: 13678, + tfc: 13679, + tfd: 13680, + tfe: 13681, + tff: 13682, + tfg: 13683, + tfh: 13684, + tfi: 13685, + tfj: 13686, + tfk: 13687, + tfl: 13688, + tfm: 13689, + tfn: 13690, + tfo: 13691, + tfp: 13692, + tfq: 13693, + tfr: 13694, + tfs: 13695, + tft: 13696, + tfu: 13697, + tfv: 13698, + tfw: 13699, + tfx: 13700, + tfy: 13701, + tgz: 13702, + tga: 13703, + tgb: 13704, + tgc: 13705, + tgd: 13706, + tge: 13707, + tgf: 13708, + tgg: 13709, + tgh: 13710, + tgi: 13711, + tgj: 13712, + tgk: 13713, + tgl: 13714, + tgm: 13715, + tgn: 13716, + tgo: 13717, + tgp: 13718, + tgq: 13719, + tgr: 13720, + tgs: 13721, + tgt: 13722, + tgu: 13723, + tgv: 13724, + tgw: 13725, + tgx: 13726, + tgy: 13727, + thz: 13728, + tha: 13729, + thb: 13730, + thc: 13731, + thd: 13732, + the: 13733, + thf: 13734, + thg: 13735, + thh: 13736, + thi: 13737, + thj: 13738, + thk: 13739, + thl: 13740, + thm: 13741, + thn: 13742, + tho: 13743, + thp: 13744, + thq: 13745, + thr: 13746, + ths: 13747, + tht: 13748, + thu: 13749, + thv: 13750, + thw: 13751, + thx: 13752, + thy: 13753, + tiz: 13754, + tia: 13755, + tib: 13756, + tic: 13757, + tid: 13758, + tie: 13759, + tif: 13760, + tig: 13761, + tih: 13762, + tii: 13763, + tij: 13764, + tik: 13765, + til: 13766, + tim: 13767, + tin: 13768, + tio: 13769, + tip: 13770, + tiq: 13771, + tir: 13772, + tis: 13773, + tit: 13774, + tiu: 13775, + tiv: 13776, + tiw: 13777, + tix: 13778, + tiy: 13779, + tjz: 13780, + tja: 13781, + tjb: 13782, + tjc: 13783, + tjd: 13784, + tje: 13785, + tjf: 13786, + tjg: 13787, + tjh: 13788, + tji: 13789, + tjj: 13790, + tjk: 13791, + tjl: 13792, + tjm: 13793, + tjn: 13794, + tjo: 13795, + tjp: 13796, + tjq: 13797, + tjr: 13798, + tjs: 13799, + tjt: 13800, + tju: 13801, + tjv: 13802, + tjw: 13803, + tjx: 13804, + tjy: 13805, + tkz: 13806, + tka: 13807, + tkb: 13808, + tkc: 13809, + tkd: 13810, + tke: 13811, + tkf: 13812, + tkg: 13813, + tkh: 13814, + tki: 13815, + tkj: 13816, + tkk: 13817, + tkl: 13818, + tkm: 13819, + tkn: 13820, + tko: 13821, + tkp: 13822, + tkq: 13823, + tkr: 13824, + tks: 13825, + tkt: 13826, + tku: 13827, + tkv: 13828, + tkw: 13829, + tkx: 13830, + tky: 13831, + tlz: 13832, + tla: 13833, + tlb: 13834, + tlc: 13835, + tld: 13836, + tle: 13837, + tlf: 13838, + tlg: 13839, + tlh: 13840, + tli: 13841, + tlj: 13842, + tlk: 13843, + tll: 13844, + tlm: 13845, + tln: 13846, + tlo: 13847, + tlp: 13848, + tlq: 13849, + tlr: 13850, + tls: 13851, + tlt: 13852, + tlu: 13853, + tlv: 13854, + tlw: 13855, + tlx: 13856, + tly: 13857, + tmz: 13858, + tma: 13859, + tmb: 13860, + tmc: 13861, + tmd: 13862, + tme: 13863, + tmf: 13864, + tmg: 13865, + tmh: 13866, + tmi: 13867, + tmj: 13868, + tmk: 13869, + tml: 13870, + tmm: 13871, + tmn: 13872, + tmo: 13873, + tmp: 13874, + tmq: 13875, + tmr: 13876, + tms: 13877, + tmt: 13878, + tmu: 13879, + tmv: 13880, + tmw: 13881, + tmx: 13882, + tmy: 13883, + tnz: 13884, + tna: 13885, + tnb: 13886, + tnc: 13887, + tnd: 13888, + tne: 13889, + tnf: 13890, + tng: 13891, + tnh: 13892, + tni: 13893, + tnj: 13894, + tnk: 13895, + tnl: 13896, + tnm: 13897, + tnn: 13898, + tno: 13899, + tnp: 13900, + tnq: 13901, + tnr: 13902, + tns: 13903, + tnt: 13904, + tnu: 13905, + tnv: 13906, + tnw: 13907, + tnx: 13908, + tny: 13909, + toz: 13910, + toa: 13911, + tob: 13912, + toc: 13913, + tod: 13914, + toe: 13915, + tof: 13916, + tog: 13917, + toh: 13918, + toi: 13919, + toj: 13920, + tok: 13921, + tol: 13922, + tom: 13923, + ton: 13924, + too: 13925, + top: 13926, + toq: 13927, + tor: 13928, + tos: 13929, + tot: 13930, + tou: 13931, + tov: 13932, + tow: 13933, + tox: 13934, + toy: 13935, + tpz: 13936, + tpa: 13937, + tpb: 13938, + tpc: 13939, + tpd: 13940, + tpe: 13941, + tpf: 13942, + tpg: 13943, + tph: 13944, + tpi: 13945, + tpj: 13946, + tpk: 13947, + tpl: 13948, + tpm: 13949, + tpn: 13950, + tpo: 13951, + tpp: 13952, + tpq: 13953, + tpr: 13954, + tps: 13955, + tpt: 13956, + tpu: 13957, + tpv: 13958, + tpw: 13959, + tpx: 13960, + tpy: 13961, + tqz: 13962, + tqa: 13963, + tqb: 13964, + tqc: 13965, + tqd: 13966, + tqe: 13967, + tqf: 13968, + tqg: 13969, + tqh: 13970, + tqi: 13971, + tqj: 13972, + tqk: 13973, + tql: 13974, + tqm: 13975, + tqn: 13976, + tqo: 13977, + tqp: 13978, + tqq: 13979, + tqr: 13980, + tqs: 13981, + tqt: 13982, + tqu: 13983, + tqv: 13984, + tqw: 13985, + tqx: 13986, + tqy: 13987, + trz: 13988, + tra: 13989, + trb: 13990, + trc: 13991, + trd: 13992, + tre: 13993, + trf: 13994, + trg: 13995, + trh: 13996, + tri: 13997, + trj: 13998, + trk: 13999, + trl: 14000, + trm: 14001, + trn: 14002, + tro: 14003, + trp: 14004, + trq: 14005, + trr: 14006, + trs: 14007, + trt: 14008, + tru: 14009, + trv: 14010, + trw: 14011, + trx: 14012, + try: 14013, + tsz: 14014, + tsa: 14015, + tsb: 14016, + tsc: 14017, + tsd: 14018, + tse: 14019, + tsf: 14020, + tsg: 14021, + tsh: 14022, + tsi: 14023, + tsj: 14024, + tsk: 14025, + tsl: 14026, + tsm: 14027, + tsn: 14028, + tso: 14029, + tsp: 14030, + tsq: 14031, + tsr: 14032, + tss: 14033, + tst: 14034, + tsu: 14035, + tsv: 14036, + tsw: 14037, + tsx: 14038, + tsy: 14039, + ttz: 14040, + tta: 14041, + ttb: 14042, + ttc: 14043, + ttd: 14044, + tte: 14045, + ttf: 14046, + ttg: 14047, + tth: 14048, + tti: 14049, + ttj: 14050, + ttk: 14051, + ttl: 14052, + ttm: 14053, + ttn: 14054, + tto: 14055, + ttp: 14056, + ttq: 14057, + ttr: 14058, + tts: 14059, + ttt: 14060, + ttu: 14061, + ttv: 14062, + ttw: 14063, + ttx: 14064, + tty: 14065, + tuz: 14066, + tua: 14067, + tub: 14068, + tuc: 14069, + tud: 14070, + tue: 14071, + tuf: 14072, + tug: 14073, + tuh: 14074, + tui: 14075, + tuj: 14076, + tuk: 14077, + tul: 14078, + tum: 14079, + tun: 14080, + tuo: 14081, + tup: 14082, + tuq: 14083, + tur: 14084, + tus: 14085, + tut: 14086, + tuu: 14087, + tuv: 14088, + tuw: 14089, + tux: 14090, + tuy: 14091, + tvz: 14092, + tva: 14093, + tvb: 14094, + tvc: 14095, + tvd: 14096, + tve: 14097, + tvf: 14098, + tvg: 14099, + tvh: 14100, + tvi: 14101, + tvj: 14102, + tvk: 14103, + tvl: 14104, + tvm: 14105, + tvn: 14106, + tvo: 14107, + tvp: 14108, + tvq: 14109, + tvr: 14110, + tvs: 14111, + tvt: 14112, + tvu: 14113, + tvv: 14114, + tvw: 14115, + tvx: 14116, + tvy: 14117, + twz: 14118, + twa: 14119, + twb: 14120, + twc: 14121, + twd: 14122, + twe: 14123, + twf: 14124, + twg: 14125, + twh: 14126, + twi: 14127, + twj: 14128, + twk: 14129, + twl: 14130, + twm: 14131, + twn: 14132, + two: 14133, + twp: 14134, + twq: 14135, + twr: 14136, + tws: 14137, + twt: 14138, + twu: 14139, + twv: 14140, + tww: 14141, + twx: 14142, + twy: 14143, + txz: 14144, + txa: 14145, + txb: 14146, + txc: 14147, + txd: 14148, + txe: 14149, + txf: 14150, + txg: 14151, + txh: 14152, + txi: 14153, + txj: 14154, + txk: 14155, + txl: 14156, + txm: 14157, + txn: 14158, + txo: 14159, + txp: 14160, + txq: 14161, + txr: 14162, + txs: 14163, + txt: 14164, + txu: 14165, + txv: 14166, + txw: 14167, + txx: 14168, + txy: 14169, + tyz: 14170, + tya: 14171, + tyb: 14172, + tyc: 14173, + tyd: 14174, + tye: 14175, + tyf: 14176, + tyg: 14177, + tyh: 14178, + tyi: 14179, + tyj: 14180, + tyk: 14181, + tyl: 14182, + tym: 14183, + tyn: 14184, + tyo: 14185, + typ: 14186, + tyq: 14187, + tyr: 14188, + tys: 14189, + tyt: 14190, + tyu: 14191, + tyv: 14192, + tyw: 14193, + tyx: 14194, + tyy: 14195, + uzz: 14196, + uza: 14197, + uzb: 14198, + uzc: 14199, + uzd: 14200, + uze: 14201, + uzf: 14202, + uzg: 14203, + uzh: 14204, + uzi: 14205, + uzj: 14206, + uzk: 14207, + uzl: 14208, + uzm: 14209, + uzn: 14210, + uzo: 14211, + uzp: 14212, + uzq: 14213, + uzr: 14214, + uzs: 14215, + uzt: 14216, + uzu: 14217, + uzv: 14218, + uzw: 14219, + uzx: 14220, + uzy: 14221, + uaz: 14222, + uaa: 14223, + uab: 14224, + uac: 14225, + uad: 14226, + uae: 14227, + uaf: 14228, + uag: 14229, + uah: 14230, + uai: 14231, + uaj: 14232, + uak: 14233, + ual: 14234, + uam: 14235, + uan: 14236, + uao: 14237, + uap: 14238, + uaq: 14239, + uar: 14240, + uas: 14241, + uat: 14242, + uau: 14243, + uav: 14244, + uaw: 14245, + uax: 14246, + uay: 14247, + ubz: 14248, + uba: 14249, + ubb: 14250, + ubc: 14251, + ubd: 14252, + ube: 14253, + ubf: 14254, + ubg: 14255, + ubh: 14256, + ubi: 14257, + ubj: 14258, + ubk: 14259, + ubl: 14260, + ubm: 14261, + ubn: 14262, + ubo: 14263, + ubp: 14264, + ubq: 14265, + ubr: 14266, + ubs: 14267, + ubt: 14268, + ubu: 14269, + ubv: 14270, + ubw: 14271, + ubx: 14272, + uby: 14273, + ucz: 14274, + uca: 14275, + ucb: 14276, + ucc: 14277, + ucd: 14278, + uce: 14279, + ucf: 14280, + ucg: 14281, + uch: 14282, + uci: 14283, + ucj: 14284, + uck: 14285, + ucl: 14286, + ucm: 14287, + ucn: 14288, + uco: 14289, + ucp: 14290, + ucq: 14291, + ucr: 14292, + ucs: 14293, + uct: 14294, + ucu: 14295, + ucv: 14296, + ucw: 14297, + ucx: 14298, + ucy: 14299, + udz: 14300, + uda: 14301, + udb: 14302, + udc: 14303, + udd: 14304, + ude: 14305, + udf: 14306, + udg: 14307, + udh: 14308, + udi: 14309, + udj: 14310, + udk: 14311, + udl: 14312, + udm: 14313, + udn: 14314, + udo: 14315, + udp: 14316, + udq: 14317, + udr: 14318, + uds: 14319, + udt: 14320, + udu: 14321, + udv: 14322, + udw: 14323, + udx: 14324, + udy: 14325, + uez: 14326, + uea: 14327, + ueb: 14328, + uec: 14329, + ued: 14330, + uee: 14331, + uef: 14332, + ueg: 14333, + ueh: 14334, + uei: 14335, + uej: 14336, + uek: 14337, + uel: 14338, + uem: 14339, + uen: 14340, + ueo: 14341, + uep: 14342, + ueq: 14343, + uer: 14344, + ues: 14345, + uet: 14346, + ueu: 14347, + uev: 14348, + uew: 14349, + uex: 14350, + uey: 14351, + ufz: 14352, + ufa: 14353, + ufb: 14354, + ufc: 14355, + ufd: 14356, + ufe: 14357, + uff: 14358, + ufg: 14359, + ufh: 14360, + ufi: 14361, + ufj: 14362, + ufk: 14363, + ufl: 14364, + ufm: 14365, + ufn: 14366, + ufo: 14367, + ufp: 14368, + ufq: 14369, + ufr: 14370, + ufs: 14371, + uft: 14372, + ufu: 14373, + ufv: 14374, + ufw: 14375, + ufx: 14376, + ufy: 14377, + ugz: 14378, + uga: 14379, + ugb: 14380, + ugc: 14381, + ugd: 14382, + uge: 14383, + ugf: 14384, + ugg: 14385, + ugh: 14386, + ugi: 14387, + ugj: 14388, + ugk: 14389, + ugl: 14390, + ugm: 14391, + ugn: 14392, + ugo: 14393, + ugp: 14394, + ugq: 14395, + ugr: 14396, + ugs: 14397, + ugt: 14398, + ugu: 14399, + ugv: 14400, + ugw: 14401, + ugx: 14402, + ugy: 14403, + uhz: 14404, + uha: 14405, + uhb: 14406, + uhc: 14407, + uhd: 14408, + uhe: 14409, + uhf: 14410, + uhg: 14411, + uhh: 14412, + uhi: 14413, + uhj: 14414, + uhk: 14415, + uhl: 14416, + uhm: 14417, + uhn: 14418, + uho: 14419, + uhp: 14420, + uhq: 14421, + uhr: 14422, + uhs: 14423, + uht: 14424, + uhu: 14425, + uhv: 14426, + uhw: 14427, + uhx: 14428, + uhy: 14429, + uiz: 14430, + uia: 14431, + uib: 14432, + uic: 14433, + uid: 14434, + uie: 14435, + uif: 14436, + uig: 14437, + uih: 14438, + uii: 14439, + uij: 14440, + uik: 14441, + uil: 14442, + uim: 14443, + uin: 14444, + uio: 14445, + uip: 14446, + uiq: 14447, + uir: 14448, + uis: 14449, + uit: 14450, + uiu: 14451, + uiv: 14452, + uiw: 14453, + uix: 14454, + uiy: 14455, + ujz: 14456, + uja: 14457, + ujb: 14458, + ujc: 14459, + ujd: 14460, + uje: 14461, + ujf: 14462, + ujg: 14463, + ujh: 14464, + uji: 14465, + ujj: 14466, + ujk: 14467, + ujl: 14468, + ujm: 14469, + ujn: 14470, + ujo: 14471, + ujp: 14472, + ujq: 14473, + ujr: 14474, + ujs: 14475, + ujt: 14476, + uju: 14477, + ujv: 14478, + ujw: 14479, + ujx: 14480, + ujy: 14481, + ukz: 14482, + uka: 14483, + ukb: 14484, + ukc: 14485, + ukd: 14486, + uke: 14487, + ukf: 14488, + ukg: 14489, + ukh: 14490, + uki: 14491, + ukj: 14492, + ukk: 14493, + ukl: 14494, + ukm: 14495, + ukn: 14496, + uko: 14497, + ukp: 14498, + ukq: 14499, + ukr: 14500, + uks: 14501, + ukt: 14502, + uku: 14503, + ukv: 14504, + ukw: 14505, + ukx: 14506, + uky: 14507, + ulz: 14508, + ula: 14509, + ulb: 14510, + ulc: 14511, + uld: 14512, + ule: 14513, + ulf: 14514, + ulg: 14515, + ulh: 14516, + uli: 14517, + ulj: 14518, + ulk: 14519, + ull: 14520, + ulm: 14521, + uln: 14522, + ulo: 14523, + ulp: 14524, + ulq: 14525, + ulr: 14526, + uls: 14527, + ult: 14528, + ulu: 14529, + ulv: 14530, + ulw: 14531, + ulx: 14532, + uly: 14533, + umz: 14534, + uma: 14535, + umb: 14536, + umc: 14537, + umd: 14538, + ume: 14539, + umf: 14540, + umg: 14541, + umh: 14542, + umi: 14543, + umj: 14544, + umk: 14545, + uml: 14546, + umm: 14547, + umn: 14548, + umo: 14549, + ump: 14550, + umq: 14551, + umr: 14552, + ums: 14553, + umt: 14554, + umu: 14555, + umv: 14556, + umw: 14557, + umx: 14558, + umy: 14559, + unz: 14560, + una: 14561, + unb: 14562, + unc: 14563, + und: 14564, + une: 14565, + unf: 14566, + ung: 14567, + unh: 14568, + uni: 14569, + unj: 14570, + unk: 14571, + unl: 14572, + unm: 14573, + unn: 14574, + uno: 14575, + unp: 14576, + unq: 14577, + unr: 14578, + uns: 14579, + unt: 14580, + unu: 14581, + unv: 14582, + unw: 14583, + unx: 14584, + uny: 14585, + uoz: 14586, + uoa: 14587, + uob: 14588, + uoc: 14589, + uod: 14590, + uoe: 14591, + uof: 14592, + uog: 14593, + uoh: 14594, + uoi: 14595, + uoj: 14596, + uok: 14597, + uol: 14598, + uom: 14599, + uon: 14600, + uoo: 14601, + uop: 14602, + uoq: 14603, + uor: 14604, + uos: 14605, + uot: 14606, + uou: 14607, + uov: 14608, + uow: 14609, + uox: 14610, + uoy: 14611, + upz: 14612, + upa: 14613, + upb: 14614, + upc: 14615, + upd: 14616, + upe: 14617, + upf: 14618, + upg: 14619, + uph: 14620, + upi: 14621, + upj: 14622, + upk: 14623, + upl: 14624, + upm: 14625, + upn: 14626, + upo: 14627, + upp: 14628, + upq: 14629, + upr: 14630, + ups: 14631, + upt: 14632, + upu: 14633, + upv: 14634, + upw: 14635, + upx: 14636, + upy: 14637, + uqz: 14638, + uqa: 14639, + uqb: 14640, + uqc: 14641, + uqd: 14642, + uqe: 14643, + uqf: 14644, + uqg: 14645, + uqh: 14646, + uqi: 14647, + uqj: 14648, + uqk: 14649, + uql: 14650, + uqm: 14651, + uqn: 14652, + uqo: 14653, + uqp: 14654, + uqq: 14655, + uqr: 14656, + uqs: 14657, + uqt: 14658, + uqu: 14659, + uqv: 14660, + uqw: 14661, + uqx: 14662, + uqy: 14663, + urz: 14664, + ura: 14665, + urb: 14666, + urc: 14667, + urd: 14668, + ure: 14669, + urf: 14670, + urg: 14671, + urh: 14672, + uri: 14673, + urj: 14674, + urk: 14675, + url: 14676, + urm: 14677, + urn: 14678, + uro: 14679, + urp: 14680, + urq: 14681, + urr: 14682, + urs: 14683, + urt: 14684, + uru: 14685, + urv: 14686, + urw: 14687, + urx: 14688, + ury: 14689, + usz: 14690, + usa: 14691, + usb: 14692, + usc: 14693, + usd: 14694, + use: 14695, + usf: 14696, + usg: 14697, + ush: 14698, + usi: 14699, + usj: 14700, + usk: 14701, + usl: 14702, + usm: 14703, + usn: 14704, + uso: 14705, + usp: 14706, + usq: 14707, + usr: 14708, + uss: 14709, + ust: 14710, + usu: 14711, + usv: 14712, + usw: 14713, + usx: 14714, + usy: 14715, + utz: 14716, + uta: 14717, + utb: 14718, + utc: 14719, + utd: 14720, + ute: 14721, + utf: 14722, + utg: 14723, + uth: 14724, + uti: 14725, + utj: 14726, + utk: 14727, + utl: 14728, + utm: 14729, + utn: 14730, + uto: 14731, + utp: 14732, + utq: 14733, + utr: 14734, + uts: 14735, + utt: 14736, + utu: 14737, + utv: 14738, + utw: 14739, + utx: 14740, + uty: 14741, + uuz: 14742, + uua: 14743, + uub: 14744, + uuc: 14745, + uud: 14746, + uue: 14747, + uuf: 14748, + uug: 14749, + uuh: 14750, + uui: 14751, + uuj: 14752, + uuk: 14753, + uul: 14754, + uum: 14755, + uun: 14756, + uuo: 14757, + uup: 14758, + uuq: 14759, + uur: 14760, + uus: 14761, + uut: 14762, + uuu: 14763, + uuv: 14764, + uuw: 14765, + uux: 14766, + uuy: 14767, + uvz: 14768, + uva: 14769, + uvb: 14770, + uvc: 14771, + uvd: 14772, + uve: 14773, + uvf: 14774, + uvg: 14775, + uvh: 14776, + uvi: 14777, + uvj: 14778, + uvk: 14779, + uvl: 14780, + uvm: 14781, + uvn: 14782, + uvo: 14783, + uvp: 14784, + uvq: 14785, + uvr: 14786, + uvs: 14787, + uvt: 14788, + uvu: 14789, + uvv: 14790, + uvw: 14791, + uvx: 14792, + uvy: 14793, + uwz: 14794, + uwa: 14795, + uwb: 14796, + uwc: 14797, + uwd: 14798, + uwe: 14799, + uwf: 14800, + uwg: 14801, + uwh: 14802, + uwi: 14803, + uwj: 14804, + uwk: 14805, + uwl: 14806, + uwm: 14807, + uwn: 14808, + uwo: 14809, + uwp: 14810, + uwq: 14811, + uwr: 14812, + uws: 14813, + uwt: 14814, + uwu: 14815, + uwv: 14816, + uww: 14817, + uwx: 14818, + uwy: 14819, + uxz: 14820, + uxa: 14821, + uxb: 14822, + uxc: 14823, + uxd: 14824, + uxe: 14825, + uxf: 14826, + uxg: 14827, + uxh: 14828, + uxi: 14829, + uxj: 14830, + uxk: 14831, + uxl: 14832, + uxm: 14833, + uxn: 14834, + uxo: 14835, + uxp: 14836, + uxq: 14837, + uxr: 14838, + uxs: 14839, + uxt: 14840, + uxu: 14841, + uxv: 14842, + uxw: 14843, + uxx: 14844, + uxy: 14845, + uyz: 14846, + uya: 14847, + uyb: 14848, + uyc: 14849, + uyd: 14850, + uye: 14851, + uyf: 14852, + uyg: 14853, + uyh: 14854, + uyi: 14855, + uyj: 14856, + uyk: 14857, + uyl: 14858, + uym: 14859, + uyn: 14860, + uyo: 14861, + uyp: 14862, + uyq: 14863, + uyr: 14864, + uys: 14865, + uyt: 14866, + uyu: 14867, + uyv: 14868, + uyw: 14869, + uyx: 14870, + uyy: 14871, + vzz: 14872, + vza: 14873, + vzb: 14874, + vzc: 14875, + vzd: 14876, + vze: 14877, + vzf: 14878, + vzg: 14879, + vzh: 14880, + vzi: 14881, + vzj: 14882, + vzk: 14883, + vzl: 14884, + vzm: 14885, + vzn: 14886, + vzo: 14887, + vzp: 14888, + vzq: 14889, + vzr: 14890, + vzs: 14891, + vzt: 14892, + vzu: 14893, + vzv: 14894, + vzw: 14895, + vzx: 14896, + vzy: 14897, + vaz: 14898, + vaa: 14899, + vab: 14900, + vac: 14901, + vad: 14902, + vae: 14903, + vaf: 14904, + vag: 14905, + vah: 14906, + vai: 14907, + vaj: 14908, + vak: 14909, + val: 14910, + vam: 14911, + van: 14912, + vao: 14913, + vap: 14914, + vaq: 14915, + var: 14916, + vas: 14917, + vat: 14918, + vau: 14919, + vav: 14920, + vaw: 14921, + vax: 14922, + vay: 14923, + vbz: 14924, + vba: 14925, + vbb: 14926, + vbc: 14927, + vbd: 14928, + vbe: 14929, + vbf: 14930, + vbg: 14931, + vbh: 14932, + vbi: 14933, + vbj: 14934, + vbk: 14935, + vbl: 14936, + vbm: 14937, + vbn: 14938, + vbo: 14939, + vbp: 14940, + vbq: 14941, + vbr: 14942, + vbs: 14943, + vbt: 14944, + vbu: 14945, + vbv: 14946, + vbw: 14947, + vbx: 14948, + vby: 14949, + vcz: 14950, + vca: 14951, + vcb: 14952, + vcc: 14953, + vcd: 14954, + vce: 14955, + vcf: 14956, + vcg: 14957, + vch: 14958, + vci: 14959, + vcj: 14960, + vck: 14961, + vcl: 14962, + vcm: 14963, + vcn: 14964, + vco: 14965, + vcp: 14966, + vcq: 14967, + vcr: 14968, + vcs: 14969, + vct: 14970, + vcu: 14971, + vcv: 14972, + vcw: 14973, + vcx: 14974, + vcy: 14975, + vdz: 14976, + vda: 14977, + vdb: 14978, + vdc: 14979, + vdd: 14980, + vde: 14981, + vdf: 14982, + vdg: 14983, + vdh: 14984, + vdi: 14985, + vdj: 14986, + vdk: 14987, + vdl: 14988, + vdm: 14989, + vdn: 14990, + vdo: 14991, + vdp: 14992, + vdq: 14993, + vdr: 14994, + vds: 14995, + vdt: 14996, + vdu: 14997, + vdv: 14998, + vdw: 14999, + vdx: 15000, + vdy: 15001, + vez: 15002, + vea: 15003, + veb: 15004, + vec: 15005, + ved: 15006, + vee: 15007, + vef: 15008, + veg: 15009, + veh: 15010, + vei: 15011, + vej: 15012, + vek: 15013, + vel: 15014, + vem: 15015, + ven: 15016, + veo: 15017, + vep: 15018, + veq: 15019, + ver: 15020, + ves: 15021, + vet: 15022, + veu: 15023, + vev: 15024, + vew: 15025, + vex: 15026, + vey: 15027, + vfz: 15028, + vfa: 15029, + vfb: 15030, + vfc: 15031, + vfd: 15032, + vfe: 15033, + vff: 15034, + vfg: 15035, + vfh: 15036, + vfi: 15037, + vfj: 15038, + vfk: 15039, + vfl: 15040, + vfm: 15041, + vfn: 15042, + vfo: 15043, + vfp: 15044, + vfq: 15045, + vfr: 15046, + vfs: 15047, + vft: 15048, + vfu: 15049, + vfv: 15050, + vfw: 15051, + vfx: 15052, + vfy: 15053, + vgz: 15054, + vga: 15055, + vgb: 15056, + vgc: 15057, + vgd: 15058, + vge: 15059, + vgf: 15060, + vgg: 15061, + vgh: 15062, + vgi: 15063, + vgj: 15064, + vgk: 15065, + vgl: 15066, + vgm: 15067, + vgn: 15068, + vgo: 15069, + vgp: 15070, + vgq: 15071, + vgr: 15072, + vgs: 15073, + vgt: 15074, + vgu: 15075, + vgv: 15076, + vgw: 15077, + vgx: 15078, + vgy: 15079, + vhz: 15080, + vha: 15081, + vhb: 15082, + vhc: 15083, + vhd: 15084, + vhe: 15085, + vhf: 15086, + vhg: 15087, + vhh: 15088, + vhi: 15089, + vhj: 15090, + vhk: 15091, + vhl: 15092, + vhm: 15093, + vhn: 15094, + vho: 15095, + vhp: 15096, + vhq: 15097, + vhr: 15098, + vhs: 15099, + vht: 15100, + vhu: 15101, + vhv: 15102, + vhw: 15103, + vhx: 15104, + vhy: 15105, + viz: 15106, + via: 15107, + vib: 15108, + vic: 15109, + vid: 15110, + vie: 15111, + vif: 15112, + vig: 15113, + vih: 15114, + vii: 15115, + vij: 15116, + vik: 15117, + vil: 15118, + vim: 15119, + vin: 15120, + vio: 15121, + vip: 15122, + viq: 15123, + vir: 15124, + vis: 15125, + vit: 15126, + viu: 15127, + viv: 15128, + viw: 15129, + vix: 15130, + viy: 15131, + vjz: 15132, + vja: 15133, + vjb: 15134, + vjc: 15135, + vjd: 15136, + vje: 15137, + vjf: 15138, + vjg: 15139, + vjh: 15140, + vji: 15141, + vjj: 15142, + vjk: 15143, + vjl: 15144, + vjm: 15145, + vjn: 15146, + vjo: 15147, + vjp: 15148, + vjq: 15149, + vjr: 15150, + vjs: 15151, + vjt: 15152, + vju: 15153, + vjv: 15154, + vjw: 15155, + vjx: 15156, + vjy: 15157, + vkz: 15158, + vka: 15159, + vkb: 15160, + vkc: 15161, + vkd: 15162, + vke: 15163, + vkf: 15164, + vkg: 15165, + vkh: 15166, + vki: 15167, + vkj: 15168, + vkk: 15169, + vkl: 15170, + vkm: 15171, + vkn: 15172, + vko: 15173, + vkp: 15174, + vkq: 15175, + vkr: 15176, + vks: 15177, + vkt: 15178, + vku: 15179, + vkv: 15180, + vkw: 15181, + vkx: 15182, + vky: 15183, + vlz: 15184, + vla: 15185, + vlb: 15186, + vlc: 15187, + vld: 15188, + vle: 15189, + vlf: 15190, + vlg: 15191, + vlh: 15192, + vli: 15193, + vlj: 15194, + vlk: 15195, + vll: 15196, + vlm: 15197, + vln: 15198, + vlo: 15199, + vlp: 15200, + vlq: 15201, + vlr: 15202, + vls: 15203, + vlt: 15204, + vlu: 15205, + vlv: 15206, + vlw: 15207, + vlx: 15208, + vly: 15209, + vmz: 15210, + vma: 15211, + vmb: 15212, + vmc: 15213, + vmd: 15214, + vme: 15215, + vmf: 15216, + vmg: 15217, + vmh: 15218, + vmi: 15219, + vmj: 15220, + vmk: 15221, + vml: 15222, + vmm: 15223, + vmn: 15224, + vmo: 15225, + vmp: 15226, + vmq: 15227, + vmr: 15228, + vms: 15229, + vmt: 15230, + vmu: 15231, + vmv: 15232, + vmw: 15233, + vmx: 15234, + vmy: 15235, + vnz: 15236, + vna: 15237, + vnb: 15238, + vnc: 15239, + vnd: 15240, + vne: 15241, + vnf: 15242, + vng: 15243, + vnh: 15244, + vni: 15245, + vnj: 15246, + vnk: 15247, + vnl: 15248, + vnm: 15249, + vnn: 15250, + vno: 15251, + vnp: 15252, + vnq: 15253, + vnr: 15254, + vns: 15255, + vnt: 15256, + vnu: 15257, + vnv: 15258, + vnw: 15259, + vnx: 15260, + vny: 15261, + voz: 15262, + voa: 15263, + vob: 15264, + voc: 15265, + vod: 15266, + voe: 15267, + vof: 15268, + vog: 15269, + voh: 15270, + voi: 15271, + voj: 15272, + vok: 15273, + vol: 15274, + vom: 15275, + von: 15276, + voo: 15277, + vop: 15278, + voq: 15279, + vor: 15280, + vos: 15281, + vot: 15282, + vou: 15283, + vov: 15284, + vow: 15285, + vox: 15286, + voy: 15287, + vpz: 15288, + vpa: 15289, + vpb: 15290, + vpc: 15291, + vpd: 15292, + vpe: 15293, + vpf: 15294, + vpg: 15295, + vph: 15296, + vpi: 15297, + vpj: 15298, + vpk: 15299, + vpl: 15300, + vpm: 15301, + vpn: 15302, + vpo: 15303, + vpp: 15304, + vpq: 15305, + vpr: 15306, + vps: 15307, + vpt: 15308, + vpu: 15309, + vpv: 15310, + vpw: 15311, + vpx: 15312, + vpy: 15313, + vqz: 15314, + vqa: 15315, + vqb: 15316, + vqc: 15317, + vqd: 15318, + vqe: 15319, + vqf: 15320, + vqg: 15321, + vqh: 15322, + vqi: 15323, + vqj: 15324, + vqk: 15325, + vql: 15326, + vqm: 15327, + vqn: 15328, + vqo: 15329, + vqp: 15330, + vqq: 15331, + vqr: 15332, + vqs: 15333, + vqt: 15334, + vqu: 15335, + vqv: 15336, + vqw: 15337, + vqx: 15338, + vqy: 15339, + vrz: 15340, + vra: 15341, + vrb: 15342, + vrc: 15343, + vrd: 15344, + vre: 15345, + vrf: 15346, + vrg: 15347, + vrh: 15348, + vri: 15349, + vrj: 15350, + vrk: 15351, + vrl: 15352, + vrm: 15353, + vrn: 15354, + vro: 15355, + vrp: 15356, + vrq: 15357, + vrr: 15358, + vrs: 15359, + vrt: 15360, + vru: 15361, + vrv: 15362, + vrw: 15363, + vrx: 15364, + vry: 15365, + vsz: 15366, + vsa: 15367, + vsb: 15368, + vsc: 15369, + vsd: 15370, + vse: 15371, + vsf: 15372, + vsg: 15373, + vsh: 15374, + vsi: 15375, + vsj: 15376, + vsk: 15377, + vsl: 15378, + vsm: 15379, + vsn: 15380, + vso: 15381, + vsp: 15382, + vsq: 15383, + vsr: 15384, + vss: 15385, + vst: 15386, + vsu: 15387, + vsv: 15388, + vsw: 15389, + vsx: 15390, + vsy: 15391, + vtz: 15392, + vta: 15393, + vtb: 15394, + vtc: 15395, + vtd: 15396, + vte: 15397, + vtf: 15398, + vtg: 15399, + vth: 15400, + vti: 15401, + vtj: 15402, + vtk: 15403, + vtl: 15404, + vtm: 15405, + vtn: 15406, + vto: 15407, + vtp: 15408, + vtq: 15409, + vtr: 15410, + vts: 15411, + vtt: 15412, + vtu: 15413, + vtv: 15414, + vtw: 15415, + vtx: 15416, + vty: 15417, + vuz: 15418, + vua: 15419, + vub: 15420, + vuc: 15421, + vud: 15422, + vue: 15423, + vuf: 15424, + vug: 15425, + vuh: 15426, + vui: 15427, + vuj: 15428, + vuk: 15429, + vul: 15430, + vum: 15431, + vun: 15432, + vuo: 15433, + vup: 15434, + vuq: 15435, + vur: 15436, + vus: 15437, + vut: 15438, + vuu: 15439, + vuv: 15440, + vuw: 15441, + vux: 15442, + vuy: 15443, + vvz: 15444, + vva: 15445, + vvb: 15446, + vvc: 15447, + vvd: 15448, + vve: 15449, + vvf: 15450, + vvg: 15451, + vvh: 15452, + vvi: 15453, + vvj: 15454, + vvk: 15455, + vvl: 15456, + vvm: 15457, + vvn: 15458, + vvo: 15459, + vvp: 15460, + vvq: 15461, + vvr: 15462, + vvs: 15463, + vvt: 15464, + vvu: 15465, + vvv: 15466, + vvw: 15467, + vvx: 15468, + vvy: 15469, + vwz: 15470, + vwa: 15471, + vwb: 15472, + vwc: 15473, + vwd: 15474, + vwe: 15475, + vwf: 15476, + vwg: 15477, + vwh: 15478, + vwi: 15479, + vwj: 15480, + vwk: 15481, + vwl: 15482, + vwm: 15483, + vwn: 15484, + vwo: 15485, + vwp: 15486, + vwq: 15487, + vwr: 15488, + vws: 15489, + vwt: 15490, + vwu: 15491, + vwv: 15492, + vww: 15493, + vwx: 15494, + vwy: 15495, + vxz: 15496, + vxa: 15497, + vxb: 15498, + vxc: 15499, + vxd: 15500, + vxe: 15501, + vxf: 15502, + vxg: 15503, + vxh: 15504, + vxi: 15505, + vxj: 15506, + vxk: 15507, + vxl: 15508, + vxm: 15509, + vxn: 15510, + vxo: 15511, + vxp: 15512, + vxq: 15513, + vxr: 15514, + vxs: 15515, + vxt: 15516, + vxu: 15517, + vxv: 15518, + vxw: 15519, + vxx: 15520, + vxy: 15521, + vyz: 15522, + vya: 15523, + vyb: 15524, + vyc: 15525, + vyd: 15526, + vye: 15527, + vyf: 15528, + vyg: 15529, + vyh: 15530, + vyi: 15531, + vyj: 15532, + vyk: 15533, + vyl: 15534, + vym: 15535, + vyn: 15536, + vyo: 15537, + vyp: 15538, + vyq: 15539, + vyr: 15540, + vys: 15541, + vyt: 15542, + vyu: 15543, + vyv: 15544, + vyw: 15545, + vyx: 15546, + vyy: 15547, + wzz: 15548, + wza: 15549, + wzb: 15550, + wzc: 15551, + wzd: 15552, + wze: 15553, + wzf: 15554, + wzg: 15555, + wzh: 15556, + wzi: 15557, + wzj: 15558, + wzk: 15559, + wzl: 15560, + wzm: 15561, + wzn: 15562, + wzo: 15563, + wzp: 15564, + wzq: 15565, + wzr: 15566, + wzs: 15567, + wzt: 15568, + wzu: 15569, + wzv: 15570, + wzw: 15571, + wzx: 15572, + wzy: 15573, + waz: 15574, + waa: 15575, + wab: 15576, + wac: 15577, + wad: 15578, + wae: 15579, + waf: 15580, + wag: 15581, + wah: 15582, + wai: 15583, + waj: 15584, + wak: 15585, + wal: 15586, + wam: 15587, + wan: 15588, + wao: 15589, + wap: 15590, + waq: 15591, + war: 15592, + was: 15593, + wat: 15594, + wau: 15595, + wav: 15596, + waw: 15597, + wax: 15598, + way: 15599, + wbz: 15600, + wba: 15601, + wbb: 15602, + wbc: 15603, + wbd: 15604, + wbe: 15605, + wbf: 15606, + wbg: 15607, + wbh: 15608, + wbi: 15609, + wbj: 15610, + wbk: 15611, + wbl: 15612, + wbm: 15613, + wbn: 15614, + wbo: 15615, + wbp: 15616, + wbq: 15617, + wbr: 15618, + wbs: 15619, + wbt: 15620, + wbu: 15621, + wbv: 15622, + wbw: 15623, + wbx: 15624, + wby: 15625, + wcz: 15626, + wca: 15627, + wcb: 15628, + wcc: 15629, + wcd: 15630, + wce: 15631, + wcf: 15632, + wcg: 15633, + wch: 15634, + wci: 15635, + wcj: 15636, + wck: 15637, + wcl: 15638, + wcm: 15639, + wcn: 15640, + wco: 15641, + wcp: 15642, + wcq: 15643, + wcr: 15644, + wcs: 15645, + wct: 15646, + wcu: 15647, + wcv: 15648, + wcw: 15649, + wcx: 15650, + wcy: 15651, + wdz: 15652, + wda: 15653, + wdb: 15654, + wdc: 15655, + wdd: 15656, + wde: 15657, + wdf: 15658, + wdg: 15659, + wdh: 15660, + wdi: 15661, + wdj: 15662, + wdk: 15663, + wdl: 15664, + wdm: 15665, + wdn: 15666, + wdo: 15667, + wdp: 15668, + wdq: 15669, + wdr: 15670, + wds: 15671, + wdt: 15672, + wdu: 15673, + wdv: 15674, + wdw: 15675, + wdx: 15676, + wdy: 15677, + wez: 15678, + wea: 15679, + web: 15680, + wec: 15681, + wed: 15682, + wee: 15683, + wef: 15684, + weg: 15685, + weh: 15686, + wei: 15687, + wej: 15688, + wek: 15689, + wel: 15690, + wem: 15691, + wen: 15692, + weo: 15693, + wep: 15694, + weq: 15695, + wer: 15696, + wes: 15697, + wet: 15698, + weu: 15699, + wev: 15700, + wew: 15701, + wex: 15702, + wey: 15703, + wfz: 15704, + wfa: 15705, + wfb: 15706, + wfc: 15707, + wfd: 15708, + wfe: 15709, + wff: 15710, + wfg: 15711, + wfh: 15712, + wfi: 15713, + wfj: 15714, + wfk: 15715, + wfl: 15716, + wfm: 15717, + wfn: 15718, + wfo: 15719, + wfp: 15720, + wfq: 15721, + wfr: 15722, + wfs: 15723, + wft: 15724, + wfu: 15725, + wfv: 15726, + wfw: 15727, + wfx: 15728, + wfy: 15729, + wgz: 15730, + wga: 15731, + wgb: 15732, + wgc: 15733, + wgd: 15734, + wge: 15735, + wgf: 15736, + wgg: 15737, + wgh: 15738, + wgi: 15739, + wgj: 15740, + wgk: 15741, + wgl: 15742, + wgm: 15743, + wgn: 15744, + wgo: 15745, + wgp: 15746, + wgq: 15747, + wgr: 15748, + wgs: 15749, + wgt: 15750, + wgu: 15751, + wgv: 15752, + wgw: 15753, + wgx: 15754, + wgy: 15755, + whz: 15756, + wha: 15757, + whb: 15758, + whc: 15759, + whd: 15760, + whe: 15761, + whf: 15762, + whg: 15763, + whh: 15764, + whi: 15765, + whj: 15766, + whk: 15767, + whl: 15768, + whm: 15769, + whn: 15770, + who: 15771, + whp: 15772, + whq: 15773, + whr: 15774, + whs: 15775, + wht: 15776, + whu: 15777, + whv: 15778, + whw: 15779, + whx: 15780, + why: 15781, + wiz: 15782, + wia: 15783, + wib: 15784, + wic: 15785, + wid: 15786, + wie: 15787, + wif: 15788, + wig: 15789, + wih: 15790, + wii: 15791, + wij: 15792, + wik: 15793, + wil: 15794, + wim: 15795, + win: 15796, + wio: 15797, + wip: 15798, + wiq: 15799, + wir: 15800, + wis: 15801, + wit: 15802, + wiu: 15803, + wiv: 15804, + wiw: 15805, + wix: 15806, + wiy: 15807, + wjz: 15808, + wja: 15809, + wjb: 15810, + wjc: 15811, + wjd: 15812, + wje: 15813, + wjf: 15814, + wjg: 15815, + wjh: 15816, + wji: 15817, + wjj: 15818, + wjk: 15819, + wjl: 15820, + wjm: 15821, + wjn: 15822, + wjo: 15823, + wjp: 15824, + wjq: 15825, + wjr: 15826, + wjs: 15827, + wjt: 15828, + wju: 15829, + wjv: 15830, + wjw: 15831, + wjx: 15832, + wjy: 15833, + wkz: 15834, + wka: 15835, + wkb: 15836, + wkc: 15837, + wkd: 15838, + wke: 15839, + wkf: 15840, + wkg: 15841, + wkh: 15842, + wki: 15843, + wkj: 15844, + wkk: 15845, + wkl: 15846, + wkm: 15847, + wkn: 15848, + wko: 15849, + wkp: 15850, + wkq: 15851, + wkr: 15852, + wks: 15853, + wkt: 15854, + wku: 15855, + wkv: 15856, + wkw: 15857, + wkx: 15858, + wky: 15859, + wlz: 15860, + wla: 15861, + wlb: 15862, + wlc: 15863, + wld: 15864, + wle: 15865, + wlf: 15866, + wlg: 15867, + wlh: 15868, + wli: 15869, + wlj: 15870, + wlk: 15871, + wll: 15872, + wlm: 15873, + wln: 15874, + wlo: 15875, + wlp: 15876, + wlq: 15877, + wlr: 15878, + wls: 15879, + wlt: 15880, + wlu: 15881, + wlv: 15882, + wlw: 15883, + wlx: 15884, + wly: 15885, + wmz: 15886, + wma: 15887, + wmb: 15888, + wmc: 15889, + wmd: 15890, + wme: 15891, + wmf: 15892, + wmg: 15893, + wmh: 15894, + wmi: 15895, + wmj: 15896, + wmk: 15897, + wml: 15898, + wmm: 15899, + wmn: 15900, + wmo: 15901, + wmp: 15902, + wmq: 15903, + wmr: 15904, + wms: 15905, + wmt: 15906, + wmu: 15907, + wmv: 15908, + wmw: 15909, + wmx: 15910, + wmy: 15911, + wnz: 15912, + wna: 15913, + wnb: 15914, + wnc: 15915, + wnd: 15916, + wne: 15917, + wnf: 15918, + wng: 15919, + wnh: 15920, + wni: 15921, + wnj: 15922, + wnk: 15923, + wnl: 15924, + wnm: 15925, + wnn: 15926, + wno: 15927, + wnp: 15928, + wnq: 15929, + wnr: 15930, + wns: 15931, + wnt: 15932, + wnu: 15933, + wnv: 15934, + wnw: 15935, + wnx: 15936, + wny: 15937, + woz: 15938, + woa: 15939, + wob: 15940, + woc: 15941, + wod: 15942, + woe: 15943, + wof: 15944, + wog: 15945, + woh: 15946, + woi: 15947, + woj: 15948, + wok: 15949, + wol: 15950, + wom: 15951, + won: 15952, + woo: 15953, + wop: 15954, + woq: 15955, + wor: 15956, + wos: 15957, + wot: 15958, + wou: 15959, + wov: 15960, + wow: 15961, + wox: 15962, + woy: 15963, + wpz: 15964, + wpa: 15965, + wpb: 15966, + wpc: 15967, + wpd: 15968, + wpe: 15969, + wpf: 15970, + wpg: 15971, + wph: 15972, + wpi: 15973, + wpj: 15974, + wpk: 15975, + wpl: 15976, + wpm: 15977, + wpn: 15978, + wpo: 15979, + wpp: 15980, + wpq: 15981, + wpr: 15982, + wps: 15983, + wpt: 15984, + wpu: 15985, + wpv: 15986, + wpw: 15987, + wpx: 15988, + wpy: 15989, + wqz: 15990, + wqa: 15991, + wqb: 15992, + wqc: 15993, + wqd: 15994, + wqe: 15995, + wqf: 15996, + wqg: 15997, + wqh: 15998, + wqi: 15999, + wqj: 16000, + wqk: 16001, + wql: 16002, + wqm: 16003, + wqn: 16004, + wqo: 16005, + wqp: 16006, + wqq: 16007, + wqr: 16008, + wqs: 16009, + wqt: 16010, + wqu: 16011, + wqv: 16012, + wqw: 16013, + wqx: 16014, + wqy: 16015, + wrz: 16016, + wra: 16017, + wrb: 16018, + wrc: 16019, + wrd: 16020, + wre: 16021, + wrf: 16022, + wrg: 16023, + wrh: 16024, + wri: 16025, + wrj: 16026, + wrk: 16027, + wrl: 16028, + wrm: 16029, + wrn: 16030, + wro: 16031, + wrp: 16032, + wrq: 16033, + wrr: 16034, + wrs: 16035, + wrt: 16036, + wru: 16037, + wrv: 16038, + wrw: 16039, + wrx: 16040, + wry: 16041, + wsz: 16042, + wsa: 16043, + wsb: 16044, + wsc: 16045, + wsd: 16046, + wse: 16047, + wsf: 16048, + wsg: 16049, + wsh: 16050, + wsi: 16051, + wsj: 16052, + wsk: 16053, + wsl: 16054, + wsm: 16055, + wsn: 16056, + wso: 16057, + wsp: 16058, + wsq: 16059, + wsr: 16060, + wss: 16061, + wst: 16062, + wsu: 16063, + wsv: 16064, + wsw: 16065, + wsx: 16066, + wsy: 16067, + wtz: 16068, + wta: 16069, + wtb: 16070, + wtc: 16071, + wtd: 16072, + wte: 16073, + wtf: 16074, + wtg: 16075, + wth: 16076, + wti: 16077, + wtj: 16078, + wtk: 16079, + wtl: 16080, + wtm: 16081, + wtn: 16082, + wto: 16083, + wtp: 16084, + wtq: 16085, + wtr: 16086, + wts: 16087, + wtt: 16088, + wtu: 16089, + wtv: 16090, + wtw: 16091, + wtx: 16092, + wty: 16093, + wuz: 16094, + wua: 16095, + wub: 16096, + wuc: 16097, + wud: 16098, + wue: 16099, + wuf: 16100, + wug: 16101, + wuh: 16102, + wui: 16103, + wuj: 16104, + wuk: 16105, + wul: 16106, + wum: 16107, + wun: 16108, + wuo: 16109, + wup: 16110, + wuq: 16111, + wur: 16112, + wus: 16113, + wut: 16114, + wuu: 16115, + wuv: 16116, + wuw: 16117, + wux: 16118, + wuy: 16119, + wvz: 16120, + wva: 16121, + wvb: 16122, + wvc: 16123, + wvd: 16124, + wve: 16125, + wvf: 16126, + wvg: 16127, + wvh: 16128, + wvi: 16129, + wvj: 16130, + wvk: 16131, + wvl: 16132, + wvm: 16133, + wvn: 16134, + wvo: 16135, + wvp: 16136, + wvq: 16137, + wvr: 16138, + wvs: 16139, + wvt: 16140, + wvu: 16141, + wvv: 16142, + wvw: 16143, + wvx: 16144, + wvy: 16145, + wwz: 16146, + wwa: 16147, + wwb: 16148, + wwc: 16149, + wwd: 16150, + wwe: 16151, + wwf: 16152, + wwg: 16153, + wwh: 16154, + wwi: 16155, + wwj: 16156, + wwk: 16157, + wwl: 16158, + wwm: 16159, + wwn: 16160, + wwo: 16161, + wwp: 16162, + wwq: 16163, + wwr: 16164, + wws: 16165, + wwt: 16166, + wwu: 16167, + wwv: 16168, + www: 16169, + wwx: 16170, + wwy: 16171, + wxz: 16172, + wxa: 16173, + wxb: 16174, + wxc: 16175, + wxd: 16176, + wxe: 16177, + wxf: 16178, + wxg: 16179, + wxh: 16180, + wxi: 16181, + wxj: 16182, + wxk: 16183, + wxl: 16184, + wxm: 16185, + wxn: 16186, + wxo: 16187, + wxp: 16188, + wxq: 16189, + wxr: 16190, + wxs: 16191, + wxt: 16192, + wxu: 16193, + wxv: 16194, + wxw: 16195, + wxx: 16196, + wxy: 16197, + wyz: 16198, + wya: 16199, + wyb: 16200, + wyc: 16201, + wyd: 16202, + wye: 16203, + wyf: 16204, + wyg: 16205, + wyh: 16206, + wyi: 16207, + wyj: 16208, + wyk: 16209, + wyl: 16210, + wym: 16211, + wyn: 16212, + wyo: 16213, + wyp: 16214, + wyq: 16215, + wyr: 16216, + wys: 16217, + wyt: 16218, + wyu: 16219, + wyv: 16220, + wyw: 16221, + wyx: 16222, + wyy: 16223, + xzz: 16224, + xza: 16225, + xzb: 16226, + xzc: 16227, + xzd: 16228, + xze: 16229, + xzf: 16230, + xzg: 16231, + xzh: 16232, + xzi: 16233, + xzj: 16234, + xzk: 16235, + xzl: 16236, + xzm: 16237, + xzn: 16238, + xzo: 16239, + xzp: 16240, + xzq: 16241, + xzr: 16242, + xzs: 16243, + xzt: 16244, + xzu: 16245, + xzv: 16246, + xzw: 16247, + xzx: 16248, + xzy: 16249, + xaz: 16250, + xaa: 16251, + xab: 16252, + xac: 16253, + xad: 16254, + xae: 16255, + xaf: 16256, + xag: 16257, + xah: 16258, + xai: 16259, + xaj: 16260, + xak: 16261, + xal: 16262, + xam: 16263, + xan: 16264, + xao: 16265, + xap: 16266, + xaq: 16267, + xar: 16268, + xas: 16269, + xat: 16270, + xau: 16271, + xav: 16272, + xaw: 16273, + xax: 16274, + xay: 16275, + xbz: 16276, + xba: 16277, + xbb: 16278, + xbc: 16279, + xbd: 16280, + xbe: 16281, + xbf: 16282, + xbg: 16283, + xbh: 16284, + xbi: 16285, + xbj: 16286, + xbk: 16287, + xbl: 16288, + xbm: 16289, + xbn: 16290, + xbo: 16291, + xbp: 16292, + xbq: 16293, + xbr: 16294, + xbs: 16295, + xbt: 16296, + xbu: 16297, + xbv: 16298, + xbw: 16299, + xbx: 16300, + xby: 16301, + xcz: 16302, + xca: 16303, + xcb: 16304, + xcc: 16305, + xcd: 16306, + xce: 16307, + xcf: 16308, + xcg: 16309, + xch: 16310, + xci: 16311, + xcj: 16312, + xck: 16313, + xcl: 16314, + xcm: 16315, + xcn: 16316, + xco: 16317, + xcp: 16318, + xcq: 16319, + xcr: 16320, + xcs: 16321, + xct: 16322, + xcu: 16323, + xcv: 16324, + xcw: 16325, + xcx: 16326, + xcy: 16327, + xdz: 16328, + xda: 16329, + xdb: 16330, + xdc: 16331, + xdd: 16332, + xde: 16333, + xdf: 16334, + xdg: 16335, + xdh: 16336, + xdi: 16337, + xdj: 16338, + xdk: 16339, + xdl: 16340, + xdm: 16341, + xdn: 16342, + xdo: 16343, + xdp: 16344, + xdq: 16345, + xdr: 16346, + xds: 16347, + xdt: 16348, + xdu: 16349, + xdv: 16350, + xdw: 16351, + xdx: 16352, + xdy: 16353, + xez: 16354, + xea: 16355, + xeb: 16356, + xec: 16357, + xed: 16358, + xee: 16359, + xef: 16360, + xeg: 16361, + xeh: 16362, + xei: 16363, + xej: 16364, + xek: 16365, + xel: 16366, + xem: 16367, + xen: 16368, + xeo: 16369, + xep: 16370, + xeq: 16371, + xer: 16372, + xes: 16373, + xet: 16374, + xeu: 16375, + xev: 16376, + xew: 16377, + xex: 16378, + xey: 16379, + xfz: 16380, + xfa: 16381, + xfb: 16382, + xfc: 16383, + xfd: 16384, + xfe: 16385, + xff: 16386, + xfg: 16387, + xfh: 16388, + xfi: 16389, + xfj: 16390, + xfk: 16391, + xfl: 16392, + xfm: 16393, + xfn: 16394, + xfo: 16395, + xfp: 16396, + xfq: 16397, + xfr: 16398, + xfs: 16399, + xft: 16400, + xfu: 16401, + xfv: 16402, + xfw: 16403, + xfx: 16404, + xfy: 16405, + xgz: 16406, + xga: 16407, + xgb: 16408, + xgc: 16409, + xgd: 16410, + xge: 16411, + xgf: 16412, + xgg: 16413, + xgh: 16414, + xgi: 16415, + xgj: 16416, + xgk: 16417, + xgl: 16418, + xgm: 16419, + xgn: 16420, + xgo: 16421, + xgp: 16422, + xgq: 16423, + xgr: 16424, + xgs: 16425, + xgt: 16426, + xgu: 16427, + xgv: 16428, + xgw: 16429, + xgx: 16430, + xgy: 16431, + xhz: 16432, + xha: 16433, + xhb: 16434, + xhc: 16435, + xhd: 16436, + xhe: 16437, + xhf: 16438, + xhg: 16439, + xhh: 16440, + xhi: 16441, + xhj: 16442, + xhk: 16443, + xhl: 16444, + xhm: 16445, + xhn: 16446, + xho: 16447, + xhp: 16448, + xhq: 16449, + xhr: 16450, + xhs: 16451, + xht: 16452, + xhu: 16453, + xhv: 16454, + xhw: 16455, + xhx: 16456, + xhy: 16457, + xiz: 16458, + xia: 16459, + xib: 16460, + xic: 16461, + xid: 16462, + xie: 16463, + xif: 16464, + xig: 16465, + xih: 16466, + xii: 16467, + xij: 16468, + xik: 16469, + xil: 16470, + xim: 16471, + xin: 16472, + xio: 16473, + xip: 16474, + xiq: 16475, + xir: 16476, + xis: 16477, + xit: 16478, + xiu: 16479, + xiv: 16480, + xiw: 16481, + xix: 16482, + xiy: 16483, + xjz: 16484, + xja: 16485, + xjb: 16486, + xjc: 16487, + xjd: 16488, + xje: 16489, + xjf: 16490, + xjg: 16491, + xjh: 16492, + xji: 16493, + xjj: 16494, + xjk: 16495, + xjl: 16496, + xjm: 16497, + xjn: 16498, + xjo: 16499, + xjp: 16500, + xjq: 16501, + xjr: 16502, + xjs: 16503, + xjt: 16504, + xju: 16505, + xjv: 16506, + xjw: 16507, + xjx: 16508, + xjy: 16509, + xkz: 16510, + xka: 16511, + xkb: 16512, + xkc: 16513, + xkd: 16514, + xke: 16515, + xkf: 16516, + xkg: 16517, + xkh: 16518, + xki: 16519, + xkj: 16520, + xkk: 16521, + xkl: 16522, + xkm: 16523, + xkn: 16524, + xko: 16525, + xkp: 16526, + xkq: 16527, + xkr: 16528, + xks: 16529, + xkt: 16530, + xku: 16531, + xkv: 16532, + xkw: 16533, + xkx: 16534, + xky: 16535, + xlz: 16536, + xla: 16537, + xlb: 16538, + xlc: 16539, + xld: 16540, + xle: 16541, + xlf: 16542, + xlg: 16543, + xlh: 16544, + xli: 16545, + xlj: 16546, + xlk: 16547, + xll: 16548, + xlm: 16549, + xln: 16550, + xlo: 16551, + xlp: 16552, + xlq: 16553, + xlr: 16554, + xls: 16555, + xlt: 16556, + xlu: 16557, + xlv: 16558, + xlw: 16559, + xlx: 16560, + xly: 16561, + xmz: 16562, + xma: 16563, + xmb: 16564, + xmc: 16565, + xmd: 16566, + xme: 16567, + xmf: 16568, + xmg: 16569, + xmh: 16570, + xmi: 16571, + xmj: 16572, + xmk: 16573, + xml: 16574, + xmm: 16575, + xmn: 16576, + xmo: 16577, + xmp: 16578, + xmq: 16579, + xmr: 16580, + xms: 16581, + xmt: 16582, + xmu: 16583, + xmv: 16584, + xmw: 16585, + xmx: 16586, + xmy: 16587, + xnz: 16588, + xna: 16589, + xnb: 16590, + xnc: 16591, + xnd: 16592, + xne: 16593, + xnf: 16594, + xng: 16595, + xnh: 16596, + xni: 16597, + xnj: 16598, + xnk: 16599, + xnl: 16600, + xnm: 16601, + xnn: 16602, + xno: 16603, + xnp: 16604, + xnq: 16605, + xnr: 16606, + xns: 16607, + xnt: 16608, + xnu: 16609, + xnv: 16610, + xnw: 16611, + xnx: 16612, + xny: 16613, + xoz: 16614, + xoa: 16615, + xob: 16616, + xoc: 16617, + xod: 16618, + xoe: 16619, + xof: 16620, + xog: 16621, + xoh: 16622, + xoi: 16623, + xoj: 16624, + xok: 16625, + xol: 16626, + xom: 16627, + xon: 16628, + xoo: 16629, + xop: 16630, + xoq: 16631, + xor: 16632, + xos: 16633, + xot: 16634, + xou: 16635, + xov: 16636, + xow: 16637, + xox: 16638, + xoy: 16639, + xpz: 16640, + xpa: 16641, + xpb: 16642, + xpc: 16643, + xpd: 16644, + xpe: 16645, + xpf: 16646, + xpg: 16647, + xph: 16648, + xpi: 16649, + xpj: 16650, + xpk: 16651, + xpl: 16652, + xpm: 16653, + xpn: 16654, + xpo: 16655, + xpp: 16656, + xpq: 16657, + xpr: 16658, + xps: 16659, + xpt: 16660, + xpu: 16661, + xpv: 16662, + xpw: 16663, + xpx: 16664, + xpy: 16665, + xqz: 16666, + xqa: 16667, + xqb: 16668, + xqc: 16669, + xqd: 16670, + xqe: 16671, + xqf: 16672, + xqg: 16673, + xqh: 16674, + xqi: 16675, + xqj: 16676, + xqk: 16677, + xql: 16678, + xqm: 16679, + xqn: 16680, + xqo: 16681, + xqp: 16682, + xqq: 16683, + xqr: 16684, + xqs: 16685, + xqt: 16686, + xqu: 16687, + xqv: 16688, + xqw: 16689, + xqx: 16690, + xqy: 16691, + xrz: 16692, + xra: 16693, + xrb: 16694, + xrc: 16695, + xrd: 16696, + xre: 16697, + xrf: 16698, + xrg: 16699, + xrh: 16700, + xri: 16701, + xrj: 16702, + xrk: 16703, + xrl: 16704, + xrm: 16705, + xrn: 16706, + xro: 16707, + xrp: 16708, + xrq: 16709, + xrr: 16710, + xrs: 16711, + xrt: 16712, + xru: 16713, + xrv: 16714, + xrw: 16715, + xrx: 16716, + xry: 16717, + xsz: 16718, + xsa: 16719, + xsb: 16720, + xsc: 16721, + xsd: 16722, + xse: 16723, + xsf: 16724, + xsg: 16725, + xsh: 16726, + xsi: 16727, + xsj: 16728, + xsk: 16729, + xsl: 16730, + xsm: 16731, + xsn: 16732, + xso: 16733, + xsp: 16734, + xsq: 16735, + xsr: 16736, + xss: 16737, + xst: 16738, + xsu: 16739, + xsv: 16740, + xsw: 16741, + xsx: 16742, + xsy: 16743, + xtz: 16744, + xta: 16745, + xtb: 16746, + xtc: 16747, + xtd: 16748, + xte: 16749, + xtf: 16750, + xtg: 16751, + xth: 16752, + xti: 16753, + xtj: 16754, + xtk: 16755, + xtl: 16756, + xtm: 16757, + xtn: 16758, + xto: 16759, + xtp: 16760, + xtq: 16761, + xtr: 16762, + xts: 16763, + xtt: 16764, + xtu: 16765, + xtv: 16766, + xtw: 16767, + xtx: 16768, + xty: 16769, + xuz: 16770, + xua: 16771, + xub: 16772, + xuc: 16773, + xud: 16774, + xue: 16775, + xuf: 16776, + xug: 16777, + xuh: 16778, + xui: 16779, + xuj: 16780, + xuk: 16781, + xul: 16782, + xum: 16783, + xun: 16784, + xuo: 16785, + xup: 16786, + xuq: 16787, + xur: 16788, + xus: 16789, + xut: 16790, + xuu: 16791, + xuv: 16792, + xuw: 16793, + xux: 16794, + xuy: 16795, + xvz: 16796, + xva: 16797, + xvb: 16798, + xvc: 16799, + xvd: 16800, + xve: 16801, + xvf: 16802, + xvg: 16803, + xvh: 16804, + xvi: 16805, + xvj: 16806, + xvk: 16807, + xvl: 16808, + xvm: 16809, + xvn: 16810, + xvo: 16811, + xvp: 16812, + xvq: 16813, + xvr: 16814, + xvs: 16815, + xvt: 16816, + xvu: 16817, + xvv: 16818, + xvw: 16819, + xvx: 16820, + xvy: 16821, + xwz: 16822, + xwa: 16823, + xwb: 16824, + xwc: 16825, + xwd: 16826, + xwe: 16827, + xwf: 16828, + xwg: 16829, + xwh: 16830, + xwi: 16831, + xwj: 16832, + xwk: 16833, + xwl: 16834, + xwm: 16835, + xwn: 16836, + xwo: 16837, + xwp: 16838, + xwq: 16839, + xwr: 16840, + xws: 16841, + xwt: 16842, + xwu: 16843, + xwv: 16844, + xww: 16845, + xwx: 16846, + xwy: 16847, + xxz: 16848, + xxa: 16849, + xxb: 16850, + xxc: 16851, + xxd: 16852, + xxe: 16853, + xxf: 16854, + xxg: 16855, + xxh: 16856, + xxi: 16857, + xxj: 16858, + xxk: 16859, + xxl: 16860, + xxm: 16861, + xxn: 16862, + xxo: 16863, + xxp: 16864, + xxq: 16865, + xxr: 16866, + xxs: 16867, + xxt: 16868, + xxu: 16869, + xxv: 16870, + xxw: 16871, + xxx: 16872, + xxy: 16873, + xyz: 16874, + xya: 16875, + xyb: 16876, + xyc: 16877, + xyd: 16878, + xye: 16879, + xyf: 16880, + xyg: 16881, + xyh: 16882, + xyi: 16883, + xyj: 16884, + xyk: 16885, + xyl: 16886, + xym: 16887, + xyn: 16888, + xyo: 16889, + xyp: 16890, + xyq: 16891, + xyr: 16892, + xys: 16893, + xyt: 16894, + xyu: 16895, + xyv: 16896, + xyw: 16897, + xyx: 16898, + xyy: 16899, + yzz: 16900, + yza: 16901, + yzb: 16902, + yzc: 16903, + yzd: 16904, + yze: 16905, + yzf: 16906, + yzg: 16907, + yzh: 16908, + yzi: 16909, + yzj: 16910, + yzk: 16911, + yzl: 16912, + yzm: 16913, + yzn: 16914, + yzo: 16915, + yzp: 16916, + yzq: 16917, + yzr: 16918, + yzs: 16919, + yzt: 16920, + yzu: 16921, + yzv: 16922, + yzw: 16923, + yzx: 16924, + yzy: 16925, + yaz: 16926, + yaa: 16927, + yab: 16928, + yac: 16929, + yad: 16930, + yae: 16931, + yaf: 16932, + yag: 16933, + yah: 16934, + yai: 16935, + yaj: 16936, + yak: 16937, + yal: 16938, + yam: 16939, + yan: 16940, + yao: 16941, + yap: 16942, + yaq: 16943, + yar: 16944, + yas: 16945, + yat: 16946, + yau: 16947, + yav: 16948, + yaw: 16949, + yax: 16950, + yay: 16951, + ybz: 16952, + yba: 16953, + ybb: 16954, + ybc: 16955, + ybd: 16956, + ybe: 16957, + ybf: 16958, + ybg: 16959, + ybh: 16960, + ybi: 16961, + ybj: 16962, + ybk: 16963, + ybl: 16964, + ybm: 16965, + ybn: 16966, + ybo: 16967, + ybp: 16968, + ybq: 16969, + ybr: 16970, + ybs: 16971, + ybt: 16972, + ybu: 16973, + ybv: 16974, + ybw: 16975, + ybx: 16976, + yby: 16977, + ycz: 16978, + yca: 16979, + ycb: 16980, + ycc: 16981, + ycd: 16982, + yce: 16983, + ycf: 16984, + ycg: 16985, + ych: 16986, + yci: 16987, + ycj: 16988, + yck: 16989, + ycl: 16990, + ycm: 16991, + ycn: 16992, + yco: 16993, + ycp: 16994, + ycq: 16995, + ycr: 16996, + ycs: 16997, + yct: 16998, + ycu: 16999, + ycv: 17000, + ycw: 17001, + ycx: 17002, + ycy: 17003, + ydz: 17004, + yda: 17005, + ydb: 17006, + ydc: 17007, + ydd: 17008, + yde: 17009, + ydf: 17010, + ydg: 17011, + ydh: 17012, + ydi: 17013, + ydj: 17014, + ydk: 17015, + ydl: 17016, + ydm: 17017, + ydn: 17018, + ydo: 17019, + ydp: 17020, + ydq: 17021, + ydr: 17022, + yds: 17023, + ydt: 17024, + ydu: 17025, + ydv: 17026, + ydw: 17027, + ydx: 17028, + ydy: 17029, + yez: 17030, + yea: 17031, + yeb: 17032, + yec: 17033, + yed: 17034, + yee: 17035, + yef: 17036, + yeg: 17037, + yeh: 17038, + yei: 17039, + yej: 17040, + yek: 17041, + yel: 17042, + yem: 17043, + yen: 17044, + yeo: 17045, + yep: 17046, + yeq: 17047, + yer: 17048, + yes: 17049, + yet: 17050, + yeu: 17051, + yev: 17052, + yew: 17053, + yex: 17054, + yey: 17055, + yfz: 17056, + yfa: 17057, + yfb: 17058, + yfc: 17059, + yfd: 17060, + yfe: 17061, + yff: 17062, + yfg: 17063, + yfh: 17064, + yfi: 17065, + yfj: 17066, + yfk: 17067, + yfl: 17068, + yfm: 17069, + yfn: 17070, + yfo: 17071, + yfp: 17072, + yfq: 17073, + yfr: 17074, + yfs: 17075, + yft: 17076, + yfu: 17077, + yfv: 17078, + yfw: 17079, + yfx: 17080, + yfy: 17081, + ygz: 17082, + yga: 17083, + ygb: 17084, + ygc: 17085, + ygd: 17086, + yge: 17087, + ygf: 17088, + ygg: 17089, + ygh: 17090, + ygi: 17091, + ygj: 17092, + ygk: 17093, + ygl: 17094, + ygm: 17095, + ygn: 17096, + ygo: 17097, + ygp: 17098, + ygq: 17099, + ygr: 17100, + ygs: 17101, + ygt: 17102, + ygu: 17103, + ygv: 17104, + ygw: 17105, + ygx: 17106, + ygy: 17107, + yhz: 17108, + yha: 17109, + yhb: 17110, + yhc: 17111, + yhd: 17112, + yhe: 17113, + yhf: 17114, + yhg: 17115, + yhh: 17116, + yhi: 17117, + yhj: 17118, + yhk: 17119, + yhl: 17120, + yhm: 17121, + yhn: 17122, + yho: 17123, + yhp: 17124, + yhq: 17125, + yhr: 17126, + yhs: 17127, + yht: 17128, + yhu: 17129, + yhv: 17130, + yhw: 17131, + yhx: 17132, + yhy: 17133, + yiz: 17134, + yia: 17135, + yib: 17136, + yic: 17137, + yid: 17138, + yie: 17139, + yif: 17140, + yig: 17141, + yih: 17142, + yii: 17143, + yij: 17144, + yik: 17145, + yil: 17146, + yim: 17147, + yin: 17148, + yio: 17149, + yip: 17150, + yiq: 17151, + yir: 17152, + yis: 17153, + yit: 17154, + yiu: 17155, + yiv: 17156, + yiw: 17157, + yix: 17158, + yiy: 17159, + yjz: 17160, + yja: 17161, + yjb: 17162, + yjc: 17163, + yjd: 17164, + yje: 17165, + yjf: 17166, + yjg: 17167, + yjh: 17168, + yji: 17169, + yjj: 17170, + yjk: 17171, + yjl: 17172, + yjm: 17173, + yjn: 17174, + yjo: 17175, + yjp: 17176, + yjq: 17177, + yjr: 17178, + yjs: 17179, + yjt: 17180, + yju: 17181, + yjv: 17182, + yjw: 17183, + yjx: 17184, + yjy: 17185, + ykz: 17186, + yka: 17187, + ykb: 17188, + ykc: 17189, + ykd: 17190, + yke: 17191, + ykf: 17192, + ykg: 17193, + ykh: 17194, + yki: 17195, + ykj: 17196, + ykk: 17197, + ykl: 17198, + ykm: 17199, + ykn: 17200, + yko: 17201, + ykp: 17202, + ykq: 17203, + ykr: 17204, + yks: 17205, + ykt: 17206, + yku: 17207, + ykv: 17208, + ykw: 17209, + ykx: 17210, + yky: 17211, + ylz: 17212, + yla: 17213, + ylb: 17214, + ylc: 17215, + yld: 17216, + yle: 17217, + ylf: 17218, + ylg: 17219, + ylh: 17220, + yli: 17221, + ylj: 17222, + ylk: 17223, + yll: 17224, + ylm: 17225, + yln: 17226, + ylo: 17227, + ylp: 17228, + ylq: 17229, + ylr: 17230, + yls: 17231, + ylt: 17232, + ylu: 17233, + ylv: 17234, + ylw: 17235, + ylx: 17236, + yly: 17237, + ymz: 17238, + yma: 17239, + ymb: 17240, + ymc: 17241, + ymd: 17242, + yme: 17243, + ymf: 17244, + ymg: 17245, + ymh: 17246, + ymi: 17247, + ymj: 17248, + ymk: 17249, + yml: 17250, + ymm: 17251, + ymn: 17252, + ymo: 17253, + ymp: 17254, + ymq: 17255, + ymr: 17256, + yms: 17257, + ymt: 17258, + ymu: 17259, + ymv: 17260, + ymw: 17261, + ymx: 17262, + ymy: 17263, + ynz: 17264, + yna: 17265, + ynb: 17266, + ync: 17267, + ynd: 17268, + yne: 17269, + ynf: 17270, + yng: 17271, + ynh: 17272, + yni: 17273, + ynj: 17274, + ynk: 17275, + ynl: 17276, + ynm: 17277, + ynn: 17278, + yno: 17279, + ynp: 17280, + ynq: 17281, + ynr: 17282, + yns: 17283, + ynt: 17284, + ynu: 17285, + ynv: 17286, + ynw: 17287, + ynx: 17288, + yny: 17289, + yoz: 17290, + yoa: 17291, + yob: 17292, + yoc: 17293, + yod: 17294, + yoe: 17295, + yof: 17296, + yog: 17297, + yoh: 17298, + yoi: 17299, + yoj: 17300, + yok: 17301, + yol: 17302, + yom: 17303, + yon: 17304, + yoo: 17305, + yop: 17306, + yoq: 17307, + yor: 17308, + yos: 17309, + yot: 17310, + you: 17311, + yov: 17312, + yow: 17313, + yox: 17314, + yoy: 17315, + ypz: 17316, + ypa: 17317, + ypb: 17318, + ypc: 17319, + ypd: 17320, + ype: 17321, + ypf: 17322, + ypg: 17323, + yph: 17324, + ypi: 17325, + ypj: 17326, + ypk: 17327, + ypl: 17328, + ypm: 17329, + ypn: 17330, + ypo: 17331, + ypp: 17332, + ypq: 17333, + ypr: 17334, + yps: 17335, + ypt: 17336, + ypu: 17337, + ypv: 17338, + ypw: 17339, + ypx: 17340, + ypy: 17341, + yqz: 17342, + yqa: 17343, + yqb: 17344, + yqc: 17345, + yqd: 17346, + yqe: 17347, + yqf: 17348, + yqg: 17349, + yqh: 17350, + yqi: 17351, + yqj: 17352, + yqk: 17353, + yql: 17354, + yqm: 17355, + yqn: 17356, + yqo: 17357, + yqp: 17358, + yqq: 17359, + yqr: 17360, + yqs: 17361, + yqt: 17362, + yqu: 17363, + yqv: 17364, + yqw: 17365, + yqx: 17366, + yqy: 17367, + yrz: 17368, + yra: 17369, + yrb: 17370, + yrc: 17371, + yrd: 17372, + yre: 17373, + yrf: 17374, + yrg: 17375, + yrh: 17376, + yri: 17377, + yrj: 17378, + yrk: 17379, + yrl: 17380, + yrm: 17381, + yrn: 17382, + yro: 17383, + yrp: 17384, + yrq: 17385, + yrr: 17386, + yrs: 17387, + yrt: 17388, + yru: 17389, + yrv: 17390, + yrw: 17391, + yrx: 17392, + yry: 17393, + ysz: 17394, + ysa: 17395, + ysb: 17396, + ysc: 17397, + ysd: 17398, + yse: 17399, + ysf: 17400, + ysg: 17401, + ysh: 17402, + ysi: 17403, + ysj: 17404, + ysk: 17405, + ysl: 17406, + ysm: 17407, + ysn: 17408, + yso: 17409, + ysp: 17410, + ysq: 17411, + ysr: 17412, + yss: 17413, + yst: 17414, + ysu: 17415, + ysv: 17416, + ysw: 17417, + ysx: 17418, + ysy: 17419, + ytz: 17420, + yta: 17421, + ytb: 17422, + ytc: 17423, + ytd: 17424, + yte: 17425, + ytf: 17426, + ytg: 17427, + yth: 17428, + yti: 17429, + ytj: 17430, + ytk: 17431, + ytl: 17432, + ytm: 17433, + ytn: 17434, + yto: 17435, + ytp: 17436, + ytq: 17437, + ytr: 17438, + yts: 17439, + ytt: 17440, + ytu: 17441, + ytv: 17442, + ytw: 17443, + ytx: 17444, + yty: 17445, + yuz: 17446, + yua: 17447, + yub: 17448, + yuc: 17449, + yud: 17450, + yue: 17451, + yuf: 17452, + yug: 17453, + yuh: 17454, + yui: 17455, + yuj: 17456, + yuk: 17457, + yul: 17458, + yum: 17459, + yun: 17460, + yuo: 17461, + yup: 17462, + yuq: 17463, + yur: 17464, + yus: 17465, + yut: 17466, + yuu: 17467, + yuv: 17468, + yuw: 17469, + yux: 17470, + yuy: 17471, + yvz: 17472, + yva: 17473, + yvb: 17474, + yvc: 17475, + yvd: 17476, + yve: 17477, + yvf: 17478, + yvg: 17479, + yvh: 17480, + yvi: 17481, + yvj: 17482, + yvk: 17483, + yvl: 17484, + yvm: 17485, + yvn: 17486, + yvo: 17487, + yvp: 17488, + yvq: 17489, + yvr: 17490, + yvs: 17491, + yvt: 17492, + yvu: 17493, + yvv: 17494, + yvw: 17495, + yvx: 17496, + yvy: 17497, + ywz: 17498, + ywa: 17499, + ywb: 17500, + ywc: 17501, + ywd: 17502, + ywe: 17503, + ywf: 17504, + ywg: 17505, + ywh: 17506, + ywi: 17507, + ywj: 17508, + ywk: 17509, + ywl: 17510, + ywm: 17511, + ywn: 17512, + ywo: 17513, + ywp: 17514, + ywq: 17515, + ywr: 17516, + yws: 17517, + ywt: 17518, + ywu: 17519, + ywv: 17520, + yww: 17521, + ywx: 17522, + ywy: 17523, + yxz: 17524, + yxa: 17525, + yxb: 17526, + yxc: 17527, + yxd: 17528, + yxe: 17529, + yxf: 17530, + yxg: 17531, + yxh: 17532, + yxi: 17533, + yxj: 17534, + yxk: 17535, + yxl: 17536, + yxm: 17537, + yxn: 17538, + yxo: 17539, + yxp: 17540, + yxq: 17541, + yxr: 17542, + yxs: 17543, + yxt: 17544, + yxu: 17545, + yxv: 17546, + yxw: 17547, + yxx: 17548, + yxy: 17549, + yyz: 17550, + yya: 17551, + yyb: 17552, + yyc: 17553, + yyd: 17554, + yye: 17555, + yyf: 17556, + yyg: 17557, + yyh: 17558, + yyi: 17559, + yyj: 17560, + yyk: 17561, + yyl: 17562, + yym: 17563, + yyn: 17564, + yyo: 17565, + yyp: 17566, + yyq: 17567, + yyr: 17568, + yys: 17569, + yyt: 17570, + yyu: 17571, + yyv: 17572, + 111: 111, + yyw: 17573, + yyx: 17574, + yyy: 17575, + get X() { print("getting X"); return "X"; }, + set X(value) { print("setting X"); }, +}; + +print(x.aaa); +print(x.hhh); +print(x.yyy); +print(x[111]); +print(x.X); +x.X = 0; +var keys = Object.keys(x); +print(keys.length); +print(keys[0]); +print(keys[703]); +print(keys[5624]); +print(keys[17575]); +print(keys[17576]); + diff --git a/nashorn/test/script/basic/JDK-8017084.js.EXPECTED b/nashorn/test/script/basic/JDK-8017084.js.EXPECTED new file mode 100644 index 00000000000..f57be50c00c --- /dev/null +++ b/nashorn/test/script/basic/JDK-8017084.js.EXPECTED @@ -0,0 +1,13 @@ +703 +5624 +17575 +111 +getting X +X +setting X +17577 +111 +aaa +hhh +yyy +X From dbe76b28bda5ed02436261208bdf60627526c615 Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Fri, 5 Jul 2013 15:10:47 +0200 Subject: [PATCH 042/156] 8019819: scope symbol didn't get a slot in certain cases Reviewed-by: hannesw, jlaskey, lagergren, sundar --- .../jdk/nashorn/internal/codegen/Attr.java | 8 ++-- .../internal/codegen/CodeGenerator.java | 27 ++++------- .../internal/codegen/CompilationPhase.java | 8 ++-- .../internal/codegen/FinalizeTypes.java | 9 ++-- .../jdk/nashorn/internal/ir/FunctionNode.java | 14 +++++- .../nashorn/internal/ir/LexicalContext.java | 28 ++++++++++- .../src/jdk/nashorn/internal/ir/Symbol.java | 3 +- .../jdk/nashorn/internal/parser/Parser.java | 2 +- nashorn/test/script/basic/JDK-8019819.js | 46 +++++++++++++++++++ 9 files changed, 108 insertions(+), 37 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8019819.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index d72e6a76c72..60de425524f 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -54,7 +54,6 @@ import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; - import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BinaryNode; @@ -343,10 +342,11 @@ final class Attr extends NodeOperatorVisitor { catchNestingLevel++; // define block-local exception variable - final Symbol def = defineSymbol(block, exception.getName(), IS_VAR | IS_LET | IS_ALWAYS_DEFINED); + final String exname = exception.getName(); + final Symbol def = defineSymbol(block, exname, IS_VAR | IS_LET | IS_ALWAYS_DEFINED); newType(def, Type.OBJECT); //we can catch anything, not just ecma exceptions - addLocalDef(exception.getName()); + addLocalDef(exname); return true; } @@ -678,7 +678,7 @@ final class Attr extends NodeOperatorVisitor { if (scopeBlock != null) { assert lc.contains(scopeBlock); - lc.setFlag(scopeBlock, Block.NEEDS_SCOPE); + lc.setBlockNeedsScope(scopeBlock); } } } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index fe4e3676e19..79936473fb9 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -881,9 +881,15 @@ final class CodeGenerator extends NodeOperatorVisitor= 0, like varargs. */ - if (function.needsParentScope()) { - initParentScope(); + if(method.hasScope()) { + if (function.needsParentScope()) { + method.loadCompilerConstant(CALLEE); + method.invoke(ScriptFunction.GET_SCOPE); + } else { + assert function.hasScopeBlock(); + method.loadNull(); + } + method.storeCompilerConstant(SCOPE); } if (function.needsArguments()) { initArguments(function); @@ -949,15 +955,6 @@ final class CodeGenerator extends NodeOperatorVisitor { if (!functionNode.needsCallee()) { functionNode.compilerConstant(CALLEE).setNeedsSlot(false); } - // Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope or its - // own scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope earlier than - // this phase. - if (!(functionNode.getBody().needsScope() || functionNode.needsParentScope())) { + // Similar reasoning applies to __scope__ symbol: if the function doesn't need either parent scope and none of + // its blocks create a scope, we ensure it doesn't get a slot, but we can't determine whether it needs a scope + // earlier than this phase. + if (!(functionNode.hasScopeBlock() || functionNode.needsParentScope())) { functionNode.compilerConstant(SCOPE).setNeedsSlot(false); } diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java index 8caff9d28fd..ec32c767308 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java @@ -160,6 +160,10 @@ public final class FunctionNode extends LexicalContextNode implements Flags= 0; i--) { if (stack[i] == node) { flags[i] |= flag; @@ -71,6 +74,29 @@ public class LexicalContext { assert false; } + /** + * Marks the block as one that creates a scope. Note that this method must + * be used instead of {@link #setFlag(LexicalContextNode, int)} with + * {@link Block#NEEDS_SCOPE} because it atomically also sets the + * {@link FunctionNode#HAS_SCOPE_BLOCK} flag on the block's containing + * function. + * @param block the block that needs to be marked as creating a scope. + */ + public void setBlockNeedsScope(final Block block) { + for (int i = sp - 1; i >= 0; i--) { + if (stack[i] == block) { + flags[i] |= Block.NEEDS_SCOPE; + for(int j = i - 1; j >=0; j --) { + if(stack[j] instanceof FunctionNode) { + flags[j] |= FunctionNode.HAS_SCOPE_BLOCK; + return; + } + } + } + } + assert false; + } + /** * Get the flags for a lexical context node on the stack * @param node node diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java index 7c1839024aa..5061ab9049a 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java @@ -29,7 +29,6 @@ import java.io.PrintWriter; import java.util.HashSet; import java.util.Set; import java.util.StringTokenizer; - import jdk.nashorn.internal.codegen.types.Range; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.runtime.Context; @@ -705,7 +704,7 @@ public final class Symbol implements Comparable { public static void setSymbolIsScope(final LexicalContext lc, final Symbol symbol) { symbol.setIsScope(); if (!symbol.isGlobal()) { - lc.setFlag(lc.getDefiningBlock(symbol), Block.NEEDS_SCOPE); + lc.setBlockNeedsScope(lc.getDefiningBlock(symbol)); } } diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java index 4c6107d570e..fd0136e463c 100644 --- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java @@ -2957,7 +2957,7 @@ loop: } else { lc.setFlag(fn, FunctionNode.HAS_NESTED_EVAL); } - lc.setFlag(lc.getFunctionBody(fn), Block.NEEDS_SCOPE); + lc.setBlockNeedsScope(lc.getFunctionBody(fn)); } } diff --git a/nashorn/test/script/basic/JDK-8019819.js b/nashorn/test/script/basic/JDK-8019819.js new file mode 100644 index 00000000000..1760ac3d333 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019819.js @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019819: scope symbol didn't get a slot in certain cases + * + * @test + * @run + */ +function f() { + try { + } catch(e if [].g(e)) { + with({}) { + throw e; + } + } +} + +function g() { + try { + } catch(e) { + with({}) { + throw e; + } + } +} From fa6c5ef45f829b45b542681c80ccc7401756e072 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Fri, 5 Jul 2013 19:35:39 +0200 Subject: [PATCH 043/156] 8019983: Void returns combined with return with expression picked the wrong return type Reviewed-by: sundar, jlaskey --- .../jdk/nashorn/internal/codegen/Attr.java | 9 ++-- nashorn/test/script/basic/JDK-8019983.js | 42 +++++++++++++++++++ .../test/script/basic/JDK-8019983.js.EXPECTED | 1 + 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8019983.js create mode 100644 nashorn/test/script/basic/JDK-8019983.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 60de425524f..6dbfa6d4c9b 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -749,6 +749,7 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveReturnNode(final ReturnNode returnNode) { final Node expr = returnNode.getExpression(); + final Type returnType; if (expr != null) { //we can't do parameter specialization if we return something that hasn't been typed yet @@ -757,10 +758,12 @@ final class Attr extends NodeOperatorVisitor { symbol.setType(Type.OBJECT); } - final Type returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType()); - returnTypes.push(returnType); - LOG.info("Returntype is now ", returnType); + returnType = Type.widest(returnTypes.pop(), symbol.getSymbolType()); + } else { + returnType = Type.OBJECT; //undefined } + LOG.info("Returntype is now ", returnType); + returnTypes.push(returnType); end(returnNode); diff --git a/nashorn/test/script/basic/JDK-8019983.js b/nashorn/test/script/basic/JDK-8019983.js new file mode 100644 index 00000000000..7851ab01849 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019983.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019983.js return without expression combined with return with expression should produce object + * return type (undefined) + * + * @test + * @run + */ + + +function g() { + switch(1) { + case 0: + case '': + default: + return; + } + return 10; +} +print(g()); diff --git a/nashorn/test/script/basic/JDK-8019983.js.EXPECTED b/nashorn/test/script/basic/JDK-8019983.js.EXPECTED new file mode 100644 index 00000000000..417b7b5370d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019983.js.EXPECTED @@ -0,0 +1 @@ +undefined From 0a7fda8dbe71a2af9cb4a62268f8d121cac98d0d Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 8 Jul 2013 16:33:50 +0530 Subject: [PATCH 044/156] 8020015: shared PropertyMaps should not be used without duplication Reviewed-by: hannesw, attila --- nashorn/buildtools/nasgen/build.xml | 3 +- .../internal/tools/nasgen/ClassGenerator.java | 85 +++++++++---- .../tools/nasgen/ConstructorGenerator.java | 18 +-- .../tools/nasgen/MethodGenerator.java | 5 + .../tools/nasgen/PrototypeGenerator.java | 19 +-- .../tools/nasgen/ScriptClassInstrumentor.java | 14 +-- .../tools/nasgen/StringConstants.java | 94 +++++++++----- nashorn/make/code_coverage.xml | 8 -- nashorn/make/project.properties | 3 + .../jdk/nashorn/internal/lookup/Lookup.java | 38 ------ .../internal/objects/ArrayBufferView.java | 9 +- .../jdk/nashorn/internal/objects/Global.java | 51 +++++--- .../internal/objects/NativeArguments.java | 12 +- .../internal/objects/NativeBoolean.java | 1 - .../nashorn/internal/objects/NativeDebug.java | 14 ++- .../nashorn/internal/objects/NativeError.java | 1 - .../internal/objects/NativeJSAdapter.java | 1 - .../nashorn/internal/objects/NativeJSON.java | 1 + .../nashorn/internal/objects/NativeMath.java | 1 + .../objects/NativeStrictArguments.java | 11 +- .../internal/objects/PrototypeObject.java | 10 +- .../internal/objects/ScriptFunctionImpl.java | 35 ++++-- .../internal/runtime/AccessorProperty.java | 14 +++ .../jdk/nashorn/internal/runtime/Context.java | 8 +- .../runtime/PropertyListenerManager.java | 10 ++ .../nashorn/internal/runtime/PropertyMap.java | 117 ++++++++++++------ .../internal/runtime/ScriptEnvironment.java | 8 ++ .../internal/runtime/ScriptObject.java | 2 +- .../runtime/resources/Options.properties | 16 +++ .../src/jdk/nashorn/internal/scripts/JO.java | 2 +- nashorn/src/jdk/nashorn/tools/Shell.java | 4 + 31 files changed, 385 insertions(+), 230 deletions(-) diff --git a/nashorn/buildtools/nasgen/build.xml b/nashorn/buildtools/nasgen/build.xml index bf56c1111df..6243bb2f02c 100644 --- a/nashorn/buildtools/nasgen/build.xml +++ b/nashorn/buildtools/nasgen/build.xml @@ -42,7 +42,8 @@ destdir="${build.classes.dir}" classpath="${javac.classpath}" debug="${javac.debug}" - includeantruntime="false"> + includeantruntime="false" fork="true"> + diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java index ed0eee61e60..3425e9fd0c0 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ClassGenerator.java @@ -37,14 +37,24 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.GETTER_PREFIX; import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.GET_CLASS_NAME_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_NEWPROPERTY_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.LOOKUP_TYPE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_NEWMAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_CREATE_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ACCESSORPROPERTY_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.LIST_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.ARRAYLIST_INIT_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTION_ADD_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.COLLECTIONS_EMPTY_LIST; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_SETISSHARED_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_NEWMAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC; @@ -161,17 +171,30 @@ public class ClassGenerator { return new MethodGenerator(mv, access, name, desc); } - static void emitStaticInitPrefix(final MethodGenerator mi, final String className) { + static void emitStaticInitPrefix(final MethodGenerator mi, final String className, final int memberCount) { mi.visitCode(); - mi.pushNull(); - mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); - mi.invokeStatic(MAP_TYPE, MAP_NEWMAP, MAP_NEWMAP_DESC); - // stack: PropertyMap + if (memberCount > 0) { + // new ArrayList(int) + mi.newObject(ARRAYLIST_TYPE); + mi.dup(); + mi.push(memberCount); + mi.invokeSpecial(ARRAYLIST_TYPE, INIT, ARRAYLIST_INIT_DESC); + // stack: ArrayList + } else { + // java.util.Collections.EMPTY_LIST + mi.getStatic(COLLECTIONS_TYPE, COLLECTIONS_EMPTY_LIST, LIST_DESC); + // stack List + } } static void emitStaticInitSuffix(final MethodGenerator mi, final String className) { - // stack: PropertyMap - mi.putStatic(className, MAP_FIELD_NAME, MAP_DESC); + // stack: Collection + // pmap = PropertyMap.newMap(Collection); + mi.invokeStatic(PROPERTYMAP_TYPE, PROPERTYMAP_NEWMAP, PROPERTYMAP_NEWMAP_DESC); + // pmap.setIsShared(); + mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_SETISSHARED, PROPERTYMAP_SETISSHARED_DESC); + // $nasgenmap$ = pmap; + mi.putStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); mi.returnVoid(); mi.computeMaxs(); mi.visitEnd(); @@ -235,9 +258,9 @@ public class ClassGenerator { } static void addMapField(final ClassVisitor cv) { - // add a MAP static field + // add a PropertyMap static field final FieldVisitor fv = cv.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, - MAP_FIELD_NAME, MAP_DESC, null, null); + PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC, null, null); if (fv != null) { fv.visitEnd(); } @@ -278,7 +301,11 @@ public class ClassGenerator { static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo memInfo) { final String propertyName = memInfo.getName(); - // stack: PropertyMap + // stack: Collection + // dup of Collection instance + mi.dup(); + + // property = AccessorProperty.create(key, flags, getter, setter); mi.loadLiteral(propertyName); // setup flags mi.push(memInfo.getAttributes()); @@ -292,13 +319,21 @@ public class ClassGenerator { javaName = SETTER_PREFIX + memInfo.getJavaName(); mi.visitLdcInsn(new Handle(H_INVOKEVIRTUAL, className, javaName, setterDesc(memInfo))); } - mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC); - // stack: PropertyMap + mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC); + // boolean Collection.add(property) + mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC); + // pop return value of Collection.add + mi.pop(); + // stack: Collection } static void linkerAddGetterSetter(final MethodGenerator mi, final String className, final MemberInfo getter, final MemberInfo setter) { final String propertyName = getter.getName(); - // stack: PropertyMap + // stack: Collection + // dup of Collection instance + mi.dup(); + + // property = AccessorProperty.create(key, flags, getter, setter); mi.loadLiteral(propertyName); // setup flags mi.push(getter.getAttributes()); @@ -312,8 +347,12 @@ public class ClassGenerator { mi.visitLdcInsn(new Handle(H_INVOKESTATIC, className, setter.getJavaName(), setter.getJavaDesc())); } - mi.invokeStatic(LOOKUP_TYPE, LOOKUP_NEWPROPERTY, LOOKUP_NEWPROPERTY_DESC); - // stack: PropertyMap + mi.invokeStatic(ACCESSORPROPERTY_TYPE, ACCESSORPROPERTY_CREATE, ACCESSORPROPERTY_CREATE_DESC); + // boolean Collection.add(property) + mi.invokeInterface(COLLECTION_TYPE, COLLECTION_ADD, COLLECTION_ADD_DESC); + // pop return value of Collection.add + mi.pop(); + // stack: Collection } static ScriptClassInfo getScriptClassInfo(final String fileName) throws IOException { diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java index 7c59f8c3c2b..e90b53ecb81 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ConstructorGenerator.java @@ -32,11 +32,11 @@ import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; import static jdk.nashorn.internal.tools.nasgen.StringConstants.CONSTRUCTOR_SUFFIX; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC; @@ -129,7 +129,7 @@ public class ConstructorGenerator extends ClassGenerator { private void emitStaticInitializer() { final MethodGenerator mi = makeStaticInitializer(); - emitStaticInitPrefix(mi, className); + emitStaticInitPrefix(mi, className, memberCount); for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { if (memInfo.isConstructorFunction() || memInfo.isConstructorProperty()) { @@ -170,10 +170,10 @@ public class ConstructorGenerator extends ClassGenerator { private void loadMap(final MethodGenerator mi) { if (memberCount > 0) { - mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC); + mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); // make sure we use duplicated PropertyMap so that original map - // stays intact and so can be used for many globals in same context - mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC); + // stays intact and so can be used for many globals. + mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC); } } diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java index c3dfd878526..475d7328c69 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/MethodGenerator.java @@ -57,6 +57,7 @@ import static jdk.internal.org.objectweb.asm.Opcodes.IALOAD; import static jdk.internal.org.objectweb.asm.Opcodes.IASTORE; import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0; import static jdk.internal.org.objectweb.asm.Opcodes.ILOAD; +import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEINTERFACE; import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESPECIAL; import static jdk.internal.org.objectweb.asm.Opcodes.INVOKESTATIC; import static jdk.internal.org.objectweb.asm.Opcodes.INVOKEVIRTUAL; @@ -347,6 +348,10 @@ public class MethodGenerator extends MethodVisitor { } // invokes, field get/sets + void invokeInterface(final String owner, final String method, final String desc) { + super.visitMethodInsn(INVOKEINTERFACE, owner, method, desc); + } + void invokeVirtual(final String owner, final String method, final String desc) { super.visitMethodInsn(INVOKEVIRTUAL, owner, method, desc); } diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java index 17750cd1bbf..98048a294b2 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/PrototypeGenerator.java @@ -30,11 +30,11 @@ import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER; import static jdk.internal.org.objectweb.asm.Opcodes.V1_7; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DUPLICATE_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_TYPE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_DUPLICATE_DESC; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_FIELD_NAME; +import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROPERTYMAP_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPEOBJECT_TYPE; import static jdk.nashorn.internal.tools.nasgen.StringConstants.PROTOTYPE_SUFFIX; @@ -67,6 +67,7 @@ public class PrototypeGenerator extends ClassGenerator { // add emitStaticInitializer(); } + // add emitConstructor(); @@ -106,7 +107,7 @@ public class PrototypeGenerator extends ClassGenerator { private void emitStaticInitializer() { final MethodGenerator mi = makeStaticInitializer(); - emitStaticInitPrefix(mi, className); + emitStaticInitPrefix(mi, className, memberCount); for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { if (memInfo.isPrototypeFunction() || memInfo.isPrototypeProperty()) { linkerAddGetterSetter(mi, className, memInfo); @@ -124,10 +125,10 @@ public class PrototypeGenerator extends ClassGenerator { mi.loadThis(); if (memberCount > 0) { // call "super(map$)" - mi.getStatic(className, MAP_FIELD_NAME, MAP_DESC); + mi.getStatic(className, PROPERTYMAP_FIELD_NAME, PROPERTYMAP_DESC); // make sure we use duplicated PropertyMap so that original map - // stays intact and so can be used for many globals in same context - mi.invokeVirtual(MAP_TYPE, MAP_DUPLICATE, MAP_DUPLICATE_DESC); + // stays intact and so can be used for many global. + mi.invokeVirtual(PROPERTYMAP_TYPE, PROPERTYMAP_DUPLICATE, PROPERTYMAP_DUPLICATE_DESC); mi.invokeSpecial(PROTOTYPEOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC); // initialize Function type fields initFunctionFields(mi); diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java index ffeb90bea3e..1622e02b469 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/ScriptClassInstrumentor.java @@ -37,10 +37,7 @@ import static jdk.nashorn.internal.tools.nasgen.StringConstants.$CLINIT$; import static jdk.nashorn.internal.tools.nasgen.StringConstants.CLINIT; import static jdk.nashorn.internal.tools.nasgen.StringConstants.DEFAULT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.INIT; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.MAP_FIELD_NAME; import static jdk.nashorn.internal.tools.nasgen.StringConstants.OBJECT_DESC; -import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_INIT_DESC; import static jdk.nashorn.internal.tools.nasgen.StringConstants.SCRIPTOBJECT_TYPE; import java.io.BufferedInputStream; @@ -159,14 +156,7 @@ public class ScriptClassInstrumentor extends ClassVisitor { public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) { if (isConstructor && opcode == INVOKESPECIAL && INIT.equals(name) && SCRIPTOBJECT_TYPE.equals(owner)) { - - // replace call to empty super-constructor with one passing PropertyMap argument - if (DEFAULT_INIT_DESC.equals(desc)) { - super.visitFieldInsn(GETSTATIC, scriptClassInfo.getJavaName(), MAP_FIELD_NAME, MAP_DESC); - super.visitMethodInsn(INVOKESPECIAL, SCRIPTOBJECT_TYPE, INIT, SCRIPTOBJECT_INIT_DESC); - } else { - super.visitMethodInsn(opcode, owner, name, desc); - } + super.visitMethodInsn(opcode, owner, name, desc); if (memberCount > 0) { // initialize @Property fields if needed @@ -256,7 +246,7 @@ public class ScriptClassInstrumentor extends ClassVisitor { } // Now generate $clinit$ final MethodGenerator mi = ClassGenerator.makeStaticInitializer(this, $CLINIT$); - ClassGenerator.emitStaticInitPrefix(mi, className); + ClassGenerator.emitStaticInitPrefix(mi, className, memberCount); if (memberCount > 0) { for (final MemberInfo memInfo : scriptClassInfo.getMembers()) { if (memInfo.isInstanceProperty() || memInfo.isInstanceFunction()) { diff --git a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java index d0e3168b31f..c4c1ab8d465 100644 --- a/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java +++ b/nashorn/buildtools/nasgen/src/jdk/nashorn/internal/tools/nasgen/StringConstants.java @@ -27,10 +27,14 @@ package jdk.nashorn.internal.tools.nasgen; import java.lang.invoke.MethodHandle; import java.lang.reflect.Method; +import java.util.Collection; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; import jdk.internal.org.objectweb.asm.Type; -import jdk.nashorn.internal.lookup.Lookup; import jdk.nashorn.internal.objects.PrototypeObject; import jdk.nashorn.internal.objects.ScriptFunctionImpl; +import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; @@ -40,15 +44,41 @@ import jdk.nashorn.internal.runtime.ScriptObject; */ @SuppressWarnings("javadoc") public interface StringConstants { + // standard jdk types, methods static final Type TYPE_METHOD = Type.getType(Method.class); static final Type TYPE_METHODHANDLE = Type.getType(MethodHandle.class); static final Type TYPE_METHODHANDLE_ARRAY = Type.getType(MethodHandle[].class); static final Type TYPE_OBJECT = Type.getType(Object.class); static final Type TYPE_CLASS = Type.getType(Class.class); static final Type TYPE_STRING = Type.getType(String.class); + static final Type TYPE_COLLECTION = Type.getType(Collection.class); + static final Type TYPE_COLLECTIONS = Type.getType(Collections.class); + static final Type TYPE_ARRAYLIST = Type.getType(ArrayList.class); + static final Type TYPE_LIST = Type.getType(List.class); - // Nashorn types - static final Type TYPE_LOOKUP = Type.getType(Lookup.class); + static final String CLINIT = ""; + static final String INIT = ""; + static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE); + + static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName(); + static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName(); + static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor(); + static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class); + static final String ARRAYLIST_TYPE = TYPE_ARRAYLIST.getInternalName(); + static final String COLLECTION_TYPE = TYPE_COLLECTION.getInternalName(); + static final String COLLECTIONS_TYPE = TYPE_COLLECTIONS.getInternalName(); + + // java.util.Collection.add(Object) + static final String COLLECTION_ADD = "add"; + static final String COLLECTION_ADD_DESC = Type.getMethodDescriptor(Type.BOOLEAN_TYPE, TYPE_OBJECT); + // java.util.ArrayList.(int) + static final String ARRAYLIST_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); + // java.util.Collections.EMPTY_LIST + static final String COLLECTIONS_EMPTY_LIST = "EMPTY_LIST"; + static final String LIST_DESC = TYPE_LIST.getDescriptor(); + + // Nashorn types, methods + static final Type TYPE_ACCESSORPROPERTY = Type.getType(AccessorProperty.class); static final Type TYPE_PROPERTYMAP = Type.getType(PropertyMap.class); static final Type TYPE_PROTOTYPEOBJECT = Type.getType(PrototypeObject.class); static final Type TYPE_SCRIPTFUNCTION = Type.getType(ScriptFunction.class); @@ -57,52 +87,56 @@ public interface StringConstants { static final String PROTOTYPE_SUFFIX = "$Prototype"; static final String CONSTRUCTOR_SUFFIX = "$Constructor"; + // This field name is known to Nashorn runtime (Context). // Synchronize the name change, if needed at all. - static final String MAP_FIELD_NAME = "$nasgenmap$"; + static final String PROPERTYMAP_FIELD_NAME = "$nasgenmap$"; static final String $CLINIT$ = "$clinit$"; - static final String CLINIT = ""; - static final String INIT = ""; - static final String DEFAULT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE); - static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP); + // AccessorProperty + static final String ACCESSORPROPERTY_TYPE = TYPE_ACCESSORPROPERTY.getInternalName(); + static final String ACCESSORPROPERTY_CREATE = "create"; + static final String ACCESSORPROPERTY_CREATE_DESC = + Type.getMethodDescriptor(TYPE_ACCESSORPROPERTY, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE); - static final String METHODHANDLE_TYPE = TYPE_METHODHANDLE.getInternalName(); + // PropertyMap + static final String PROPERTYMAP_TYPE = TYPE_PROPERTYMAP.getInternalName(); + static final String PROPERTYMAP_DESC = TYPE_PROPERTYMAP.getDescriptor(); + static final String PROPERTYMAP_NEWMAP = "newMap"; + static final String PROPERTYMAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_COLLECTION); + static final String PROPERTYMAP_DUPLICATE = "duplicate"; + static final String PROPERTYMAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); + static final String PROPERTYMAP_SETISSHARED = "setIsShared"; + static final String PROPERTYMAP_SETISSHARED_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); - static final String OBJECT_TYPE = TYPE_OBJECT.getInternalName(); - static final String OBJECT_DESC = TYPE_OBJECT.getDescriptor(); - static final String OBJECT_ARRAY_DESC = Type.getDescriptor(Object[].class); + // PrototypeObject + static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName(); + static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor"; + static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT); + // ScriptFunction static final String SCRIPTFUNCTION_TYPE = TYPE_SCRIPTFUNCTION.getInternalName(); + static final String SCRIPTFUNCTION_SETARITY = "setArity"; + static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); + static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype"; + static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT); + + // ScriptFunctionImpl static final String SCRIPTFUNCTIONIMPL_TYPE = TYPE_SCRIPTFUNCTIONIMPL.getInternalName(); static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION = "makeFunction"; static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_DESC = Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE); static final String SCRIPTFUNCTIONIMPL_MAKEFUNCTION_SPECS_DESC = Type.getMethodDescriptor(TYPE_SCRIPTFUNCTION, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY); - static final String SCRIPTFUNCTIONIMPL_INIT_DESC3 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_METHODHANDLE_ARRAY); static final String SCRIPTFUNCTIONIMPL_INIT_DESC4 = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_STRING, TYPE_METHODHANDLE, TYPE_PROPERTYMAP, TYPE_METHODHANDLE_ARRAY); - static final String SCRIPTFUNCTION_SETARITY = "setArity"; - static final String SCRIPTFUNCTION_SETARITY_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, Type.INT_TYPE); - static final String SCRIPTFUNCTION_SETPROTOTYPE = "setPrototype"; - static final String SCRIPTFUNCTION_SETPROTOTYPE_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT); - static final String PROTOTYPEOBJECT_TYPE = TYPE_PROTOTYPEOBJECT.getInternalName(); - static final String PROTOTYPEOBJECT_SETCONSTRUCTOR = "setConstructor"; - static final String PROTOTYPEOBJECT_SETCONSTRUCTOR_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_OBJECT, TYPE_OBJECT); + + // ScriptObject static final String SCRIPTOBJECT_TYPE = TYPE_SCRIPTOBJECT.getInternalName(); - static final String MAP_TYPE = TYPE_PROPERTYMAP.getInternalName(); - static final String MAP_DESC = TYPE_PROPERTYMAP.getDescriptor(); - static final String MAP_NEWMAP = "newMap"; - static final String MAP_NEWMAP_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); - static final String MAP_DUPLICATE = "duplicate"; - static final String MAP_DUPLICATE_DESC = Type.getMethodDescriptor(TYPE_PROPERTYMAP); - static final String LOOKUP_TYPE = TYPE_LOOKUP.getInternalName(); - static final String LOOKUP_NEWPROPERTY = "newProperty"; - static final String LOOKUP_NEWPROPERTY_DESC = - Type.getMethodDescriptor(TYPE_PROPERTYMAP, TYPE_PROPERTYMAP, TYPE_STRING, Type.INT_TYPE, TYPE_METHODHANDLE, TYPE_METHODHANDLE); + static final String SCRIPTOBJECT_INIT_DESC = Type.getMethodDescriptor(Type.VOID_TYPE, TYPE_PROPERTYMAP); + static final String GETTER_PREFIX = "G$"; static final String SETTER_PREFIX = "S$"; diff --git a/nashorn/make/code_coverage.xml b/nashorn/make/code_coverage.xml index 3e2860f8d9d..dea03099e36 100644 --- a/nashorn/make/code_coverage.xml +++ b/nashorn/make/code_coverage.xml @@ -60,16 +60,8 @@ - - - - - - - - diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties index 66bbdbebab7..dbd9efce80c 100644 --- a/nashorn/make/project.properties +++ b/nashorn/make/project.properties @@ -200,6 +200,9 @@ test262-test-sys-prop.test.failed.list.file=${build.dir}/test/failedTests # test262 test frameworks test262-test-sys-prop.test.js.framework=\ + --class-cache-size=0 \ + --no-java \ + --no-typed-arrays \ -timezone=PST \ ${test.script.dir}/test262.js \ ${test262.dir}/test/harness/framework.js \ diff --git a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java index a454527aec2..e874cfd7bbe 100644 --- a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java +++ b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java @@ -124,44 +124,6 @@ public final class Lookup { throw typeError("strict.getter.setter.poison", ScriptRuntime.safeToString(self)); } - /** - * Create a new {@link Property} - * - * @param map property map - * @param key property key - * @param flags property flags - * @param propertyGetter getter for property if available, null otherwise - * @param propertySetter setter for property if available, null otherwise - * - * @return new property map, representing {@code PropertyMap} with the new property added to it - */ - @SuppressWarnings("fallthrough") - public static PropertyMap newProperty(final PropertyMap map, final String key, final int flags, final MethodHandle propertyGetter, final MethodHandle propertySetter) { - MethodHandle getter = propertyGetter; - MethodHandle setter = propertySetter; - - // TODO: this is temporary code. This code exists to support reflective - // field reader/writer handles generated by "unreflect" lookup. - - switch (getter.type().parameterCount()) { - case 0: - // A static field reader, so drop the 'self' argument. - getter = MH.dropArguments(getter, 0, Object.class); - if (setter != null) { - setter = MH.dropArguments(setter, 0, Object.class); - } - // fall through - case 1: - // standard getter that accepts 'self'. - break; - default: - // Huh!! something wrong.. - throw new IllegalArgumentException("getter/setter has wrong arguments"); - } - - return map.newProperty(key, flags, -1, getter, setter); - } - /** * This method filters primitive return types using JavaScript semantics. For example, * an (int) cast of a double in Java land is not the same thing as invoking toInt32 on it. diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java index 60da65a113a..73969fa5cb1 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java +++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java @@ -46,14 +46,17 @@ abstract class ArrayBufferView extends ScriptObject { return $nasgenmap$; } - ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) { + private ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength, final Global global) { + super(global.getArrayBufferViewMap()); checkConstructorArgs(buffer, byteOffset, elementLength); - final Global global = Global.instance(); - this.setMap(global.getArrayBufferViewMap()); this.setProto(getPrototype(global)); this.setArray(factory().createArrayData(buffer, byteOffset, elementLength)); } + ArrayBufferView(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) { + this(buffer, byteOffset, elementLength, Global.instance()); + } + private void checkConstructorArgs(final NativeArrayBuffer buffer, final int byteOffset, final int elementLength) { if (byteOffset < 0 || elementLength < 0) { throw new RuntimeException("byteOffset or length must not be negative"); diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java index a92de8e11ee..e54fbb45e6d 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/Global.java +++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java @@ -43,7 +43,6 @@ import java.util.List; import java.util.Map; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; -import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Property; import jdk.nashorn.internal.objects.annotations.ScriptClass; @@ -389,6 +388,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { private PropertyMap prototypeObjectMap; private PropertyMap objectMap; private PropertyMap functionMap; + private PropertyMap anonymousFunctionMap; private PropertyMap strictFunctionMap; private PropertyMap boundFunctionMap; @@ -409,7 +409,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { private static final MethodHandle EXIT = findOwnMH("exit", Object.class, Object.class, Object.class); // initialized by nasgen - @SuppressWarnings("unused") private static PropertyMap $nasgenmap$; /** @@ -418,14 +417,14 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { * @param context the context */ public Global(final Context context) { - this.setContext(context); - this.setIsScope(); /* * Duplicate global's map and use it. This way the initial Map filled * by nasgen (referenced from static field in this class) is retained - * 'as is'. This allows multiple globals to be used within a context. + * 'as is' (as that one is process wide singleton. */ - this.setMap(getMap().duplicate()); + super($nasgenmap$.duplicate()); + this.setContext(context); + this.setIsScope(); final int cacheSize = context.getEnv()._class_cache_size; if (cacheSize > 0) { @@ -1018,6 +1017,10 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { return functionMap; } + PropertyMap getAnonymousFunctionMap() { + return anonymousFunctionMap; + } + PropertyMap getStrictFunctionMap() { return strictFunctionMap; } @@ -1538,7 +1541,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { final ScriptEnvironment env = getContext().getEnv(); // duplicate PropertyMaps of Native* classes - copyInitialMaps(); + copyInitialMaps(env); // initialize Function and Object constructor initFunctionAndObject(); @@ -1599,12 +1602,16 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { initErrorObjects(); // java access - initJavaAccess(); + if (! env._no_java) { + initJavaAccess(); + } - initTypedArray(); + if (! env._no_typed_arrays) { + initTypedArray(); + } if (env._scripting) { - initScripting(); + initScripting(env); } if (Context.DEBUG && System.getSecurityManager() == null) { @@ -1685,7 +1692,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { this.builtinJavaApi = initConstructor("Java"); } - private void initScripting() { + private void initScripting(final ScriptEnvironment scriptEnv) { Object value; value = ScriptFunctionImpl.makeFunction("readLine", ScriptingFunctions.READLINE); addOwnProperty("readLine", Attribute.NOT_ENUMERABLE, value); @@ -1704,7 +1711,6 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { // Nashorn extension: global.$OPTIONS (scripting-mode-only) final ScriptObject options = newObject(); - final ScriptEnvironment scriptEnv = getContext().getEnv(); copyOptions(options, scriptEnv); addOwnProperty("$OPTIONS", Attribute.NOT_ENUMERABLE, options); @@ -1857,20 +1863,17 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { } } - private void copyInitialMaps() { + private void copyInitialMaps(final ScriptEnvironment env) { this.accessorPropertyDescriptorMap = AccessorPropertyDescriptor.getInitialMap().duplicate(); - this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate(); this.dataPropertyDescriptorMap = DataPropertyDescriptor.getInitialMap().duplicate(); this.genericPropertyDescriptorMap = GenericPropertyDescriptor.getInitialMap().duplicate(); this.nativeArgumentsMap = NativeArguments.getInitialMap().duplicate(); this.nativeArrayMap = NativeArray.getInitialMap().duplicate(); - this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate(); this.nativeBooleanMap = NativeBoolean.getInitialMap().duplicate(); this.nativeDateMap = NativeDate.getInitialMap().duplicate(); this.nativeErrorMap = NativeError.getInitialMap().duplicate(); this.nativeEvalErrorMap = NativeEvalError.getInitialMap().duplicate(); this.nativeJSAdapterMap = NativeJSAdapter.getInitialMap().duplicate(); - this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate(); this.nativeNumberMap = NativeNumber.getInitialMap().duplicate(); this.nativeRangeErrorMap = NativeRangeError.getInitialMap().duplicate(); this.nativeReferenceErrorMap = NativeReferenceError.getInitialMap().duplicate(); @@ -1883,9 +1886,21 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { this.nativeURIErrorMap = NativeURIError.getInitialMap().duplicate(); this.prototypeObjectMap = PrototypeObject.getInitialMap().duplicate(); this.objectMap = JO.getInitialMap().duplicate(); - this.functionMap = ScriptFunctionImpl.getInitialMap(); + this.functionMap = ScriptFunctionImpl.getInitialMap().duplicate(); + this.anonymousFunctionMap = ScriptFunctionImpl.getInitialAnonymousMap().duplicate(); this.strictFunctionMap = ScriptFunctionImpl.getInitialStrictMap().duplicate(); this.boundFunctionMap = ScriptFunctionImpl.getInitialBoundMap().duplicate(); + + // java + if (! env._no_java) { + this.nativeJavaImporterMap = NativeJavaImporter.getInitialMap().duplicate(); + } + + // typed arrays + if (! env._no_typed_arrays) { + this.arrayBufferViewMap = ArrayBufferView.getInitialMap().duplicate(); + this.nativeArrayBufferMap = NativeArrayBuffer.getInitialMap().duplicate(); + } } // Function and Object constructors are inter-dependent. Also, @@ -1899,7 +1914,7 @@ public final class Global extends ScriptObject implements GlobalObject, Scope { this.builtinFunction = (ScriptFunction)initConstructor("Function"); // create global anonymous function - final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(); + final ScriptFunction anon = ScriptFunctionImpl.newAnonymousFunction(this); // need to copy over members of Function.prototype to anon function anon.addBoundProperties(getFunctionPrototype()); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java index 4a5b5986197..3bd74d523d8 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java @@ -31,8 +31,10 @@ import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; +import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyDescriptor; import jdk.nashorn.internal.runtime.PropertyMap; @@ -41,8 +43,6 @@ import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.arrays.ArrayData; import jdk.nashorn.internal.runtime.arrays.ArrayIndex; -import jdk.nashorn.internal.lookup.Lookup; -import jdk.nashorn.internal.lookup.MethodHandleFactory; /** * ECMA 10.6 Arguments Object. @@ -64,10 +64,10 @@ public final class NativeArguments extends ScriptObject { private static final PropertyMap map$; static { - PropertyMap map = PropertyMap.newMap(); - map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH); - map = Lookup.newProperty(map, "callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE); - map$ = map; + final ArrayList properties = new ArrayList<>(2); + properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH)); + properties.add(AccessorProperty.create("callee", Property.NOT_ENUMERABLE, G$CALLEE, S$CALLEE)); + map$ = PropertyMap.newMap(properties).setIsShared(); } static PropertyMap getInitialMap() { diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java index 962086c491e..bb57cc71a39 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeBoolean.java @@ -40,7 +40,6 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.runtime.linker.PrimitiveLookup; /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java index 43106eeb7b8..30a4228958e 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java @@ -49,6 +49,7 @@ import jdk.nashorn.internal.runtime.linker.LinkerCallSite; public final class NativeDebug extends ScriptObject { // initialized by nasgen + @SuppressWarnings("unused") private static PropertyMap $nasgenmap$; private NativeDebug() { @@ -144,7 +145,7 @@ public final class NativeDebug extends ScriptObject { */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) public static Object equals(final Object self, final Object obj1, final Object obj2) { - return (obj1 != null) ? obj1.equals(obj2) : false; + return Objects.equals(obj1, obj2); } /** @@ -176,6 +177,15 @@ public final class NativeDebug extends ScriptObject { return obj.getClass() + "@" + Integer.toHexString(hash); } + /** + * Returns the property listener count for a script object + * @return listener count + */ + @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) + public static Object getListenerCount(final Object self, final Object obj) { + return (obj instanceof ScriptObject)? ((ScriptObject)obj).getListenerCount() : 0; + } + /** * Dump all Nashorn debug mode counters. Calling this may be better if * you want to print all counters. This way you can avoid too many callsites @@ -197,6 +207,8 @@ public final class NativeDebug extends ScriptObject { out.println("ScriptFunction allocations " + ScriptFunction.getAllocations()); out.println("PropertyMap count " + PropertyMap.getCount()); out.println("PropertyMap cloned " + PropertyMap.getClonedCount()); + out.println("PropertyMap shared " + PropertyMap.getSharedCount()); + out.println("PropertyMap duplicated " + PropertyMap.getDuplicatedCount()); out.println("PropertyMap history hit " + PropertyMap.getHistoryHit()); out.println("PropertyMap proto invalidations " + PropertyMap.getProtoInvalidations()); out.println("PropertyMap proto history hit " + PropertyMap.getProtoHistoryHit()); diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java index 0f233f18b17..dc6aef906d9 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeError.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeError.java @@ -31,7 +31,6 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import jdk.nashorn.api.scripting.NashornException; -import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java index 8e98f4e1825..1fda3767874 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSAdapter.java @@ -48,7 +48,6 @@ import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; import jdk.nashorn.internal.runtime.arrays.ArrayLikeIterator; import jdk.nashorn.internal.lookup.Lookup; -import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.scripts.JO; /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java index 0fdb170f44b..863d531bda9 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJSON.java @@ -60,6 +60,7 @@ public final class NativeJSON extends ScriptObject { ScriptFunction.class, ScriptObject.class, Object.class, Object.class); // initialized by nasgen + @SuppressWarnings("unused") private static PropertyMap $nasgenmap$; private NativeJSON() { diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java index c952bd1d295..cc50fbb4f00 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java @@ -43,6 +43,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; public final class NativeMath extends ScriptObject { // initialized by nasgen + @SuppressWarnings("unused") private static PropertyMap $nasgenmap$; private NativeMath() { diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java index df2d17dd054..de6e4b51435 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeStrictArguments.java @@ -30,14 +30,14 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; import java.util.Arrays; +import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.arrays.ArrayData; -import jdk.nashorn.internal.lookup.Lookup; -import jdk.nashorn.internal.lookup.MethodHandleFactory; /** * ECMA 10.6 Arguments Object. @@ -54,14 +54,15 @@ public final class NativeStrictArguments extends ScriptObject { private static final PropertyMap map$; static { - PropertyMap map = PropertyMap.newMap(); - map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH); + final ArrayList properties = new ArrayList<>(1); + properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE, G$LENGTH, S$LENGTH)); + PropertyMap map = PropertyMap.newMap(properties); // In strict mode, the caller and callee properties should throw TypeError // Need to add properties directly to map since slots are assigned speculatively by newUserAccessors. final int flags = Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE; map = map.addProperty(map.newUserAccessors("caller", flags)); map = map.addProperty(map.newUserAccessors("callee", flags)); - map$ = map; + map$ = map.setIsShared(); } static PropertyMap getInitialMap() { diff --git a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java index 64af421598f..837fee8b789 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java +++ b/nashorn/src/jdk/nashorn/internal/objects/PrototypeObject.java @@ -30,12 +30,12 @@ import static jdk.nashorn.internal.lookup.Lookup.MH; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.ArrayList; +import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; -import jdk.nashorn.internal.lookup.Lookup; -import jdk.nashorn.internal.lookup.MethodHandleFactory; /** * Instances of this class serve as "prototype" object for script functions. @@ -52,9 +52,9 @@ public class PrototypeObject extends ScriptObject { private static final MethodHandle SET_CONSTRUCTOR = findOwnMH("setConstructor", void.class, Object.class, Object.class); static { - PropertyMap map = PropertyMap.newMap(); - map = Lookup.newProperty(map, "constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR); - map$ = map; + final ArrayList properties = new ArrayList<>(1); + properties.add(AccessorProperty.create("constructor", Property.NOT_ENUMERABLE, GET_CONSTRUCTOR, SET_CONSTRUCTOR)); + map$ = PropertyMap.newMap(properties).setIsShared(); } static PropertyMap getInitialMap() { diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java index 921073d4484..643d9acddf3 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java @@ -28,6 +28,7 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; import java.lang.invoke.MethodHandle; +import java.util.ArrayList; import jdk.nashorn.internal.runtime.GlobalFunctions; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; @@ -36,6 +37,7 @@ import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptFunctionData; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.lookup.Lookup; +import jdk.nashorn.internal.runtime.AccessorProperty; /** * Concrete implementation of ScriptFunction. This sets correct map for the @@ -57,6 +59,10 @@ public class ScriptFunctionImpl extends ScriptFunction { return map$; } + static PropertyMap getInitialAnonymousMap() { + return AnonymousFunction.getInitialMap(); + } + static PropertyMap getInitialStrictMap() { return strictmodemap$; } @@ -149,13 +155,18 @@ public class ScriptFunctionImpl extends ScriptFunction { } static { - PropertyMap map = PropertyMap.newMap(); - map = Lookup.newProperty(map, "prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE); - map = Lookup.newProperty(map, "length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null); - map = Lookup.newProperty(map, "name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null); - map$ = map; + final ArrayList properties = new ArrayList<>(3); + properties.add(AccessorProperty.create("prototype", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE, G$PROTOTYPE, S$PROTOTYPE)); + properties.add(AccessorProperty.create("length", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$LENGTH, null)); + properties.add(AccessorProperty.create("name", Property.NOT_ENUMERABLE | Property.NOT_CONFIGURABLE | Property.NOT_WRITABLE, G$NAME, null)); + map$ = PropertyMap.newMap(properties); strictmodemap$ = createStrictModeMap(map$); boundfunctionmap$ = createBoundFunctionMap(strictmodemap$); + // There are order dependencies between normal map, struct map and bound map + // We can make these 'shared' only after initialization of all three. + map$.setIsShared(); + strictmodemap$.setIsShared(); + boundfunctionmap$.setIsShared(); } // function object representing TypeErrorThrower @@ -201,15 +212,19 @@ public class ScriptFunctionImpl extends ScriptFunction { // Instance of this class is used as global anonymous function which // serves as Function.prototype object. private static class AnonymousFunction extends ScriptFunctionImpl { - private static final PropertyMap nasgenmap$$ = PropertyMap.newMap(); + private static final PropertyMap map$ = PropertyMap.newMap().setIsShared(); - AnonymousFunction() { - super("", GlobalFunctions.ANONYMOUS, nasgenmap$$, null); + static PropertyMap getInitialMap() { + return map$; + } + + AnonymousFunction(final Global global) { + super("", GlobalFunctions.ANONYMOUS, global.getAnonymousFunctionMap(), null); } } - static ScriptFunctionImpl newAnonymousFunction() { - return new AnonymousFunction(); + static ScriptFunctionImpl newAnonymousFunction(final Global global) { + return new AnonymousFunction(global); } /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java index 6840d458c4e..f7ece9df533 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java @@ -107,6 +107,20 @@ public class AccessorProperty extends Property { SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter); } + /** + * Create a new accessor property. Factory method used by nasgen generated code. + * + * @param key {@link Property} key. + * @param propertyFlags {@link Property} flags. + * @param getter {@link Property} get accessor method. + * @param setter {@link Property} set accessor method. + * + * @return New {@link AccessorProperty} created. + */ + public static AccessorProperty create(final String key, final int propertyFlags, final MethodHandle getter, final MethodHandle setter) { + return new AccessorProperty(key, propertyFlags, -1, getter, setter); + } + /** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */ private MethodHandle primitiveGetter; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 218be74e3bd..8f00d52127e 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -253,13 +253,7 @@ public final class Context { this.env = new ScriptEnvironment(options, out, err); this._strict = env._strict; this.appLoader = appLoader; - this.scriptLoader = (ScriptLoader)AccessController.doPrivileged( - new PrivilegedAction() { - @Override - public ClassLoader run() { - return new ScriptLoader(sharedLoader, Context.this); - } - }); + this.scriptLoader = env._loader_per_compile? null : createNewLoader(); this.errors = errors; // if user passed -classpath option, make a class loader with that and set it as diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java index 34db0cb3877..1ce18b63d8f 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyListenerManager.java @@ -41,6 +41,7 @@ public class PropertyListenerManager implements PropertyListener { private static int listenersRemoved; /** + * Return aggregate listeners added to all PropertyListenerManagers * @return the listenersAdded */ public static int getListenersAdded() { @@ -48,12 +49,21 @@ public class PropertyListenerManager implements PropertyListener { } /** + * Return aggregate listeners removed from all PropertyListenerManagers * @return the listenersRemoved */ public static int getListenersRemoved() { return listenersRemoved; } + /** + * Return listeners added to this PropertyListenerManager. + * @return the listener count + */ + public final int getListenerCount() { + return listeners != null? listeners.size() : 0; + } + // Property listener management methods /** diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java index f8d9b437c07..05e8dc78235 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java @@ -25,11 +25,8 @@ package jdk.nashorn.internal.runtime; -import jdk.nashorn.internal.scripts.JO; - import static jdk.nashorn.internal.runtime.PropertyHashMap.EMPTY_HASHMAP; -import java.lang.invoke.MethodHandle; import java.lang.invoke.SwitchPoint; import java.lang.ref.WeakReference; import java.util.Arrays; @@ -57,9 +54,8 @@ public final class PropertyMap implements Iterable, PropertyListener { private static final int CLONEABLE_FLAGS_MASK = 0b0000_1111; /** Has a listener been added to this property map. This flag is not copied when cloning a map. See {@link PropertyListener} */ public static final int IS_LISTENER_ADDED = 0b0001_0000; - - /** Empty map used for seed map for JO$ objects */ - private static final PropertyMap EMPTY_MAP = new PropertyMap(EMPTY_HASHMAP); + /** Is this process wide "shared" map?. This flag is not copied when cloning a map */ + public static final int IS_SHARED = 0b0010_0000; /** Map status flags. */ private int flags; @@ -145,16 +141,17 @@ public final class PropertyMap implements Iterable, PropertyListener { } /** - * Duplicates this PropertyMap instance. This is used by nasgen generated - * prototype and constructor classes. {@link PropertyMap} used for singletons - * like these (and global instance) are duplicated using this method and used. - * The original filled map referenced by static fields of prototype and - * constructor classes are not touched. This allows multiple independent global - * instances to be used within a single context instance. + * Duplicates this PropertyMap instance. This is used to duplicate 'shared' + * maps {@link PropertyMap} used as process wide singletons. Shared maps are + * duplicated for every global scope object. That way listeners, proto and property + * histories are scoped within a global scope. * * @return Duplicated {@link PropertyMap}. */ public PropertyMap duplicate() { + if (Context.DEBUG) { + duplicatedCount++; + } return new PropertyMap(this.properties); } @@ -172,6 +169,15 @@ public final class PropertyMap implements Iterable, PropertyListener { return new PropertyMap(newProperties, fieldCount, fieldMaximum, spillLength); } + /** + * Public property map allocator. Used by nasgen generated code. + * @param properties Collection of initial properties. + * @return New {@link PropertyMap}. + */ + public static PropertyMap newMap(final Collection properties) { + return (properties == null || properties.isEmpty())? newMap() : newMap(properties, 0, 0, 0); + } + /** * Return a sharable empty map. * @@ -199,6 +205,8 @@ public final class PropertyMap implements Iterable, PropertyListener { * @return A shared {@link SwitchPoint} for the property. */ public SwitchPoint getProtoGetSwitchPoint(final ScriptObject proto, final String key) { + assert !isShared() : "proto SwitchPoint from a shared PropertyMap"; + if (proto == null) { return null; } @@ -227,6 +235,8 @@ public final class PropertyMap implements Iterable, PropertyListener { * @param property {@link Property} to invalidate. */ private void invalidateProtoGetSwitchPoint(final Property property) { + assert !isShared() : "proto invalidation on a shared PropertyMap"; + if (protoGetSwitches != null) { final String key = property.getKey(); final SwitchPoint sp = protoGetSwitches.get(key); @@ -240,17 +250,6 @@ public final class PropertyMap implements Iterable, PropertyListener { } } - /** - * Add a property to the map. - * - * @param property {@link Property} being added. - * - * @return New {@link PropertyMap} with {@link Property} added. - */ - public PropertyMap newProperty(final Property property) { - return addProperty(property); - } - /** * Add a property to the map, re-binding its getters and setters, * if available, to a given receiver. This is typically the global scope. See @@ -261,23 +260,8 @@ public final class PropertyMap implements Iterable, PropertyListener { * * @return New {@link PropertyMap} with {@link Property} added. */ - PropertyMap newPropertyBind(final AccessorProperty property, final ScriptObject bindTo) { - return newProperty(new AccessorProperty(property, bindTo)); - } - - /** - * Add a new accessor property to the map. - * - * @param key {@link Property} key. - * @param propertyFlags {@link Property} flags. - * @param slot {@link Property} slot. - * @param getter {@link Property} get accessor method. - * @param setter {@link Property} set accessor method. - * - * @return New {@link PropertyMap} with {@link AccessorProperty} added. - */ - public PropertyMap newProperty(final String key, final int propertyFlags, final int slot, final MethodHandle getter, final MethodHandle setter) { - return newProperty(new AccessorProperty(key, propertyFlags, slot, getter, setter)); + PropertyMap addPropertyBind(final AccessorProperty property, final ScriptObject bindTo) { + return addProperty(new AccessorProperty(property, bindTo)); } /** @@ -478,6 +462,28 @@ public final class PropertyMap implements Iterable, PropertyListener { return newMap; } + /** + * Make this property map 'shared' one. Shared property map instances are + * process wide singleton objects. A shaped map should never be added as a listener + * to a proto object. Nor it should have history or proto history. A shared map + * is just a template that is meant to be duplicated before use. All nasgen initialized + * property maps are shared. + * + * @return this map after making it as shared + */ + public PropertyMap setIsShared() { + assert !isListenerAdded() : "making PropertyMap shared after listener added"; + assert protoHistory == null : "making PropertyMap shared after associating a proto with it"; + if (Context.DEBUG) { + sharedCount++; + } + + flags |= IS_SHARED; + // clear any history on this PropertyMap, won't be used. + history = null; + return this; + } + /** * Check for any configurable properties. * @@ -544,6 +550,8 @@ public final class PropertyMap implements Iterable, PropertyListener { * @param newMap {@link PropertyMap} associated with prototype. */ private void addToProtoHistory(final ScriptObject newProto, final PropertyMap newMap) { + assert !isShared() : "proto history modified on a shared PropertyMap"; + if (protoHistory == null) { protoHistory = new WeakHashMap<>(); } @@ -558,6 +566,8 @@ public final class PropertyMap implements Iterable, PropertyListener { * @param newMap Modified {@link PropertyMap}. */ private void addToHistory(final Property property, final PropertyMap newMap) { + assert !isShared() : "history modified on a shared PropertyMap"; + if (!properties.isEmpty()) { if (history == null) { history = new LinkedHashMap<>(); @@ -682,6 +692,15 @@ public final class PropertyMap implements Iterable, PropertyListener { return (flags & IS_LISTENER_ADDED) != 0; } + /** + * Check if this map shared or not. + * + * @return true if this map is shared. + */ + public boolean isShared() { + return (flags & IS_SHARED) != 0; + } + /** * Test to see if {@link PropertyMap} is extensible. * @@ -745,6 +764,8 @@ public final class PropertyMap implements Iterable, PropertyListener { * @return New {@link PropertyMap} with prototype changed. */ PropertyMap changeProto(final ScriptObject oldProto, final ScriptObject newProto) { + assert !isShared() : "proto associated with a shared PropertyMap"; + if (oldProto == newProto) { return this; } @@ -860,6 +881,8 @@ public final class PropertyMap implements Iterable, PropertyListener { // counters updated only in debug mode private static int count; private static int clonedCount; + private static int sharedCount; + private static int duplicatedCount; private static int historyHit; private static int protoInvalidations; private static int protoHistoryHit; @@ -879,6 +902,20 @@ public final class PropertyMap implements Iterable, PropertyListener { return clonedCount; } + /** + * @return The number of maps that are shared. + */ + public static int getSharedCount() { + return sharedCount; + } + + /** + * @return The number of maps that are duplicated. + */ + public static int getDuplicatedCount() { + return duplicatedCount; + } + /** * @return The number of times history was successfully used. */ diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java index f04dedf05c9..a2f1f4a0880 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java @@ -119,9 +119,15 @@ public final class ScriptEnvironment { /** Create a new class loaded for each compilation */ public final boolean _loader_per_compile; + /** Do not support Java support extensions. */ + public final boolean _no_java; + /** Do not support non-standard syntax extensions. */ public final boolean _no_syntax_extensions; + /** Do not support typed arrays. */ + public final boolean _no_typed_arrays; + /** Package to which generated class files are added */ public final String _package; @@ -207,7 +213,9 @@ public final class ScriptEnvironment { _fx = options.getBoolean("fx"); _lazy_compilation = options.getBoolean("lazy.compilation"); _loader_per_compile = options.getBoolean("loader.per.compile"); + _no_java = options.getBoolean("no.java"); _no_syntax_extensions = options.getBoolean("no.syntax.extensions"); + _no_typed_arrays = options.getBoolean("no.typed.arrays"); _package = options.getString("package"); _parse_only = options.getBoolean("parse.only"); _print_ast = options.getBoolean("print.ast"); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index e4eaf77e581..c56c32c7257 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -213,7 +213,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source)); newMap = newMap.addProperty(prop); } else { - newMap = newMap.newPropertyBind((AccessorProperty)property, source); + newMap = newMap.addPropertyBind((AccessorProperty)property, source); } } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties index 4d7be62b2de..452ae88c928 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties @@ -192,6 +192,14 @@ nashorn.option.loader.per.compile = { \ default=true \ } +nashorn.option.no.java = { \ + name="--no-java", \ + short_name="-nj", \ + is_undocumented=true, \ + desc="No Java support", \ + default=false \ +} + nashorn.option.no.syntax.extensions = { \ name="--no-syntax-extensions", \ short_name="-nse", \ @@ -200,6 +208,14 @@ nashorn.option.no.syntax.extensions = { \ default=false \ } +nashorn.option.no.typed.arrays = { \ + name="--no-typed-arrays", \ + short_name="-nta", \ + is_undocumented=true, \ + desc="No Typed arrays support", \ + default=false \ +} + nashorn.option.package = { \ name="--package", \ is_undocumented=true, \ diff --git a/nashorn/src/jdk/nashorn/internal/scripts/JO.java b/nashorn/src/jdk/nashorn/internal/scripts/JO.java index d6173918933..f2f000625d9 100644 --- a/nashorn/src/jdk/nashorn/internal/scripts/JO.java +++ b/nashorn/src/jdk/nashorn/internal/scripts/JO.java @@ -33,7 +33,7 @@ import jdk.nashorn.internal.runtime.ScriptObject; */ public class JO extends ScriptObject { - private static final PropertyMap map$ = PropertyMap.newMap(); + private static final PropertyMap map$ = PropertyMap.newMap().setIsShared(); /** * Returns the initial property map to be used. diff --git a/nashorn/src/jdk/nashorn/tools/Shell.java b/nashorn/src/jdk/nashorn/tools/Shell.java index 914c7b6e5cc..55840078e64 100644 --- a/nashorn/src/jdk/nashorn/tools/Shell.java +++ b/nashorn/src/jdk/nashorn/tools/Shell.java @@ -435,6 +435,10 @@ public class Shell { break; } + if (source.isEmpty()) { + continue; + } + Object res; try { res = context.eval(global, source, global, "", env._strict); From 1e0c0dc73ec40a8ec91e881e47682a5ab418a472 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Mon, 8 Jul 2013 18:36:10 +0530 Subject: [PATCH 045/156] 8020035: nashorn jdk buildfile BuildNashorn.gmk still renamed jdk.nashorn.internal.objects package Reviewed-by: attila, jlaskey --- nashorn/makefiles/BuildNashorn.gmk | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/nashorn/makefiles/BuildNashorn.gmk b/nashorn/makefiles/BuildNashorn.gmk index d08f7e8fa6f..96bedf44ac4 100644 --- a/nashorn/makefiles/BuildNashorn.gmk +++ b/nashorn/makefiles/BuildNashorn.gmk @@ -71,7 +71,6 @@ $(eval $(call SetupJavaCompilation,BUILD_NASGEN,\ $(BUILD_NASGEN): $(BUILD_NASHORN) # Copy classes to final classes dir and run nasgen to modify classes in jdk.nashorn.internal.objects package -# Finally rename classes in jdk.nashorn.internal.objects package $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN) $(ECHO) Running nasgen $(MKDIR) -p $(@D) @@ -80,9 +79,6 @@ $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run: $(BUILD_NASGEN) $(FIXPATH) $(JAVA) \ -cp "$(NASHORN_OUTPUTDIR)/nasgen_classes$(PATH_SEP)$(NASHORN_OUTPUTDIR)/nashorn_classes" \ jdk.nashorn.internal.tools.nasgen.Main $(@D) jdk.nashorn.internal.objects $(@D) - for f in `$(FIND) $(@D)/jdk/nashorn/internal/objects/ -name "*.class"`; do \ - mv "$$f" `$(ECHO) "$$f" | $(SED) "s/\.class$$/\.clazz/"`; \ - done $(TOUCH) $@ # Version file needs to be processed with version numbers @@ -104,7 +100,7 @@ $(eval $(call SetupArchive,BUILD_NASHORN_JAR,\ $(NASHORN_OUTPUTDIR)/classes/_the.nasgen.run \ $(VERSION_FILE),\ SRCS:=$(NASHORN_OUTPUTDIR)/classes,\ - SUFFIXES:=.class .clazz .js .properties Factory,\ + SUFFIXES:=.class .js .properties Factory,\ MANIFEST:=$(NASHORN_TOPDIR)/src/META-INF/MANIFEST.MF,\ EXTRA_MANIFEST_ATTR:=$(MANIFEST_ATTRIBUTES),\ SKIP_METAINF:=true,\ From 007e944455c195c9a82efb6f3b61e9b2a2b42ad5 Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Mon, 8 Jul 2013 19:47:40 +0400 Subject: [PATCH 046/156] 8019265: [macosx] apple.laf.useScreenMenuBar regression comparing with jdk6 Reviewed-by: anthony --- jdk/src/macosx/native/sun/awt/CMenuItem.m | 9 +++++++-- .../ActionListenerCalledTwiceTest.java | 5 +++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/jdk/src/macosx/native/sun/awt/CMenuItem.m b/jdk/src/macosx/native/sun/awt/CMenuItem.m index eaabb3e06ab..0d1ade68ab6 100644 --- a/jdk/src/macosx/native/sun/awt/CMenuItem.m +++ b/jdk/src/macosx/native/sun/awt/CMenuItem.m @@ -82,8 +82,13 @@ JNF_COCOA_ENTER(env); // keys, so we need to do the same translation here that we do // for the regular key down events if ([eventKey length] == 1) { - unichar ch = NsCharToJavaChar([eventKey characterAtIndex:0], 0); - eventKey = [NSString stringWithCharacters: &ch length: 1]; + unichar origChar = [eventKey characterAtIndex:0]; + unichar newChar = NsCharToJavaChar(origChar, 0); + if (newChar == java_awt_event_KeyEvent_CHAR_UNDEFINED) { + newChar = origChar; + } + + eventKey = [NSString stringWithCharacters: &newChar length: 1]; } if ([menuKey isEqualToString:eventKey]) { diff --git a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java index 4cf1c750da5..d9cedf423e6 100644 --- a/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java +++ b/jdk/test/javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java @@ -35,10 +35,11 @@ import java.awt.event.*; import javax.swing.*; public class ActionListenerCalledTwiceTest { - static String menuItems[] = { "Item1", "Item2" }; + static String menuItems[] = { "Item1", "Item2", "Item3" }; static KeyStroke keyStrokes[] = { KeyStroke.getKeyStroke(KeyEvent.VK_E, InputEvent.META_MASK), - KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0) + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + KeyStroke.getKeyStroke(KeyEvent.VK_UP, InputEvent.SHIFT_MASK), }; static volatile int listenerCallCounter = 0; From 4e011cfb8c0805708981bbccb01d5e5b42878610 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Mon, 8 Jul 2013 19:34:55 +0200 Subject: [PATCH 047/156] 8019963: empty char range in regex Reviewed-by: jlaskey, sundar --- .../runtime/regexp/joni/CodeRangeBuffer.java | 2 +- .../internal/runtime/regexp/joni/Parser.java | 57 ++-------------- nashorn/test/script/basic/JDK-8019963.js | 66 +++++++++++++++++++ .../test/script/basic/JDK-8019963.js.EXPECTED | 29 ++++++++ 4 files changed, 102 insertions(+), 52 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8019963.js create mode 100644 nashorn/test/script/basic/JDK-8019963.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java index 87e0f8e1fc3..d6c2a61e23a 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CodeRangeBuffer.java @@ -183,7 +183,7 @@ public final class CodeRangeBuffer { // add_code_range, be aware of it returning null! public static CodeRangeBuffer addCodeRange(CodeRangeBuffer pbuf, ScanEnvironment env, int from, int to) { - if (from >to) { + if (from > to) { if (env.syntax.allowEmptyRangeInCC()) { return pbuf; } else { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java index 03c99a3c03c..45c8838e5d4 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java @@ -125,32 +125,8 @@ class Parser extends Lexer { break; case RAW_BYTE: - if (token.base != 0) { /* tok->base != 0 : octal or hexadec. */ - byte[] buf = new byte[4]; - int psave = p; - int base = token.base; - buf[0] = (byte)token.getC(); - int i; - for (i=1; i<4; i++) { - fetchTokenInCC(); - if (token.type != TokenType.RAW_BYTE || token.base != base) { - fetched = true; - break; - } - buf[i] = (byte)token.getC(); - } - - if (i == 1) { - arg.v = buf[0] & 0xff; - arg.inType = CCVALTYPE.SB; // goto raw_single - } else { - arg.v = EncodingHelper.mbcToCode(buf, 0, buf.length); - arg.inType = CCVALTYPE.CODE_POINT; - } - } else { - arg.v = token.getC(); - arg.inType = CCVALTYPE.SB; // raw_single: - } + arg.v = token.getC(); + arg.inType = CCVALTYPE.SB; // raw_single: arg.vIsRaw = true; parseCharClassValEntry2(cc, arg); // goto val_entry2 break; @@ -615,31 +591,10 @@ class Parser extends Lexer { StringNode node = new StringNode((char)token.getC()); node.setRaw(); - int len = 1; - while (true) { - if (len >= 1) { - if (len == 1) { - fetchToken(); - node.clearRaw(); - // !goto string_end;! - return parseExpRepeat(node, group); - } - } - - fetchToken(); - if (token.type != TokenType.RAW_BYTE) { - /* Don't use this, it is wrong for little endian encodings. */ - // USE_PAD_TO_SHORT_BYTE_CHAR ... - - newValueException(ERR_TOO_SHORT_MULTI_BYTE_STRING); - } - - // important: we don't use 0xff mask here neither in the compiler - // (in the template string) so we won't have to mask target - // strings when comparing against them in the matcher - node.cat((char)token.getC()); - len++; - } // while + fetchToken(); + node.clearRaw(); + // !goto string_end;! + return parseExpRepeat(node, group); } private Node parseExpRepeat(Node target, boolean group) { diff --git a/nashorn/test/script/basic/JDK-8019963.js b/nashorn/test/script/basic/JDK-8019963.js new file mode 100644 index 00000000000..5767a414a49 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019963.js @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8019963: empty char range in regex + * + * @test + * @run + */ + +var re1 = /[\x00-\x08\x0B\x0C\x0E-\x9F\uD800-\uDFFF\uFFFE\uFFFF]/; + +print(re1.test("\x00")); +print(re1.test("\x04")); +print(re1.test("\x08")); +print(re1.test("\x0a")); +print(re1.test("\x0B")); +print(re1.test("\x0C")); +print(re1.test("\x0E")); +print(re1.test("\x10")); +print(re1.test("\x1A")); +print(re1.test("\x2F")); +print(re1.test("\x8E")); +print(re1.test("\x8F")); +print(re1.test("\x9F")); +print(re1.test("\xA0")); +print(re1.test("\xAF")); +print(re1.test("\uD800")); +print(re1.test("\xDA00")); +print(re1.test("\xDCFF")); +print(re1.test("\xDFFF")); +print(re1.test("\xFFFE")); +print(re1.test("\xFFFF")); + +var re2 = /[\x1F\x7F-\x84\x86]/; + +print(re2.test("\x1F")); +print(re2.test("\x2F")); +print(re2.test("\x3F")); +print(re2.test("\x7F")); +print(re2.test("\x80")); +print(re2.test("\x84")); +print(re2.test("\x85")); +print(re2.test("\x86")); + +var re3 = /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/; diff --git a/nashorn/test/script/basic/JDK-8019963.js.EXPECTED b/nashorn/test/script/basic/JDK-8019963.js.EXPECTED new file mode 100644 index 00000000000..ffde31fe38d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8019963.js.EXPECTED @@ -0,0 +1,29 @@ +true +true +true +false +true +true +true +true +true +true +true +true +true +false +false +true +true +true +true +true +true +true +false +false +true +true +true +false +true From 1958240c6fd39e8845d439a3fd6363aa824bfa62 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Mon, 8 Jul 2013 10:58:48 -0700 Subject: [PATCH 048/156] 8016903: Thread::_handle_area initial size too big Changed initial size to Chunk::tiny_size (216 bytes) Reviewed-by: coleenp, dholmes, sspitsyn --- hotspot/src/share/vm/memory/allocation.cpp | 9 ++++++++- hotspot/src/share/vm/memory/allocation.hpp | 3 ++- hotspot/src/share/vm/runtime/handles.hpp | 2 +- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp index c45dab1c4c5..6a80c47385e 100644 --- a/hotspot/src/share/vm/memory/allocation.cpp +++ b/hotspot/src/share/vm/memory/allocation.cpp @@ -236,10 +236,11 @@ class ChunkPool: public CHeapObj { size_t _num_used; // number of chunks currently checked out const size_t _size; // size of each chunk (must be uniform) - // Our three static pools + // Our four static pools static ChunkPool* _large_pool; static ChunkPool* _medium_pool; static ChunkPool* _small_pool; + static ChunkPool* _tiny_pool; // return first element or null void* get_first() { @@ -319,15 +320,18 @@ class ChunkPool: public CHeapObj { static ChunkPool* large_pool() { assert(_large_pool != NULL, "must be initialized"); return _large_pool; } static ChunkPool* medium_pool() { assert(_medium_pool != NULL, "must be initialized"); return _medium_pool; } static ChunkPool* small_pool() { assert(_small_pool != NULL, "must be initialized"); return _small_pool; } + static ChunkPool* tiny_pool() { assert(_tiny_pool != NULL, "must be initialized"); return _tiny_pool; } static void initialize() { _large_pool = new ChunkPool(Chunk::size + Chunk::aligned_overhead_size()); _medium_pool = new ChunkPool(Chunk::medium_size + Chunk::aligned_overhead_size()); _small_pool = new ChunkPool(Chunk::init_size + Chunk::aligned_overhead_size()); + _tiny_pool = new ChunkPool(Chunk::tiny_size + Chunk::aligned_overhead_size()); } static void clean() { enum { BlocksToKeep = 5 }; + _tiny_pool->free_all_but(BlocksToKeep); _small_pool->free_all_but(BlocksToKeep); _medium_pool->free_all_but(BlocksToKeep); _large_pool->free_all_but(BlocksToKeep); @@ -337,6 +341,7 @@ class ChunkPool: public CHeapObj { ChunkPool* ChunkPool::_large_pool = NULL; ChunkPool* ChunkPool::_medium_pool = NULL; ChunkPool* ChunkPool::_small_pool = NULL; +ChunkPool* ChunkPool::_tiny_pool = NULL; void chunkpool_init() { ChunkPool::initialize(); @@ -376,6 +381,7 @@ void* Chunk::operator new (size_t requested_size, AllocFailType alloc_failmode, case Chunk::size: return ChunkPool::large_pool()->allocate(bytes, alloc_failmode); case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes, alloc_failmode); case Chunk::init_size: return ChunkPool::small_pool()->allocate(bytes, alloc_failmode); + case Chunk::tiny_size: return ChunkPool::tiny_pool()->allocate(bytes, alloc_failmode); default: { void* p = os::malloc(bytes, mtChunk, CALLER_PC); if (p == NULL && alloc_failmode == AllocFailStrategy::EXIT_OOM) { @@ -392,6 +398,7 @@ void Chunk::operator delete(void* p) { case Chunk::size: ChunkPool::large_pool()->free(c); break; case Chunk::medium_size: ChunkPool::medium_pool()->free(c); break; case Chunk::init_size: ChunkPool::small_pool()->free(c); break; + case Chunk::tiny_size: ChunkPool::tiny_pool()->free(c); break; default: os::free(c, mtChunk); } } diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp index 17654f06984..aa916660d8b 100644 --- a/hotspot/src/share/vm/memory/allocation.hpp +++ b/hotspot/src/share/vm/memory/allocation.hpp @@ -353,7 +353,8 @@ class Chunk: CHeapObj { slack = 20, // suspected sizeof(Chunk) + internal malloc headers #endif - init_size = 1*K - slack, // Size of first chunk + tiny_size = 256 - slack, // Size of first chunk (tiny) + init_size = 1*K - slack, // Size of first chunk (normal aka small) medium_size= 10*K - slack, // Size of medium-sized chunk size = 32*K - slack, // Default size of an Arena chunk (following the first) non_pool_size = init_size + 32 // An initial size which is not one of above diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp index 82506bd7049..4a2a90c74c0 100644 --- a/hotspot/src/share/vm/runtime/handles.hpp +++ b/hotspot/src/share/vm/runtime/handles.hpp @@ -227,7 +227,7 @@ class HandleArea: public Arena { HandleArea* _prev; // link to outer (older) area public: // Constructor - HandleArea(HandleArea* prev) { + HandleArea(HandleArea* prev) : Arena(Chunk::tiny_size) { debug_only(_handle_mark_nesting = 0); debug_only(_no_handle_mark_nesting = 0); _prev = prev; From 85fedf271478c4b4a6c678769c74b935a4b71bc0 Mon Sep 17 00:00:00 2001 From: Goetz Lindenmaier Date: Mon, 8 Jul 2013 14:15:02 -0700 Subject: [PATCH 049/156] 8020059: The flag introduced by 8014972 is not defined if Hotspot is built without a compiler (zero, ppc64 core build) Define CodeCacheMinimumUseSpace flag for cppInterpeter build. Reviewed-by: kvn --- hotspot/src/share/vm/runtime/globals.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index d07785d0b61..f8e4ae1f7e1 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -175,6 +175,7 @@ define_pd_global(intx, InitialCodeCacheSize, 160*K); define_pd_global(intx, ReservedCodeCacheSize, 32*M); define_pd_global(intx, CodeCacheExpansionSize, 32*K); define_pd_global(intx, CodeCacheMinBlockLength, 1); +define_pd_global(intx, CodeCacheMinimumUseSpace, 200*K); define_pd_global(uintx,MetaspaceSize, ScaleForWordSize(4*M)); define_pd_global(bool, NeverActAsServerClassMachine, true); define_pd_global(uint64_t,MaxRAM, 1ULL*G); From 65405fd6138100c59f9d9e884b5281118055119a Mon Sep 17 00:00:00 2001 From: Eric Mccorkle Date: Mon, 8 Jul 2013 19:36:22 -0400 Subject: [PATCH 050/156] 8014399: Remove JVM_SetProtectionDomain from hotspot JVM_SetProtectionDomain has been deprecated since 1.5 and is being removed Reviewed-by: coleenp, hseigel --- hotspot/make/bsd/makefiles/mapfile-vers-debug | 1 - .../make/bsd/makefiles/mapfile-vers-product | 1 - .../make/linux/makefiles/mapfile-vers-debug | 1 - .../make/linux/makefiles/mapfile-vers-product | 1 - hotspot/make/solaris/makefiles/mapfile-vers | 1 - .../src/share/vm/classfile/javaClasses.hpp | 2 +- hotspot/src/share/vm/prims/jvm.cpp | 20 ------------------- hotspot/src/share/vm/prims/jvm.h | 3 --- 8 files changed, 1 insertion(+), 29 deletions(-) diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-debug b/hotspot/make/bsd/makefiles/mapfile-vers-debug index d371239ab06..9a8fc822bc4 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-debug +++ b/hotspot/make/bsd/makefiles/mapfile-vers-debug @@ -221,7 +221,6 @@ _JVM_SetLength _JVM_SetNativeThreadName _JVM_SetPrimitiveArrayElement - _JVM_SetProtectionDomain _JVM_SetSockOpt _JVM_SetThreadPriority _JVM_Sleep diff --git a/hotspot/make/bsd/makefiles/mapfile-vers-product b/hotspot/make/bsd/makefiles/mapfile-vers-product index ba9cb516620..d446cc81d84 100644 --- a/hotspot/make/bsd/makefiles/mapfile-vers-product +++ b/hotspot/make/bsd/makefiles/mapfile-vers-product @@ -221,7 +221,6 @@ _JVM_SetLength _JVM_SetNativeThreadName _JVM_SetPrimitiveArrayElement - _JVM_SetProtectionDomain _JVM_SetSockOpt _JVM_SetThreadPriority _JVM_Sleep diff --git a/hotspot/make/linux/makefiles/mapfile-vers-debug b/hotspot/make/linux/makefiles/mapfile-vers-debug index b18fb74fd9a..68be2ffefb3 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-debug +++ b/hotspot/make/linux/makefiles/mapfile-vers-debug @@ -223,7 +223,6 @@ SUNWprivate_1.1 { JVM_SetLength; JVM_SetNativeThreadName; JVM_SetPrimitiveArrayElement; - JVM_SetProtectionDomain; JVM_SetSockOpt; JVM_SetThreadPriority; JVM_Sleep; diff --git a/hotspot/make/linux/makefiles/mapfile-vers-product b/hotspot/make/linux/makefiles/mapfile-vers-product index 168d84c1e90..4641af0af20 100644 --- a/hotspot/make/linux/makefiles/mapfile-vers-product +++ b/hotspot/make/linux/makefiles/mapfile-vers-product @@ -223,7 +223,6 @@ SUNWprivate_1.1 { JVM_SetLength; JVM_SetNativeThreadName; JVM_SetPrimitiveArrayElement; - JVM_SetProtectionDomain; JVM_SetSockOpt; JVM_SetThreadPriority; JVM_Sleep; diff --git a/hotspot/make/solaris/makefiles/mapfile-vers b/hotspot/make/solaris/makefiles/mapfile-vers index 1a0b572a5c6..01b31b6fffb 100644 --- a/hotspot/make/solaris/makefiles/mapfile-vers +++ b/hotspot/make/solaris/makefiles/mapfile-vers @@ -223,7 +223,6 @@ SUNWprivate_1.1 { JVM_SetLength; JVM_SetNativeThreadName; JVM_SetPrimitiveArrayElement; - JVM_SetProtectionDomain; JVM_SetSockOpt; JVM_SetThreadPriority; JVM_Sleep; diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp index 81f5705816c..899d3ba48a3 100644 --- a/hotspot/src/share/vm/classfile/javaClasses.hpp +++ b/hotspot/src/share/vm/classfile/javaClasses.hpp @@ -234,6 +234,7 @@ class java_lang_Class : AllStatic { static GrowableArray* _fixup_mirror_list; static void set_init_lock(oop java_class, oop init_lock); + static void set_protection_domain(oop java_class, oop protection_domain); public: static void compute_offsets(); @@ -272,7 +273,6 @@ class java_lang_Class : AllStatic { // Support for embedded per-class oops static oop protection_domain(oop java_class); - static void set_protection_domain(oop java_class, oop protection_domain); static oop init_lock(oop java_class); static objArrayOop signers(oop java_class); static void set_signers(oop java_class, objArrayOop signers); diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp index da34f2e1316..caed2d13612 100644 --- a/hotspot/src/share/vm/prims/jvm.cpp +++ b/hotspot/src/share/vm/prims/jvm.cpp @@ -1121,26 +1121,6 @@ JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls)) JVM_END -// Obsolete since 1.2 (Class.setProtectionDomain removed), although -// still defined in core libraries as of 1.5. -JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain)) - JVMWrapper("JVM_SetProtectionDomain"); - if (JNIHandles::resolve(cls) == NULL) { - THROW(vmSymbols::java_lang_NullPointerException()); - } - if (!java_lang_Class::is_primitive(JNIHandles::resolve(cls))) { - // Call is ignored for primitive types - Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls)); - - // cls won't be an array, as this called only from ClassLoader.defineClass - if (k->oop_is_instance()) { - oop pd = JNIHandles::resolve(protection_domain); - assert(pd == NULL || pd->is_oop(), "just checking"); - java_lang_Class::set_protection_domain(k->java_mirror(), pd); - } - } -JVM_END - static bool is_authorized(Handle context, instanceKlassHandle klass, TRAPS) { // If there is a security manager and protection domain, check the access // in the protection domain, otherwise it is authorized. diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h index 486b13531af..6248f4d793d 100644 --- a/hotspot/src/share/vm/prims/jvm.h +++ b/hotspot/src/share/vm/prims/jvm.h @@ -471,9 +471,6 @@ JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signers); JNIEXPORT jobject JNICALL JVM_GetProtectionDomain(JNIEnv *env, jclass cls); -JNIEXPORT void JNICALL -JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protection_domain); - JNIEXPORT jboolean JNICALL JVM_IsArrayClass(JNIEnv *env, jclass cls); From 1bc320c73a39ce7fb01ba2c1b609d7efce2bcf30 Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Tue, 9 Jul 2013 11:48:05 +0200 Subject: [PATCH 051/156] 8015635: Crash when specifying very large code cache size Limit the size of the code cache to at most 2G when arguments are checked; added regression test Reviewed-by: kvn, twisti --- hotspot/src/share/vm/runtime/arguments.cpp | 14 +++++- .../compiler/codecache/CheckUpperLimit.java | 47 +++++++++++++++++++ 2 files changed, 59 insertions(+), 2 deletions(-) create mode 100644 hotspot/test/compiler/codecache/CheckUpperLimit.java diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index c52959d6976..7f3e09c270c 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -1855,8 +1855,13 @@ bool Arguments::check_gc_consistency() { "please refer to the release notes for the combinations " "allowed\n"); status = false; + } else if (ReservedCodeCacheSize > 2*G) { + // Code cache size larger than MAXINT is not supported. + jio_fprintf(defaultStream::error_stream(), + "Invalid ReservedCodeCacheSize=%dM. Must be at most %uM.\n", ReservedCodeCacheSize/M, + (2*G)/M); + status = false; } - return status; } @@ -2239,8 +2244,13 @@ bool Arguments::check_vm_args_consistency() { "Invalid ReservedCodeCacheSize=%dK. Must be at least %uK.\n", ReservedCodeCacheSize/K, min_code_cache_size/K); status = false; + } else if (ReservedCodeCacheSize > 2*G) { + // Code cache size larger than MAXINT is not supported. + jio_fprintf(defaultStream::error_stream(), + "Invalid ReservedCodeCacheSize=%dM. Must be at most %uM.\n", ReservedCodeCacheSize/M, + (2*G)/M); + status = false; } - return status; } diff --git a/hotspot/test/compiler/codecache/CheckUpperLimit.java b/hotspot/test/compiler/codecache/CheckUpperLimit.java new file mode 100644 index 00000000000..5e4803226d5 --- /dev/null +++ b/hotspot/test/compiler/codecache/CheckUpperLimit.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8015635 + * @summary Test ensures that the ReservedCodeCacheSize is at most MAXINT + * @library /testlibrary + * + */ +import com.oracle.java.testlibrary.*; + +public class CheckUpperLimit { + public static void main(String[] args) throws Exception { + ProcessBuilder pb; + OutputAnalyzer out; + + pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2048m", "-version"); + out = new OutputAnalyzer(pb.start()); + out.shouldHaveExitValue(0); + + pb = ProcessTools.createJavaProcessBuilder("-XX:ReservedCodeCacheSize=2049m", "-version"); + out = new OutputAnalyzer(pb.start()); + out.shouldContain("Invalid ReservedCodeCacheSize="); + out.shouldHaveExitValue(1); + } +} From 3e0c71b6c11e9b87e6e510915e8ecbe0b1e90bbf Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Tue, 9 Jul 2013 13:57:24 +0200 Subject: [PATCH 052/156] 8009758: reactivate the 8006529 test Reviewed-by: jlaskey, sundar --- .../jdk/nashorn/internal/codegen/Attr.java | 18 ++- .../internal/codegen/CompilerConstants.java | 4 +- .../codegen/ObjectClassGenerator.java | 4 +- .../nashorn/internal/codegen/types/Type.java | 66 ++++----- .../internal/runtime/AccessorProperty.java | 7 +- .../internal/runtime/FunctionScope.java | 4 +- .../JDK-8006529.js | 131 +++++++++++------- 7 files changed, 134 insertions(+), 100 deletions(-) rename nashorn/test/script/{currently-failing => trusted}/JDK-8006529.js (68%) diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index 6dbfa6d4c9b..e076825dfe0 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -94,7 +94,6 @@ import jdk.nashorn.internal.runtime.DebugLogger; import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; -import jdk.nashorn.internal.runtime.ScriptObject; /** * This is the attribution pass of the code generator. Attr takes Lowered IR, @@ -166,19 +165,19 @@ final class Attr extends NodeOperatorVisitor { } private void initFunctionWideVariables(final FunctionNode functionNode, final Block body) { - initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL, FunctionNode.FUNCTION_TYPE); + initCompileConstant(CALLEE, body, IS_PARAM | IS_INTERNAL); initCompileConstant(THIS, body, IS_PARAM | IS_THIS, Type.OBJECT); if (functionNode.isVarArg()) { - initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL, Type.OBJECT_ARRAY); + initCompileConstant(VARARGS, body, IS_PARAM | IS_INTERNAL); if (functionNode.needsArguments()) { - initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.typeFor(ScriptObject.class)); + initCompileConstant(ARGUMENTS, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); addLocalDef(ARGUMENTS.symbolName()); } } initParameters(functionNode, body); - initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.typeFor(ScriptObject.class)); + initCompileConstant(SCOPE, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED); initCompileConstant(RETURN, body, IS_VAR | IS_INTERNAL | IS_ALWAYS_DEFINED, Type.OBJECT); } @@ -1424,9 +1423,16 @@ final class Attr extends NodeOperatorVisitor { return end(ensureSymbol(type, ternaryNode)); } + private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags) { + final Class type = cc.type(); + // Must not call this method for constants with no explicit types; use the one with (..., Type) signature instead. + assert type != null; + initCompileConstant(cc, block, flags, Type.typeFor(type)); + } + private void initCompileConstant(final CompilerConstants cc, final Block block, final int flags, final Type type) { final Symbol symbol = defineSymbol(block, cc.symbolName(), flags); - newType(symbol, type); + symbol.setTypeOverride(type); symbol.setNeedsSlot(true); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java index 3deff98c00a..c8ccc1cedc1 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java @@ -100,10 +100,10 @@ public enum CompilerConstants { CALLEE(":callee", ScriptFunction.class), /** the varargs variable when necessary */ - VARARGS(":varargs"), + VARARGS(":varargs", Object[].class), /** the arguments vector when necessary and the slot */ - ARGUMENTS("arguments", Object.class, 2), + ARGUMENTS("arguments", ScriptObject.class, 2), /** prefix for iterators for for (x in ...) */ ITERATOR_PREFIX(":i", Iterator.class), diff --git a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java index 7d61db1f691..fa3d19e5d05 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/ObjectClassGenerator.java @@ -435,13 +435,13 @@ public final class ObjectClassGenerator { * @return Open method emitter. */ private static MethodEmitter newInitScopeWithArgumentsMethod(final ClassEmitter classEmitter) { - final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, Object.class); + final MethodEmitter init = classEmitter.init(PropertyMap.class, ScriptObject.class, ScriptObject.class); init.begin(); init.load(Type.OBJECT, JAVA_THIS.slot()); init.load(Type.OBJECT, INIT_MAP.slot()); init.load(Type.OBJECT, INIT_SCOPE.slot()); init.load(Type.OBJECT, INIT_ARGUMENTS.slot()); - init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, Object.class)); + init.invoke(constructorNoLookup(FunctionScope.class, PropertyMap.class, ScriptObject.class, ScriptObject.class)); return init; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java index ab32a779703..c1e8bfbb432 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java @@ -47,9 +47,8 @@ import static jdk.internal.org.objectweb.asm.Opcodes.T_INT; import static jdk.internal.org.objectweb.asm.Opcodes.T_LONG; import java.lang.invoke.MethodHandle; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.nashorn.internal.codegen.CompilerConstants.Call; @@ -548,19 +547,19 @@ public abstract class Type implements Comparable, BytecodeOps { * @return the Type representing this class */ public static Type typeFor(final Class clazz) { - Type type = cache.get(clazz); - - if (type == null) { - assert !clazz.isPrimitive() || clazz == void.class; - if (clazz.isArray()) { - type = new ArrayType(clazz); - } else { - type = new ObjectType(clazz); - } - cache.put(clazz, type); + final Type type = cache.get(clazz); + if(type != null) { + return type; } - - return type; + assert !clazz.isPrimitive() || clazz == void.class; + final Type newType; + if (clazz.isArray()) { + newType = new ArrayType(clazz); + } else { + newType = new ObjectType(clazz); + } + final Type existingType = cache.putIfAbsent(clazz, newType); + return existingType == null ? newType : existingType; } @Override @@ -663,35 +662,38 @@ public abstract class Type implements Comparable, BytecodeOps { } } + /** Mappings between java classes and their Type singletons */ + private static final ConcurrentMap, Type> cache = new ConcurrentHashMap<>(); + /** * This is the boolean singleton, used for all boolean types */ - public static final Type BOOLEAN = new BooleanType(); + public static final Type BOOLEAN = putInCache(new BooleanType()); /** * This is an integer type, i.e INT, INT32. */ - public static final Type INT = new IntType(); + public static final Type INT = putInCache(new IntType()); /** * This is the number singleton, used for all number types */ - public static final Type NUMBER = new NumberType(); + public static final Type NUMBER = putInCache(new NumberType()); /** * This is the long singleton, used for all long types */ - public static final Type LONG = new LongType(); + public static final Type LONG = putInCache(new LongType()); /** * A string singleton */ - public static final Type STRING = new ObjectType(String.class); + public static final Type STRING = putInCache(new ObjectType(String.class)); /** * This is the object singleton, used for all object types */ - public static final Type OBJECT = new ObjectType(); + public static final Type OBJECT = putInCache(new ObjectType()); /** * This is the singleton for integer arrays @@ -775,13 +777,13 @@ public abstract class Type implements Comparable, BytecodeOps { }; /** Singleton for method handle arrays used for properties etc. */ - public static final ArrayType METHODHANDLE_ARRAY = new ArrayType(MethodHandle[].class); + public static final ArrayType METHODHANDLE_ARRAY = putInCache(new ArrayType(MethodHandle[].class)); /** This is the singleton for string arrays */ - public static final ArrayType STRING_ARRAY = new ArrayType(String[].class); + public static final ArrayType STRING_ARRAY = putInCache(new ArrayType(String[].class)); /** This is the singleton for object arrays */ - public static final ArrayType OBJECT_ARRAY = new ArrayType(Object[].class); + public static final ArrayType OBJECT_ARRAY = putInCache(new ArrayType(Object[].class)); /** This type, always an object type, just a toString override */ public static final Type THIS = new ObjectType() { @@ -855,18 +857,8 @@ public abstract class Type implements Comparable, BytecodeOps { } }; - /** Mappings between java classes and their Type singletons */ - private static final Map, Type> cache = Collections.synchronizedMap(new HashMap, Type>()); - - //TODO may need to be cleared, as all types are retained throughout code generation - static { - cache.put(BOOLEAN.getTypeClass(), BOOLEAN); - cache.put(INT.getTypeClass(), INT); - cache.put(LONG.getTypeClass(), LONG); - cache.put(NUMBER.getTypeClass(), NUMBER); - cache.put(STRING.getTypeClass(), STRING); - cache.put(OBJECT.getTypeClass(), OBJECT); - cache.put(OBJECT_ARRAY.getTypeClass(), OBJECT_ARRAY); + private static T putInCache(T type) { + cache.put(type.getTypeClass(), type); + return type; } - } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java index f7ece9df533..f1f0ebe33c0 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java @@ -248,11 +248,10 @@ public class AccessorProperty extends Property { primitiveSetter = null; if (isParameter() && hasArguments()) { - final MethodHandle arguments = MH.getter(lookup, structure, "arguments", Object.class); - final MethodHandle argumentsSO = MH.asType(arguments, arguments.type().changeReturnType(ScriptObject.class)); + final MethodHandle arguments = MH.getter(lookup, structure, "arguments", ScriptObject.class); - objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.GET_OBJECT_TYPE); - objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, argumentsSO), 1, slot), Lookup.SET_OBJECT_TYPE); + objectGetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.GET_ARGUMENT.methodHandle(), 0, arguments), 1, slot), Lookup.GET_OBJECT_TYPE); + objectSetter = MH.asType(MH.insertArguments(MH.filterArguments(ScriptObject.SET_ARGUMENT.methodHandle(), 0, arguments), 1, slot), Lookup.SET_OBJECT_TYPE); } else { final GettersSetters gs = GETTERS_SETTERS.get(structure); objectGetter = gs.getters[slot]; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java index 59a9d5ede03..b3872c45cd7 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/FunctionScope.java @@ -41,7 +41,7 @@ package jdk.nashorn.internal.runtime; public class FunctionScope extends ScriptObject implements Scope { /** Area to store scope arguments. (public for access from scripts.) */ - public final Object arguments; + public final ScriptObject arguments; /** Flag to indicate that a split method issued a return statement */ private int splitState = -1; @@ -53,7 +53,7 @@ public class FunctionScope extends ScriptObject implements Scope { * @param callerScope caller scope * @param arguments arguments */ - public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final Object arguments) { + public FunctionScope(final PropertyMap map, final ScriptObject callerScope, final ScriptObject arguments) { super(callerScope, map); this.arguments = arguments; setIsScope(); diff --git a/nashorn/test/script/currently-failing/JDK-8006529.js b/nashorn/test/script/trusted/JDK-8006529.js similarity index 68% rename from nashorn/test/script/currently-failing/JDK-8006529.js rename to nashorn/test/script/trusted/JDK-8006529.js index ca21f0b9c48..378cd6cf7a6 100644 --- a/nashorn/test/script/currently-failing/JDK-8006529.js +++ b/nashorn/test/script/trusted/JDK-8006529.js @@ -39,30 +39,35 @@ * and FunctionNode because of package-access check and so reflective calls. */ -var Parser = Java.type("jdk.nashorn.internal.parser.Parser") -var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler") -var Context = Java.type("jdk.nashorn.internal.runtime.Context") -var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment") -var Source = Java.type("jdk.nashorn.internal.runtime.Source") -var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode") -var ThrowErrorManager = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager"); +var forName = java.lang.Class["forName(String)"] + +var Parser = forName("jdk.nashorn.internal.parser.Parser").static +var Compiler = forName("jdk.nashorn.internal.codegen.Compiler").static +var Context = forName("jdk.nashorn.internal.runtime.Context").static +var ScriptEnvironment = forName("jdk.nashorn.internal.runtime.ScriptEnvironment").static +var Source = forName("jdk.nashorn.internal.runtime.Source").static +var FunctionNode = forName("jdk.nashorn.internal.ir.FunctionNode").static +var Block = forName("jdk.nashorn.internal.ir.Block").static +var VarNode = forName("jdk.nashorn.internal.ir.VarNode").static +var ExecuteNode = forName("jdk.nashorn.internal.ir.ExecuteNode").static +var UnaryNode = forName("jdk.nashorn.internal.ir.UnaryNode").static +var BinaryNode = forName("jdk.nashorn.internal.ir.BinaryNode").static +var ThrowErrorManager = forName("jdk.nashorn.internal.runtime.Context$ThrowErrorManager").static +var Debug = forName("jdk.nashorn.internal.runtime.Debug").static -// Compiler class methods and fields var parseMethod = Parser.class.getMethod("parse"); -var compileMethod = Compiler.class.getMethod("compile"); - -// NOTE: private field. But this is a trusted test! -// Compiler.functionNode -var functionNodeField = Compiler.class.getDeclaredField("functionNode"); -functionNodeField.setAccessible(true); - -// FunctionNode methods - -// FunctionNode.getFunctions method -var getFunctionsMethod = FunctionNode.class.getMethod("getFunctions"); +var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class); +var getBodyMethod = FunctionNode.class.getMethod("getBody"); +var getStatementsMethod = Block.class.getMethod("getStatements"); +var getInitMethod = VarNode.class.getMethod("getInit"); +var getExpressionMethod = ExecuteNode.class.getMethod("getExpression") +var rhsMethod = UnaryNode.class.getMethod("rhs") +var lhsMethod = BinaryNode.class.getMethod("lhs") +var binaryRhsMethod = BinaryNode.class.getMethod("rhs") +var debugIdMethod = Debug.class.getMethod("id", java.lang.Object.class) // These are method names of methods in FunctionNode class -var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'needsScope', 'needsSelfSymbol', 'isSplit', 'hasEval', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope', 'isStrictMode'] +var allAssertionList = ['isVarArg', 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'needsSelfSymbol', 'isSplit', 'hasEval', 'allVarsInScope', 'isStrict'] // corresponding Method objects of FunctionNode class var functionNodeMethods = {}; @@ -74,30 +79,54 @@ var functionNodeMethods = {}; } })(); -// returns "script" functionNode from Compiler instance -function getScriptNode(compiler) { - // compiler.functionNode - return functionNodeField.get(compiler); +// returns functionNode.getBody().getStatements().get(0) +function getFirstFunction(functionNode) { + var f = findFunction(getBodyMethod.invoke(functionNode)) + if (f == null) { + throw new Error(); + } + return f; } -// returns functionNode.getFunctions().get(0) -function getFirstFunction(functionNode) { - // functionNode.getFunctions().get(0) - return getFunctionsMethod.invoke(functionNode).get(0); +function findFunction(node) { + if(node instanceof Block) { + var stmts = getStatementsMethod.invoke(node) + for(var i = 0; i < stmts.size(); ++i) { + var retval = findFunction(stmts.get(i)) + if(retval != null) { + return retval; + } + } + } else if(node instanceof VarNode) { + return findFunction(getInitMethod.invoke(node)) + } else if(node instanceof UnaryNode) { + return findFunction(rhsMethod.invoke(node)) + } else if(node instanceof BinaryNode) { + return findFunction(lhsMethod.invoke(node)) || findFunction(binaryRhsMethod.invoke(node)) + } else if(node instanceof ExecuteNode) { + return findFunction(getExpressionMethod.invoke(node)) + } else if(node instanceof FunctionNode) { + return node + } } +var getContextMethod = Context.class.getMethod("getContext") +var getEnvMethod = Context.class.getMethod("getEnv") + // compile(script) -- compiles a script specified as a string with its // source code, returns a jdk.nashorn.internal.ir.FunctionNode object // representing it. function compile(source) { var source = new Source("", source); - var parser = new Parser(Context.getContext().getEnv(), source, new ThrowErrorManager()); + + var env = getEnvMethod.invoke(getContextMethod.invoke(null)) + + var parser = new Parser(env, source, new ThrowErrorManager()); var func = parseMethod.invoke(parser); - var compiler = new Compiler(Context.getContext().getEnv(), func); - compileMethod.invoke(compiler); + var compiler = new Compiler(env); - return getScriptNode(compiler); + return compileMethod.invoke(compiler, func); }; var allAssertions = (function() { @@ -122,8 +151,9 @@ function test(f) { } for(var assertion in allAssertions) { var expectedValue = !!assertions[assertion] - if(functionNodeMethods[assertion].invoke(f) !== expectedValue) { - throw "Expected " + assertion + " === " + expectedValue + " for " + f; + var actualValue = functionNodeMethods[assertion].invoke(f) + if(actualValue !== expectedValue) { + throw "Expected " + assertion + " === " + expectedValue + ", got " + actualValue + " for " + f + ":" + debugIdMethod.invoke(null, f); } } } @@ -152,7 +182,7 @@ testFirstFn("function f() { arguments }", 'needsCallee', 'isVarArg') // A function referencing "arguments" will have to be vararg. If it is // strict, it will not have to have a callee, though. -testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrictMode') +testFirstFn("function f() {'use strict'; arguments }", 'isVarArg', 'isStrict') // A function defining "arguments" as a parameter will not be vararg. testFirstFn("function f(arguments) { arguments }") @@ -173,11 +203,11 @@ testFirstFn("(function f() { f() })", 'needsCallee', 'needsSelfSymbol') // A child function accessing parent's variable triggers the need for scope // in parent -testFirstFn("(function f() { var x; function g() { x } })", 'needsScope') +testFirstFn("(function f() { var x; function g() { x } })", 'hasScopeBlock') // A child function accessing parent's parameter triggers the need for scope // in parent -testFirstFn("(function f(x) { function g() { x } })", 'needsScope') +testFirstFn("(function f(x) { function g() { x } })", 'hasScopeBlock') // A child function accessing a global variable triggers the need for parent // scope in parent @@ -187,22 +217,29 @@ testFirstFn("(function f() { function g() { x } })", 'needsParentScope', 'needsC // affect the parent function in any way testFirstFn("(function f() { var x; function g() { var x; x } })") -// Using "with" unleashes a lot of needs: parent scope, callee, own scope, -// and all variables in scope. Actually, we could make "with" less wasteful, -// and only put those variables in scope that it actually references, similar -// to what nested functions do with variables in their parents. -testFirstFn("(function f() { var o; with(o) {} })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasWith', 'hasDeepWithOrEval', 'allVarsInScope') +// Using "with" on its own doesn't do much. +testFirstFn("(function f() { var o; with(o) {} })") -// Using "eval" is as bad as using "with" with the added requirement of -// being vararg, 'cause we don't know if eval will be using "arguments". -testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasEval', 'isVarArg', 'hasDeepWithOrEval', 'allVarsInScope') +// "with" referencing a local variable triggers scoping. +testFirstFn("(function f() { var x; var y; with(x) { y } })", 'hasScopeBlock') + +// "with" referencing a non-local variable triggers parent scope. +testFirstFn("(function f() { var x; with(x) { y } })", 'needsCallee', 'needsParentScope') // Nested function using "with" is pretty much the same as the parent // function needing with. -testFirstFn("(function f() { function g() { var o; with(o) {} } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope') +testFirstFn("(function f() { function g() { var o; with(o) {} } })") + +// Nested function using "with" referencing a local variable. +testFirstFn("(function f() { var x; function g() { var o; with(o) { x } } })", 'hasScopeBlock') + +// Using "eval" triggers pretty much everything. The function even needs to be +// vararg, 'cause we don't know if eval will be using "arguments". +testFirstFn("(function f() { eval() })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'hasEval', 'isVarArg', 'allVarsInScope') + // Nested function using "eval" is almost the same as parent function using // eval, but at least the parent doesn't have to be vararg. -testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'needsScope', 'hasDeepWithOrEval', 'allVarsInScope') +testFirstFn("(function f() { function g() { eval() } })", 'needsParentScope', 'needsCallee', 'hasScopeBlock', 'allVarsInScope') // Function with 250 named parameters is ordinary testFirstFn("function f(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, p17, p18, p19, p20, p21, p22, p23, p24, p25, p26, p27, p28, p29, p30, p31, p32, p33, p34, p35, p36, p37, p38, p39, p40, p41, p42, p43, p44, p45, p46, p47, p48, p49, p50, p51, p52, p53, p54, p55, p56, p57, p58, p59, p60, p61, p62, p63, p64, p65, p66, p67, p68, p69, p70, p71, p72, p73, p74, p75, p76, p77, p78, p79, p80, p81, p82, p83, p84, p85, p86, p87, p88, p89, p90, p91, p92, p93, p94, p95, p96, p97, p98, p99, p100, p101, p102, p103, p104, p105, p106, p107, p108, p109, p110, p111, p112, p113, p114, p115, p116, p117, p118, p119, p120, p121, p122, p123, p124, p125, p126, p127, p128, p129, p130, p131, p132, p133, p134, p135, p136, p137, p138, p139, p140, p141, p142, p143, p144, p145, p146, p147, p148, p149, p150, p151, p152, p153, p154, p155, p156, p157, p158, p159, p160, p161, p162, p163, p164, p165, p166, p167, p168, p169, p170, p171, p172, p173, p174, p175, p176, p177, p178, p179, p180, p181, p182, p183, p184, p185, p186, p187, p188, p189, p190, p191, p192, p193, p194, p195, p196, p197, p198, p199, p200, p201, p202, p203, p204, p205, p206, p207, p208, p209, p210, p211, p212, p213, p214, p215, p216, p217, p218, p219, p220, p221, p222, p223, p224, p225, p226, p227, p228, p229, p230, p231, p232, p233, p234, p235, p236, p237, p238, p239, p240, p241, p242, p243, p244, p245, p246, p247, p248, p249, p250) { p250 = p249 }") From 8854b24a3034df1b4751789d403ae7a8205abf23 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Tue, 9 Jul 2013 17:37:46 +0530 Subject: [PATCH 053/156] 8014785: Ability to extend global instance by binding properties of another object Reviewed-by: attila, hannesw, jlaskey, lagergren --- .../internal/objects/NativeObject.java | 116 ++++++++++++++++++ .../internal/runtime/AccessorProperty.java | 4 +- .../jdk/nashorn/internal/runtime/Context.java | 8 +- .../nashorn/internal/runtime/PropertyMap.java | 2 +- .../internal/runtime/ScriptObject.java | 32 ++++- .../internal/runtime/linker/InvokeByName.java | 2 +- nashorn/test/script/basic/JDK-8014785.js | 62 ++++++++++ .../test/script/basic/JDK-8014785.js.EXPECTED | 8 ++ 8 files changed, 224 insertions(+), 10 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8014785.js create mode 100644 nashorn/test/script/basic/JDK-8014785.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java index 6e4791bd20c..c8bff8b0203 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java @@ -27,18 +27,24 @@ package jdk.nashorn.internal.objects; import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED; + +import java.lang.invoke.MethodHandle; +import java.util.ArrayList; import jdk.nashorn.api.scripting.ScriptObjectMirror; import jdk.nashorn.internal.objects.annotations.Attribute; import jdk.nashorn.internal.objects.annotations.Constructor; import jdk.nashorn.internal.objects.annotations.Function; import jdk.nashorn.internal.objects.annotations.ScriptClass; import jdk.nashorn.internal.objects.annotations.Where; +import jdk.nashorn.internal.runtime.AccessorProperty; import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.JSType; +import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; +import jdk.nashorn.internal.runtime.linker.Bootstrap; import jdk.nashorn.internal.runtime.linker.InvokeByName; /** @@ -471,4 +477,114 @@ public final class NativeObject { return false; } + + /** + * Nashorn extension: Object.bindProperties + * + * Binds the source object's properties to the target object. Binding + * properties allows two-way read/write for the properties of the source object. + * + * Example: + *
    +     * var obj = { x: 34, y: 100 };
    +     * var foo = {}
    +     *
    +     * // bind properties of "obj" to "foo" object
    +     * Object.bindProperties(foo, obj);
    +     *
    +     * // now, we can access/write on 'foo' properties
    +     * print(foo.x); // prints obj.x which is 34
    +     *
    +     * // update obj.x via foo.x
    +     * foo.x = "hello";
    +     * print(obj.x); // prints "hello" now
    +     *
    +     * obj.x = 42;   // foo.x also becomes 42
    +     * print(foo.x); // prints 42
    +     * 
    + *

    + * The source object bound can be a ScriptObject or a ScriptOjectMirror. + * null or undefined source object results in TypeError being thrown. + *

    + * Example: + *
    +     * var obj = loadWithNewGlobal({
    +     *    name: "test",
    +     *    script: "obj = { x: 33, y: 'hello' }"
    +     * });
    +     *
    +     * // bind 'obj's properties to global scope 'this'
    +     * Object.bindProperties(this, obj);
    +     * print(x);         // prints 33
    +     * print(y);         // prints "hello"
    +     * x = Math.PI;      // changes obj.x to Math.PI
    +     * print(obj.x);     // prints Math.PI
    +     * 
    + * + * Limitations of property binding: + *
      + *
    • Only enumerable, immediate (not proto inherited) properties of the source object are bound. + *
    • If the target object already contains a property called "foo", the source's "foo" is skipped (not bound). + *
    • Properties added to the source object after binding to the target are not bound. + *
    • Property configuration changes on the source object (or on the target) is not propagated. + *
    • Delete of property on the target (or the source) is not propagated - + * only the property value is set to 'undefined' if the property happens to be a data property. + *
    + *

    + * It is recommended that the bound properties be treated as non-configurable + * properties to avoid surprises. + *

    + * + * @param self self reference + * @param target the target object to which the source object's properties are bound + * @param source the source object whose properties are bound to the target + * @return the target object after property binding + */ + @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) + public static Object bindProperties(final Object self, final Object target, final Object source) { + // target object has to be a ScriptObject + Global.checkObject(target); + // check null or undefined source object + Global.checkObjectCoercible(source); + + final ScriptObject targetObj = (ScriptObject)target; + + if (source instanceof ScriptObject) { + final ScriptObject sourceObj = (ScriptObject)source; + final Property[] properties = sourceObj.getMap().getProperties(); + + // filter non-enumerable properties + final ArrayList propList = new ArrayList<>(); + for (Property prop : properties) { + if (prop.isEnumerable()) { + propList.add(prop); + } + } + + if (! propList.isEmpty()) { + targetObj.addBoundProperties(sourceObj, propList.toArray(new Property[propList.size()])); + } + } else if (source instanceof ScriptObjectMirror) { + // get enumerable, immediate properties of mirror + final ScriptObjectMirror mirror = (ScriptObjectMirror)source; + final String[] keys = mirror.getOwnKeys(false); + if (keys.length == 0) { + // nothing to bind + return target; + } + + // make accessor properties using dynamic invoker getters and setters + final AccessorProperty[] props = new AccessorProperty[keys.length]; + for (int idx = 0; idx < keys.length; idx++) { + final String name = keys[idx]; + final MethodHandle getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, Object.class, ScriptObjectMirror.class); + final MethodHandle setter = Bootstrap.createDynamicInvoker("dyn:setProp|setElem:" + name, Object.class, ScriptObjectMirror.class, Object.class); + props[idx] = (AccessorProperty.create(name, 0, getter, setter)); + } + + targetObj.addBoundProperties(source, props); + } + + return target; + } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java index f1f0ebe33c0..c9d2a04229f 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java @@ -147,9 +147,9 @@ public class AccessorProperty extends Property { * and are thus rebound with that as receiver * * @param property accessor property to rebind - * @param delegate delegate script object to rebind receiver to + * @param delegate delegate object to rebind receiver to */ - public AccessorProperty(final AccessorProperty property, final ScriptObject delegate) { + public AccessorProperty(final AccessorProperty property, final Object delegate) { super(property); this.primitiveGetter = bindTo(property.primitiveGetter, delegate); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 8f00d52127e..7d639cd31c3 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -199,6 +199,7 @@ public final class Context { private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; + private static final AccessControlContext NO_PERMISSIONS_CONTEXT; static { sharedLoader = AccessController.doPrivileged(new PrivilegedAction() { @@ -207,6 +208,7 @@ public final class Context { return new StructureLoader(myLoader, null); } }); + NO_PERMISSIONS_CONTEXT = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); } /** @@ -564,7 +566,7 @@ public final class Context { sm.checkPackageAccess(fullName.substring(0, index)); return null; } - }, createNoPermissionsContext()); + }, NO_PERMISSIONS_CONTEXT); } } @@ -707,10 +709,6 @@ public final class Context { return (context != null) ? context : Context.getContextTrusted(); } - private static AccessControlContext createNoPermissionsContext() { - return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); - } - private Object evaluateSource(final Source source, final ScriptObject scope, final ScriptObject thiz) { ScriptFunction script = null; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java index 05e8dc78235..511ff666cd5 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/PropertyMap.java @@ -260,7 +260,7 @@ public final class PropertyMap implements Iterable, PropertyListener { * * @return New {@link PropertyMap} with {@link Property} added. */ - PropertyMap addPropertyBind(final AccessorProperty property, final ScriptObject bindTo) { + PropertyMap addPropertyBind(final AccessorProperty property, final Object bindTo) { return addProperty(new AccessorProperty(property, bindTo)); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java index c56c32c7257..f770bd65a6f 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java @@ -203,9 +203,19 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr * @param source The source object to copy from. */ public void addBoundProperties(final ScriptObject source) { + addBoundProperties(source, source.getMap().getProperties()); + } + + /** + * Copy all properties from the array with their receiver bound to the source. + * + * @param source The source object to copy from. + * @param properties The array of properties to copy. + */ + public void addBoundProperties(final ScriptObject source, final Property[] properties) { PropertyMap newMap = this.getMap(); - for (final Property property : source.getMap().getProperties()) { + for (final Property property : properties) { final String key = property.getKey(); if (newMap.findProperty(key) == null) { @@ -221,6 +231,26 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr this.setMap(newMap); } + /** + * Copy all properties from the array with their receiver bound to the source. + * + * @param source The source object to copy from. + * @param properties The collection of accessor properties to copy. + */ + public void addBoundProperties(final Object source, final AccessorProperty[] properties) { + PropertyMap newMap = this.getMap(); + + for (final AccessorProperty property : properties) { + final String key = property.getKey(); + + if (newMap.findProperty(key) == null) { + newMap = newMap.addPropertyBind(property, source); + } + } + + this.setMap(newMap); + } + /** * Bind the method handle to the specified receiver, while preserving its original type (it will just ignore the * first argument in lieu of the bound argument). diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java index 4bfb6851c08..efec5b44738 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/InvokeByName.java @@ -83,7 +83,7 @@ public class InvokeByName { */ public InvokeByName(final String name, final Class targetClass, final Class rtype, final Class... ptypes) { this.name = name; - getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getItem:" + name, Object.class, targetClass); + getter = Bootstrap.createDynamicInvoker("dyn:getMethod|getProp|getElem:" + name, Object.class, targetClass); final Class[] finalPtypes; final int plength = ptypes.length; diff --git a/nashorn/test/script/basic/JDK-8014785.js b/nashorn/test/script/basic/JDK-8014785.js new file mode 100644 index 00000000000..27b05bd1f32 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8014785.js @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8014785: Ability to extend global instance by binding properties of another object + * + * @test + * @run + */ + +var obj = { x: 34, y: 100 }; +var foo = {} + +// bind properties of "obj" to "foo" obj +Object.bindProperties(foo, obj); + +// now we can access/write on foo properties +print("foo.x = " + foo.x); // prints obj.x which is 34 + +// update obj.x via foo.x +foo.x = "hello"; +print("obj.x = " + obj.x); // prints "hello" now + +obj.x = 42; // foo.x also becomes 42 +print("obj.x = " + obj.x); // prints 42 +print("foo.x = " + foo.x); // prints 42 + +// now bind a mirror object to an object +var obj = loadWithNewGlobal({ + name: "test", + script: "obj = { x: 33, y: 'hello' }" +}); + +Object.bindProperties(this, obj); +print("x = " + x); // prints 33 +print("y = " + y); // prints "hello" + +x = Math.PI; // changes obj.x to Math.PI +print("obj.x = " +obj.x); // prints Math.PI + +obj.y = 32; +print("y = " + y); // should print 32 diff --git a/nashorn/test/script/basic/JDK-8014785.js.EXPECTED b/nashorn/test/script/basic/JDK-8014785.js.EXPECTED new file mode 100644 index 00000000000..cb2b154cffe --- /dev/null +++ b/nashorn/test/script/basic/JDK-8014785.js.EXPECTED @@ -0,0 +1,8 @@ +foo.x = 34 +obj.x = hello +obj.x = 42 +foo.x = 42 +x = 33 +y = hello +obj.x = 3.141592653589793 +y = 32 From 5de04505c1c6e1365f0ebe09f587b954bc9f15cd Mon Sep 17 00:00:00 2001 From: Niclas Adlertz Date: Tue, 9 Jul 2013 17:20:32 +0200 Subject: [PATCH 054/156] 8019625: Test compiler/8005956/PolynomialRoot.java timeouts on Solaris SPARCs Disable the test for SPARC and reduce the number of test iterations Reviewed-by: kvn --- .../test/compiler/8005956/PolynomialRoot.java | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/hotspot/test/compiler/8005956/PolynomialRoot.java b/hotspot/test/compiler/8005956/PolynomialRoot.java index ce896ae651e..1ec220955a5 100644 --- a/hotspot/test/compiler/8005956/PolynomialRoot.java +++ b/hotspot/test/compiler/8005956/PolynomialRoot.java @@ -15,7 +15,7 @@ * @bug 8005956 * @summary C2: assert(!def_outside->member(r)) failed: Use of external LRG overlaps the same LRG defined in this block * -* @run main PolynomialRoot +* @run main/timeout=300 PolynomialRoot */ public class PolynomialRoot { @@ -757,19 +757,26 @@ public static int root4(final double [] p,final double [] re_root,final double [ public static void main(final String [] args) { - final long t0=System.currentTimeMillis(); - final double eps=1e-6; - //checkRoots(); - final java.util.Random r=new java.util.Random(-1381923); - printSpecialValues(); + if (System.getProperty("os.arch").equals("x86") || + System.getProperty("os.arch").equals("amd64") || + System.getProperty("os.arch").equals("x86_64")){ + final long t0=System.currentTimeMillis(); + final double eps=1e-6; + //checkRoots(); + final java.util.Random r=new java.util.Random(-1381923); + printSpecialValues(); - final int n_tests=10000000; - //testRoots(2,n_tests,r,eps); - //testRoots(3,n_tests,r,eps); - testRoots(4,n_tests,r,eps); - final long t1=System.currentTimeMillis(); - System.err.println("PolynomialRoot.main: "+n_tests+" tests OK done in "+(t1-t0)+" milliseconds. ver=$Id: PolynomialRoot.java,v 1.105 2012/08/18 00:00:05 mal Exp $"); - } + final int n_tests=100000; + //testRoots(2,n_tests,r,eps); + //testRoots(3,n_tests,r,eps); + testRoots(4,n_tests,r,eps); + final long t1=System.currentTimeMillis(); + System.err.println("PolynomialRoot.main: "+n_tests+" tests OK done in "+(t1-t0)+" milliseconds. ver=$Id: PolynomialRoot.java,v 1.105 2012/08/18 00:00:05 mal Exp $"); + System.out.println("PASSED"); + } else { + System.out.println("PASS test for non-x86"); + } + } From 94609df5dab9a14b8d7738aec662d703ff225784 Mon Sep 17 00:00:00 2001 From: David Chase Date: Tue, 9 Jul 2013 08:56:04 -0400 Subject: [PATCH 055/156] 8017578: Hotspot compilation error with latest Studio compiler Make the destructor virtual (note more non-compiler hotspot errors occur downstream) Reviewed-by: kvn, twisti --- hotspot/src/share/vm/adlc/forms.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/adlc/forms.hpp b/hotspot/src/share/vm/adlc/forms.hpp index a682e65a36f..63e367dd730 100644 --- a/hotspot/src/share/vm/adlc/forms.hpp +++ b/hotspot/src/share/vm/adlc/forms.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -146,7 +146,7 @@ public: // Public Methods Form(int formType=0, int line=0) : _next(NULL), _linenum(line), _ftype(formType) { }; - ~Form() {}; + virtual ~Form() {}; virtual bool ideal_only() const { assert(0,"Check of ideal status on non-instruction/operand form.\n"); From cfbe70e2231e591d8888d654f2148cac5168e147 Mon Sep 17 00:00:00 2001 From: Marcus Lagergren Date: Tue, 9 Jul 2013 15:56:59 +0200 Subject: [PATCH 056/156] 8020124: In the case of an eval switch, we might need explicit conversions of the tag store, as it was not known in the surrounding environment Reviewed-by: sundar, jlaskey --- .../internal/codegen/CodeGenerator.java | 2 ++ nashorn/test/script/basic/JDK-8020124.js | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 nashorn/test/script/basic/JDK-8020124.js diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 79936473fb9..250c44c1541 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -1869,6 +1869,8 @@ final class CodeGenerator extends NodeOperatorVisitor Date: Tue, 9 Jul 2013 18:01:58 +0400 Subject: [PATCH 057/156] 6707231: Wrong read Method returned for boolen properties Reviewed-by: alexsch --- .../classes/java/beans/Introspector.java | 5 +- .../java/beans/Introspector/Test6707231.java | 80 +++++++++++++++++++ 2 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 jdk/test/java/beans/Introspector/Test6707231.java diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java index 65d95eb4e80..783fcbef315 100644 --- a/jdk/src/share/classes/java/beans/Introspector.java +++ b/jdk/src/share/classes/java/beans/Introspector.java @@ -652,11 +652,12 @@ public class Introspector { } } else { if (pd.getReadMethod() != null) { + String pdName = pd.getReadMethod().getName(); if (gpd != null) { // Don't replace the existing read // method if it starts with "is" - Method method = gpd.getReadMethod(); - if (!method.getName().startsWith(IS_PREFIX)) { + String gpdName = gpd.getReadMethod().getName(); + if (gpdName.equals(pdName) || !gpdName.startsWith(IS_PREFIX)) { gpd = new PropertyDescriptor(gpd, pd); } } else { diff --git a/jdk/test/java/beans/Introspector/Test6707231.java b/jdk/test/java/beans/Introspector/Test6707231.java new file mode 100644 index 00000000000..67f935d6ec1 --- /dev/null +++ b/jdk/test/java/beans/Introspector/Test6707231.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.beans.PropertyDescriptor; + +/* + * @test + * @bug 6707231 + * @summary Tests the boolean getter + * @author Sergey Malenkov + */ + +public class Test6707231 { + public static void main(String[] args) throws Exception { + test(Bean.class, Bean.class); + test(Public.class, Public.class); + test(Private.class, Bean.class); + } + + public static class Bean { + private boolean value; + + public boolean isValue() { + return this.value; + } + + public void setValue(boolean value) { + this.value = value; + } + } + + public static class Public extends Bean { + public boolean isValue() { + return super.isValue(); + } + + public void setValue(boolean value) { + super.setValue(value); + } + } + + private static class Private extends Bean { + public boolean isValue() { + return super.isValue(); + } + + public void setValue(boolean value) { + super.setValue(value); + } + } + + private static void test(Class actual, Class expected) { + PropertyDescriptor pd = BeanUtils.getPropertyDescriptor(actual, "value"); + Class getter = pd.getReadMethod().getDeclaringClass(); + Class setter = pd.getWriteMethod().getDeclaringClass(); + if ((getter != expected) || (setter != expected)) { + throw new Error(actual.getName()); + } + } +} From 4382d4055501ee6637a491718cbbd62dbb9955ab Mon Sep 17 00:00:00 2001 From: Zhengyu Gu Date: Tue, 9 Jul 2013 13:18:16 -0400 Subject: [PATCH 058/156] 8011760: assert(delta != 0) failed: dup pointer in MemBaseline::malloc_sort_by_addr Some of qsort implementation on Linux x86 compares element to itself, which is mistakenly treated as duplicate pointer Reviewed-by: dcubed, acorn --- hotspot/src/share/vm/services/memBaseline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hotspot/src/share/vm/services/memBaseline.cpp b/hotspot/src/share/vm/services/memBaseline.cpp index 21eb8b5d422..62e51873c7b 100644 --- a/hotspot/src/share/vm/services/memBaseline.cpp +++ b/hotspot/src/share/vm/services/memBaseline.cpp @@ -486,7 +486,7 @@ int MemBaseline::malloc_sort_by_addr(const void* p1, const void* p2) { const MemPointerRecord* mp1 = (const MemPointerRecord*)p1; const MemPointerRecord* mp2 = (const MemPointerRecord*)p2; int delta = UNSIGNED_COMPARE(mp1->addr(), mp2->addr()); - assert(delta != 0, "dup pointer"); + assert(p1 == p2 || delta != 0, "dup pointer"); return delta; } From b2b2d519cafa52436bd15425cd9592991a1d2b69 Mon Sep 17 00:00:00 2001 From: Sergey Bylokhov Date: Tue, 9 Jul 2013 21:21:55 +0400 Subject: [PATCH 059/156] 8019587: [macosx] Possibility to set the same frame for the different screens Reviewed-by: art, anthony --- .../classes/java/awt/GraphicsDevice.java | 6 ++ .../IncorrectDisplayModeExitFullscreen.java | 94 +++++++++++++++++++ 2 files changed, 100 insertions(+) create mode 100644 jdk/test/java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java diff --git a/jdk/src/share/classes/java/awt/GraphicsDevice.java b/jdk/src/share/classes/java/awt/GraphicsDevice.java index b99d7ef8def..c619a2aee19 100644 --- a/jdk/src/share/classes/java/awt/GraphicsDevice.java +++ b/jdk/src/share/classes/java/awt/GraphicsDevice.java @@ -296,6 +296,12 @@ public abstract class GraphicsDevice { bgColor.getBlue(), 255); w.setBackground(bgColor); } + // Check if this window is in fullscreen mode on another device. + final GraphicsConfiguration gc = w.getGraphicsConfiguration(); + if (gc != null && gc.getDevice() != this + && gc.getDevice().getFullScreenWindow() == w) { + gc.getDevice().setFullScreenWindow(null); + } } if (fullScreenWindow != null && windowedModeBounds != null) { // if the window went into fs mode before it was realized it may diff --git a/jdk/test/java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java b/jdk/test/java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java new file mode 100644 index 00000000000..1d42db8f47d --- /dev/null +++ b/jdk/test/java/awt/GraphicsDevice/IncorrectDisplayModeExitFullscreen.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +import java.awt.Color; +import java.awt.DisplayMode; +import java.awt.Frame; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Toolkit; + +import sun.awt.SunToolkit; + +/** + * @test + * @bug 8019587 + * @author Sergey Bylokhov + */ +public class IncorrectDisplayModeExitFullscreen { + + public static void main(final String[] args) { + + final GraphicsDevice[] devices = + GraphicsEnvironment.getLocalGraphicsEnvironment() + .getScreenDevices(); + if (devices.length < 2 || devices[0].getDisplayModes().length < 2 + || !devices[0].isFullScreenSupported() + || !devices[1].isFullScreenSupported()) { + System.err.println("Testcase is not applicable"); + return; + } + final DisplayMode defaultDM = devices[0].getDisplayMode(); + final DisplayMode[] dms = devices[0].getDisplayModes(); + DisplayMode nonDefaultDM = null; + + for (final DisplayMode dm : dms) { + if (!dm.equals(defaultDM)) { + nonDefaultDM = dm; + break; + } + } + if (nonDefaultDM == null) { + System.err.println("Testcase is not applicable"); + return; + } + + final Frame frame = new Frame(); + frame.setBackground(Color.GREEN); + frame.setUndecorated(true); + try { + devices[0].setFullScreenWindow(frame); + sleep(); + devices[0].setDisplayMode(nonDefaultDM); + sleep(); + devices[1].setFullScreenWindow(frame); + sleep(); + if (!defaultDM.equals(devices[0].getDisplayMode())) { + throw new RuntimeException("DisplayMode is not restored"); + } + } finally { + // cleaning up + devices[0].setFullScreenWindow(null); + devices[1].setFullScreenWindow(null); + frame.dispose(); + } + } + private static void sleep() { + ((SunToolkit) Toolkit.getDefaultToolkit()).realSync(); + try { + Thread.sleep(1500); + } catch (InterruptedException ignored) { + } + } +} From ed46fe2de95379a104a98d831a99577b8aee2325 Mon Sep 17 00:00:00 2001 From: Karen Kinnear Date: Tue, 9 Jul 2013 14:02:28 -0400 Subject: [PATCH 060/156] 8013635: VM should no longer create bridges for generic signatures Requires: 8013789: Compiler bridges, 8015402: metafactory Reviewed-by: sspitsyn, coleenp, bharadwaj --- .../src/share/vm/classfile/defaultMethods.cpp | 638 ++++++++++++------ hotspot/src/share/vm/runtime/globals.hpp | 3 + 2 files changed, 451 insertions(+), 190 deletions(-) diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp index d6529ca4439..3ff2996b3ed 100644 --- a/hotspot/src/share/vm/classfile/defaultMethods.cpp +++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp @@ -318,17 +318,17 @@ class KeepAliveVisitor : public HierarchyVisitor { } }; + // A method family contains a set of all methods that implement a single -// language-level method. Because of erasure, these methods may have different -// signatures. As members of the set are collected while walking over the +// erased method. As members of the set are collected while walking over the // hierarchy, they are tagged with a qualification state. The qualification // state for an erased method is set to disqualified if there exists a path // from the root of hierarchy to the method that contains an interleaving -// language-equivalent method defined in an interface. +// erased method defined in an interface. + class MethodFamily : public ResourceObj { private: - generic::MethodDescriptor* _descriptor; // language-level description GrowableArray > _members; ResourceHashtable _member_index; @@ -358,15 +358,8 @@ class MethodFamily : public ResourceObj { public: - MethodFamily(generic::MethodDescriptor* canonical_desc) - : _descriptor(canonical_desc), _selected_target(NULL), - _exception_message(NULL) {} - - generic::MethodDescriptor* descriptor() const { return _descriptor; } - - bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { - return descriptor()->covariant_match(md, ctx); - } + MethodFamily() + : _selected_target(NULL), _exception_message(NULL) {} void set_target_if_empty(Method* m) { if (_selected_target == NULL && !m->is_overpass()) { @@ -441,16 +434,10 @@ class MethodFamily : public ResourceObj { } #ifndef PRODUCT - void print_on(outputStream* str) const { - print_on(str, 0); - } - - void print_on(outputStream* str, int indent) const { + void print_sig_on(outputStream* str, Symbol* signature, int indent) const { streamIndentor si(str, indent * 2); - generic::Context ctx(NULL); // empty, as _descriptor already canonicalized - TempNewSymbol family = descriptor()->reify_signature(&ctx, Thread::current()); - str->indent().print_cr("Logical Method %s:", family->as_C_string()); + str->indent().print_cr("Logical Method %s:", signature->as_C_string()); streamIndentor si2(str); for (int i = 0; i < _members.length(); ++i) { @@ -516,38 +503,94 @@ Symbol* MethodFamily::generate_conflicts_message(GrowableArray* methods return SymbolTable::new_symbol(ss.base(), (int)ss.size(), CHECK_NULL); } +// A generic method family contains a set of all methods that implement a single +// language-level method. Because of erasure, these methods may have different +// signatures. As members of the set are collected while walking over the +// hierarchy, they are tagged with a qualification state. The qualification +// state for an erased method is set to disqualified if there exists a path +// from the root of hierarchy to the method that contains an interleaving +// language-equivalent method defined in an interface. +class GenericMethodFamily : public MethodFamily { + private: + + generic::MethodDescriptor* _descriptor; // language-level description + + public: + + GenericMethodFamily(generic::MethodDescriptor* canonical_desc) + : _descriptor(canonical_desc) {} + + generic::MethodDescriptor* descriptor() const { return _descriptor; } + + bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { + return descriptor()->covariant_match(md, ctx); + } + +#ifndef PRODUCT + Symbol* get_generic_sig() const { + + generic::Context ctx(NULL); // empty, as _descriptor already canonicalized + TempNewSymbol sig = descriptor()->reify_signature(&ctx, Thread::current()); + return sig; + } +#endif // ndef PRODUCT +}; + class StateRestorer; -// StatefulMethodFamily is a wrapper around MethodFamily that maintains the +// StatefulMethodFamily is a wrapper around a MethodFamily that maintains the // qualification state during hierarchy visitation, and applies that state -// when adding members to the MethodFamily. +// when adding members to the MethodFamily class StatefulMethodFamily : public ResourceObj { friend class StateRestorer; private: - MethodFamily* _method; QualifiedState _qualification_state; void set_qualification_state(QualifiedState state) { _qualification_state = state; } + protected: + MethodFamily* _method_family; + public: - StatefulMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx) { - _method = new MethodFamily(md->canonicalize(ctx)); - _qualification_state = QUALIFIED; + StatefulMethodFamily() { + _method_family = new MethodFamily(); + _qualification_state = QUALIFIED; } - void set_target_if_empty(Method* m) { _method->set_target_if_empty(m); } - - MethodFamily* get_method_family() { return _method; } - - bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { - return _method->descriptor_matches(md, ctx); + StatefulMethodFamily(MethodFamily* mf) { + _method_family = mf; + _qualification_state = QUALIFIED; } + void set_target_if_empty(Method* m) { _method_family->set_target_if_empty(m); } + + MethodFamily* get_method_family() { return _method_family; } + StateRestorer* record_method_and_dq_further(Method* mo); }; + +// StatefulGenericMethodFamily is a wrapper around GenericMethodFamily that maintains the +// qualification state during hierarchy visitation, and applies that state +// when adding members to the GenericMethodFamily. +class StatefulGenericMethodFamily : public StatefulMethodFamily { + + public: + StatefulGenericMethodFamily(generic::MethodDescriptor* md, generic::Context* ctx) + : StatefulMethodFamily(new GenericMethodFamily(md->canonicalize(ctx))) { + + } + GenericMethodFamily* get_method_family() { + return (GenericMethodFamily*)_method_family; + } + + bool descriptor_matches(generic::MethodDescriptor* md, generic::Context* ctx) { + return get_method_family()->descriptor_matches(md, ctx); + } +}; + class StateRestorer : public PseudoScopeMark { private: StatefulMethodFamily* _method; @@ -563,9 +606,9 @@ class StateRestorer : public PseudoScopeMark { StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) { StateRestorer* mark = new StateRestorer(this, _qualification_state); if (_qualification_state == QUALIFIED) { - _method->record_qualified_method(mo); + _method_family->record_qualified_method(mo); } else { - _method->record_disqualified_method(mo); + _method_family->record_disqualified_method(mo); } // Everything found "above"??? this method in the hierarchy walk is set to // disqualified @@ -573,15 +616,15 @@ StateRestorer* StatefulMethodFamily::record_method_and_dq_further(Method* mo) { return mark; } -class StatefulMethodFamilies : public ResourceObj { +class StatefulGenericMethodFamilies : public ResourceObj { private: - GrowableArray _methods; + GrowableArray _methods; public: - StatefulMethodFamily* find_matching( + StatefulGenericMethodFamily* find_matching( generic::MethodDescriptor* md, generic::Context* ctx) { for (int i = 0; i < _methods.length(); ++i) { - StatefulMethodFamily* existing = _methods.at(i); + StatefulGenericMethodFamily* existing = _methods.at(i); if (existing->descriptor_matches(md, ctx)) { return existing; } @@ -589,17 +632,17 @@ class StatefulMethodFamilies : public ResourceObj { return NULL; } - StatefulMethodFamily* find_matching_or_create( + StatefulGenericMethodFamily* find_matching_or_create( generic::MethodDescriptor* md, generic::Context* ctx) { - StatefulMethodFamily* method = find_matching(md, ctx); + StatefulGenericMethodFamily* method = find_matching(md, ctx); if (method == NULL) { - method = new StatefulMethodFamily(md, ctx); + method = new StatefulGenericMethodFamily(md, ctx); _methods.append(method); } return method; } - void extract_families_into(GrowableArray* array) { + void extract_families_into(GrowableArray* array) { for (int i = 0; i < _methods.length(); ++i) { array->append(_methods.at(i)->get_method_family()); } @@ -683,26 +726,79 @@ static GrowableArray* find_empty_vtable_slots( return slots; } +// Iterates over the superinterface type hierarchy looking for all methods +// with a specific erased signature. +class FindMethodsByErasedSig : public HierarchyVisitor { + private: + // Context data + Symbol* _method_name; + Symbol* _method_signature; + StatefulMethodFamily* _family; + + public: + FindMethodsByErasedSig(Symbol* name, Symbol* signature) : + _method_name(name), _method_signature(signature), + _family(NULL) {} + + void get_discovered_family(MethodFamily** family) { + if (_family != NULL) { + *family = _family->get_method_family(); + } else { + *family = NULL; + } + } + + void* new_node_data(InstanceKlass* cls) { return new PseudoScope(); } + void free_node_data(void* node_data) { + PseudoScope::cast(node_data)->destroy(); + } + + // Find all methods on this hierarchy that match this + // method's erased (name, signature) + bool visit() { + PseudoScope* scope = PseudoScope::cast(current_data()); + InstanceKlass* iklass = current_class(); + + Method* m = iklass->find_method(_method_name, _method_signature); + if (m != NULL) { + if (_family == NULL) { + _family = new StatefulMethodFamily(); + } + + if (iklass->is_interface()) { + StateRestorer* restorer = _family->record_method_and_dq_further(m); + scope->add_mark(restorer); + } else { + // This is the rule that methods in classes "win" (bad word) over + // methods in interfaces. This works because of single inheritance + _family->set_target_if_empty(m); + } + } + return true; + } + +}; + // Iterates over the type hierarchy looking for all methods with a specific // method name. The result of this is a set of method families each of // which is populated with a set of methods that implement the same // language-level signature. -class FindMethodsByName : public HierarchyVisitor { +class FindMethodsByGenericSig : public HierarchyVisitor { private: // Context data Thread* THREAD; generic::DescriptorCache* _cache; Symbol* _method_name; generic::Context* _ctx; - StatefulMethodFamilies _families; + StatefulGenericMethodFamilies _families; public: - FindMethodsByName(generic::DescriptorCache* cache, Symbol* name, + FindMethodsByGenericSig(generic::DescriptorCache* cache, Symbol* name, generic::Context* ctx, Thread* thread) : _cache(cache), _method_name(name), _ctx(ctx), THREAD(thread) {} - void get_discovered_families(GrowableArray* methods) { + void get_discovered_families(GrowableArray* methods) { _families.extract_families_into(methods); } @@ -733,7 +829,7 @@ class FindMethodsByName : public HierarchyVisitor { // Find all methods on this hierarchy that match this method // (name, signature). This class collects other families of this // method name. - StatefulMethodFamily* family = + StatefulGenericMethodFamily* family = _families.find_matching_or_create(md, _ctx); if (klass->is_interface()) { @@ -752,8 +848,8 @@ class FindMethodsByName : public HierarchyVisitor { }; #ifndef PRODUCT -static void print_families( - GrowableArray* methods, Symbol* match) { +static void print_generic_families( + GrowableArray* methods, Symbol* match) { streamIndentor si(tty, 4); if (methods->length() == 0) { tty->indent(); @@ -761,22 +857,87 @@ static void print_families( } for (int i = 0; i < methods->length(); ++i) { tty->indent(); - MethodFamily* lm = methods->at(i); + GenericMethodFamily* lm = methods->at(i); if (lm->contains_signature(match)) { tty->print_cr(""); } else { tty->print_cr(""); } - lm->print_on(tty, 1); + lm->print_sig_on(tty, lm->get_generic_sig(), 1); } } #endif // ndef PRODUCT -static void merge_in_new_methods(InstanceKlass* klass, - GrowableArray* new_methods, TRAPS); static void create_overpasses( GrowableArray* slots, InstanceKlass* klass, TRAPS); +static void generate_generic_defaults( + InstanceKlass* klass, GrowableArray* empty_slots, + EmptyVtableSlot* slot, int current_slot_index, TRAPS) { + + if (slot->is_bound()) { +#ifndef PRODUCT + if (TraceDefaultMethods) { + streamIndentor si(tty, 4); + tty->indent().print_cr("Already bound to logical method:"); + GenericMethodFamily* lm = (GenericMethodFamily*)(slot->get_binding()); + lm->print_sig_on(tty, lm->get_generic_sig(), 1); + } +#endif // ndef PRODUCT + return; // covered by previous processing + } + + generic::DescriptorCache cache; + + generic::Context ctx(&cache); + FindMethodsByGenericSig visitor(&cache, slot->name(), &ctx, CHECK); + visitor.run(klass); + + GrowableArray discovered_families; + visitor.get_discovered_families(&discovered_families); + +#ifndef PRODUCT + if (TraceDefaultMethods) { + print_generic_families(&discovered_families, slot->signature()); + } +#endif // ndef PRODUCT + + // Find and populate any other slots that match the discovered families + for (int j = current_slot_index; j < empty_slots->length(); ++j) { + EmptyVtableSlot* open_slot = empty_slots->at(j); + + if (slot->name() == open_slot->name()) { + for (int k = 0; k < discovered_families.length(); ++k) { + GenericMethodFamily* lm = discovered_families.at(k); + + if (lm->contains_signature(open_slot->signature())) { + lm->determine_target(klass, CHECK); + open_slot->bind_family(lm); + } + } + } + } +} + +static void generate_erased_defaults( + InstanceKlass* klass, GrowableArray* empty_slots, + EmptyVtableSlot* slot, TRAPS) { + + // sets up a set of methods with the same exact erased signature + FindMethodsByErasedSig visitor(slot->name(), slot->signature()); + visitor.run(klass); + + MethodFamily* family; + visitor.get_discovered_family(&family); + if (family != NULL) { + family->determine_target(klass, CHECK); + slot->bind_family(family); + } +} + +static void merge_in_new_methods(InstanceKlass* klass, + GrowableArray* new_methods, TRAPS); + // This is the guts of the default methods implementation. This is called just // after the classfile has been parsed if some ancestor has default methods. // @@ -807,8 +968,6 @@ void DefaultMethods::generate_default_methods( // whatever scope it's in. ResourceMark rm(THREAD); - generic::DescriptorCache cache; - // Keep entire hierarchy alive for the duration of the computation KeepAliveRegistrar keepAlive(THREAD); KeepAliveVisitor loadKeepAlive(&keepAlive); @@ -837,47 +996,13 @@ void DefaultMethods::generate_default_methods( tty->print_cr(""); } #endif // ndef PRODUCT - if (slot->is_bound()) { -#ifndef PRODUCT - if (TraceDefaultMethods) { - streamIndentor si(tty, 4); - tty->indent().print_cr("Already bound to logical method:"); - slot->get_binding()->print_on(tty, 1); - } -#endif // ndef PRODUCT - continue; // covered by previous processing + + if (ParseGenericDefaults) { + generate_generic_defaults(klass, empty_slots, slot, i, CHECK); + } else { + generate_erased_defaults(klass, empty_slots, slot, CHECK); } - - generic::Context ctx(&cache); - FindMethodsByName visitor(&cache, slot->name(), &ctx, CHECK); - visitor.run(klass); - - GrowableArray discovered_families; - visitor.get_discovered_families(&discovered_families); - -#ifndef PRODUCT - if (TraceDefaultMethods) { - print_families(&discovered_families, slot->signature()); - } -#endif // ndef PRODUCT - - // Find and populate any other slots that match the discovered families - for (int j = i; j < empty_slots->length(); ++j) { - EmptyVtableSlot* open_slot = empty_slots->at(j); - - if (slot->name() == open_slot->name()) { - for (int k = 0; k < discovered_families.length(); ++k) { - MethodFamily* lm = discovered_families.at(k); - - if (lm->contains_signature(open_slot->signature())) { - lm->determine_target(klass, CHECK); - open_slot->bind_family(lm); - } - } - } - } - } - + } #ifndef PRODUCT if (TraceDefaultMethods) { tty->print_cr("Creating overpasses..."); @@ -893,7 +1018,6 @@ void DefaultMethods::generate_default_methods( #endif // ndef PRODUCT } - /** * Generic analysis was used upon interface '_target' and found a unique * default method candidate with generic signature '_method_desc'. This @@ -912,17 +1036,85 @@ void DefaultMethods::generate_default_methods( * the selected method along that path. */ class ShadowChecker : public HierarchyVisitor { - private: - generic::DescriptorCache* _cache; + protected: Thread* THREAD; InstanceKlass* _target; Symbol* _method_name; InstanceKlass* _method_holder; - generic::MethodDescriptor* _method_desc; bool _found_shadow; + + public: + + ShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, + InstanceKlass* target) + : THREAD(thread), _method_name(name), _method_holder(holder), + _target(target), _found_shadow(false) {} + + void* new_node_data(InstanceKlass* cls) { return NULL; } + void free_node_data(void* data) { return; } + + bool visit() { + InstanceKlass* ik = current_class(); + if (ik == _target && current_depth() == 1) { + return false; // This was the specified super -- no need to search it + } + if (ik == _method_holder || ik == _target) { + // We found a path that should be examined to see if it shadows _method + if (path_has_shadow()) { + _found_shadow = true; + cancel_iteration(); + } + return false; // no need to continue up hierarchy + } + return true; + } + + virtual bool path_has_shadow() = 0; + bool found_shadow() { return _found_shadow; } +}; + +// Used for Invokespecial. +// Invokespecial is allowed to invoke a concrete interface method +// and can be used to disambuiguate among qualified candidates, +// which are methods in immediate superinterfaces, +// but may not be used to invoke a candidate that would be shadowed +// from the perspective of the caller. +// Invokespecial is also used in the overpass generation today +// We re-run the shadowchecker because we can't distinguish this case, +// but it should return the same answer, since the overpass target +// is now the invokespecial caller. +class ErasedShadowChecker : public ShadowChecker { + private: + bool path_has_shadow() { + + for (int i = current_depth() - 1; i > 0; --i) { + InstanceKlass* ik = class_at_depth(i); + + if (ik->is_interface()) { + int end; + int start = ik->find_method_by_name(_method_name, &end); + if (start != -1) { + return true; + } + } + } + return false; + } + public: + + ErasedShadowChecker(Thread* thread, Symbol* name, InstanceKlass* holder, + InstanceKlass* target) + : ShadowChecker(thread, name, holder, target) {} +}; + +class GenericShadowChecker : public ShadowChecker { + private: + generic::DescriptorCache* _cache; + generic::MethodDescriptor* _method_desc; + bool path_has_shadow() { generic::Context ctx(_cache); @@ -950,104 +1142,42 @@ class ShadowChecker : public HierarchyVisitor { public: - ShadowChecker(generic::DescriptorCache* cache, Thread* thread, + GenericShadowChecker(generic::DescriptorCache* cache, Thread* thread, Symbol* name, InstanceKlass* holder, generic::MethodDescriptor* desc, InstanceKlass* target) - : _cache(cache), THREAD(thread), _method_name(name), _method_holder(holder), - _method_desc(desc), _target(target), _found_shadow(false) {} - - void* new_node_data(InstanceKlass* cls) { return NULL; } - void free_node_data(void* data) { return; } - - bool visit() { - InstanceKlass* ik = current_class(); - if (ik == _target && current_depth() == 1) { - return false; // This was the specified super -- no need to search it - } - if (ik == _method_holder || ik == _target) { - // We found a path that should be examined to see if it shadows _method - if (path_has_shadow()) { - _found_shadow = true; - cancel_iteration(); - } - return false; // no need to continue up hierarchy - } - return true; - } - - bool found_shadow() { return _found_shadow; } + : ShadowChecker(thread, name, holder, target) { + _cache = cache; + _method_desc = desc; + } }; -// This is called during linktime when we find an invokespecial call that -// refers to a direct superinterface. It indicates that we should find the -// default method in the hierarchy of that superinterface, and if that method -// would have been a candidate from the point of view of 'this' class, then we -// return that method. -Method* DefaultMethods::find_super_default( - Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) { - ResourceMark rm(THREAD); - assert(cls != NULL && super != NULL, "Need real classes"); +// Find the unique qualified candidate from the perspective of the super_class +// which is the resolved_klass, which must be an immediate superinterface +// of klass +Method* find_erased_super_default(InstanceKlass* current_class, InstanceKlass* super_class, Symbol* method_name, Symbol* sig, TRAPS) { - InstanceKlass* current_class = InstanceKlass::cast(cls); - InstanceKlass* direction = InstanceKlass::cast(super); + FindMethodsByErasedSig visitor(method_name, sig); + visitor.run(super_class); // find candidates from resolved_klass - // Keep entire hierarchy alive for the duration of the computation - KeepAliveRegistrar keepAlive(THREAD); - KeepAliveVisitor loadKeepAlive(&keepAlive); - loadKeepAlive.run(current_class); + MethodFamily* family; + visitor.get_discovered_family(&family); -#ifndef PRODUCT - if (TraceDefaultMethods) { - tty->print_cr("Finding super default method %s.%s%s from %s", - direction->name()->as_C_string(), - method_name->as_C_string(), sig->as_C_string(), - current_class->name()->as_C_string()); - } -#endif // ndef PRODUCT - - if (!direction->is_interface()) { - // We should not be here - return NULL; + if (family != NULL) { + family->determine_target(current_class, CHECK_NULL); // get target from current_class } - generic::DescriptorCache cache; - generic::Context ctx(&cache); - - // Prime the initial generic context for current -> direction - ctx.apply_type_arguments(current_class, direction, CHECK_NULL); - - FindMethodsByName visitor(&cache, method_name, &ctx, CHECK_NULL); - visitor.run(direction); - - GrowableArray families; - visitor.get_discovered_families(&families); - -#ifndef PRODUCT - if (TraceDefaultMethods) { - print_families(&families, sig); - } -#endif // ndef PRODUCT - - MethodFamily* selected_family = NULL; - - for (int i = 0; i < families.length(); ++i) { - MethodFamily* lm = families.at(i); - if (lm->contains_signature(sig)) { - lm->determine_target(current_class, CHECK_NULL); - selected_family = lm; - } - } - - if (selected_family->has_target()) { - Method* target = selected_family->get_selected_target(); + if (family->has_target()) { + Method* target = family->get_selected_target(); InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); // Verify that the identified method is valid from the context of - // the current class - ShadowChecker checker(&cache, THREAD, target->name(), - holder, selected_family->descriptor(), direction); + // the current class, which is the caller class for invokespecial + // link resolution, i.e. ensure there it is not shadowed. + // You can use invokespecial to disambiguate interface methods, but + // you can not use it to skip over an interface method that would shadow it. + ErasedShadowChecker checker(THREAD, target->name(), holder, super_class); checker.run(current_class); if (checker.found_shadow()) { @@ -1061,13 +1191,71 @@ Method* DefaultMethods::find_super_default( } else { #ifndef PRODUCT if (TraceDefaultMethods) { - tty->print(" Returning "); - print_method(tty, target, true); - tty->print_cr(""); + family->print_sig_on(tty, target->signature(), 1); } #endif // ndef PRODUCT return target; } + } else { + assert(family->throws_exception(), "must have target or throw"); + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), + family->get_exception_message()->as_C_string(), NULL); + } +} + +// super_class is assumed to be the direct super of current_class +Method* find_generic_super_default( InstanceKlass* current_class, + InstanceKlass* super_class, + Symbol* method_name, Symbol* sig, TRAPS) { + generic::DescriptorCache cache; + generic::Context ctx(&cache); + + // Prime the initial generic context for current -> super_class + ctx.apply_type_arguments(current_class, super_class, CHECK_NULL); + + FindMethodsByGenericSig visitor(&cache, method_name, &ctx, CHECK_NULL); + visitor.run(super_class); + + GrowableArray families; + visitor.get_discovered_families(&families); + +#ifndef PRODUCT + if (TraceDefaultMethods) { + print_generic_families(&families, sig); + } +#endif // ndef PRODUCT + + GenericMethodFamily* selected_family = NULL; + + for (int i = 0; i < families.length(); ++i) { + GenericMethodFamily* lm = families.at(i); + if (lm->contains_signature(sig)) { + lm->determine_target(current_class, CHECK_NULL); + selected_family = lm; + } + } + + if (selected_family->has_target()) { + Method* target = selected_family->get_selected_target(); + InstanceKlass* holder = InstanceKlass::cast(target->method_holder()); + + // Verify that the identified method is valid from the context of + // the current class + GenericShadowChecker checker(&cache, THREAD, target->name(), + holder, selected_family->descriptor(), super_class); + checker.run(current_class); + + if (checker.found_shadow()) { +#ifndef PRODUCT + if (TraceDefaultMethods) { + tty->print_cr(" Only candidate found was shadowed."); + } +#endif // ndef PRODUCT + THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), + "Accessible default method not found", NULL); + } else { + return target; + } } else { assert(selected_family->throws_exception(), "must have target or throw"); THROW_MSG_(vmSymbols::java_lang_AbstractMethodError(), @@ -1075,6 +1263,71 @@ Method* DefaultMethods::find_super_default( } } +// This is called during linktime when we find an invokespecial call that +// refers to a direct superinterface. It indicates that we should find the +// default method in the hierarchy of that superinterface, and if that method +// would have been a candidate from the point of view of 'this' class, then we +// return that method. +// This logic assumes that the super is a direct superclass of the caller +Method* DefaultMethods::find_super_default( + Klass* cls, Klass* super, Symbol* method_name, Symbol* sig, TRAPS) { + + ResourceMark rm(THREAD); + + assert(cls != NULL && super != NULL, "Need real classes"); + + InstanceKlass* current_class = InstanceKlass::cast(cls); + InstanceKlass* super_class = InstanceKlass::cast(super); + + // Keep entire hierarchy alive for the duration of the computation + KeepAliveRegistrar keepAlive(THREAD); + KeepAliveVisitor loadKeepAlive(&keepAlive); + loadKeepAlive.run(current_class); // get hierarchy from current class + +#ifndef PRODUCT + if (TraceDefaultMethods) { + tty->print_cr("Finding super default method %s.%s%s from %s", + super_class->name()->as_C_string(), + method_name->as_C_string(), sig->as_C_string(), + current_class->name()->as_C_string()); + } +#endif // ndef PRODUCT + + assert(super_class->is_interface(), "only call for default methods"); + + Method* target = NULL; + if (ParseGenericDefaults) { + target = find_generic_super_default(current_class, super_class, + method_name, sig, CHECK_NULL); + } else { + target = find_erased_super_default(current_class, super_class, + method_name, sig, CHECK_NULL); + } + +#ifndef PRODUCT + if (target != NULL) { + if (TraceDefaultMethods) { + tty->print(" Returning "); + print_method(tty, target, true); + tty->print_cr(""); + } + } +#endif // ndef PRODUCT + return target; +} + +#ifndef PRODUCT +// Return true is broad type is a covariant return of narrow type +static bool covariant_return_type(BasicType narrow, BasicType broad) { + if (narrow == broad) { + return true; + } + if (broad == T_OBJECT) { + return true; + } + return false; +} +#endif // ndef PRODUCT static int assemble_redirect( BytecodeConstantPool* cp, BytecodeBuffer* buffer, @@ -1103,7 +1356,7 @@ static int assemble_redirect( out.next(); } assert(out.at_return_type(), "Parameter counts do not match"); - assert(in.type() == out.type(), "Return types are not compatible"); + assert(covariant_return_type(out.type(), in.type()), "Return types are not compatible"); if (parameter_count == 1 && (in.type() == T_LONG || in.type() == T_DOUBLE)) { ++parameter_count; // need room for return value @@ -1144,10 +1397,15 @@ static Method* new_method( Symbol* sig, AccessFlags flags, int max_stack, int params, ConstMethod::MethodType mt, TRAPS) { - address code_start = static_cast
    (bytecodes->adr_at(0)); - int code_length = bytecodes->length(); + address code_start = 0; + int code_length = 0; InlineTableSizes sizes; + if (bytecodes != NULL && bytecodes->length() > 0) { + code_start = static_cast
    (bytecodes->adr_at(0)); + code_length = bytecodes->length(); + } + Method* m = Method::allocate(cp->pool_holder()->class_loader_data(), code_length, flags, &sizes, mt, CHECK_NULL); diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp index d07785d0b61..8167013b372 100644 --- a/hotspot/src/share/vm/runtime/globals.hpp +++ b/hotspot/src/share/vm/runtime/globals.hpp @@ -3679,6 +3679,9 @@ class CommandLineFlags { develop(bool, VerifyGenericSignatures, false, \ "Abort VM on erroneous or inconsistent generic signatures") \ \ + product(bool, ParseGenericDefaults, false, \ + "Parse generic signatures for default method handling") \ + \ product(bool, UseVMInterruptibleIO, false, \ "(Unstable, Solaris-specific) Thread interrupt before or with " \ "EINTR for I/O operations results in OS_INTRPT. The default value"\ From 424ac16db051cc9523ae3c0138640d12f37a1066 Mon Sep 17 00:00:00 2001 From: Kumar Srinivasan Date: Tue, 9 Jul 2013 14:54:20 -0700 Subject: [PATCH 061/156] 8020214: TEST_BUG: test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java broken Reviewed-by: jjg --- .../javap/8007907/JavapReturns0AfterClassNotFoundTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java b/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java index 06e94963faf..709d8cbded9 100644 --- a/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java +++ b/langtools/test/tools/javap/8007907/JavapReturns0AfterClassNotFoundTest.java @@ -35,7 +35,7 @@ import java.io.StringWriter; public class JavapReturns0AfterClassNotFoundTest { static final String fileNotFoundErrorMsg = - "Error: class not found: Unexisting.class"; + "Error: class not found: Unexisting.class"; static final String exitCodeClassNotFoundAssertionMsg = "Javap's exit code for class not found should be 1"; static final String classNotFoundMsgAssertionMsg = From 255a9b3dd1e0a62d9fb446a6f33a54f7b044bc17 Mon Sep 17 00:00:00 2001 From: Joe Wang Date: Tue, 9 Jul 2013 16:34:52 -0700 Subject: [PATCH 062/156] 8016648: FEATURE_SECURE_PROCESSING set to true or false causes SAXParseException to be thrown Jaxp 1.5 feature update Reviewed-by: alanb, dfuchs, lancea --- .../apache/xalan/internal/XalanConstants.java | 34 +++- .../xalan/internal/utils/SecuritySupport.java | 16 +- .../utils/XMLSecurityPropertyManager.java | 192 ++++++++++++++++++ .../xsltc/trax/TransformerFactoryImpl.java | 55 +++-- .../internal/dom/DOMConfigurationImpl.java | 25 +-- .../xerces/internal/impl/Constants.java | 33 ++- .../xerces/internal/impl/PropertyManager.java | 38 ++-- .../impl/XMLDocumentFragmentScannerImpl.java | 29 +-- .../internal/impl/XMLEntityManager.java | 28 ++- .../internal/impl/xs/XMLSchemaLoader.java | 21 +- .../internal/impl/xs/XMLSchemaValidator.java | 11 +- .../impl/xs/traversers/XSDHandler.java | 34 +++- .../internal/jaxp/DocumentBuilderImpl.java | 64 ++++-- .../xerces/internal/jaxp/SAXParserImpl.java | 43 ++-- .../validation/StreamValidatorHelper.java | 4 +- .../jaxp/validation/ValidatorHandlerImpl.java | 9 +- .../jaxp/validation/XMLSchemaFactory.java | 42 ++-- .../XMLSchemaValidatorComponentManager.java | 28 ++- .../xerces/internal/parsers/DOMParser.java | 12 ++ .../xerces/internal/parsers/SAXParser.java | 23 +++ .../internal/parsers/XML11Configuration.java | 24 +-- .../internal/utils/SecuritySupport.java | 16 +- .../utils/XMLSecurityPropertyManager.java | 190 +++++++++++++++++ .../internal/xinclude/XIncludeHandler.java | 31 ++- .../xml/internal/utils/XMLReaderManager.java | 14 +- 25 files changed, 786 insertions(+), 230 deletions(-) create mode 100644 jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java create mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java index 9667b544944..ce50626a612 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/XalanConstants.java @@ -73,13 +73,39 @@ public final class XalanConstants { * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true */ public static final String EXTERNAL_ACCESS_DEFAULT_FSP = ""; - /** - * JDK version by which the default is to restrict external connection - */ - public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8; + /** * FEATURE_SECURE_PROCESSING (FSP) is false by default */ public static final String EXTERNAL_ACCESS_DEFAULT = ACCESS_EXTERNAL_ALL; + public static final String XML_SECURITY_PROPERTY_MANAGER = + ORACLE_JAXP_PROPERTY_PREFIX + "xmlSecurityPropertyManager"; + + /** + * Check if we're in jdk8 or above + */ + public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); + + /* + * Check the version of the current JDK against that specified in the + * parameter + * + * There is a proposal to change the java version string to: + * MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL + * This method would work with both the current format and that proposed + * + * @param compareTo a JDK version to be compared to + * @return true if the current version is the same or above that represented + * by the parameter + */ + public static boolean isJavaVersionAtLeast(int compareTo) { + String javaVersion = SecuritySupport.getSystemProperty("java.version"); + String versions[] = javaVersion.split("\\.", 3); + if (Integer.parseInt(versions[0]) >= compareTo || + Integer.parseInt(versions[1]) >= compareTo) { + return true; + } + return false; + } } // class Constants diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java index e418fd55275..0c2d2b1c9ba 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/SecuritySupport.java @@ -229,7 +229,8 @@ public final class SecuritySupport { * @return the name of the protocol if rejected, null otherwise */ public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException { - if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) { + if (systemId == null || (allowedProtocols != null && + allowedProtocols.equalsIgnoreCase(accessAny))) { return null; } @@ -262,6 +263,9 @@ public final class SecuritySupport { * @return true if the protocol is in the list */ private static boolean isProtocolAllowed(String protocol, String allowedProtocols) { + if (allowedProtocols == null) { + return false; + } String temp[] = allowedProtocols.split(","); for (String t : temp) { t = t.trim(); @@ -273,18 +277,16 @@ public final class SecuritySupport { } /** - * Read from $java.home/lib/jaxp.properties for the specified property + * Read JAXP system property in this order: system property, + * $java.home/lib/jaxp.properties if the system property is not specified * * @param propertyId the Id of the property * @return the value of the property */ - public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) { - String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId); + public static String getJAXPSystemProperty(String sysPropertyId) { + String accessExternal = getSystemProperty(sysPropertyId); if (accessExternal == null) { accessExternal = readJAXPProperty(sysPropertyId); - if (accessExternal == null) { - accessExternal = defaultVal; - } } return accessExternal; } diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java new file mode 100644 index 00000000000..5f5501a3434 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xalan/internal/utils/XMLSecurityPropertyManager.java @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xalan.internal.utils; + + +import com.sun.org.apache.xalan.internal.XalanConstants; +import javax.xml.XMLConstants; + +/** + * This class manages security related properties + * + */ +public final class XMLSecurityPropertyManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + } + + /** + * Limits managed by the security manager + */ + public static enum Property { + ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, + XalanConstants.EXTERNAL_ACCESS_DEFAULT), + ACCESS_EXTERNAL_STYLESHEET(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, + XalanConstants.EXTERNAL_ACCESS_DEFAULT); + + final String name; + final String defaultValue; + + Property(String name, String value) { + this.name = name; + this.defaultValue = value; + } + + public boolean equalsName(String propertyName) { + return (propertyName == null) ? false : name.equals(propertyName); + } + + String defaultValue() { + return defaultValue; + } + } + + + /** + * Values of the properties as defined in enum Properties + */ + private final String[] values; + /** + * States of the settings for each property in Properties above + */ + private State[] states = {State.DEFAULT, State.DEFAULT}; + + /** + * Default constructor. Establishes default values + */ + public XMLSecurityPropertyManager() { + values = new String[Property.values().length]; + for (Property property : Property.values()) { + values[property.ordinal()] = property.defaultValue(); + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Set the value for a specific property. + * + * @param property the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(Property property, State state, String value) { + //only update if it shall override + if (state.compareTo(states[property.ordinal()]) >= 0) { + values[property.ordinal()] = value; + states[property.ordinal()] = state; + } + } + + /** + * Set the value of a property by its index + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(int index, State state, String value) { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + } + } + /** + * Return the value of the specified property + * + * @param property the property + * @return the value of the property + */ + public String getValue(Property property) { + return values[property.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * @param index the index of a property + * @return value of a property + */ + public String getValueByIndex(int index) { + return values[index]; + } + + /** + * Get the index by property name + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName){ + for (Property property : Property.values()) { + if (property.equalsName(propertyName)) { + //internally, ordinal is used as index + return property.ordinal(); + } + } + return -1; + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + getSystemProperty(Property.ACCESS_EXTERNAL_DTD, + XalanConstants.SP_ACCESS_EXTERNAL_DTD); + getSystemProperty(Property.ACCESS_EXTERNAL_STYLESHEET, + XalanConstants.SP_ACCESS_EXTERNAL_STYLESHEET); + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the property + * @param systemProperty the name of the system property + */ + private void getSystemProperty(Property property, String systemProperty) { + try { + String value = SecuritySupport.getSystemProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.SYSTEMPROPERTY; + return; + } + + value = SecuritySupport.readJAXPProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.JAXPDOTPROPERTIES; + } + } catch (NumberFormatException e) { + //invalid setting ignored + } + } +} diff --git a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index fdd89643721..874892942f9 100644 --- a/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/jaxp/src/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -27,6 +27,9 @@ import com.sun.org.apache.xalan.internal.XalanConstants; import com.sun.org.apache.xalan.internal.utils.FactoryImpl; import com.sun.org.apache.xalan.internal.utils.ObjectFactory; import com.sun.org.apache.xalan.internal.utils.SecuritySupport; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.Property; +import com.sun.org.apache.xalan.internal.utils.XMLSecurityPropertyManager.State; import com.sun.org.apache.xalan.internal.xsltc.compiler.Constants; import com.sun.org.apache.xalan.internal.xsltc.compiler.SourceLoader; import com.sun.org.apache.xalan.internal.xsltc.compiler.XSLTC; @@ -215,11 +218,13 @@ public class TransformerFactoryImpl * protocols allowed for external references set by the stylesheet processing instruction, Import and Include element. */ private String _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + /** * protocols allowed for external DTD references in source file and/or stylesheet. */ private String _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT; + private XMLSecurityPropertyManager _xmlSecurityPropertyMgr; /** * javax.xml.transform.sax.TransformerFactory implementation. @@ -235,15 +240,16 @@ public class TransformerFactoryImpl private TransformerFactoryImpl(boolean useServicesMechanism) { this._useServicesMechanism = useServicesMechanism; - String defaultAccess = XalanConstants.EXTERNAL_ACCESS_DEFAULT; if (System.getSecurityManager() != null) { _isSecureMode = true; _isNotSecureProcessing = false; } - _accessExternalStylesheet = SecuritySupport.getDefaultAccessProperty( - XalanConstants.SP_ACCESS_EXTERNAL_STYLESHEET, defaultAccess); - _accessExternalDTD = SecuritySupport.getDefaultAccessProperty( - XalanConstants.SP_ACCESS_EXTERNAL_DTD, defaultAccess); + + _xmlSecurityPropertyMgr = new XMLSecurityPropertyManager(); + _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_DTD); + _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_STYLESHEET); } /** @@ -306,11 +312,10 @@ public class TransformerFactoryImpl else return Boolean.FALSE; } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { - return _accessExternalStylesheet; - } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { - return _accessExternalDTD; + + int index = _xmlSecurityPropertyMgr.getIndex(name); + if (index > -1) { + return _xmlSecurityPropertyMgr.getValueByIndex(index); } // Throw an exception for all other attributes @@ -413,12 +418,15 @@ public class TransformerFactoryImpl return; } } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_STYLESHEET)) { - _accessExternalStylesheet = (String)value; - return; - } - else if (name.equals(XMLConstants.ACCESS_EXTERNAL_DTD)) { - _accessExternalDTD = (String)value; + + int index = _xmlSecurityPropertyMgr.getIndex(name); + if (index > -1) { + _xmlSecurityPropertyMgr.setValue(index, + State.APIPROPERTY, (String)value); + _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_DTD); + _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_STYLESHEET); return; } @@ -466,11 +474,18 @@ public class TransformerFactoryImpl } _isNotSecureProcessing = !value; - // set restriction, allowing no access to external stylesheet - if (value) { - _accessExternalStylesheet = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP; - _accessExternalDTD = XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP; + // set external access restriction when FSP is explicitly set + if (value && XalanConstants.IS_JDK8_OR_ABOVE) { + _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, + State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP); + _xmlSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_STYLESHEET, + State.FSP, XalanConstants.EXTERNAL_ACCESS_DEFAULT_FSP); + _accessExternalDTD = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_DTD); + _accessExternalStylesheet = _xmlSecurityPropertyMgr.getValue( + Property.ACCESS_EXTERNAL_STYLESHEET); } + return; } else if (name.equals(XalanConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java index 23be56b5b58..832724ac586 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/dom/DOMConfigurationImpl.java @@ -33,7 +33,7 @@ import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.utils.ObjectFactory; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; @@ -156,13 +156,9 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; - /** Property identifier: access to external dtd */ - protected static final String ACCESS_EXTERNAL_DTD = - XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - protected static final String ACCESS_EXTERNAL_SCHEMA = - XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; // // Data @@ -283,8 +279,7 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings JAXP_SCHEMA_LANGUAGE, DTD_VALIDATOR_FACTORY_PROPERTY, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -318,14 +313,8 @@ public class DOMConfigurationImpl extends ParserConfigurationSettings fValidationManager = createValidationManager(); setProperty(VALIDATION_MANAGER, fValidationManager); - //For DOM, the secure feature is set to true by default - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - setProperty(ACCESS_EXTERNAL_DTD, accessExternal); - - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal); + setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, + new XMLSecurityPropertyManager()); // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java index 01328adf012..bcc2a796b08 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Constants.java @@ -184,6 +184,9 @@ public final class Constants { public static final String ORACLE_JAXP_PROPERTY_PREFIX = "http://www.oracle.com/xml/jaxp/properties/"; + public static final String XML_SECURITY_PROPERTY_MANAGER = + ORACLE_JAXP_PROPERTY_PREFIX + "xmlSecurityPropertyManager"; + //System Properties corresponding to ACCESS_EXTERNAL_* properties public static final String SP_ACCESS_EXTERNAL_DTD = "javax.xml.accessExternalDTD"; public static final String SP_ACCESS_EXTERNAL_SCHEMA = "javax.xml.accessExternalSchema"; @@ -194,16 +197,17 @@ public final class Constants { * Default value when FEATURE_SECURE_PROCESSING (FSP) is set to true */ public static final String EXTERNAL_ACCESS_DEFAULT_FSP = ""; - /** - * JDK version by which the default is to restrict external connection - */ - public static final int RESTRICT_BY_DEFAULT_JDK_VERSION = 8; /** * FEATURE_SECURE_PROCESSING (FSP) is true by default */ public static final String EXTERNAL_ACCESS_DEFAULT = ACCESS_EXTERNAL_ALL; + /** + * Check if we're in jdk8 or above + */ + public static final boolean IS_JDK8_OR_ABOVE = isJavaVersionAtLeast(8); + // // DOM features // @@ -697,6 +701,27 @@ public final class Constants { ? new ArrayEnumeration(fgXercesProperties) : fgEmptyEnumeration; } // getXercesProperties():Enumeration + /* + * Check the version of the current JDK against that specified in the + * parameter + * + * There is a proposal to change the java version string to: + * MAJOR.MINOR.FU.CPU.PSU-BUILDNUMBER_BUGIDNUMBER_OPTIONAL + * This method would work with both the current format and that proposed + * + * @param compareTo a JDK version to be compared to + * @return true if the current version is the same or above that represented + * by the parameter + */ + public static boolean isJavaVersionAtLeast(int compareTo) { + String javaVersion = SecuritySupport.getSystemProperty("java.version"); + String versions[] = javaVersion.split("\\.", 3); + if (Integer.parseInt(versions[0]) >= compareTo || + Integer.parseInt(versions[1]) >= compareTo) { + return true; + } + return false; + } // // Classes diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java index b85ea503fa3..2b8d5476e57 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/PropertyManager.java @@ -25,10 +25,9 @@ package com.sun.org.apache.xerces.internal.impl; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.xml.internal.stream.StaxEntityResolverWrapper; import java.util.HashMap; -import javax.xml.XMLConstants; import javax.xml.stream.XMLInputFactory; import javax.xml.stream.XMLOutputFactory; import javax.xml.stream.XMLResolver; @@ -51,15 +50,14 @@ public class PropertyManager { private static final String STRING_INTERNING = "http://xml.org/sax/features/string-interning"; - - /** Property identifier: access to external dtd */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; HashMap supportedProps = new HashMap(); + private XMLSecurityPropertyManager fSecurityPropertyMgr; + public static final int CONTEXT_READER = 1; public static final int CONTEXT_WRITER = 2; @@ -84,6 +82,7 @@ public class PropertyManager { HashMap properties = propertyManager.getProperties(); supportedProps.putAll(properties); + fSecurityPropertyMgr = (XMLSecurityPropertyManager)getProperty(XML_SECURITY_PROPERTY_MANAGER); } private HashMap getProperties(){ @@ -125,14 +124,8 @@ public class PropertyManager { supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_DUPLICATE_ENTITYDEF_FEATURE, new Boolean(false)); supportedProps.put(Constants.XERCES_FEATURE_PREFIX + Constants.WARN_ON_UNDECLARED_ELEMDEF_FEATURE, new Boolean(false)); - //For DOM/SAX, the secure feature is set to true by default - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - supportedProps.put(ACCESS_EXTERNAL_DTD, accessExternal); - - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - supportedProps.put(ACCESS_EXTERNAL_SCHEMA, accessExternal); + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + supportedProps.put(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); } private void initWriterProps(){ @@ -148,7 +141,8 @@ public class PropertyManager { * } */ public boolean containsProperty(String property){ - return supportedProps.containsKey(property) ; + return supportedProps.containsKey(property) || + fSecurityPropertyMgr.getIndex(property) > -1 ; } public Object getProperty(String property){ @@ -174,7 +168,15 @@ public class PropertyManager { //add internal stax property supportedProps.put( Constants.XERCES_PROPERTY_PREFIX + Constants.STAX_ENTITY_RESOLVER_PROPERTY , new StaxEntityResolverWrapper((XMLResolver)value)) ; } - supportedProps.put(property, value ) ; + + int index = fSecurityPropertyMgr.getIndex(property); + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + } else { + supportedProps.put(property, value); + } + if(equivalentProperty != null){ supportedProps.put(equivalentProperty, value ) ; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index 82c009bbdd3..050b852e84d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -53,6 +53,7 @@ import com.sun.org.apache.xerces.internal.impl.XMLEntityHandler; import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.NamespaceSupport; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.xml.internal.stream.Entity; import javax.xml.XMLConstants; @@ -166,8 +167,9 @@ public class XMLDocumentFragmentScannerImpl protected static final String STANDARD_URI_CONFORMANT = Constants.XERCES_FEATURE_PREFIX +Constants.STANDARD_URI_CONFORMANT_FEATURE; - /** property identifier: access external dtd. */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; /** access external dtd: file protocol * For DOM/SAX, the secure feature is set to true by default @@ -199,7 +201,7 @@ public class XMLDocumentFragmentScannerImpl SYMBOL_TABLE, ERROR_REPORTER, ENTITY_MANAGER, - ACCESS_EXTERNAL_DTD + XML_SECURITY_PROPERTY_MANAGER }; /** Property defaults. */ @@ -610,7 +612,10 @@ public class XMLDocumentFragmentScannerImpl dtdGrammarUtil = null; // JAXP 1.5 features and properties - fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + fStrictURI = componentManager.getFeature(STANDARD_URI_CONFORMANT, false); //fEntityManager.test(); @@ -662,9 +667,10 @@ public class XMLDocumentFragmentScannerImpl dtdGrammarUtil = null; - // Oracle jdk feature - fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD); - + // JAXP 1.5 features and properties + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); } // reset(XMLComponentManager) /** @@ -762,11 +768,10 @@ public class XMLDocumentFragmentScannerImpl } //JAXP 1.5 properties - if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) { - if (propertyId.equals(ACCESS_EXTERNAL_DTD)) - { - fAccessExternalDTD = (String)value; - } + if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) + { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value; + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); } } // setProperty(String,Object) diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index ee6ff0a6b2e..da902908dce 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -31,6 +31,7 @@ import com.sun.org.apache.xerces.internal.util.*; import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.XMLResourceIdentifier; import com.sun.org.apache.xerces.internal.xni.XNIException; @@ -166,8 +167,9 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { protected static final String PARSER_SETTINGS = Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; - /** property identifier: access external dtd. */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; /** access external dtd: file protocol */ static final String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT; @@ -203,7 +205,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { VALIDATION_MANAGER, BUFFER_SIZE, SECURITY_MANAGER, - ACCESS_EXTERNAL_DTD + XML_SECURITY_PROPERTY_MANAGER }; /** Property defaults. */ @@ -214,7 +216,7 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { null, new Integer(DEFAULT_BUFFER_SIZE), null, - EXTERNAL_ACCESS_DEFAULT + null }; private static final String XMLEntity = "[xml]".intern(); @@ -1421,7 +1423,8 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fLoadExternalDTD = !((Boolean)propertyManager.getProperty(Constants.ZEPHYR_PROPERTY_PREFIX + Constants.IGNORE_EXTERNAL_DTD)).booleanValue(); // JAXP 1.5 feature - fAccessExternalDTD = (String) propertyManager.getProperty(ACCESS_EXTERNAL_DTD); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) propertyManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); // initialize state //fStandalone = false; @@ -1485,7 +1488,11 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { fSecurityManager = (SecurityManager)componentManager.getProperty(SECURITY_MANAGER, null); // JAXP 1.5 feature - fAccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD, EXTERNAL_ACCESS_DEFAULT); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER, null); + if (spm == null) { + spm = new XMLSecurityPropertyManager(); + } + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); //reset general state reset(); @@ -1641,11 +1648,10 @@ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { } //JAXP 1.5 properties - if (propertyId.startsWith(Constants.JAXPAPI_PROPERTY_PREFIX)) { - if (propertyId.equals(ACCESS_EXTERNAL_DTD)) - { - fAccessExternalDTD = (String)value; - } + if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) + { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)value; + fAccessExternalDTD = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); } } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java index 3fbe23475d7..d37a0300ed8 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaLoader.java @@ -54,6 +54,7 @@ import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -218,6 +219,10 @@ XSLoader, DOMConfiguration { protected static final String ENTITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.ENTITY_MANAGER_PROPERTY; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + /** Property identifier: access to external dtd */ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; @@ -238,8 +243,7 @@ XSLoader, DOMConfiguration { SECURITY_MANAGER, LOCALE, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; // Data @@ -270,7 +274,6 @@ XSLoader, DOMConfiguration { private final CMNodeFactory fNodeFactory = new CMNodeFactory(); //component mgr will be set later private CMBuilder fCMBuilder; private XSDDescription fXSDDescription = new XSDDescription(); - private String faccessExternalDTD = Constants.EXTERNAL_ACCESS_DEFAULT; private String faccessExternalSchema = Constants.EXTERNAL_ACCESS_DEFAULT; private Map fJAXPCache; @@ -466,11 +469,9 @@ XSLoader, DOMConfiguration { fErrorReporter.putMessageFormatter(XSMessageFormatter.SCHEMA_DOMAIN, new XSMessageFormatter()); } } - else if (propertyId.equals(ACCESS_EXTERNAL_DTD)) { - faccessExternalDTD = (String) state; - } - else if (propertyId.equals(ACCESS_EXTERNAL_SCHEMA)) { - faccessExternalSchema = (String) state; + else if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)state; + faccessExternalSchema = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA); } } // setProperty(String, Object) @@ -1066,8 +1067,8 @@ XSLoader, DOMConfiguration { fSchemaHandler.setGenerateSyntheticAnnotations(componentManager.getFeature(GENERATE_SYNTHETIC_ANNOTATIONS, false)); fSchemaHandler.reset(componentManager); - faccessExternalDTD = (String) componentManager.getProperty(ACCESS_EXTERNAL_DTD); - faccessExternalSchema = (String) componentManager.getProperty(ACCESS_EXTERNAL_SCHEMA); + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager)componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + faccessExternalSchema = spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA); } private void initGrammarBucket(){ diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java index 170601cb46a..f7fc09a6d00 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/XMLSchemaValidator.java @@ -233,11 +233,9 @@ public class XMLSchemaValidator protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; - /** property identifier: access external dtd. */ - private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; protected static final String USE_SERVICE_MECHANISM = Constants.ORACLE_FEATURE_SERVICE_MECHANISM; @@ -297,8 +295,7 @@ public class XMLSchemaValidator JAXP_SCHEMA_SOURCE, JAXP_SCHEMA_LANGUAGE, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; /** Property defaults. */ diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java index eba1ac0de20..d947cf8815d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/xs/traversers/XSDHandler.java @@ -78,6 +78,7 @@ import com.sun.org.apache.xerces.internal.util.SymbolTable; import com.sun.org.apache.xerces.internal.util.XMLSymbols; import com.sun.org.apache.xerces.internal.util.URI.MalformedURIException; import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.QName; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; @@ -112,6 +113,7 @@ import org.w3c.dom.Element; import org.w3c.dom.Node; import org.xml.sax.InputSource; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; import org.xml.sax.SAXParseException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; @@ -223,11 +225,9 @@ public class XSDHandler { protected static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; - /** property identifier: access external dtd. */ - public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; protected static final boolean DEBUG_NODE_POOL = false; @@ -260,6 +260,7 @@ public class XSDHandler { protected SecurityManager fSecureProcessing = null; private String fAccessExternalSchema; + private String fAccessExternalDTD; // These tables correspond to the symbol spaces defined in the // spec. @@ -2249,6 +2250,13 @@ public class XSDHandler { } } catch (SAXException se) {} + + try { + parser.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, fAccessExternalDTD); + } catch (SAXNotRecognizedException exc) { + System.err.println("Warning: " + parser.getClass().getName() + ": " + + exc.getMessage()); + } } // If XML names and Namespace URIs are already internalized we // can avoid running them through the SymbolTable. @@ -3580,11 +3588,17 @@ public class XSDHandler { } catch (XMLConfigurationException e) { } - //For Schema validation, the secure feature is set to true by default - fSchemaParser.setProperty(ACCESS_EXTERNAL_DTD, - componentManager.getProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT)); - fAccessExternalSchema = (String) componentManager.getProperty( - ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); + XMLSecurityPropertyManager securityPropertyMgr = (XMLSecurityPropertyManager) + componentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); + //Passing on the setting to the parser + fSchemaParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, securityPropertyMgr); + + fAccessExternalDTD = securityPropertyMgr.getValue( + XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD); + + fAccessExternalSchema = securityPropertyMgr.getValue( + XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA); + } // reset(XMLComponentManager) diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java index 520bc87ea6a..0c90afec1f8 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java @@ -37,6 +37,9 @@ import com.sun.org.apache.xerces.internal.impl.xs.XMLSchemaValidator; import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer; import com.sun.org.apache.xerces.internal.parsers.DOMParser; import com.sun.org.apache.xerces.internal.util.SecurityManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager.Property; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager.State; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -97,12 +100,17 @@ public class DocumentBuilderImpl extends DocumentBuilder private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + /** property identifier: access external dtd. */ public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; /** Property identifier: access to external schema */ public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + private final DOMParser domParser; private final Schema grammar; @@ -117,6 +125,8 @@ public class DocumentBuilderImpl extends DocumentBuilder /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; + private XMLSecurityPropertyManager fSecurityPropertyMgr; + DocumentBuilderImpl(DocumentBuilderFactoryImpl dbf, Hashtable dbfAttrs, Hashtable features) throws SAXNotRecognizedException, SAXNotSupportedException { this(dbf, dbfAttrs, features, false); @@ -160,23 +170,27 @@ public class DocumentBuilderImpl extends DocumentBuilder domParser.setFeature(XINCLUDE_FEATURE, true); } + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + domParser.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + // If the secure processing feature is on set a security manager. if (secureProcessing) { domParser.setProperty(SECURITY_MANAGER, new SecurityManager()); /** - * By default, secure processing is set, no external access is allowed. - * However, we need to check if it is actively set on the factory since we - * allow the use of the System Property or jaxp.properties to override - * the default value + * If secure processing is explicitly set on the factory, the + * access properties will be set unless the corresponding + * System Properties or jaxp.properties are set */ if (features != null) { Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); if (temp != null) { boolean value = ((Boolean) temp).booleanValue(); - if (value) { - domParser.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + if (value && Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_DTD, + State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(Property.ACCESS_EXTERNAL_SCHEMA, + State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); } } } @@ -220,7 +234,7 @@ public class DocumentBuilderImpl extends DocumentBuilder setFeatures(features); } - // Set attributes + //setAttribute override those that may be set by other means setDocumentBuilderFactoryAttributes(dbfAttrs); // Initial EntityResolver @@ -275,26 +289,32 @@ public class DocumentBuilderImpl extends DocumentBuilder // spec when schema validation is enabled domParser.setProperty(JAXP_SCHEMA_LANGUAGE, W3C_XML_SCHEMA); } - } - } else if(JAXP_SCHEMA_SOURCE.equals(name)){ - if( isValidating() ) { - String value=(String)dbfAttrs.get(JAXP_SCHEMA_LANGUAGE); - if(value !=null && W3C_XML_SCHEMA.equals(value)){ - domParser.setProperty(name, val); - }else{ + } + } else if(JAXP_SCHEMA_SOURCE.equals(name)){ + if( isValidating() ) { + String value=(String)dbfAttrs.get(JAXP_SCHEMA_LANGUAGE); + if(value !=null && W3C_XML_SCHEMA.equals(value)){ + domParser.setProperty(name, val); + }else{ throw new IllegalArgumentException( DOMMessageFormatter.formatMessage(DOMMessageFormatter.DOM_DOMAIN, "jaxp-order-not-supported", new Object[] {JAXP_SCHEMA_LANGUAGE, JAXP_SCHEMA_SOURCE})); - } - } - } else { - // Let Xerces code handle the property - domParser.setProperty(name, val); - } } - } + } + } else { + int index = fSecurityPropertyMgr.getIndex(name); + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)val); + } else { + // Let Xerces code handle the property + domParser.setProperty(name, val); + } + } + } } + } /** * Non-preferred: use the getDOMImplementation() method instead of this diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java index a57c1543d84..21323af9469 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java @@ -36,6 +36,7 @@ import com.sun.org.apache.xerces.internal.jaxp.validation.XSGrammarPoolContainer import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponentManager; @@ -92,11 +93,9 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; - /** property identifier: access external dtd. */ - public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; private final JAXPSAXParser xmlReader; private String schemaLanguage = null; // null means DTD @@ -113,6 +112,8 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser /** Initial EntityResolver */ private final EntityResolver fInitEntityResolver; + private XMLSecurityPropertyManager fSecurityPropertyMgr; + /** * Create a SAX parser with the associated features * @param features Hashtable of SAX features, may be null @@ -149,6 +150,9 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser xmlReader.setFeature0(XINCLUDE_FEATURE, true); } + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + xmlReader.setProperty0(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + // If the secure processing feature is on set a security manager. if (secureProcessing) { xmlReader.setProperty0(SECURITY_MANAGER, new SecurityManager()); @@ -162,9 +166,12 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser Object temp = features.get(XMLConstants.FEATURE_SECURE_PROCESSING); if (temp != null) { boolean value = ((Boolean) temp).booleanValue(); - if (value) { - xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + if (value && Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + } } } @@ -530,14 +537,21 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser return; } } - if (!fInitProperties.containsKey(name)) { - fInitProperties.put(name, super.getProperty(name)); - } /** Forward property to the schema validator if there is one. **/ if (fSAXParser != null && fSAXParser.fSchemaValidator != null) { setSchemaValidatorProperty(name, value); } - super.setProperty(name, value); + /** Check to see if the property is managed by the property manager **/ + int index = fSAXParser.fSecurityPropertyMgr.getIndex(name); + if (index > -1) { + fSAXParser.fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + } else { + if (!fInitProperties.containsKey(name)) { + fInitProperties.put(name, super.getProperty(name)); + } + super.setProperty(name, value); + } } public synchronized Object getProperty(String name) @@ -550,6 +564,11 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser // JAXP 1.2 support return fSAXParser.schemaLanguage; } + int index = fSAXParser.fSecurityPropertyMgr.getIndex(name); + if (index > -1) { + return fSAXParser.fSecurityPropertyMgr.getValueByIndex(index); + } + return super.getProperty(name); } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java index 1b4f6875611..c3f1b674134 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/StreamValidatorHelper.java @@ -177,11 +177,11 @@ final class StreamValidatorHelper implements ValidatorHelper { } config.setProperty(SYMBOL_TABLE, fComponentManager.getProperty(SYMBOL_TABLE)); config.setProperty(VALIDATION_MANAGER, fComponentManager.getProperty(VALIDATION_MANAGER)); - config.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); config.setDocumentHandler(fSchemaValidator); config.setDTDHandler(null); config.setDTDContentModelHandler(null); + config.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, + fComponentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER)); fConfiguration = new SoftReference(config); return config; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java index 3f493517209..8add5d26441 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/ValidatorHandlerImpl.java @@ -53,6 +53,7 @@ import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.URI; import com.sun.org.apache.xerces.internal.util.XMLAttributesImpl; import com.sun.org.apache.xerces.internal.util.XMLSymbols; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.Augmentations; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.QName; @@ -134,6 +135,10 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements private static final String VALIDATION_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.VALIDATION_MANAGER_PROPERTY; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + // // Data // @@ -686,8 +691,10 @@ final class ValidatorHandlerImpl extends ValidatorHandler implements catch (SAXException exc) {} } try { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + fComponentManager.getProperty(XML_SECURITY_PROPERTY_MANAGER); reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, - fComponentManager.getProperty(XMLConstants.ACCESS_EXTERNAL_DTD)); + spm.getValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD)); } catch (SAXException exc) { System.err.println("Warning: " + reader.getClass().getName() + ": " + exc.getMessage()); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index 763fcdbd29f..a19088d9a67 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -45,7 +45,7 @@ import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.StAXInputSource; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.XMLGrammarPoolImpl; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.Grammar; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarDescription; @@ -83,11 +83,10 @@ public final class XMLSchemaFactory extends SchemaFactory { private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; - /** property identifier: access external dtd. */ - public static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; - /** Property identifier: access to external schema */ - public static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; // // Data @@ -111,6 +110,9 @@ public final class XMLSchemaFactory extends SchemaFactory { /** The SecurityManager. */ private SecurityManager fSecurityManager; + /** The Security property manager. */ + private XMLSecurityPropertyManager fSecurityPropertyMgr; + /** The container for the real grammar pool. */ private XMLGrammarPoolWrapper fXMLGrammarPoolWrapper; @@ -120,6 +122,8 @@ public final class XMLSchemaFactory extends SchemaFactory { * Note the default value (false) is the safe option.. */ private final boolean fUseServicesMechanism; + + public XMLSchemaFactory() { this(true); } @@ -140,13 +144,9 @@ public final class XMLSchemaFactory extends SchemaFactory { fSecurityManager = new SecurityManager(); fXMLSchemaLoader.setProperty(SECURITY_MANAGER, fSecurityManager); - //by default, the secure feature is set to true, otherwise the default would have been 'file' - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, accessExternal); - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, accessExternal); + fSecurityPropertyMgr = new XMLSecurityPropertyManager(); + fXMLSchemaLoader.setProperty(XML_SECURITY_PROPERTY_MANAGER, + fSecurityPropertyMgr); } /** @@ -282,6 +282,7 @@ public final class XMLSchemaFactory extends SchemaFactory { schema = new EmptyXMLSchema(); } propagateFeatures(schema); + propagateProperties(schema); return schema; } @@ -366,8 +367,13 @@ public final class XMLSchemaFactory extends SchemaFactory { } if (value) { fSecurityManager = new SecurityManager(); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); - fXMLSchemaLoader.setProperty(ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + + if (Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + } } else { fSecurityManager = null; } @@ -414,7 +420,13 @@ public final class XMLSchemaFactory extends SchemaFactory { "property-not-supported", new Object [] {name})); } try { - fXMLSchemaLoader.setProperty(name, object); + int index = fSecurityPropertyMgr.getIndex(name); + if (index > -1) { + fSecurityPropertyMgr.setValue(index, + XMLSecurityPropertyManager.State.APIPROPERTY, (String)object); + } else { + fXMLSchemaLoader.setProperty(name, object); + } } catch (XMLConfigurationException e) { String identifier = e.getIdentifier(); diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index 241d02cbf85..74e30daec1d 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -42,6 +42,7 @@ import com.sun.org.apache.xerces.internal.util.PropertyState; import com.sun.org.apache.xerces.internal.util.SecurityManager; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.NamespaceContext; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.parser.XMLComponent; @@ -107,6 +108,10 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private static final String SECURITY_MANAGER = Constants.XERCES_PROPERTY_PREFIX + Constants.SECURITY_MANAGER_PROPERTY; + /** Property identifier: security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + /** Property identifier: symbol table. */ private static final String SYMBOL_TABLE = Constants.XERCES_PROPERTY_PREFIX + Constants.SYMBOL_TABLE_PROPERTY; @@ -123,12 +128,6 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private static final String LOCALE = Constants.XERCES_PROPERTY_PREFIX + Constants.LOCALE_PROPERTY; - /** property identifier: access external dtd. */ - private static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** Property identifier: access to external schema */ - private static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; - // // Data // @@ -184,6 +183,9 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin /** Stores the initial security manager. */ private final SecurityManager fInitSecurityManager; + /** Stores the initial security property manager. */ + private final XMLSecurityPropertyManager fSecurityPropertyMgr; + // // User Objects // @@ -250,8 +252,9 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin fComponents.put(SECURITY_MANAGER, fInitSecurityManager); //pass on properties set on SchemaFactory - setProperty(ACCESS_EXTERNAL_DTD, grammarContainer.getProperty(ACCESS_EXTERNAL_DTD)); - setProperty(ACCESS_EXTERNAL_SCHEMA, grammarContainer.getProperty(ACCESS_EXTERNAL_SCHEMA)); + fSecurityPropertyMgr = (XMLSecurityPropertyManager) + grammarContainer.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER); + setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); } /** @@ -309,6 +312,15 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin throw new XMLConfigurationException(Status.NOT_ALLOWED, XMLConstants.FEATURE_SECURE_PROCESSING); } setProperty(SECURITY_MANAGER, value ? new SecurityManager() : null); + + if (value && Constants.IS_JDK8_OR_ABOVE) { + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_SCHEMA, + XMLSecurityPropertyManager.State.FSP, Constants.EXTERNAL_ACCESS_DEFAULT_FSP); + setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); + } + return; } fConfigUpdated = true; diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java index cfdab6b4024..f681fadbd33 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/DOMParser.java @@ -29,6 +29,7 @@ import com.sun.org.apache.xerces.internal.util.ErrorHandlerWrapper; import com.sun.org.apache.xerces.internal.util.SAXMessageFormatter; import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XNIException; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLConfigurationException; @@ -74,6 +75,10 @@ public class DOMParser protected static final String REPORT_WHITESPACE = Constants.SUN_SCHEMA_FEATURE_PREFIX + Constants.SUN_REPORT_IGNORED_ELEMENT_CONTENT_WHITESPACE; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; + // recognized features: private static final String[] RECOGNIZED_FEATURES = { REPORT_WHITESPACE @@ -579,6 +584,13 @@ public class DOMParser } try { + XMLSecurityPropertyManager spm = (XMLSecurityPropertyManager) + fConfiguration.getProperty(XML_SECURITY_PROPERTY_MANAGER); + int index = spm.getIndex(propertyId); + if (index > -1) { + return spm.getValueByIndex(index); + } + return fConfiguration.getProperty(propertyId); } catch (XMLConfigurationException e) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java index d134454e8cc..cf9e9a79f92 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/SAXParser.java @@ -22,8 +22,11 @@ package com.sun.org.apache.xerces.internal.parsers; import com.sun.org.apache.xerces.internal.impl.Constants; import com.sun.org.apache.xerces.internal.util.SymbolTable; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.grammars.XMLGrammarPool; import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; /** * This is the main Xerces SAX parser class. It uses the abstract SAX @@ -120,4 +123,24 @@ public class SAXParser } // (SymbolTable,XMLGrammarPool) + /** + * Sets the particular property in the underlying implementation of + * org.xml.sax.XMLReader. + */ + public void setProperty(String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException { + XMLSecurityPropertyManager spm = new XMLSecurityPropertyManager(); + int index = spm.getIndex(name); + if (index > -1) { + /** + * this is a direct call to this parser, not a subclass since + * internally the support of this property is done through + * XMLSecurityPropertyManager + */ + spm.setValue(index, XMLSecurityPropertyManager.State.APIPROPERTY, (String)value); + super.setProperty(Constants.XML_SECURITY_PROPERTY_MANAGER, spm); + } else { + super.setProperty(name, value); + } + } } // class SAXParser diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java index 32ac6a86d78..993ef6132bd 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/parsers/XML11Configuration.java @@ -20,12 +20,10 @@ package com.sun.org.apache.xerces.internal.parsers; -import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; -import java.util.Properties; import javax.xml.XMLConstants; import com.sun.org.apache.xerces.internal.impl.Constants; @@ -53,9 +51,8 @@ import com.sun.org.apache.xerces.internal.impl.xs.XSMessageFormatter; import com.sun.org.apache.xerces.internal.util.FeatureState; import com.sun.org.apache.xerces.internal.util.ParserConfigurationSettings; import com.sun.org.apache.xerces.internal.util.PropertyState; -import com.sun.org.apache.xerces.internal.util.Status; import com.sun.org.apache.xerces.internal.util.SymbolTable; -import com.sun.org.apache.xerces.internal.utils.SecuritySupport; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import com.sun.org.apache.xerces.internal.xni.XMLDTDContentModelHandler; import com.sun.org.apache.xerces.internal.xni.XMLDTDHandler; import com.sun.org.apache.xerces.internal.xni.XMLDocumentHandler; @@ -278,11 +275,10 @@ public class XML11Configuration extends ParserConfigurationSettings protected static final String SCHEMA_DV_FACTORY = Constants.XERCES_PROPERTY_PREFIX + Constants.SCHEMA_DV_FACTORY_PROPERTY; - /** Property identifier: access to external dtd */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; + /** Property identifier: Security property manager. */ + private static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; - /** Property identifier: access to external schema */ - protected static final String ACCESS_EXTERNAL_SCHEMA = XMLConstants.ACCESS_EXTERNAL_SCHEMA; // debugging @@ -535,8 +531,7 @@ public class XML11Configuration extends ParserConfigurationSettings SCHEMA_NONS_LOCATION, LOCALE, SCHEMA_DV_FACTORY, - ACCESS_EXTERNAL_DTD, - ACCESS_EXTERNAL_SCHEMA + XML_SECURITY_PROPERTY_MANAGER }; addRecognizedProperties(recognizedProperties); @@ -584,14 +579,7 @@ public class XML11Configuration extends ParserConfigurationSettings fVersionDetector = new XMLVersionDetector(); - //FEATURE_SECURE_PROCESSING is true, see the feature above - String accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_DTD, Constants.EXTERNAL_ACCESS_DEFAULT); - fProperties.put(ACCESS_EXTERNAL_DTD, accessExternal); - - accessExternal = SecuritySupport.getDefaultAccessProperty( - Constants.SP_ACCESS_EXTERNAL_SCHEMA, Constants.EXTERNAL_ACCESS_DEFAULT); - fProperties.put(ACCESS_EXTERNAL_SCHEMA, accessExternal); + fProperties.put(XML_SECURITY_PROPERTY_MANAGER, new XMLSecurityPropertyManager()); // add message formatters if (fErrorReporter.getMessageFormatter(XMLMessageFormatter.XML_DOMAIN) == null) { diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java index 7b6d1d553d8..995105902f1 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/SecuritySupport.java @@ -223,7 +223,8 @@ public final class SecuritySupport { * @return the name of the protocol if rejected, null otherwise */ public static String checkAccess(String systemId, String allowedProtocols, String accessAny) throws IOException { - if (systemId == null || allowedProtocols.equalsIgnoreCase(accessAny)) { + if (systemId == null || (allowedProtocols != null && + allowedProtocols.equalsIgnoreCase(accessAny))) { return null; } @@ -256,6 +257,9 @@ public final class SecuritySupport { * @return true if the protocol is in the list */ private static boolean isProtocolAllowed(String protocol, String allowedProtocols) { + if (allowedProtocols == null) { + return false; + } String temp[] = allowedProtocols.split(","); for (String t : temp) { t = t.trim(); @@ -267,18 +271,16 @@ public final class SecuritySupport { } /** - * Read from $java.home/lib/jaxp.properties for the specified property + * Read JAXP system property in this order: system property, + * $java.home/lib/jaxp.properties if the system property is not specified * * @param propertyId the Id of the property * @return the value of the property */ - public static String getDefaultAccessProperty(String sysPropertyId, String defaultVal) { - String accessExternal = SecuritySupport.getSystemProperty(sysPropertyId); + public static String getJAXPSystemProperty(String sysPropertyId) { + String accessExternal = getSystemProperty(sysPropertyId); if (accessExternal == null) { accessExternal = readJAXPProperty(sysPropertyId); - if (accessExternal == null) { - accessExternal = defaultVal; - } } return accessExternal; } diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java new file mode 100644 index 00000000000..c6bb0310702 --- /dev/null +++ b/jaxp/src/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.org.apache.xerces.internal.utils; + +import com.sun.org.apache.xerces.internal.impl.Constants; +import javax.xml.XMLConstants; + +/** + * This class manages security related properties + * + */ +public final class XMLSecurityPropertyManager { + + /** + * States of the settings of a property, in the order: default value, value + * set by FEATURE_SECURE_PROCESSING, jaxp.properties file, jaxp system + * properties, and jaxp api properties + */ + public static enum State { + //this order reflects the overriding order + DEFAULT, FSP, JAXPDOTPROPERTIES, SYSTEMPROPERTY, APIPROPERTY + } + + /** + * Limits managed by the security manager + */ + public static enum Property { + ACCESS_EXTERNAL_DTD(XMLConstants.ACCESS_EXTERNAL_DTD, + Constants.EXTERNAL_ACCESS_DEFAULT), + ACCESS_EXTERNAL_SCHEMA(XMLConstants.ACCESS_EXTERNAL_SCHEMA, + Constants.EXTERNAL_ACCESS_DEFAULT); + + final String name; + final String defaultValue; + + Property(String name, String value) { + this.name = name; + this.defaultValue = value; + } + + public boolean equalsName(String propertyName) { + return (propertyName == null) ? false : name.equals(propertyName); + } + + String defaultValue() { + return defaultValue; + } + } + + /** + * Values of the properties as defined in enum Properties + */ + private final String[] values; + /** + * States of the settings for each property in Properties above + */ + private State[] states = {State.DEFAULT, State.DEFAULT}; + + /** + * Default constructor. Establishes default values + */ + public XMLSecurityPropertyManager() { + values = new String[Property.values().length]; + for (Property property : Property.values()) { + values[property.ordinal()] = property.defaultValue(); + } + //read system properties or jaxp.properties + readSystemProperties(); + } + + /** + * Set the value for a specific property. + * + * @param property the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(Property property, State state, String value) { + //only update if it shall override + if (state.compareTo(states[property.ordinal()]) >= 0) { + values[property.ordinal()] = value; + states[property.ordinal()] = state; + } + } + + /** + * Set the value of a property by its index + * @param index the index of the property + * @param state the state of the property + * @param value the value of the property + */ + public void setValue(int index, State state, String value) { + //only update if it shall override + if (state.compareTo(states[index]) >= 0) { + values[index] = value; + states[index] = state; + } + } + /** + * Return the value of the specified property + * + * @param property the property + * @return the value of the property + */ + public String getValue(Property property) { + return values[property.ordinal()]; + } + + /** + * Return the value of a property by its ordinal + * @param index the index of a property + * @return value of a property + */ + public String getValueByIndex(int index) { + return values[index]; + } + + /** + * Get the index by property name + * @param propertyName property name + * @return the index of the property if found; return -1 if not + */ + public int getIndex(String propertyName){ + for (Property property : Property.values()) { + if (property.equalsName(propertyName)) { + //internally, ordinal is used as index + return property.ordinal(); + } + } + return -1; + } + + /** + * Read from system properties, or those in jaxp.properties + */ + private void readSystemProperties() { + getSystemProperty(Property.ACCESS_EXTERNAL_DTD, + Constants.SP_ACCESS_EXTERNAL_DTD); + getSystemProperty(Property.ACCESS_EXTERNAL_SCHEMA, + Constants.SP_ACCESS_EXTERNAL_SCHEMA); + } + + /** + * Read from system properties, or those in jaxp.properties + * + * @param property the property + * @param systemProperty the name of the system property + */ + private void getSystemProperty(Property property, String systemProperty) { + try { + String value = SecuritySupport.getSystemProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.SYSTEMPROPERTY; + return; + } + + value = SecuritySupport.readJAXPProperty(systemProperty); + if (value != null) { + values[property.ordinal()] = value; + states[property.ordinal()] = State.JAXPDOTPROPERTIES; + } + } catch (NumberFormatException e) { + //invalid setting ignored + } + } +} diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java index ba7284609e1..0c01d601c06 100644 --- a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java +++ b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/XIncludeHandler.java @@ -68,6 +68,7 @@ import com.sun.org.apache.xerces.internal.xni.parser.XMLParserConfiguration; import com.sun.org.apache.xerces.internal.xpointer.XPointerHandler; import com.sun.org.apache.xerces.internal.xpointer.XPointerProcessor; import com.sun.org.apache.xerces.internal.utils.ObjectFactory; +import com.sun.org.apache.xerces.internal.utils.XMLSecurityPropertyManager; import java.util.Objects; /** @@ -231,13 +232,9 @@ public class XIncludeHandler protected static final String PARSER_SETTINGS = Constants.XERCES_FEATURE_PREFIX + Constants.PARSER_SETTINGS; - /** property identifier: access external dtd. */ - protected static final String ACCESS_EXTERNAL_DTD = XMLConstants.ACCESS_EXTERNAL_DTD; - - /** access external dtd: file protocol - * For DOM/SAX, the secure feature is set to true by default - */ - final static String EXTERNAL_ACCESS_DEFAULT = Constants.EXTERNAL_ACCESS_DEFAULT; + /** property identifier: XML security property manager. */ + protected static final String XML_SECURITY_PROPERTY_MANAGER = + Constants.XML_SECURITY_PROPERTY_MANAGER; /** Recognized features. */ private static final String[] RECOGNIZED_FEATURES = @@ -293,12 +290,7 @@ public class XIncludeHandler protected XMLErrorReporter fErrorReporter; protected XMLEntityResolver fEntityResolver; protected SecurityManager fSecurityManager; - /** - * comma-delimited list of protocols that are allowed for the purpose - * of accessing external dtd or entity references - */ - protected String fAccessExternalDTD = EXTERNAL_ACCESS_DEFAULT; - + protected XMLSecurityPropertyManager fSecurityPropertyMgr; // these are needed for text include processing protected XIncludeTextReader fXInclude10TextReader; @@ -540,7 +532,8 @@ public class XIncludeHandler fSecurityManager = null; } - fAccessExternalDTD = (String)componentManager.getProperty(ACCESS_EXTERNAL_DTD); + fSecurityPropertyMgr = (XMLSecurityPropertyManager) + componentManager.getProperty(Constants.XML_SECURITY_PROPERTY_MANAGER); // Get buffer size. try { @@ -687,11 +680,13 @@ public class XIncludeHandler } return; } - if (propertyId.equals(ACCESS_EXTERNAL_DTD)) { - fAccessExternalDTD = (String)value; + if (propertyId.equals(XML_SECURITY_PROPERTY_MANAGER)) { + fSecurityPropertyMgr = (XMLSecurityPropertyManager)value; + if (fChildConfig != null) { - fChildConfig.setProperty(propertyId, value); + fChildConfig.setProperty(XML_SECURITY_PROPERTY_MANAGER, value); } + return; } @@ -1652,7 +1647,7 @@ public class XIncludeHandler if (fErrorReporter != null) fChildConfig.setProperty(ERROR_REPORTER, fErrorReporter); if (fEntityResolver != null) fChildConfig.setProperty(ENTITY_RESOLVER, fEntityResolver); fChildConfig.setProperty(SECURITY_MANAGER, fSecurityManager); - fChildConfig.setProperty(ACCESS_EXTERNAL_DTD, fAccessExternalDTD); + fChildConfig.setProperty(XML_SECURITY_PROPERTY_MANAGER, fSecurityPropertyMgr); fChildConfig.setProperty(BUFFER_SIZE, new Integer(fBufferSize)); // features must be copied to child configuration diff --git a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index 28002037272..cab4f46bd42 100644 --- a/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/jaxp/src/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -140,12 +140,6 @@ public class XMLReaderManager { // Try to carry on if we've got a parser that // doesn't know about namespace prefixes. } - try { - reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); - } catch (SAXException se) { - System.err.println("Warning: " + reader.getClass().getName() + ": " - + se.getMessage()); - } } catch (ParserConfigurationException ex) { throw new SAXException(ex); } catch (FactoryConfigurationError ex1) { @@ -162,6 +156,14 @@ public class XMLReaderManager { } } + try { + //reader is cached, but this property might have been reset + reader.setProperty(XMLConstants.ACCESS_EXTERNAL_DTD, _accessExternalDTD); + } catch (SAXException se) { + System.err.println("Warning: " + reader.getClass().getName() + ": " + + se.getMessage()); + } + return reader; } From 41c47ddf53a1337f7809796bd6ef6e115d97a37b Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 10 Jul 2013 13:25:07 +0530 Subject: [PATCH 063/156] 8020224: LinkageError: attempted duplicate class definition when --loader-per-compiler=false Reviewed-by: hannesw --- .../nashorn/internal/codegen/Compiler.java | 5 +- .../internal/runtime/CodeInstaller.java | 6 +++ .../jdk/nashorn/internal/runtime/Context.java | 12 +++++ .../runtime/TrustedScriptEngineTest.java | 51 +++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java index 72fcf178bea..e40986d4e4a 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java @@ -528,7 +528,7 @@ public final class Compiler { return this.env; } - private static String safeSourceName(final Source source) { + private String safeSourceName(final Source source) { String baseName = new File(source.getName()).getName(); final int index = baseName.lastIndexOf(".js"); @@ -537,6 +537,9 @@ public final class Compiler { } baseName = baseName.replace('.', '_').replace('-', '_'); + if (! env._loader_per_compile) { + baseName = baseName + installer.getUniqueScriptId(); + } final String mangled = NameCodec.encode(baseName); return mangled != null ? mangled : baseName; diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java index 80fac179cb0..be9976e7d84 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/CodeInstaller.java @@ -62,4 +62,10 @@ public interface CodeInstaller { * @param code bytecode to verify */ public void verify(final byte[] code); + + /** + * Get next unique script id + * @return unique script id + */ + public long getUniqueScriptId(); } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index 7d639cd31c3..dae27cd9e42 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -96,6 +96,11 @@ public final class Context { public void verify(final byte[] code) { context.verify(code); } + + @Override + public long getUniqueScriptId() { + return context.getUniqueScriptId(); + } } /** Is Context global debug mode enabled ? */ @@ -197,6 +202,9 @@ public final class Context { /** Current error manager. */ private final ErrorManager errors; + /** Unique id for script. Used only when --loader-per-compile=false */ + private long uniqueScriptId; + private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; private static final AccessControlContext NO_PERMISSIONS_CONTEXT; @@ -816,4 +824,8 @@ public final class Context { private ScriptObject newGlobalTrusted() { return new Global(this); } + + private synchronized long getUniqueScriptId() { + return uniqueScriptId++; + } } diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java index 0f740a483c6..f7f7c6ae298 100644 --- a/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java @@ -145,4 +145,55 @@ public class TrustedScriptEngineTest { fail("Cannot find nashorn factory!"); } + + @Test + /** + * Test repeated evals with --loader-per-compile=false + * We used to get "class redefinition error". + */ + public void noLoaderPerCompilerTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + final String[] options = new String[] { "--loader-per-compile=false" }; + final ScriptEngine e = nfac.getScriptEngine(options); + try { + e.eval("2 + 3"); + e.eval("4 + 4"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + return; + } + } + fail("Cannot find nashorn factory!"); + } + + @Test + /** + * Test that we can use same script name in repeated evals with --loader-per-compile=false + * We used to get "class redefinition error" as name was derived from script name. + */ + public void noLoaderPerCompilerWithSameNameTest() { + final ScriptEngineManager sm = new ScriptEngineManager(); + for (ScriptEngineFactory fac : sm.getEngineFactories()) { + if (fac instanceof NashornScriptEngineFactory) { + final NashornScriptEngineFactory nfac = (NashornScriptEngineFactory)fac; + final String[] options = new String[] { "--loader-per-compile=false" }; + final ScriptEngine e = nfac.getScriptEngine(options); + e.put(ScriptEngine.FILENAME, "test.js"); + try { + e.eval("2 + 3"); + e.eval("4 + 4"); + } catch (final ScriptException se) { + se.printStackTrace(); + fail(se.getMessage()); + } + return; + } + } + fail("Cannot find nashorn factory!"); + } } From 652b0209056637422dc9b76f479a558487e6cfc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= Date: Wed, 10 Jul 2013 10:54:19 +0200 Subject: [PATCH 064/156] 8016681: regex capture behaves differently than on V8 Reviewed-by: lagergren, sundar --- .../runtime/regexp/RegExpScanner.java | 58 ++++++++++--------- nashorn/test/script/basic/JDK-8016681.js | 42 ++++++++++++++ .../test/script/basic/JDK-8016681.js.EXPECTED | 15 +++++ 3 files changed, 87 insertions(+), 28 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8016681.js create mode 100644 nashorn/test/script/basic/JDK-8016681.js.EXPECTED diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java index 52829fac099..68df99f3af3 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java @@ -57,7 +57,10 @@ final class RegExpScanner extends Scanner { private final LinkedList forwardReferences = new LinkedList<>(); /** Current level of zero-width negative lookahead assertions. */ - private int negativeLookaheadLevel; + private int negLookaheadLevel; + + /** Sequential id of current top-level zero-width negative lookahead assertion. */ + private int negLookaheadGroup; /** Are we currently inside a character class? */ private boolean inCharClass = false; @@ -68,17 +71,18 @@ final class RegExpScanner extends Scanner { private static final String NON_IDENT_ESCAPES = "$^*+(){}[]|\\.?-"; private static class Capture { - /** - * Zero-width negative lookaheads enclosing the capture. - */ - private final int negativeLookaheadLevel; + /** Zero-width negative lookaheads enclosing the capture. */ + private final int negLookaheadLevel; + /** Sequential id of top-level negative lookaheads containing the capture. */ + private final int negLookaheadGroup; - Capture(final int negativeLookaheadLevel) { - this.negativeLookaheadLevel = negativeLookaheadLevel; + Capture(final int negLookaheadGroup, final int negLookaheadLevel) { + this.negLookaheadGroup = negLookaheadGroup; + this.negLookaheadLevel = negLookaheadLevel; } - public int getNegativeLookaheadLevel() { - return negativeLookaheadLevel; + boolean isContained(final int group, final int level) { + return group == this.negLookaheadGroup && level >= this.negLookaheadLevel; } } @@ -152,7 +156,7 @@ final class RegExpScanner extends Scanner { BitVector vec = null; for (int i = 0; i < caps.size(); i++) { final Capture cap = caps.get(i); - if (cap.getNegativeLookaheadLevel() > 0) { + if (cap.negLookaheadLevel > 0) { if (vec == null) { vec = new BitVector(caps.size() + 1); } @@ -311,11 +315,14 @@ final class RegExpScanner extends Scanner { commit(3); if (isNegativeLookahead) { - negativeLookaheadLevel++; + if (negLookaheadLevel == 0) { + negLookaheadGroup++; + } + negLookaheadLevel++; } disjunction(); if (isNegativeLookahead) { - negativeLookaheadLevel--; + negLookaheadLevel--; } if (ch0 == ')') { @@ -432,20 +439,17 @@ final class RegExpScanner extends Scanner { } if (ch0 == '(') { - boolean capturingParens = true; commit(1); if (ch0 == '?' && ch1 == ':') { - capturingParens = false; commit(2); + } else { + caps.add(new Capture(negLookaheadGroup, negLookaheadLevel)); } disjunction(); if (ch0 == ')') { commit(1); - if (capturingParens) { - caps.add(new Capture(negativeLookaheadLevel)); - } return true; } } @@ -675,24 +679,22 @@ final class RegExpScanner extends Scanner { sb.setLength(sb.length() - 1); octalOrLiteral(Integer.toString(decimalValue), sb); - } else if (decimalValue <= caps.size() && caps.get(decimalValue - 1).getNegativeLookaheadLevel() > 0) { - // Captures that live inside a negative lookahead are dead after the - // lookahead and will be undefined if referenced from outside. - if (caps.get(decimalValue - 1).getNegativeLookaheadLevel() > negativeLookaheadLevel) { + } else if (decimalValue <= caps.size()) { + // Captures inside a negative lookahead are undefined when referenced from the outside. + if (!caps.get(decimalValue - 1).isContained(negLookaheadGroup, negLookaheadLevel)) { + // Reference to capture in negative lookahead, omit from output buffer. sb.setLength(sb.length() - 1); } else { + // Append backreference to output buffer. sb.append(decimalValue); } - } else if (decimalValue > caps.size()) { - // Forward reference to a capture group. Forward references are always undefined so we can omit - // it from the output buffer. However, if the target capture does not exist, we need to rewrite - // the reference as hex escape or literal string, so register the reference for later processing. + } else { + // Forward references to a capture group are always undefined so we can omit it from the output buffer. + // However, if the target capture does not exist, we need to rewrite the reference as hex escape + // or literal string, so register the reference for later processing. sb.setLength(sb.length() - 1); forwardReferences.add(decimalValue); forwardReferences.add(sb.length()); - } else { - // Append as backreference - sb.append(decimalValue); } } diff --git a/nashorn/test/script/basic/JDK-8016681.js b/nashorn/test/script/basic/JDK-8016681.js new file mode 100644 index 00000000000..9596b0ddbd3 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8016681.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8016681: regex capture behaves differently than on V8 + * + * @test + * @run + */ + +// regexp similar to the one used in marked.js +/^((?:[^\n]+\n?(?!( *[-*_]){3,} *(?:\n+|$)| *(#{1,6}) *([^\n]+?) *#* *(?:\n+|$)|([^\n]+)\n *(=|-){3,} *\n*))+)\n*/ + .exec("a\n\nb") + .forEach(function(e) { print(e); }); + +// simplified regexp +/(x(?!(a))(?!(b))y)/ + .exec("xy") + .forEach(function(e) { print(e); }); + +// should not match as cross-negative-lookeahead backreference \2 should be undefined +print(/(x(?!(a))(?!(b)\2))/.exec("xbc")); diff --git a/nashorn/test/script/basic/JDK-8016681.js.EXPECTED b/nashorn/test/script/basic/JDK-8016681.js.EXPECTED new file mode 100644 index 00000000000..06b855074ea --- /dev/null +++ b/nashorn/test/script/basic/JDK-8016681.js.EXPECTED @@ -0,0 +1,15 @@ +a + + +a + +undefined +undefined +undefined +undefined +undefined +xy +xy +undefined +undefined +null From 54b18575504438613967559557645be00ae5494c Mon Sep 17 00:00:00 2001 From: Erik Helin Date: Wed, 10 Jul 2013 15:28:43 +0200 Subject: [PATCH 065/156] 8013939: Metaspace capacity not available Reviewed-by: tschatzl, mgerdin, stefank --- hotspot/src/share/vm/gc_interface/collectedHeap.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp index 4c6c026e74b..dfc963c3bc4 100644 --- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp +++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp @@ -85,16 +85,16 @@ GCHeapSummary CollectedHeap::create_heap_summary() { MetaspaceSummary CollectedHeap::create_metaspace_summary() { const MetaspaceSizes meta_space( - 0, /*MetaspaceAux::capacity_in_bytes(),*/ - 0, /*MetaspaceAux::used_in_bytes(),*/ + MetaspaceAux::allocated_capacity_bytes(), + MetaspaceAux::allocated_used_bytes(), MetaspaceAux::reserved_in_bytes()); const MetaspaceSizes data_space( - 0, /*MetaspaceAux::capacity_in_bytes(Metaspace::NonClassType),*/ - 0, /*MetaspaceAux::used_in_bytes(Metaspace::NonClassType),*/ + MetaspaceAux::allocated_capacity_bytes(Metaspace::NonClassType), + MetaspaceAux::allocated_used_bytes(Metaspace::NonClassType), MetaspaceAux::reserved_in_bytes(Metaspace::NonClassType)); const MetaspaceSizes class_space( - 0, /*MetaspaceAux::capacity_in_bytes(Metaspace::ClassType),*/ - 0, /*MetaspaceAux::used_in_bytes(Metaspace::ClassType),*/ + MetaspaceAux::allocated_capacity_bytes(Metaspace::ClassType), + MetaspaceAux::allocated_used_bytes(Metaspace::ClassType), MetaspaceAux::reserved_in_bytes(Metaspace::ClassType)); return MetaspaceSummary(meta_space, data_space, class_space); From 48c4649f17a8ce482c8b5a442d695b4d3fa3df94 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Wed, 10 Jul 2013 19:08:04 +0530 Subject: [PATCH 066/156] 8020276: interface checks in Invocable.getInterface implementation Reviewed-by: jlaskey, hannesw, attila --- .../api/scripting/NashornScriptEngine.java | 19 +++++++ .../jdk/nashorn/internal/runtime/Context.java | 15 ++++-- .../runtime/linker/JavaAdapterFactory.java | 11 +++++ .../api/scripting/ScriptEngineTest.java | 49 +++++++++++++++++++ 4 files changed, 90 insertions(+), 4 deletions(-) diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index d38e63c88b8..64574229d0a 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -33,6 +33,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.Reader; import java.lang.reflect.Method; +import java.lang.reflect.Modifier; import java.net.URL; import java.nio.charset.Charset; import java.security.AccessController; @@ -184,6 +185,23 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } private T getInterfaceInner(final Object self, final Class clazz) { + if (clazz == null || !clazz.isInterface()) { + throw new IllegalArgumentException("interface Class expected"); + } + + // perform security access check as early as possible + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + if (! Modifier.isPublic(clazz.getModifiers())) { + throw new SecurityException("attempt to implement non-public interfce: " + clazz); + } + final String fullName = clazz.getName(); + final int index = fullName.lastIndexOf('.'); + if (index != -1) { + sm.checkPackageAccess(fullName.substring(0, index)); + } + } + final ScriptObject realSelf; final ScriptObject ctxtGlobal = getNashornGlobalFrom(context); if(self == null) { @@ -193,6 +211,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C } else { realSelf = (ScriptObject)self; } + try { final ScriptObject oldGlobal = getNashornGlobal(); try { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index dae27cd9e42..fb362b1725e 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -36,6 +36,7 @@ import java.io.IOException; import java.io.PrintWriter; import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; +import java.util.concurrent.atomic.AtomicLong; import java.net.MalformedURLException; import java.net.URL; import java.security.AccessControlContext; @@ -203,7 +204,7 @@ public final class Context { private final ErrorManager errors; /** Unique id for script. Used only when --loader-per-compile=false */ - private long uniqueScriptId; + private final AtomicLong uniqueScriptId; private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; @@ -263,7 +264,13 @@ public final class Context { this.env = new ScriptEnvironment(options, out, err); this._strict = env._strict; this.appLoader = appLoader; - this.scriptLoader = env._loader_per_compile? null : createNewLoader(); + if (env._loader_per_compile) { + this.scriptLoader = null; + this.uniqueScriptId = null; + } else { + this.scriptLoader = createNewLoader(); + this.uniqueScriptId = new AtomicLong(); + } this.errors = errors; // if user passed -classpath option, make a class loader with that and set it as @@ -825,7 +832,7 @@ public final class Context { return new Global(this); } - private synchronized long getUniqueScriptId() { - return uniqueScriptId++; + private long getUniqueScriptId() { + return uniqueScriptId.getAndIncrement(); } } diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java index f207d37cf66..77dcc695a0a 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java @@ -99,6 +99,17 @@ public final class JavaAdapterFactory { */ public static StaticClass getAdapterClassFor(final Class[] types, ScriptObject classOverrides) { assert types != null && types.length > 0; + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + for (Class type : types) { + // check for restricted package access + final String fullName = type.getName(); + final int index = fullName.lastIndexOf('.'); + if (index != -1) { + sm.checkPackageAccess(fullName.substring(0, index)); + } + } + } return getAdapterInfo(types).getAdapterClassFor(classOverrides); } diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index a6c015a1e54..73572502605 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -36,6 +36,7 @@ import java.io.StringWriter; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; +import java.util.Objects; import java.util.concurrent.Callable; import javax.script.Bindings; import javax.script.Compilable; @@ -344,6 +345,23 @@ public class ScriptEngineTest { foo2.bar2(); } + @Test + /** + * Try passing non-interface Class object for interface implementation. + */ + public void getNonInterfaceGetInterfaceTest() { + final ScriptEngineManager manager = new ScriptEngineManager(); + final ScriptEngine engine = manager.getEngineByName("nashorn"); + try { + log(Objects.toString(((Invocable)engine).getInterface(Object.class))); + fail("Should have thrown IllegalArgumentException"); + } catch (final Exception exp) { + if (! (exp instanceof IllegalArgumentException)) { + fail("IllegalArgumentException expected, got " + exp); + } + } + } + @Test public void accessGlobalTest() { final ScriptEngineManager m = new ScriptEngineManager(); @@ -927,4 +945,35 @@ public class ScriptEngineTest { Assert.assertEquals(itf.test1(42, "a", "b"), "i == 42, strings instanceof java.lang.String[] == true, strings == [a, b]"); Assert.assertEquals(itf.test2(44, "c", "d", "e"), "arguments[0] == 44, arguments[1] instanceof java.lang.String[] == true, arguments[1] == [c, d, e]"); } + + @Test + /** + * Check that script can't implement sensitive package interfaces. + */ + public void checkSensitiveInterfaceImplTest() throws ScriptException { + final ScriptEngineManager m = new ScriptEngineManager(); + final ScriptEngine e = m.getEngineByName("nashorn"); + final Object[] holder = new Object[1]; + e.put("holder", holder); + // put an empty script object into array + e.eval("holder[0] = {}"); + // holder[0] is an object of some subclass of ScriptObject + Class ScriptObjectClass = holder[0].getClass().getSuperclass(); + Class PropertyAccessClass = ScriptObjectClass.getInterfaces()[0]; + // implementation methods for PropertyAccess class + e.eval("function set() {}; function get() {}; function getInt(){} " + + "function getDouble(){}; function getLong() {}; " + + "this.delete = function () {}; function has() {}; " + + "function hasOwnProperty() {}"); + + // get implementation of a restricted package interface + try { + log(Objects.toString(((Invocable)e).getInterface(PropertyAccessClass))); + fail("should have thrown SecurityException"); + } catch (final Exception exp) { + if (! (exp instanceof SecurityException)) { + fail("SecurityException expected, got " + exp); + } + } + } } From 701d77dfd1192fd17cc2cb9242262eabbb16ebc5 Mon Sep 17 00:00:00 2001 From: Jennifer Godinez Date: Wed, 10 Jul 2013 11:49:04 -0700 Subject: [PATCH 067/156] 8016737: After clicking on "Print UNCOLLATED" button, the print out come in order 'Page 1', 'Page 2', 'Page 1' Reviewed-by: jchen, prr --- .../solaris/classes/sun/print/IPPPrintService.java | 11 ++++++++++- .../classes/sun/print/UnixPrintServiceLookup.java | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/jdk/src/solaris/classes/sun/print/IPPPrintService.java b/jdk/src/solaris/classes/sun/print/IPPPrintService.java index 1c441bd197e..dea62374103 100644 --- a/jdk/src/solaris/classes/sun/print/IPPPrintService.java +++ b/jdk/src/solaris/classes/sun/print/IPPPrintService.java @@ -1029,7 +1029,16 @@ public class IPPPrintService implements PrintService, SunPrinterJobService { // now supports collation and that most OS has a way // of setting it, it is a safe assumption to just always // include SheetCollate as supported attribute. - catList.add(SheetCollate.class); + + /* + In Linux, we use Postscript for rendering but Linux still + has issues in propagating Postscript-embedded setpagedevice + setting like collation. Therefore, we temporarily exclude + Linux. + */ + if (!UnixPrintServiceLookup.isLinux()) { + catList.add(SheetCollate.class); + } } // With the assumption that Chromaticity is equivalent to diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java index c682634b7b6..2c2a6406293 100644 --- a/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java +++ b/jdk/src/solaris/classes/sun/print/UnixPrintServiceLookup.java @@ -123,6 +123,10 @@ public class UnixPrintServiceLookup extends PrintServiceLookup return osname.equals("SunOS"); } + static boolean isLinux() { + return (osname.equals("Linux")); + } + static boolean isBSD() { return (osname.equals("Linux") || osname.contains("OS X")); From 93d49935a98699582213ccb19c441f70742d0510 Mon Sep 17 00:00:00 2001 From: Albert Noll Date: Wed, 10 Jul 2013 13:33:56 -0700 Subject: [PATCH 068/156] 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005 Remove obsolete code that relates to ISM which was used only on Solaris 8. Reviewed-by: kvn, twisti --- hotspot/src/os/solaris/vm/globals_solaris.hpp | 9 - hotspot/src/os/solaris/vm/os_solaris.cpp | 285 ++---------------- hotspot/src/os/solaris/vm/os_solaris.hpp | 5 +- hotspot/src/share/vm/runtime/arguments.cpp | 12 +- 4 files changed, 36 insertions(+), 275 deletions(-) diff --git a/hotspot/src/os/solaris/vm/globals_solaris.hpp b/hotspot/src/os/solaris/vm/globals_solaris.hpp index a567a357e16..2abbe15a7fd 100644 --- a/hotspot/src/os/solaris/vm/globals_solaris.hpp +++ b/hotspot/src/os/solaris/vm/globals_solaris.hpp @@ -30,15 +30,6 @@ // #define RUNTIME_OS_FLAGS(develop, develop_pd, product, product_pd, diagnostic, notproduct) \ \ - product(bool, UseISM, false, \ - "Use Intimate Shared Memory (Solaris Only)") \ - \ - product(bool, UsePermISM, false, \ - "Obsolete flag for compatibility (same as UseISM)") \ - \ - product(bool, UseMPSS, true, \ - "Use Multiple Page Size Support (Solaris 9 Only)") \ - \ product(bool, UseExtendedFileIO, true, \ "Enable workaround for limitations of stdio FILE structure") diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp index ad8c52914be..1d9ff5daa3c 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.cpp +++ b/hotspot/src/os/solaris/vm/os_solaris.cpp @@ -115,45 +115,6 @@ // for timer info max values which include all bits #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) -#ifdef _GNU_SOURCE -// See bug #6514594 -extern "C" int madvise(caddr_t, size_t, int); -extern "C" int memcntl(caddr_t addr, size_t len, int cmd, caddr_t arg, - int attr, int mask); -#endif //_GNU_SOURCE - -/* - MPSS Changes Start. - The JVM binary needs to be built and run on pre-Solaris 9 - systems, but the constants needed by MPSS are only in Solaris 9 - header files. They are textually replicated here to allow - building on earlier systems. Once building on Solaris 8 is - no longer a requirement, these #defines can be replaced by ordinary - system .h inclusion. - - In earlier versions of the JDK and Solaris, we used ISM for large pages. - But ISM requires shared memory to achieve this and thus has many caveats. - MPSS is a fully transparent and is a cleaner way to get large pages. - Although we still require keeping ISM for backward compatiblitiy as well as - giving the opportunity to use large pages on older systems it is - recommended that MPSS be used for Solaris 9 and above. - -*/ - -#ifndef MC_HAT_ADVISE - -struct memcntl_mha { - uint_t mha_cmd; /* command(s) */ - uint_t mha_flags; - size_t mha_pagesize; -}; -#define MC_HAT_ADVISE 7 /* advise hat map size */ -#define MHA_MAPSIZE_VA 0x1 /* set preferred page size */ -#define MAP_ALIGN 0x200 /* addr specifies alignment */ - -#endif -// MPSS Changes End. - // Here are some liblgrp types from sys/lgrp_user.h to be able to // compile on older systems without this header file. @@ -172,32 +133,6 @@ struct memcntl_mha { # define LGRP_RSRC_MEM 1 /* memory resources */ #endif -// Some more macros from sys/mman.h that are not present in Solaris 8. - -#ifndef MAX_MEMINFO_CNT -/* - * info_req request type definitions for meminfo - * request types starting with MEMINFO_V are used for Virtual addresses - * and should not be mixed with MEMINFO_PLGRP which is targeted for Physical - * addresses - */ -# define MEMINFO_SHIFT 16 -# define MEMINFO_MASK (0xFF << MEMINFO_SHIFT) -# define MEMINFO_VPHYSICAL (0x01 << MEMINFO_SHIFT) /* get physical addr */ -# define MEMINFO_VLGRP (0x02 << MEMINFO_SHIFT) /* get lgroup */ -# define MEMINFO_VPAGESIZE (0x03 << MEMINFO_SHIFT) /* size of phys page */ -# define MEMINFO_VREPLCNT (0x04 << MEMINFO_SHIFT) /* no. of replica */ -# define MEMINFO_VREPL (0x05 << MEMINFO_SHIFT) /* physical replica */ -# define MEMINFO_VREPL_LGRP (0x06 << MEMINFO_SHIFT) /* lgrp of replica */ -# define MEMINFO_PLGRP (0x07 << MEMINFO_SHIFT) /* lgroup for paddr */ - -/* maximum number of addresses meminfo() can process at a time */ -# define MAX_MEMINFO_CNT 256 - -/* maximum number of request types */ -# define MAX_MEMINFO_REQ 31 -#endif - // see thr_setprio(3T) for the basis of these numbers #define MinimumPriority 0 #define NormalPriority 64 @@ -2859,7 +2794,7 @@ int os::Solaris::commit_memory_impl(char* addr, size_t bytes, size_t alignment_hint, bool exec) { int err = Solaris::commit_memory_impl(addr, bytes, exec); if (err == 0) { - if (UseMPSS && alignment_hint > (size_t)vm_page_size()) { + if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) { // If the large page size has been set and the VM // is using large pages, use the large page size // if it is smaller than the alignment hint. This is @@ -2878,7 +2813,7 @@ int os::Solaris::commit_memory_impl(char* addr, size_t bytes, page_size = alignment_hint; } // Since this is a hint, ignore any failures. - (void)Solaris::set_mpss_range(addr, bytes, page_size); + (void)Solaris::setup_large_pages(addr, bytes, page_size); } } return err; @@ -2921,8 +2856,8 @@ bool os::remove_stack_guard_pages(char* addr, size_t size) { void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); - if (UseLargePages && UseMPSS) { - Solaris::set_mpss_range(addr, bytes, alignment_hint); + if (UseLargePages) { + Solaris::setup_large_pages(addr, bytes, alignment_hint); } } @@ -3321,47 +3256,8 @@ bool os::unguard_memory(char* addr, size_t bytes) { } // Large page support - -// UseLargePages is the master flag to enable/disable large page memory. -// UseMPSS and UseISM are supported for compatibility reasons. Their combined -// effects can be described in the following table: -// -// UseLargePages UseMPSS UseISM -// false * * => UseLargePages is the master switch, turning -// it off will turn off both UseMPSS and -// UseISM. VM will not use large page memory -// regardless the settings of UseMPSS/UseISM. -// true false false => Unless future Solaris provides other -// mechanism to use large page memory, this -// combination is equivalent to -UseLargePages, -// VM will not use large page memory -// true true false => JVM will use MPSS for large page memory. -// This is the default behavior. -// true false true => JVM will use ISM for large page memory. -// true true true => JVM will use ISM if it is available. -// Otherwise, JVM will fall back to MPSS. -// Becaues ISM is now available on all -// supported Solaris versions, this combination -// is equivalent to +UseISM -UseMPSS. - static size_t _large_page_size = 0; -bool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) { - // x86 uses either 2M or 4M page, depending on whether PAE (Physical Address - // Extensions) mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. Sparc - // can support multiple page sizes. - - // Don't bother to probe page size because getpagesizes() comes with MPSS. - // ISM is only recommended on old Solaris where there is no MPSS support. - // Simply choose a conservative value as default. - *page_size = LargePageSizeInBytes ? LargePageSizeInBytes : - SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M) - ARM_ONLY(2 * M); - - // ISM is available on all supported Solaris versions - return true; -} - // Insertion sort for small arrays (descending order). static void insertion_sort_descending(size_t* array, int len) { for (int i = 0; i < len; i++) { @@ -3374,7 +3270,7 @@ static void insertion_sort_descending(size_t* array, int len) { } } -bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) { +bool os::Solaris::mpss_sanity_check(bool warn, size_t* page_size) { const unsigned int usable_count = VM_Version::page_size_count(); if (usable_count == 1) { return false; @@ -3440,41 +3336,24 @@ bool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) { } void os::large_page_init() { - if (!UseLargePages) { - UseISM = false; - UseMPSS = false; - return; + if (UseLargePages) { + // print a warning if any large page related flag is specified on command line + bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || + !FLAG_IS_DEFAULT(LargePageSizeInBytes); + + UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size); } - - // print a warning if any large page related flag is specified on command line - bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || - !FLAG_IS_DEFAULT(UseISM) || - !FLAG_IS_DEFAULT(UseMPSS) || - !FLAG_IS_DEFAULT(LargePageSizeInBytes); - UseISM = UseISM && - Solaris::ism_sanity_check(warn_on_failure, &_large_page_size); - if (UseISM) { - // ISM disables MPSS to be compatible with old JDK behavior - UseMPSS = false; - _page_sizes[0] = _large_page_size; - _page_sizes[1] = vm_page_size(); - } - - UseMPSS = UseMPSS && - Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size); - - UseLargePages = UseISM || UseMPSS; } -bool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) { +bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) { // Signal to OS that we want large pages for addresses // from addr, addr + bytes struct memcntl_mha mpss_struct; mpss_struct.mha_cmd = MHA_MAPSIZE_VA; mpss_struct.mha_pagesize = align; mpss_struct.mha_flags = 0; - if (memcntl(start, bytes, MC_HAT_ADVISE, - (caddr_t) &mpss_struct, 0, 0) < 0) { + // Upon successful completion, memcntl() returns 0 + if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) { debug_only(warning("Attempt to use MPSS failed.")); return false; } @@ -3482,72 +3361,13 @@ bool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) { } char* os::reserve_memory_special(size_t size, char* addr, bool exec) { - // "exec" is passed in but not used. Creating the shared image for - // the code cache doesn't have an SHM_X executable permission to check. - assert(UseLargePages && UseISM, "only for ISM large pages"); - - char* retAddr = NULL; - int shmid; - key_t ismKey; - - bool warn_on_failure = UseISM && - (!FLAG_IS_DEFAULT(UseLargePages) || - !FLAG_IS_DEFAULT(UseISM) || - !FLAG_IS_DEFAULT(LargePageSizeInBytes) - ); - char msg[128]; - - ismKey = IPC_PRIVATE; - - // Create a large shared memory region to attach to based on size. - // Currently, size is the total size of the heap - shmid = shmget(ismKey, size, SHM_R | SHM_W | IPC_CREAT); - if (shmid == -1){ - if (warn_on_failure) { - jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno); - warning(msg); - } - return NULL; - } - - // Attach to the region - retAddr = (char *) shmat(shmid, 0, SHM_SHARE_MMU | SHM_R | SHM_W); - int err = errno; - - // Remove shmid. If shmat() is successful, the actual shared memory segment - // will be deleted when it's detached by shmdt() or when the process - // terminates. If shmat() is not successful this will remove the shared - // segment immediately. - shmctl(shmid, IPC_RMID, NULL); - - if (retAddr == (char *) -1) { - if (warn_on_failure) { - jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err); - warning(msg); - } - return NULL; - } - if ((retAddr != NULL) && UseNUMAInterleaving) { - numa_make_global(retAddr, size); - } - - // The memory is committed - MemTracker::record_virtual_memory_reserve_and_commit((address)retAddr, size, mtNone, CURRENT_PC); - - return retAddr; + fatal("os::reserve_memory_special should not be called on Solaris."); + return NULL; } bool os::release_memory_special(char* base, size_t bytes) { - MemTracker::Tracker tkr = MemTracker::get_virtual_memory_release_tracker(); - // detaching the SHM segment will also delete it, see reserve_memory_special() - int rslt = shmdt(base); - if (rslt == 0) { - tkr.record((address)base, bytes); - return true; - } else { - tkr.discard(); - return false; - } + fatal("os::release_memory_special should not be called on Solaris."); + return false; } size_t os::large_page_size() { @@ -3557,11 +3377,11 @@ size_t os::large_page_size() { // MPSS allows application to commit large page memory on demand; with ISM // the entire memory region must be allocated as shared memory. bool os::can_commit_large_page_memory() { - return UseISM ? false : true; + return true; } bool os::can_execute_large_page_memory() { - return UseISM ? false : true; + return true; } static int os_sleep(jlong millis, bool interruptible) { @@ -3835,28 +3655,6 @@ static bool priocntl_enable = false; static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4 static int java_MaxPriority_to_os_priority = 0; // Saved mapping -// Call the version of priocntl suitable for all supported versions -// of Solaris. We need to call through this wrapper so that we can -// build on Solaris 9 and run on Solaris 8, 9 and 10. -// -// This code should be removed if we ever stop supporting Solaris 8 -// and earlier releases. - -static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg); -typedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg); -static priocntl_type priocntl_ptr = priocntl_stub; - -// Stub to set the value of the real pointer, and then call the real -// function. - -static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) { - // Try Solaris 8- name only. - priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl"); - guarantee(tmp != NULL, "priocntl function not found."); - priocntl_ptr = tmp; - return (*priocntl_ptr)(PC_VERSION, idtype, id, cmd, arg); -} - // lwp_priocntl_init // @@ -3864,9 +3662,7 @@ static long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t // // Return errno or 0 if OK. // -static -int lwp_priocntl_init () -{ +static int lwp_priocntl_init () { int rslt; pcinfo_t ClassInfo; pcparms_t ParmInfo; @@ -3906,7 +3702,7 @@ int lwp_priocntl_init () strcpy(ClassInfo.pc_clname, "TS"); ClassInfo.pc_cid = -1; - rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); + rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); if (rslt < 0) return errno; assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); tsLimits.schedPolicy = ClassInfo.pc_cid; @@ -3915,7 +3711,7 @@ int lwp_priocntl_init () strcpy(ClassInfo.pc_clname, "IA"); ClassInfo.pc_cid = -1; - rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); + rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); if (rslt < 0) return errno; assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); iaLimits.schedPolicy = ClassInfo.pc_cid; @@ -3924,7 +3720,7 @@ int lwp_priocntl_init () strcpy(ClassInfo.pc_clname, "RT"); ClassInfo.pc_cid = -1; - rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); + rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); if (rslt < 0) return errno; assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); rtLimits.schedPolicy = ClassInfo.pc_cid; @@ -3933,7 +3729,7 @@ int lwp_priocntl_init () strcpy(ClassInfo.pc_clname, "FX"); ClassInfo.pc_cid = -1; - rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); + rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); if (rslt < 0) return errno; assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); fxLimits.schedPolicy = ClassInfo.pc_cid; @@ -3944,7 +3740,7 @@ int lwp_priocntl_init () // This will normally be IA, TS or, rarely, FX or RT. memset(&ParmInfo, 0, sizeof(ParmInfo)); ParmInfo.pc_cid = PC_CLNULL; - rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); + rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); if (rslt < 0) return errno; myClass = ParmInfo.pc_cid; @@ -3952,7 +3748,7 @@ int lwp_priocntl_init () // about the class. ClassInfo.pc_cid = myClass; ClassInfo.pc_clname[0] = 0; - rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); + rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); if (rslt < 0) return errno; if (ThreadPriorityVerbose) { @@ -3961,7 +3757,7 @@ int lwp_priocntl_init () memset(&ParmInfo, 0, sizeof(pcparms_t)); ParmInfo.pc_cid = PC_CLNULL; - rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); + rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); if (rslt < 0) return errno; if (ParmInfo.pc_cid == rtLimits.schedPolicy) { @@ -4065,7 +3861,7 @@ int set_lwp_class_and_priority(int ThreadID, int lwpid, memset(&ParmInfo, 0, sizeof(pcparms_t)); ParmInfo.pc_cid = PC_CLNULL; - rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); + rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); if (rslt < 0) return errno; int cur_class = ParmInfo.pc_cid; @@ -4133,7 +3929,7 @@ int set_lwp_class_and_priority(int ThreadID, int lwpid, return EINVAL; // no clue, punt } - rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); + rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); if (ThreadPriorityVerbose && rslt) { tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); } @@ -4152,7 +3948,7 @@ int set_lwp_class_and_priority(int ThreadID, int lwpid, memset(&ReadBack, 0, sizeof(pcparms_t)); ReadBack.pc_cid = PC_CLNULL; - rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); + rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); assert(rslt >= 0, "priocntl failed"); Actual = Expected = 0xBAD; assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match"); @@ -5244,11 +5040,6 @@ uint_t os::Solaris::getisax(uint32_t* array, uint_t n) { return _getisax(array, n); } -// Symbol doesn't exist in Solaris 8 pset.h -#ifndef PS_MYID -#define PS_MYID -3 -#endif - // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem); static pset_getloadavg_type pset_getloadavg_ptr = NULL; @@ -5418,20 +5209,6 @@ jint os::init_2(void) { UseNUMA = false; } } - // ISM is not compatible with the NUMA allocator - it always allocates - // pages round-robin across the lgroups. - if (UseNUMA && UseLargePages && UseISM) { - if (!FLAG_IS_DEFAULT(UseNUMA)) { - if (FLAG_IS_DEFAULT(UseLargePages) && FLAG_IS_DEFAULT(UseISM)) { - UseLargePages = false; - } else { - warning("UseNUMA is not compatible with ISM large pages, disabling NUMA allocator"); - UseNUMA = false; - } - } else { - UseNUMA = false; - } - } if (!UseNUMA && ForceNUMA) { UseNUMA = true; } diff --git a/hotspot/src/os/solaris/vm/os_solaris.hpp b/hotspot/src/os/solaris/vm/os_solaris.hpp index f7f0a3d7283..330d4fbc591 100644 --- a/hotspot/src/os/solaris/vm/os_solaris.hpp +++ b/hotspot/src/os/solaris/vm/os_solaris.hpp @@ -106,8 +106,8 @@ class Solaris { static meminfo_func_t _meminfo; - // Large Page Support--mpss. - static bool set_mpss_range(caddr_t start, size_t bytes, size_t align); + // Large Page Support + static bool setup_large_pages(caddr_t start, size_t bytes, size_t align); static void init_thread_fpu_state(void); @@ -174,7 +174,6 @@ class Solaris { static char* mmap_chunk(char *addr, size_t size, int flags, int prot); static char* anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed); static bool mpss_sanity_check(bool warn, size_t * page_size); - static bool ism_sanity_check (bool warn, size_t * page_size); // Workaround for 4352906. thr_stksegment sometimes returns // a bad value for the primordial thread's stack base when diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp index 7f3e09c270c..b3fe586a565 100644 --- a/hotspot/src/share/vm/runtime/arguments.cpp +++ b/hotspot/src/share/vm/runtime/arguments.cpp @@ -261,6 +261,9 @@ static ObsoleteFlag obsolete_jvm_flags[] = { { "PrintRevisitStats", JDK_Version::jdk(8), JDK_Version::jdk(9) }, { "UseVectoredExceptions", JDK_Version::jdk(8), JDK_Version::jdk(9) }, { "UseSplitVerifier", JDK_Version::jdk(8), JDK_Version::jdk(9) }, + { "UseISM", JDK_Version::jdk(8), JDK_Version::jdk(9) }, + { "UsePermISM", JDK_Version::jdk(8), JDK_Version::jdk(9) }, + { "UseMPSS", JDK_Version::jdk(8), JDK_Version::jdk(9) }, #ifdef PRODUCT { "DesiredMethodLimit", JDK_Version::jdk_update(7, 2), JDK_Version::jdk(8) }, @@ -2967,13 +2970,6 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, FLAG_SET_CMDLINE(bool, UseTLAB, true); } else if (match_option(option, "-XX:-UseTLE", &tail)) { FLAG_SET_CMDLINE(bool, UseTLAB, false); -SOLARIS_ONLY( - } else if (match_option(option, "-XX:+UsePermISM", &tail)) { - warning("-XX:+UsePermISM is obsolete."); - FLAG_SET_CMDLINE(bool, UseISM, true); - } else if (match_option(option, "-XX:-UsePermISM", &tail)) { - FLAG_SET_CMDLINE(bool, UseISM, false); -) } else if (match_option(option, "-XX:+DisplayVMOutputToStderr", &tail)) { FLAG_SET_CMDLINE(bool, DisplayVMOutputToStdout, false); FLAG_SET_CMDLINE(bool, DisplayVMOutputToStderr, true); @@ -3146,8 +3142,6 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req // Note that large pages are enabled/disabled for both the // Java heap and the code cache. FLAG_SET_DEFAULT(UseLargePages, false); - SOLARIS_ONLY(FLAG_SET_DEFAULT(UseMPSS, false)); - SOLARIS_ONLY(FLAG_SET_DEFAULT(UseISM, false)); } // Tiered compilation is undefined with C1. From 0f82640543629c9264c216ffabf5a6e4553e5ee2 Mon Sep 17 00:00:00 2001 From: Bengt Rutisson Date: Thu, 11 Jul 2013 11:33:27 +0200 Subject: [PATCH 069/156] 8020155: PSR:PERF G1 not collecting old regions when humongous allocations interfer Take _last_young_gc into account when deciding on starting a concurrent mark. Also reviewed-by: per.liden@oracle.com. Reviewed-by: tschatzl, johnc --- .../src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp index 3bd04281955..4c6d2bbf877 100644 --- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp +++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp @@ -873,7 +873,7 @@ bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc size_t alloc_byte_size = alloc_word_size * HeapWordSize; if ((cur_used_bytes + alloc_byte_size) > marking_initiating_used_threshold) { - if (gcs_are_young()) { + if (gcs_are_young() && !_last_young_gc) { ergo_verbose5(ErgoConcCycles, "request concurrent cycle initiation", ergo_format_reason("occupancy higher than threshold") @@ -931,7 +931,7 @@ void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms, Evacua last_pause_included_initial_mark = during_initial_mark_pause(); if (last_pause_included_initial_mark) { record_concurrent_mark_init_end(0.0); - } else if (!_last_young_gc && need_to_start_conc_mark("end of GC")) { + } else if (need_to_start_conc_mark("end of GC")) { // Note: this might have already been set, if during the last // pause we decided to start a cycle but at the beginning of // this pause we decided to postpone it. That's OK. From f0144d9d93a3b2907573437f448ecf45d8bb2858 Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 11 Jul 2013 16:34:55 +0530 Subject: [PATCH 070/156] 8020325: static property does not work on accessible, public classes Reviewed-by: attila, hannesw, lagergren --- nashorn/make/build.xml | 6 ++- .../api/scripting/NashornScriptEngine.java | 6 +-- .../internal/codegen/CodeGenerator.java | 2 +- .../nashorn/internal/codegen/Compiler.java | 4 +- .../jdk/nashorn/internal/lookup/Lookup.java | 2 - .../nashorn/internal/objects/NativeDebug.java | 3 ++ .../internal/objects/NativeNumber.java | 1 - .../internal/objects/ScriptFunctionImpl.java | 4 +- .../jdk/nashorn/internal/runtime/Context.java | 34 ++++++++--------- .../runtime/linker/JavaAdapterFactory.java | 9 ++--- .../runtime/linker/ReflectionCheckLinker.java | 23 +++++++++++ nashorn/test/script/basic/JDK-8020325.js | 38 +++++++++++++++++++ .../test/script/basic/JDK-8020325.js.EXPECTED | 4 ++ nashorn/test/script/trusted/JDK-8006529.js | 28 +++++++------- .../api/scripting/ScriptEngineTest.java | 2 +- 15 files changed, 111 insertions(+), 55 deletions(-) create mode 100644 nashorn/test/script/basic/JDK-8020325.js create mode 100644 nashorn/test/script/basic/JDK-8020325.js.EXPECTED diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml index da2ded1ea1d..2bda503fd88 100644 --- a/nashorn/make/build.xml +++ b/nashorn/make/build.xml @@ -219,8 +219,10 @@ target="${javac.target}" debug="${javac.debug}" encoding="${javac.encoding}" - includeantruntime="false"> - + includeantruntime="false" fork="true"> + + + diff --git a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java index 64574229d0a..682975a85d5 100644 --- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java +++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java @@ -195,11 +195,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C if (! Modifier.isPublic(clazz.getModifiers())) { throw new SecurityException("attempt to implement non-public interfce: " + clazz); } - final String fullName = clazz.getName(); - final int index = fullName.lastIndexOf('.'); - if (index != -1) { - sm.checkPackageAccess(fullName.substring(0, index)); - } + Context.checkPackageAccess(clazz.getName()); } final ScriptObject realSelf; diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index 250c44c1541..b9d35682458 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -1313,7 +1313,7 @@ final class CodeGenerator extends NodeOperatorVisitor literalNode) { assert literalNode.getSymbol() != null : literalNode + " has no symbol"; load(literalNode).store(literalNode.getSymbol()); return false; diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java index e40986d4e4a..a31358f6503 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java @@ -528,8 +528,8 @@ public final class Compiler { return this.env; } - private String safeSourceName(final Source source) { - String baseName = new File(source.getName()).getName(); + private String safeSourceName(final Source src) { + String baseName = new File(src.getName()).getName(); final int index = baseName.lastIndexOf(".js"); if (index != -1) { diff --git a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java index e874cfd7bbe..0dd2741e00c 100644 --- a/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java +++ b/nashorn/src/jdk/nashorn/internal/lookup/Lookup.java @@ -32,8 +32,6 @@ import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodType; import jdk.nashorn.internal.runtime.JSType; -import jdk.nashorn.internal.runtime.Property; -import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptRuntime; /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java index 30a4228958e..82757cbae51 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java @@ -179,6 +179,9 @@ public final class NativeDebug extends ScriptObject { /** * Returns the property listener count for a script object + * + * @param self self reference + * @param obj script object whose listener count is returned * @return listener count */ @Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR) diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java index c69478967f4..d9d568b7e38 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java +++ b/nashorn/src/jdk/nashorn/internal/objects/NativeNumber.java @@ -48,7 +48,6 @@ import jdk.nashorn.internal.runtime.JSType; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.runtime.ScriptRuntime; -import jdk.nashorn.internal.lookup.MethodHandleFactory; import jdk.nashorn.internal.runtime.linker.PrimitiveLookup; /** diff --git a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java index 643d9acddf3..88421a70bd1 100644 --- a/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java +++ b/nashorn/src/jdk/nashorn/internal/objects/ScriptFunctionImpl.java @@ -212,10 +212,10 @@ public class ScriptFunctionImpl extends ScriptFunction { // Instance of this class is used as global anonymous function which // serves as Function.prototype object. private static class AnonymousFunction extends ScriptFunctionImpl { - private static final PropertyMap map$ = PropertyMap.newMap().setIsShared(); + private static final PropertyMap anonmap$ = PropertyMap.newMap().setIsShared(); static PropertyMap getInitialMap() { - return map$; + return anonmap$; } AnonymousFunction(final Global global) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Context.java b/nashorn/src/jdk/nashorn/internal/runtime/Context.java index fb362b1725e..9d603c66b72 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java @@ -39,13 +39,10 @@ import java.lang.invoke.MethodHandles; import java.util.concurrent.atomic.AtomicLong; import java.net.MalformedURLException; import java.net.URL; -import java.security.AccessControlContext; import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; -import java.security.Permissions; import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import java.util.Map; import jdk.internal.org.objectweb.asm.ClassReader; import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; @@ -208,7 +205,6 @@ public final class Context { private static final ClassLoader myLoader = Context.class.getClassLoader(); private static final StructureLoader sharedLoader; - private static final AccessControlContext NO_PERMISSIONS_CONTEXT; static { sharedLoader = AccessController.doPrivileged(new PrivilegedAction() { @@ -217,7 +213,6 @@ public final class Context { return new StructureLoader(myLoader, null); } }); - NO_PERMISSIONS_CONTEXT = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) }); } /** @@ -559,6 +554,21 @@ public final class Context { return Class.forName(fullName, true, sharedLoader); } + /** + * Checks that the given package can be accessed from current call stack. + * + * @param fullName fully qualified package name + */ + public static void checkPackageAccess(final String fullName) { + final int index = fullName.lastIndexOf('.'); + if (index != -1) { + final SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPackageAccess(fullName.substring(0, index)); + } + } + } + /** * Lookup a Java class. This is used for JSR-223 stuff linking in from * {@code jdk.nashorn.internal.objects.NativeJava} and {@code jdk.nashorn.internal.runtime.NativeJavaPackage} @@ -571,19 +581,7 @@ public final class Context { */ public Class findClass(final String fullName) throws ClassNotFoundException { // check package access as soon as possible! - final int index = fullName.lastIndexOf('.'); - if (index != -1) { - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - AccessController.doPrivileged(new PrivilegedAction() { - @Override - public Void run() { - sm.checkPackageAccess(fullName.substring(0, index)); - return null; - } - }, NO_PERMISSIONS_CONTEXT); - } - } + checkPackageAccess(fullName); // try the script -classpath loader, if that is set if (classPathLoader != null) { diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java index 77dcc695a0a..472b8dcd727 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java @@ -43,6 +43,7 @@ import java.util.Map; import jdk.internal.dynalink.beans.StaticClass; import jdk.internal.dynalink.support.LinkRequestImpl; import jdk.nashorn.internal.objects.NativeJava; +import jdk.nashorn.internal.runtime.Context; import jdk.nashorn.internal.runtime.ECMAException; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.ScriptObject; @@ -101,13 +102,9 @@ public final class JavaAdapterFactory { assert types != null && types.length > 0; final SecurityManager sm = System.getSecurityManager(); if (sm != null) { - for (Class type : types) { + for (Class type : types) { // check for restricted package access - final String fullName = type.getName(); - final int index = fullName.lastIndexOf('.'); - if (index != -1) { - sm.checkPackageAccess(fullName.substring(0, index)); - } + Context.checkPackageAccess(type.getName()); } } return getAdapterInfo(types).getAdapterClassFor(classOverrides); diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java index eb8837a8d70..53c652cab15 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java +++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java @@ -25,10 +25,14 @@ package jdk.nashorn.internal.runtime.linker; +import java.lang.reflect.Modifier; +import jdk.internal.dynalink.CallSiteDescriptor; import jdk.internal.dynalink.linker.GuardedInvocation; import jdk.internal.dynalink.linker.LinkRequest; import jdk.internal.dynalink.linker.LinkerServices; import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; +import jdk.internal.dynalink.support.CallSiteDescriptorFactory; +import jdk.nashorn.internal.runtime.Context; /** * Check java reflection permission for java reflective and java.lang.invoke access from scripts @@ -52,6 +56,25 @@ final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{ throws Exception { final SecurityManager sm = System.getSecurityManager(); if (sm != null) { + final LinkRequest requestWithoutContext = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context + final Object self = requestWithoutContext.getReceiver(); + // allow 'static' access on Class objects representing public classes of non-restricted packages + if ((self instanceof Class) && Modifier.isPublic(((Class)self).getModifiers())) { + final CallSiteDescriptor desc = requestWithoutContext.getCallSiteDescriptor(); + final String operator = CallSiteDescriptorFactory.tokenizeOperators(desc).get(0); + // check for 'get' on 'static' property + switch (operator) { + case "getProp": + case "getMethod": { + if ("static".equals(desc.getNameToken(CallSiteDescriptor.NAME_OPERAND))) { + Context.checkPackageAccess(((Class)self).getName()); + // let bean linker do the actual linking part + return null; + } + } + break; + } // fall through for all other stuff + } sm.checkPermission(new RuntimePermission("nashorn.JavaReflection")); } // let the next linker deal with actual linking diff --git a/nashorn/test/script/basic/JDK-8020325.js b/nashorn/test/script/basic/JDK-8020325.js new file mode 100644 index 00000000000..5c8e64f530d --- /dev/null +++ b/nashorn/test/script/basic/JDK-8020325.js @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8020325: static property does not work on accessible, public classes + * + * @test + * @run + */ + +function printStatic(obj) { + print(obj.getClass().static); +} + +printStatic(new java.util.ArrayList()); +printStatic(new java.util.HashMap()); +printStatic(new java.lang.Object()); +printStatic(new (Java.type("java.lang.Object[]"))(0)); diff --git a/nashorn/test/script/basic/JDK-8020325.js.EXPECTED b/nashorn/test/script/basic/JDK-8020325.js.EXPECTED new file mode 100644 index 00000000000..96542b75cf3 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8020325.js.EXPECTED @@ -0,0 +1,4 @@ +[JavaClass java.util.ArrayList] +[JavaClass java.util.HashMap] +[JavaClass java.lang.Object] +[JavaClass [Ljava.lang.Object;] diff --git a/nashorn/test/script/trusted/JDK-8006529.js b/nashorn/test/script/trusted/JDK-8006529.js index 378cd6cf7a6..6837fcd8d83 100644 --- a/nashorn/test/script/trusted/JDK-8006529.js +++ b/nashorn/test/script/trusted/JDK-8006529.js @@ -39,21 +39,19 @@ * and FunctionNode because of package-access check and so reflective calls. */ -var forName = java.lang.Class["forName(String)"] - -var Parser = forName("jdk.nashorn.internal.parser.Parser").static -var Compiler = forName("jdk.nashorn.internal.codegen.Compiler").static -var Context = forName("jdk.nashorn.internal.runtime.Context").static -var ScriptEnvironment = forName("jdk.nashorn.internal.runtime.ScriptEnvironment").static -var Source = forName("jdk.nashorn.internal.runtime.Source").static -var FunctionNode = forName("jdk.nashorn.internal.ir.FunctionNode").static -var Block = forName("jdk.nashorn.internal.ir.Block").static -var VarNode = forName("jdk.nashorn.internal.ir.VarNode").static -var ExecuteNode = forName("jdk.nashorn.internal.ir.ExecuteNode").static -var UnaryNode = forName("jdk.nashorn.internal.ir.UnaryNode").static -var BinaryNode = forName("jdk.nashorn.internal.ir.BinaryNode").static -var ThrowErrorManager = forName("jdk.nashorn.internal.runtime.Context$ThrowErrorManager").static -var Debug = forName("jdk.nashorn.internal.runtime.Debug").static +var Parser = Java.type("jdk.nashorn.internal.parser.Parser") +var Compiler = Java.type("jdk.nashorn.internal.codegen.Compiler") +var Context = Java.type("jdk.nashorn.internal.runtime.Context") +var ScriptEnvironment = Java.type("jdk.nashorn.internal.runtime.ScriptEnvironment") +var Source = Java.type("jdk.nashorn.internal.runtime.Source") +var FunctionNode = Java.type("jdk.nashorn.internal.ir.FunctionNode") +var Block = Java.type("jdk.nashorn.internal.ir.Block") +var VarNode = Java.type("jdk.nashorn.internal.ir.VarNode") +var ExecuteNode = Java.type("jdk.nashorn.internal.ir.ExecuteNode") +var UnaryNode = Java.type("jdk.nashorn.internal.ir.UnaryNode") +var BinaryNode = Java.type("jdk.nashorn.internal.ir.BinaryNode") +var ThrowErrorManager = Java.type("jdk.nashorn.internal.runtime.Context$ThrowErrorManager") +var Debug = Java.type("jdk.nashorn.internal.runtime.Debug") var parseMethod = Parser.class.getMethod("parse"); var compileMethod = Compiler.class.getMethod("compile", FunctionNode.class); diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java index 73572502605..1ba08657a6f 100644 --- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java +++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java @@ -968,7 +968,7 @@ public class ScriptEngineTest { // get implementation of a restricted package interface try { - log(Objects.toString(((Invocable)e).getInterface(PropertyAccessClass))); + log(Objects.toString(((Invocable)e).getInterface((Class)PropertyAccessClass))); fail("should have thrown SecurityException"); } catch (final Exception exp) { if (! (exp instanceof SecurityException)) { From f22f9eb04b4f8b9e0b2b3c7c3a756664ed1d15ee Mon Sep 17 00:00:00 2001 From: Petr Pchelko Date: Thu, 11 Jul 2013 16:42:13 +0400 Subject: [PATCH 071/156] 8020210: [macosx] JVM crashes in CWrapper$NSWindow.screen(long) Reviewed-by: anthony, art --- .../sun/lwawt/macosx/CPlatformWindow.java | 22 ++-- .../classes/sun/lwawt/macosx/CWrapper.java | 8 -- jdk/src/macosx/native/sun/awt/CWrapper.m | 111 ------------------ .../MaximizeOffscreenTest.java | 67 +++++++++++ 4 files changed, 76 insertions(+), 132 deletions(-) create mode 100644 jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 7230b2eeeb5..dc711c28f0e 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -479,12 +479,14 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo deliverZoom(true); this.normalBounds = peer.getBounds(); - long screen = CWrapper.NSWindow.screen(getNSWindowPtr()); - Rectangle toBounds = CWrapper.NSScreen.visibleFrame(screen).getBounds(); - // Flip the y coordinate - Rectangle frame = CWrapper.NSScreen.frame(screen).getBounds(); - toBounds.y = frame.height - toBounds.y - toBounds.height; - setBounds(toBounds.x, toBounds.y, toBounds.width, toBounds.height); + + GraphicsConfiguration config = getPeer().getGraphicsConfiguration(); + Insets i = ((CGraphicsDevice)config.getDevice()).getScreenInsets(); + Rectangle toBounds = config.getBounds(); + setBounds(toBounds.x + i.left, + toBounds.y + i.top, + toBounds.width - i.left - i.right, + toBounds.height - i.top - i.bottom); } } @@ -751,13 +753,7 @@ public class CPlatformWindow extends CFRetainedResource implements PlatformWindo // the move/size notification from the underlying system comes // but it contains a bounds smaller than the whole screen // and therefore we need to create the synthetic notifications - Rectangle screenBounds; - final long screenPtr = CWrapper.NSWindow.screen(getNSWindowPtr()); - try { - screenBounds = CWrapper.NSScreen.frame(screenPtr).getBounds(); - } finally { - CWrapper.NSObject.release(screenPtr); - } + Rectangle screenBounds = getPeer().getGraphicsConfiguration().getBounds(); peer.notifyReshape(screenBounds.x, screenBounds.y, screenBounds.width, screenBounds.height); } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java index 67d3ea1cf1f..7dc421e26b1 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java @@ -71,8 +71,6 @@ public final class CWrapper { public static native void zoom(long window); public static native void makeFirstResponder(long window, long responder); - - public static native long screen(long window); } public static final class NSView { @@ -95,12 +93,6 @@ public final class CWrapper { public static native void release(long object); } - public static final class NSScreen { - public static native Rectangle2D frame(long screen); - public static native Rectangle2D visibleFrame(long screen); - public static native long screenByDisplayId(int displayID); - } - public static final class NSColor { public static native long clearColor(); } diff --git a/jdk/src/macosx/native/sun/awt/CWrapper.m b/jdk/src/macosx/native/sun/awt/CWrapper.m index bef1d47cb9f..ccc688e802d 100644 --- a/jdk/src/macosx/native/sun/awt/CWrapper.m +++ b/jdk/src/macosx/native/sun/awt/CWrapper.m @@ -396,31 +396,6 @@ JNF_COCOA_ENTER(env); JNF_COCOA_EXIT(env); } -/* - * Class: sun_lwawt_macosx_CWrapper$NSWindow - * Method: screen - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_sun_lwawt_macosx_CWrapper_00024NSWindow_screen -(JNIEnv *env, jclass cls, jlong windowPtr) -{ - __block jlong screenPtr = 0L; - -JNF_COCOA_ENTER(env); - - AWTWindow *window = (AWTWindow *)jlong_to_ptr(windowPtr); - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - const NSScreen *screen = [window screen]; - CFRetain(screen); // GC - screenPtr = ptr_to_jlong(screen); - }]; - -JNF_COCOA_EXIT(env); - - return screenPtr; -} - /* * Method: miniaturize * Signature: (J)V @@ -690,92 +665,6 @@ JNF_COCOA_ENTER(env); JNF_COCOA_EXIT(env); } - -/* - * Class: sun_lwawt_macosx_CWrapper$NSScreen - * Method: frame - * Signature: (J)Ljava/awt/Rectangle; - */ -JNIEXPORT jobject JNICALL -Java_sun_lwawt_macosx_CWrapper_00024NSScreen_frame -(JNIEnv *env, jclass cls, jlong screenPtr) -{ - jobject jRect = NULL; - -JNF_COCOA_ENTER(env); - - __block NSRect rect = NSZeroRect; - - NSScreen *screen = (NSScreen *)jlong_to_ptr(screenPtr); - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - rect = [screen frame]; - }]; - - jRect = NSToJavaRect(env, rect); - -JNF_COCOA_EXIT(env); - - return jRect; -} - -/* - * Class: sun_lwawt_macosx_CWrapper_NSScreen - * Method: visibleFrame - * Signature: (J)Ljava/awt/geom/Rectangle2D; - */ -JNIEXPORT jobject JNICALL -Java_sun_lwawt_macosx_CWrapper_00024NSScreen_visibleFrame -(JNIEnv *env, jclass cls, jlong screenPtr) -{ - jobject jRect = NULL; - -JNF_COCOA_ENTER(env); - - __block NSRect rect = NSZeroRect; - - NSScreen *screen = (NSScreen *)jlong_to_ptr(screenPtr); - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - rect = [screen visibleFrame]; - }]; - - jRect = NSToJavaRect(env, rect); - -JNF_COCOA_EXIT(env); - - return jRect; -} - -/* - * Class: sun_lwawt_macosx_CWrapper_NSScreen - * Method: screenByDisplayId - * Signature: (J)J - */ -JNIEXPORT jlong JNICALL -Java_sun_lwawt_macosx_CWrapper_00024NSScreen_screenByDisplayId -(JNIEnv *env, jclass cls, jint displayID) -{ - __block jlong screenPtr = 0L; - -JNF_COCOA_ENTER(env); - - [ThreadUtilities performOnMainThreadWaiting:YES block:^(){ - NSArray *screens = [NSScreen screens]; - for (NSScreen *screen in screens) { - NSDictionary *screenInfo = [screen deviceDescription]; - NSNumber *screenID = [screenInfo objectForKey:@"NSScreenNumber"]; - if ([screenID intValue] == displayID){ - CFRetain(screen); // GC - screenPtr = ptr_to_jlong(screen); - break; - } - } - }]; - -JNF_COCOA_EXIT(env); - - return screenPtr; -} - /* * Class: sun_lwawt_macosx_CWrapper$NSColor * Method: clearColor diff --git a/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java b/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java new file mode 100644 index 00000000000..014637acec0 --- /dev/null +++ b/jdk/test/java/awt/Window/MaximizeOffscreen/MaximizeOffscreenTest.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test @summary JVM crash if the frame maximized from offscreen + * @author Petr Pchelko + * @library ../../regtesthelpers + * @build Util + * @compile MaximizeOffscreenTest.java + * @run main/othervm MaximizeOffscreenTest + */ + +import test.java.awt.regtesthelpers.Util; + +import javax.swing.*; +import java.awt.*; + +public class MaximizeOffscreenTest { + + private static JFrame frame; + + public static void main(String[] args) throws Throwable { + + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + constructTestUI(); + } + }); + + Util.waitForIdle(null); + SwingUtilities.invokeAndWait(new Runnable() { + @Override + public void run() { + frame.setExtendedState(Frame.MAXIMIZED_BOTH); + } + }); + Util.waitForIdle(null); + } + + private static void constructTestUI() { + frame = new JFrame("Test frame"); + frame.setUndecorated(true); + frame.setBounds(-1000, -1000, 100, 100); + frame.setVisible(true); + } +} From 80f5124f23fb0e7288b03382aede08ff87f4d3ac Mon Sep 17 00:00:00 2001 From: Athijegannathan Sundararajan Date: Thu, 11 Jul 2013 18:23:13 +0530 Subject: [PATCH 072/156] 8020380: __noSuchProperty__ defined in mozilla_compat.js script should be non-enumerable Reviewed-by: jlaskey, hannesw, attila --- .../runtime/resources/mozilla_compat.js | 7 +++- nashorn/test/script/basic/JDK-8020380.js | 36 +++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) create mode 100644 nashorn/test/script/basic/JDK-8020380.js diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js index 206a193f7fa..8a9fcc7de0c 100644 --- a/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js +++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/mozilla_compat.js @@ -48,7 +48,7 @@ Object.defineProperty(this, "importPackage", { var _packages = []; var global = this; var oldNoSuchProperty = global.__noSuchProperty__; - global.__noSuchProperty__ = function(name) { + var __noSuchProperty__ = function(name) { 'use strict'; for (var i in _packages) { try { @@ -69,6 +69,11 @@ Object.defineProperty(this, "importPackage", { } } + Object.defineProperty(global, "__noSuchProperty__", { + writable: true, configurable: true, enumerable: false, + value: __noSuchProperty__ + }); + var prefix = "[JavaPackage "; return function() { for (var i in arguments) { diff --git a/nashorn/test/script/basic/JDK-8020380.js b/nashorn/test/script/basic/JDK-8020380.js new file mode 100644 index 00000000000..90357fa7606 --- /dev/null +++ b/nashorn/test/script/basic/JDK-8020380.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * JDK-8020380: __noSuchProperty__ defined in mozilla_compat.js script should be non-enumerable + * + * @test + * @run + */ + +load("nashorn:mozilla_compat.js"); + +var desc = Object.getOwnPropertyDescriptor(this, "__noSuchProperty__"); +if (typeof desc.enumerable != 'boolean' || desc.enumerable != false) { + fail("__noSuchProperty__ is enumerable"); +} From 94e178de87e76bed08e69d38787d307fcc304c32 Mon Sep 17 00:00:00 2001 From: David Katleman Date: Thu, 11 Jul 2013 10:13:57 -0700 Subject: [PATCH 073/156] Added tag jdk8-b98 for changeset d3db5fb3d72f --- langtools/.hgtags | 1 + 1 file changed, 1 insertion(+) diff --git a/langtools/.hgtags b/langtools/.hgtags index d8403722780..cfb5a39701e 100644 --- a/langtools/.hgtags +++ b/langtools/.hgtags @@ -219,3 +219,4 @@ e19283cd30a43fca94d8f7639c73ef66db493b1e jdk8-b90 4cb1136231275a1f8af53f5bfdef0b488e4b5bab jdk8-b95 988aef3a8c3adac482363293f65e77ec4c5ce98d jdk8-b96 6a11a81a8824c17f6cd2ec8f8492e1229b694e96 jdk8-b97 +ce5a90df517bdceb2739d7dd3e6764b070def802 jdk8-b98 From d3d1da337a96ea28739e5246285c11ade231dc9f Mon Sep 17 00:00:00 2001 From: Robert Field Date: Thu, 11 Jul 2013 14:07:39 +0100 Subject: [PATCH 074/156] 8016281: The SAM method should be passed to the metafactory as a MethodType not a MethodHandle 8020010: Move lambda bridge creation from metafactory and VM to compiler Langtools/javac component of the bridge support and MethodType vs. MethodHandle changes. Reviewed-by: jjg, vromero, briangoetz, forax --- .../com/sun/tools/javac/code/Types.java | 86 +++++ .../com/sun/tools/javac/comp/Attr.java | 40 +- .../com/sun/tools/javac/comp/Check.java | 18 - .../sun/tools/javac/comp/LambdaToMethod.java | 93 +++-- .../com/sun/tools/javac/comp/TransTypes.java | 13 +- .../com/sun/tools/javac/tree/JCTree.java | 8 +- .../com/sun/tools/javac/util/Names.java | 8 +- .../tools/javac/generics/bridges/Bridge.java | 28 ++ .../javac/generics/bridges/BridgeHarness.java | 218 +++++++++++ .../tools/javac/generics/bridges/Bridges.java | 25 ++ .../bridges/tests/TestBridgeWithDefault.java | 31 ++ ...estClassAndInterfaceBridgeIdentical01.java | 45 +++ ...estClassAndInterfaceBridgeIdentical02.java | 45 +++ .../tests/TestNoBridgeInSiblingsSuper.java | 34 ++ .../tests/TestNoDuplicateBridges01.java | 29 ++ .../tests/TestNoDuplicateBridges02.java | 38 ++ .../lambda/bridge/TestMetafactoryBridges.java | 359 ++++++++++++++++++ .../lambda/lambdaExpression/LambdaTest6.java | 2 +- .../lambda/methodReference/BridgeMethod.java | 2 +- .../openjdk/tests/vm/DefaultMethodsTest.java | 4 + 20 files changed, 1042 insertions(+), 84 deletions(-) create mode 100644 langtools/test/tools/javac/generics/bridges/Bridge.java create mode 100644 langtools/test/tools/javac/generics/bridges/BridgeHarness.java create mode 100644 langtools/test/tools/javac/generics/bridges/Bridges.java create mode 100644 langtools/test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java create mode 100644 langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java create mode 100644 langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java create mode 100644 langtools/test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java create mode 100644 langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java create mode 100644 langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java create mode 100644 langtools/test/tools/javac/lambda/bridge/TestMetafactoryBridges.java diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java index 8a3b4235714..51768424722 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java +++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java @@ -33,10 +33,15 @@ import java.util.Map; import java.util.Set; import java.util.WeakHashMap; +import javax.tools.JavaFileObject; + import com.sun.tools.javac.code.Attribute.RetentionPolicy; import com.sun.tools.javac.code.Lint.LintCategory; import com.sun.tools.javac.code.Type.UndetVar.InferenceBound; +import com.sun.tools.javac.comp.AttrContext; import com.sun.tools.javac.comp.Check; +import com.sun.tools.javac.comp.Enter; +import com.sun.tools.javac.comp.Env; import com.sun.tools.javac.jvm.ClassReader; import com.sun.tools.javac.util.*; import static com.sun.tools.javac.code.BoundKind.*; @@ -83,6 +88,7 @@ public class Types { final boolean allowDefaultMethods; final ClassReader reader; final Check chk; + final Enter enter; JCDiagnostic.Factory diags; List warnStack = List.nil(); final Name capturedName; @@ -109,6 +115,7 @@ public class Types { allowDefaultMethods = source.allowDefaultMethods(); reader = ClassReader.instance(context); chk = Check.instance(context); + enter = Enter.instance(context); capturedName = names.fromString(""); messages = JavacMessages.instance(context); diags = JCDiagnostic.Factory.instance(context); @@ -605,6 +612,84 @@ public class Types { return site; } } + + /** + * Create a symbol for a class that implements a given functional interface + * and overrides its functional descriptor. This routine is used for two + * main purposes: (i) checking well-formedness of a functional interface; + * (ii) perform functional interface bridge calculation. + */ + public ClassSymbol makeFunctionalInterfaceClass(Env env, Name name, List targets, long cflags) { + Assert.check(targets.nonEmpty() && isFunctionalInterface(targets.head)); + Symbol descSym = findDescriptorSymbol(targets.head.tsym); + Type descType = findDescriptorType(targets.head); + ClassSymbol csym = new ClassSymbol(cflags, name, env.enclClass.sym.outermostClass()); + csym.completer = null; + csym.members_field = new Scope(csym); + MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym); + csym.members_field.enter(instDescSym); + Type.ClassType ctype = new Type.ClassType(Type.noType, List.nil(), csym); + ctype.supertype_field = syms.objectType; + ctype.interfaces_field = targets; + csym.type = ctype; + csym.sourcefile = ((ClassSymbol)csym.owner).sourcefile; + return csym; + } + + /** + * Find the minimal set of methods that are overridden by the functional + * descriptor in 'origin'. All returned methods are assumed to have different + * erased signatures. + */ + public List functionalInterfaceBridges(TypeSymbol origin) { + Assert.check(isFunctionalInterface(origin)); + Symbol descSym = findDescriptorSymbol(origin); + CompoundScope members = membersClosure(origin.type, false); + ListBuffer overridden = ListBuffer.lb(); + outer: for (Symbol m2 : members.getElementsByName(descSym.name, bridgeFilter)) { + if (m2 == descSym) continue; + else if (descSym.overrides(m2, origin, Types.this, false)) { + for (Symbol m3 : overridden) { + if (isSameType(m3.erasure(Types.this), m2.erasure(Types.this)) || + (m3.overrides(m2, origin, Types.this, false) && + (pendingBridges((ClassSymbol)origin, m3.enclClass()) || + (((MethodSymbol)m2).binaryImplementation((ClassSymbol)m3.owner, Types.this) != null)))) { + continue outer; + } + } + overridden.add(m2); + } + } + return overridden.toList(); + } + //where + private Filter bridgeFilter = new Filter() { + public boolean accepts(Symbol t) { + return t.kind == Kinds.MTH && + t.name != names.init && + t.name != names.clinit && + (t.flags() & SYNTHETIC) == 0; + } + }; + private boolean pendingBridges(ClassSymbol origin, TypeSymbol s) { + //a symbol will be completed from a classfile if (a) symbol has + //an associated file object with CLASS kind and (b) the symbol has + //not been entered + if (origin.classfile != null && + origin.classfile.getKind() == JavaFileObject.Kind.CLASS && + enter.getEnv(origin) == null) { + return false; + } + if (origin == s) { + return true; + } + for (Type t : interfaces(origin.type)) { + if (pendingBridges((ClassSymbol)t.tsym, s)) { + return true; + } + } + return false; + } // /** @@ -2672,6 +2757,7 @@ public class Types { public boolean accepts(Symbol s) { return s.kind == Kinds.MTH && s.name == msym.name && + (s.flags() & SYNTHETIC) == 0 && s.isInheritedIn(site.tsym, Types.this) && overrideEquivalent(memberType(site, s), memberType(site, msym)); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java index 1be8604319f..5db4dee8850 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2334,13 +2334,12 @@ public class Attr extends JCTree.Visitor { if (pt() != Type.recoveryType) { target = targetChecker.visit(target, that); lambdaType = types.findDescriptorType(target); - chk.checkFunctionalInterface(that, target); } else { target = Type.recoveryType; lambdaType = fallbackDescriptorType(that); } - setFunctionalInfo(that, pt(), lambdaType, target, resultInfo.checkContext.inferenceContext()); + setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext); if (lambdaType.hasTag(FORALL)) { //lambda expression target desc cannot be a generic method @@ -2682,13 +2681,12 @@ public class Attr extends JCTree.Visitor { if (pt() != Type.recoveryType) { target = targetChecker.visit(pt(), that); desc = types.findDescriptorType(target); - chk.checkFunctionalInterface(that, target); } else { target = Type.recoveryType; desc = fallbackDescriptorType(that); } - setFunctionalInfo(that, pt(), desc, target, resultInfo.checkContext.inferenceContext()); + setFunctionalInfo(localEnv, that, pt(), desc, target, resultInfo.checkContext); List argtypes = desc.getParameterTypes(); Pair refResult = @@ -2890,31 +2888,37 @@ public class Attr extends JCTree.Visitor { * might contain inference variables, we might need to register an hook in the * current inference context. */ - private void setFunctionalInfo(final JCFunctionalExpression fExpr, final Type pt, - final Type descriptorType, final Type primaryTarget, InferenceContext inferenceContext) { - if (inferenceContext.free(descriptorType)) { - inferenceContext.addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { + private void setFunctionalInfo(final Env env, final JCFunctionalExpression fExpr, + final Type pt, final Type descriptorType, final Type primaryTarget, final CheckContext checkContext) { + if (checkContext.inferenceContext().free(descriptorType)) { + checkContext.inferenceContext().addFreeTypeListener(List.of(pt, descriptorType), new FreeTypeListener() { public void typesInferred(InferenceContext inferenceContext) { - setFunctionalInfo(fExpr, pt, inferenceContext.asInstType(descriptorType), - inferenceContext.asInstType(primaryTarget), inferenceContext); + setFunctionalInfo(env, fExpr, pt, inferenceContext.asInstType(descriptorType), + inferenceContext.asInstType(primaryTarget), checkContext); } }); } else { - ListBuffer targets = ListBuffer.lb(); + ListBuffer targets = ListBuffer.lb(); if (pt.hasTag(CLASS)) { if (pt.isCompound()) { - targets.append(primaryTarget.tsym); //this goes first + targets.append(types.removeWildcards(primaryTarget)); //this goes first for (Type t : ((IntersectionClassType)pt()).interfaces_field) { if (t != primaryTarget) { - targets.append(t.tsym); + targets.append(types.removeWildcards(t)); } } } else { - targets.append(pt.tsym); + targets.append(types.removeWildcards(primaryTarget)); } } fExpr.targets = targets.toList(); - fExpr.descriptorType = descriptorType; + if (checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK && + pt != Type.recoveryType) { + //check that functional interface class is well-formed + ClassSymbol csym = types.makeFunctionalInterfaceClass(env, + names.empty, List.of(fExpr.targets.head), ABSTRACT); + chk.checkImplementations(env.tree, csym, csym); + } } } @@ -4579,9 +4583,6 @@ public class Attr extends JCTree.Visitor { @Override public void visitLambda(JCLambda that) { super.visitLambda(that); - if (that.descriptorType == null) { - that.descriptorType = syms.unknownType; - } if (that.targets == null) { that.targets = List.nil(); } @@ -4593,9 +4594,6 @@ public class Attr extends JCTree.Visitor { if (that.sym == null) { that.sym = new MethodSymbol(0, names.empty, syms.unknownType, syms.noSymbol); } - if (that.descriptorType == null) { - that.descriptorType = syms.unknownType; - } if (that.targets == null) { that.targets = List.nil(); } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java index 76440d0b7d1..c1371992d0e 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java @@ -2275,24 +2275,6 @@ public class Check { c.flags_field |= ACYCLIC; } - /** - * Check that functional interface methods would make sense when seen - * from the perspective of the implementing class - */ - void checkFunctionalInterface(JCTree tree, Type funcInterface) { - ClassType c = new ClassType(Type.noType, List.nil(), null); - ClassSymbol csym = new ClassSymbol(0, names.empty, c, syms.noSymbol); - c.interfaces_field = List.of(types.removeWildcards(funcInterface)); - c.supertype_field = syms.objectType; - c.tsym = csym; - csym.members_field = new Scope(csym); - Symbol descSym = types.findDescriptorSymbol(funcInterface.tsym); - Type descType = types.findDescriptorType(funcInterface); - csym.members_field.enter(new MethodSymbol(PUBLIC, descSym.name, descType, csym)); - csym.completer = null; - checkImplementations(tree, csym, csym); - } - /** Check that all methods which implement some * method conform to the method they implement. * @param tree The class definition whose members are checked. diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java index 9acfdba9c88..21b6791bb7d 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/LambdaToMethod.java @@ -100,6 +100,9 @@ public class LambdaToMethod extends TreeTranslator { /** Flag for alternate metafactories indicating the lambda object has multiple targets */ public static final int FLAG_MARKERS = 1 << 1; + /** Flag for alternate metafactories indicating the lambda object requires multiple bridges */ + public static final int FLAG_BRIDGES = 1 << 2; + private class KlassInfo { /** @@ -321,7 +324,7 @@ public class LambdaToMethod extends TreeTranslator { int refKind = referenceKind(sym); //convert to an invokedynamic call - result = makeMetaFactoryIndyCall(tree, context.needsAltMetafactory(), context.isSerializable(), refKind, sym, indy_args); + result = makeMetafactoryIndyCall(context, refKind, sym, indy_args); } private JCIdent makeThis(Type type, Symbol owner) { @@ -382,7 +385,7 @@ public class LambdaToMethod extends TreeTranslator { //build a sam instance using an indy call to the meta-factory - result = makeMetaFactoryIndyCall(tree, localContext.needsAltMetafactory(), localContext.isSerializable(), localContext.referenceKind(), refSym, indy_args); + result = makeMetafactoryIndyCall(localContext, localContext.referenceKind(), refSym, indy_args); } /** @@ -606,8 +609,8 @@ public class LambdaToMethod extends TreeTranslator { make.Return(makeIndyCall( pos, syms.lambdaMetafactory, - names.altMetaFactory, - staticArgs, indyType, serArgs.toList())), + names.altMetafactory, + staticArgs, indyType, serArgs.toList(), samSym.name)), null); ListBuffer stmts = kInfo.deserializeCases.get(implMethodName); if (stmts == null) { @@ -905,22 +908,26 @@ public class LambdaToMethod extends TreeTranslator { kInfo.addMethod(new MemberReferenceBridger(tree, localContext).bridge()); } + private MethodType typeToMethodType(Type mt) { + Type type = types.erasure(mt); + return new MethodType(type.getParameterTypes(), + type.getReturnType(), + type.getThrownTypes(), + syms.methodClass); + } + /** * Generate an indy method call to the meta factory */ - private JCExpression makeMetaFactoryIndyCall(JCFunctionalExpression tree, boolean needsAltMetafactory, - boolean isSerializable, int refKind, Symbol refSym, List indy_args) { + private JCExpression makeMetafactoryIndyCall(TranslationContext context, + int refKind, Symbol refSym, List indy_args) { + JCFunctionalExpression tree = context.tree; //determine the static bsm args - Type mtype = types.erasure(tree.descriptorType); MethodSymbol samSym = (MethodSymbol) types.findDescriptorSymbol(tree.type.tsym); List staticArgs = List.of( - new Pool.MethodHandle(ClassFile.REF_invokeInterface, - types.findDescriptorSymbol(tree.type.tsym), types), + typeToMethodType(samSym.type), new Pool.MethodHandle(refKind, refSym, types), - new MethodType(mtype.getParameterTypes(), - mtype.getReturnType(), - mtype.getThrownTypes(), - syms.methodClass)); + typeToMethodType(tree.getDescriptorType(types))); //computed indy arg types ListBuffer indy_args_types = ListBuffer.lb(); @@ -934,31 +941,46 @@ public class LambdaToMethod extends TreeTranslator { List.nil(), syms.methodClass); - Name metafactoryName = needsAltMetafactory ? - names.altMetaFactory : names.metaFactory; + Name metafactoryName = context.needsAltMetafactory() ? + names.altMetafactory : names.metafactory; - if (needsAltMetafactory) { + if (context.needsAltMetafactory()) { ListBuffer markers = ListBuffer.lb(); - for (Symbol t : tree.targets.tail) { - if (t != syms.serializableType.tsym) { - markers.append(t); + for (Type t : tree.targets.tail) { + if (t.tsym != syms.serializableType.tsym) { + markers.append(t.tsym); } } - int flags = isSerializable? FLAG_SERIALIZABLE : 0; + int flags = context.isSerializable() ? FLAG_SERIALIZABLE : 0; boolean hasMarkers = markers.nonEmpty(); - flags |= hasMarkers ? FLAG_MARKERS : 0; + boolean hasBridges = context.bridges.nonEmpty(); + if (hasMarkers) { + flags |= FLAG_MARKERS; + } + if (hasBridges) { + flags |= FLAG_BRIDGES; + } staticArgs = staticArgs.append(flags); if (hasMarkers) { staticArgs = staticArgs.append(markers.length()); staticArgs = staticArgs.appendList(markers.toList()); } - if (isSerializable) { + if (hasBridges) { + staticArgs = staticArgs.append(context.bridges.length() - 1); + for (Symbol s : context.bridges) { + Type s_erasure = s.erasure(types); + if (!types.isSameType(s_erasure, samSym.erasure(types))) { + staticArgs = staticArgs.append(s.erasure(types)); + } + } + } + if (context.isSerializable()) { addDeserializationCase(refKind, refSym, tree.type, samSym, tree, staticArgs, indyType); } } - return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args); + return makeIndyCall(tree, syms.lambdaMetafactory, metafactoryName, staticArgs, indyType, indy_args, samSym.name); } /** @@ -966,7 +988,8 @@ public class LambdaToMethod extends TreeTranslator { * arguments types */ private JCExpression makeIndyCall(DiagnosticPosition pos, Type site, Name bsmName, - List staticArgs, MethodType indyType, List indyArgs) { + List staticArgs, MethodType indyType, List indyArgs, + Name methName) { int prevPos = make.pos; try { make.at(pos); @@ -978,7 +1001,7 @@ public class LambdaToMethod extends TreeTranslator { bsmName, bsm_staticArgs, List.nil()); DynamicMethodSymbol dynSym = - new DynamicMethodSymbol(names.lambda, + new DynamicMethodSymbol(methName, syms.noSymbol, bsm.isStatic() ? ClassFile.REF_invokeStatic : @@ -1299,7 +1322,6 @@ public class LambdaToMethod extends TreeTranslator { // Make lambda holding the new-class call JCLambda slam = make.Lambda(params, nc); - slam.descriptorType = tree.descriptorType; slam.targets = tree.targets; slam.type = tree.type; slam.pos = tree.pos; @@ -1634,23 +1656,30 @@ public class LambdaToMethod extends TreeTranslator { /** the enclosing translation context (set for nested lambdas/mref) */ TranslationContext prev; + /** list of methods to be bridged by the meta-factory */ + List bridges; + TranslationContext(T tree) { this.tree = tree; this.owner = owner(); this.depth = frameStack.size() - 1; this.prev = context(); + ClassSymbol csym = + types.makeFunctionalInterfaceClass(attrEnv, names.empty, tree.targets, ABSTRACT | INTERFACE); + this.bridges = types.functionalInterfaceBridges(csym); } /** does this functional expression need to be created using alternate metafactory? */ boolean needsAltMetafactory() { - return (tree.targets.length() > 1 || - isSerializable()); + return tree.targets.length() > 1 || + isSerializable() || + bridges.length() > 1; } /** does this functional expression require serialization support? */ boolean isSerializable() { - for (Symbol target : tree.targets) { - if (types.asSuper(target.type, syms.serializableType.tsym) != null) { + for (Type target : tree.targets) { + if (types.asSuper(target, syms.serializableType.tsym) != null) { return true; } } @@ -1833,7 +1862,7 @@ public class LambdaToMethod extends TreeTranslator { } Type generatedLambdaSig() { - return types.erasure(tree.descriptorType); + return types.erasure(tree.getDescriptorType(types)); } } @@ -1909,7 +1938,7 @@ public class LambdaToMethod extends TreeTranslator { } Type bridgedRefSig() { - return types.erasure(types.findDescriptorSymbol(tree.targets.head).type); + return types.erasure(types.findDescriptorSymbol(tree.targets.head.tsym).type); } } } diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java index 61761ba9b35..710617bce36 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java +++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java @@ -68,6 +68,7 @@ public class TransTypes extends TreeTranslator { private TreeMaker make; private Enter enter; private boolean allowEnums; + private boolean allowInterfaceBridges; private Types types; private final Resolve resolve; @@ -91,6 +92,7 @@ public class TransTypes extends TreeTranslator { Source source = Source.instance(context); allowEnums = source.allowEnums(); addBridges = source.addBridges(); + allowInterfaceBridges = source.allowDefaultMethods(); types = Types.instance(context); make = TreeMaker.instance(context); resolve = Resolve.instance(context); @@ -252,7 +254,8 @@ public class TransTypes extends TreeTranslator { // Create a bridge method symbol and a bridge definition without a body. Type bridgeType = meth.erasure(types); - long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE; + long flags = impl.flags() & AccessFlags | SYNTHETIC | BRIDGE | + (origin.isInterface() ? DEFAULT : 0); if (hypothetical) flags |= HYPOTHETICAL; MethodSymbol bridge = new MethodSymbol(flags, meth.name, @@ -387,11 +390,12 @@ public class TransTypes extends TreeTranslator { } } // where - Filter overrideBridgeFilter = new Filter() { + private Filter overrideBridgeFilter = new Filter() { public boolean accepts(Symbol s) { return (s.flags() & (SYNTHETIC | OVERRIDE_BRIDGE)) != SYNTHETIC; } }; + /** * @param method The symbol for which a bridge might have to be added * @param impl The implementation of method @@ -999,8 +1003,9 @@ public class TransTypes extends TreeTranslator { ListBuffer bridges = new ListBuffer(); if (false) //see CR: 6996415 bridges.appendList(addOverrideBridgesIfNeeded(tree, c)); - if ((tree.sym.flags() & INTERFACE) == 0) - addBridges(tree.pos(), tree.sym, bridges); + if (allowInterfaceBridges || (tree.sym.flags() & INTERFACE) == 0) { + addBridges(tree.pos(), c, bridges); + } tree.defs = bridges.toList().prependList(tree.defs); } tree.type = erasure(tree.type); diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java index 191dda07adf..846a4a2e2aa 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java +++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java @@ -641,10 +641,12 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition { polyKind = PolyKind.POLY; } - /** target descriptor inferred for this functional expression. */ - public Type descriptorType; /** list of target types inferred for this functional expression. */ - public List targets; + public List targets; + + public Type getDescriptorType(Types types) { + return types.findDescriptorType(targets.head); + } } /** diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java index 623f27605f8..6533c1fde77 100644 --- a/langtools/src/share/classes/com/sun/tools/javac/util/Names.java +++ b/langtools/src/share/classes/com/sun/tools/javac/util/Names.java @@ -174,8 +174,8 @@ public class Names { //lambda-related public final Name lambda; - public final Name metaFactory; - public final Name altMetaFactory; + public final Name metafactory; + public final Name altMetafactory; public final Name.Table table; @@ -310,8 +310,8 @@ public class Names { //lambda-related lambda = fromString("lambda$"); - metaFactory = fromString("metaFactory"); - altMetaFactory = fromString("altMetaFactory"); + metafactory = fromString("metafactory"); + altMetafactory = fromString("altMetafactory"); } protected Name.Table createTable(Options options) { diff --git a/langtools/test/tools/javac/generics/bridges/Bridge.java b/langtools/test/tools/javac/generics/bridges/Bridge.java new file mode 100644 index 00000000000..76e323eeadc --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/Bridge.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +import java.lang.annotation.Repeatable; + +@Repeatable(Bridges.class) +@interface Bridge { + String value(); +} diff --git a/langtools/test/tools/javac/generics/bridges/BridgeHarness.java b/langtools/test/tools/javac/generics/bridges/BridgeHarness.java new file mode 100644 index 00000000000..bc4c7129825 --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/BridgeHarness.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8013789 + * @summary Compiler should emit bridges in interfaces + * @library /tools/javac/lib + * @build JavacTestingAbstractProcessor BridgeHarness + * @run main BridgeHarness + */ + +import com.sun.source.util.JavacTask; +import com.sun.tools.classfile.AccessFlags; +import com.sun.tools.classfile.ClassFile; +import com.sun.tools.classfile.ConstantPool; +import com.sun.tools.classfile.ConstantPoolException; +import com.sun.tools.classfile.Method; +import com.sun.tools.javac.code.Symbol.ClassSymbol; +import com.sun.tools.javac.util.List; + +import java.io.File; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.element.Element; +import javax.lang.model.element.TypeElement; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.StandardJavaFileManager; +import javax.tools.ToolProvider; + +import static javax.tools.StandardLocation.*; + +public class BridgeHarness { + + /** number of errors found (must be zero for the test to pass) */ + static int nerrors = 0; + + /** the (shared) Java compiler used for compiling the tests */ + static final JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + + /** the (shared) file manager used by the compiler */ + static final StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); + + public static void main(String[] args) throws Exception { + //set sourcepath + fm.setLocation(SOURCE_PATH, + Arrays.asList(new File(System.getProperty("test.src"), "tests"))); + //set output (-d) + fm.setLocation(javax.tools.StandardLocation.CLASS_OUTPUT, + Arrays.asList(new File(System.getProperty("user.dir")))); + for (JavaFileObject jfo : fm.list(SOURCE_PATH, "", Collections.singleton(JavaFileObject.Kind.SOURCE), true)) { + //for each source, compile and check against annotations + new BridgeHarness(jfo).compileAndCheck(); + } + //if there were errors, fail + if (nerrors > 0) { + throw new AssertionError("Errors were found"); + } + } + + /* utility methods */ + + /** + * Remove an element from a list + */ + static List drop(List lz, Z z) { + if (lz.head == z) { + return drop(lz.tail, z); + } else if (lz.isEmpty()) { + return lz; + } else { + return drop(lz.tail, z).prepend(lz.head); + } + } + + /** + * return a string representation of a bytecode method + */ + static String descriptor(Method m, ConstantPool cp) throws ConstantPoolException { + return m.getName(cp) + m.descriptor.getValue(cp); + } + + /* test harness */ + + /** Test file to be compiled */ + JavaFileObject jfo; + + /** Mapping between class name and list of bridges in class with that name */ + Map> bridgesMap = new HashMap>(); + + protected BridgeHarness(JavaFileObject jfo) { + this.jfo = jfo; + } + + /** + * Compile a test using a custom annotation processor and check the generated + * bytecode against discovered annotations. + */ + protected void compileAndCheck() throws Exception { + JavacTask ct = (JavacTask)comp.getTask(null, fm, null, null, null, Arrays.asList(jfo)); + ct.setProcessors(Collections.singleton(new BridgeFinder())); + + for (JavaFileObject jfo : ct.generate()) { + checkBridges(jfo); + } + } + + /** + * Check that every bridge in the generated classfile has a matching bridge + * annotation in the bridge map + */ + protected void checkBridges(JavaFileObject jfo) { + try { + ClassFile cf = ClassFile.read(jfo.openInputStream()); + System.err.println("checking: " + cf.getName()); + + List bridgeList = bridgesMap.get(cf.getName()); + if (bridgeList == null) { + //no bridges - nothing to check; + bridgeList = List.nil(); + } + + for (Method m : cf.methods) { + if (m.access_flags.is(AccessFlags.ACC_SYNTHETIC | AccessFlags.ACC_BRIDGE)) { + //this is a bridge - see if there's a match in the bridge list + Bridge match = null; + for (Bridge b : bridgeList) { + if (b.value().equals(descriptor(m, cf.constant_pool))) { + match = b; + break; + } + } + if (match == null) { + error("No annotation for bridge method: " + descriptor(m, cf.constant_pool)); + } else { + bridgeList = drop(bridgeList, match); + } + } + } + if (bridgeList.nonEmpty()) { + error("Redundant bridge annotation found: " + bridgeList.head.value()); + } + } catch (Exception e) { + e.printStackTrace(); + throw new Error("error reading " + jfo.toUri() +": " + e); + } + } + + /** + * Log an error + */ + protected void error(String msg) { + nerrors++; + System.err.printf("Error occurred while checking file: %s\nreason: %s\n", jfo.getName(), msg); + } + + /** + * This annotation processor is used to populate the bridge map with the + * contents of the annotations that are found on the tests being compiled + */ + @SupportedAnnotationTypes({"Bridges","Bridge"}) + class BridgeFinder extends JavacTestingAbstractProcessor { + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) + return true; + + TypeElement bridgeAnno = elements.getTypeElement("Bridge"); + TypeElement bridgesAnno = elements.getTypeElement("Bridges"); + + //see if there are repeated annos + for (Element elem: roundEnv.getElementsAnnotatedWith(bridgesAnno)) { + List bridgeList = List.nil(); + Bridges bridges = elem.getAnnotation(Bridges.class); + for (Bridge bridge : bridges.value()) { + bridgeList = bridgeList.prepend(bridge); + } + bridgesMap.put(((ClassSymbol)elem).flatname.toString(), bridgeList); + } + + //see if there are non-repeated annos + for (Element elem: roundEnv.getElementsAnnotatedWith(bridgeAnno)) { + Bridge bridge = elem.getAnnotation(Bridge.class); + bridgesMap.put(((ClassSymbol)elem).flatname.toString(), + List.of(bridge)); + } + + return true; + } + } +} diff --git a/langtools/test/tools/javac/generics/bridges/Bridges.java b/langtools/test/tools/javac/generics/bridges/Bridges.java new file mode 100644 index 00000000000..1980cf19a0b --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/Bridges.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +@interface Bridges { + Bridge[] value(); +} diff --git a/langtools/test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java b/langtools/test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java new file mode 100644 index 00000000000..51a7ada9624 --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/tests/TestBridgeWithDefault.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +class TestBridgeWithDefault { + interface A { Object m(int x); } + + @Bridge("m(I)Ljava/lang/Object;") + interface B extends A { + String m(int x); + default Integer m(long x) { return null; } + } +} diff --git a/langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java b/langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java new file mode 100644 index 00000000000..370cddc54e3 --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical01.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +class TestClassAndInterfaceBridgeIdentical01 { + + interface A { Object m(); } + interface B { Number m(); } + + @Bridge("m()Ljava/lang/Object;") + @Bridge("m()Ljava/lang/Number;") + interface C extends A, B { + Integer m(); + } + + @Bridge("m()Ljava/lang/Object;") + @Bridge("m()Ljava/lang/Number;") + static abstract class D implements A, B { + public abstract Integer m(); + } + + @Bridge("m()Ljava/lang/Object;") + @Bridge("m()Ljava/lang/Number;") + static class E implements A, B { + public Integer m() { return 1; } + } +} diff --git a/langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java b/langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java new file mode 100644 index 00000000000..c774d609d35 --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/tests/TestClassAndInterfaceBridgeIdentical02.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +class TestClassAndInterfaceBridgeIdentical02 { + + interface A { void m(X x); } + interface B { void m(X x); } + + @Bridge("m(Ljava/lang/Object;)V") + @Bridge("m(Ljava/lang/Number;)V") + interface C extends A, B { + void m(Integer i); + } + + @Bridge("m(Ljava/lang/Object;)V") + @Bridge("m(Ljava/lang/Number;)V") + static abstract class D implements A, B { + public abstract void m(Integer i); + } + + @Bridge("m(Ljava/lang/Object;)V") + @Bridge("m(Ljava/lang/Number;)V") + static class E implements A, B { + public void m(Integer i) { } + } +} diff --git a/langtools/test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java b/langtools/test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java new file mode 100644 index 00000000000..bfe1dcb5367 --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/tests/TestNoBridgeInSiblingsSuper.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +class TestNoBridgeInSiblingSuper { + interface A { Object m(); } + interface B { String m(); } + //no bridge here! + interface C extends A, B { } + + @Bridge("m()Ljava/lang/Object;") + interface D extends C { + String m(); + } +} + diff --git a/langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java b/langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java new file mode 100644 index 00000000000..d575ef9d8c3 --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges01.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +class TestNoDuplicateBridges01 { + interface A1 { Object m(); } + interface A2 { Object m(); } + + @Bridge("m()Ljava/lang/Object;") + interface B extends A1, A2 { B m(); } +} diff --git a/langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java b/langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java new file mode 100644 index 00000000000..adab090ac9e --- /dev/null +++ b/langtools/test/tools/javac/generics/bridges/tests/TestNoDuplicateBridges02.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +class TestNoDuplicateBridges02 { + interface A { + A get(); + } + + @Bridge("get()LTestNoDuplicateBridges02$A;") + interface B extends A { + B get(); + } + + @Bridge("get()LTestNoDuplicateBridges02$A;") + @Bridge("get()LTestNoDuplicateBridges02$B;") + interface C extends A, B { + C get(); + } +} diff --git a/langtools/test/tools/javac/lambda/bridge/TestMetafactoryBridges.java b/langtools/test/tools/javac/lambda/bridge/TestMetafactoryBridges.java new file mode 100644 index 00000000000..3a4a695acfe --- /dev/null +++ b/langtools/test/tools/javac/lambda/bridge/TestMetafactoryBridges.java @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code 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 General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8013789 + * @summary Compiler should emit bridges in interfaces + */ + +import com.sun.source.util.JavacTask; +import com.sun.tools.javac.api.ClientCodeWrapper.DiagnosticSourceUnwrapper; +import com.sun.tools.javac.code.Symbol; +import com.sun.tools.javac.util.JCDiagnostic; + +import java.io.File; +import java.io.PrintWriter; +import java.net.URI; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumSet; +import java.util.List; +import java.util.Set; + +import javax.tools.Diagnostic; +import javax.tools.Diagnostic.Kind; +import javax.tools.JavaCompiler; +import javax.tools.JavaFileObject; +import javax.tools.SimpleJavaFileObject; +import javax.tools.ToolProvider; + +public class TestMetafactoryBridges { + + static int checkCount = 0; + + enum ClasspathKind { + NONE(), + B7(7, ClassKind.B), + A7(7, ClassKind.A), + B8(8, ClassKind.B), + A8(8, ClassKind.A); + + int version; + ClassKind ck; + + ClasspathKind() { + this(-1, null); + } + + ClasspathKind(int version, ClassKind ck) { + this.version = version; + this.ck = ck; + } + } + + enum PreferPolicy { + SOURCE("-Xprefer:source"), + NEWER("-Xprefer:newer"); + + String preferOpt; + + PreferPolicy(String preferOpt) { + this.preferOpt = preferOpt; + } + } + + enum SourcepathKind { + NONE, + A(ClassKind.A), + B(ClassKind.B), + C(ClassKind.C), + AB(ClassKind.A, ClassKind.B), + BC(ClassKind.B, ClassKind.C), + AC(ClassKind.A, ClassKind.C), + ABC(ClassKind.A, ClassKind.B, ClassKind.C); + + List sources; + + SourcepathKind(ClassKind... sources) { + this.sources = Arrays.asList(sources); + } + } + + enum SourceSet { + ALL() { + @Override + List> permutations() { + return Arrays.asList( + Arrays.asList(ClassKind.A, ClassKind.B, ClassKind.C), + Arrays.asList(ClassKind.A, ClassKind.B, ClassKind.C), + Arrays.asList(ClassKind.B, ClassKind.A, ClassKind.C), + Arrays.asList(ClassKind.B, ClassKind.C, ClassKind.A), + Arrays.asList(ClassKind.C, ClassKind.A, ClassKind.B), + Arrays.asList(ClassKind.C, ClassKind.B, ClassKind.A) + ); + } + }, + AC() { + @Override + List> permutations() { + return Arrays.asList( + Arrays.asList(ClassKind.A, ClassKind.C), + Arrays.asList(ClassKind.C, ClassKind.A) + ); + } + }, + C() { + @Override + List> permutations() { + return Arrays.asList(Arrays.asList(ClassKind.C)); + } + }; + + abstract List> permutations(); + } + + enum ClassKind { + A("A", "interface A { Object m(); }"), + B("B", "interface B extends A { Integer m(); }", A), + C("C", "class C { B b = ()->42; }", A, B); + + String name; + String source; + ClassKind[] deps; + + ClassKind(String name, String source, ClassKind... deps) { + this.name = name; + this.source = source; + this.deps = deps; + } + } + + public static void main(String... args) throws Exception { + String SCRATCH_DIR = System.getProperty("user.dir"); + //create default shared JavaCompiler - reused across multiple compilations + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); + + int n = 0; + for (SourceSet ss : SourceSet.values()) { + for (List sources : ss.permutations()) { + for (SourcepathKind spKind : SourcepathKind.values()) { + for (ClasspathKind cpKind : ClasspathKind.values()) { + for (PreferPolicy pp : PreferPolicy.values()) { + Set deps = EnumSet.noneOf(ClassKind.class); + if (cpKind.ck != null) { + deps.add(cpKind.ck); + } + deps.addAll(sources); + if (deps.size() < 3) continue; + File testDir = new File(SCRATCH_DIR, "test" + n); + testDir.mkdir(); + try (PrintWriter debugWriter = new PrintWriter(new File(testDir, "debug.txt"))) { + new TestMetafactoryBridges(testDir, sources, spKind, cpKind, pp, debugWriter).run(comp); + n++; + } + } + } + } + } + } + System.out.println("Total check executed: " + checkCount); + } + + File testDir; + List sources; + SourcepathKind spKind; + ClasspathKind cpKind; + PreferPolicy pp; + PrintWriter debugWriter; + DiagnosticChecker diagChecker; + + TestMetafactoryBridges(File testDir, Listsources, SourcepathKind spKind, + ClasspathKind cpKind, PreferPolicy pp, PrintWriter debugWriter) { + this.testDir = testDir; + this.sources = sources; + this.spKind = spKind; + this.cpKind = cpKind; + this.pp = pp; + this.debugWriter = debugWriter; + this.diagChecker = new DiagnosticChecker(); + } + + class JavaSource extends SimpleJavaFileObject { + + final String source; + + public JavaSource(ClassKind ck) { + super(URI.create(String.format("myfo:/%s.java", ck.name)), JavaFileObject.Kind.SOURCE); + this.source = ck.source; + } + + @Override + public CharSequence getCharContent(boolean ignoreEncodingErrors) { + return source; + } + } + + void run(JavaCompiler tool) throws Exception { + File classesDir = new File(testDir, "classes"); + File outDir = new File(testDir, "out"); + File srcDir = new File(testDir, "src"); + classesDir.mkdir(); + outDir.mkdir(); + srcDir.mkdir(); + + debugWriter.append(testDir.getName() + "\n"); + debugWriter.append("sources = " + sources + "\n"); + debugWriter.append("spKind = " + spKind + "\n"); + debugWriter.append("cpKind = " + cpKind + "\n"); + debugWriter.append("preferPolicy = " + pp.preferOpt + "\n"); + + //step 1 - prepare sources (older!!) + debugWriter.append("Preparing sources\n"); + for (ClassKind ck : spKind.sources) { + //skip sources explicitly provided on command line + if (!sources.contains(ck)) { + debugWriter.append("Copy " + ck.name + ".java to" + srcDir.getAbsolutePath() + "\n"); + File dest = new File(srcDir, ck.name + ".java"); + PrintWriter pw = new PrintWriter(dest); + pw.append(ck.source); + pw.close(); + } + } + + //step 2 - prepare classes + debugWriter.append("Preparing classes\n"); + if (cpKind != ClasspathKind.NONE) { + List sources = new ArrayList<>(); + ClassKind toRemove = null; + sources.add(new JavaSource(cpKind.ck)); + if (cpKind.ck.deps.length != 0) { + //at most only one dependency + toRemove = cpKind.ck.deps[0]; + sources.add(new JavaSource(toRemove)); + } + JavacTask ct = (JavacTask)tool.getTask(debugWriter, null, null, + Arrays.asList("-d", classesDir.getAbsolutePath(), "-source", String.valueOf(cpKind.version)), null, sources); + try { + ct.generate(); + if (toRemove != null) { + debugWriter.append("Remove " + toRemove.name + ".class from" + classesDir.getAbsolutePath() + "\n"); + File fileToRemove = new File(classesDir, toRemove.name + ".class"); + fileToRemove.delete(); + } + } catch (Throwable ex) { + throw new AssertionError("Error thrown when generating side-classes"); + } + } + + //step 3 - compile + debugWriter.append("Compiling test\n"); + List sourcefiles = new ArrayList<>(); + for (ClassKind ck : sources) { + sourcefiles.add(new JavaSource(ck)); + } + JavacTask ct = (JavacTask)tool.getTask(debugWriter, null, diagChecker, + Arrays.asList("-XDdumpLambdaToMethodStats", "-d", outDir.getAbsolutePath(), + "-sourcepath", srcDir.getAbsolutePath(), + "-classpath", classesDir.getAbsolutePath(), + pp.preferOpt), null, sourcefiles); + try { + ct.generate(); + } catch (Throwable ex) { + throw new AssertionError("Error thrown when compiling test case"); + } + check(); + } + + void check() { + checkCount++; + if (diagChecker.errorFound) { + throw new AssertionError("Unexpected compilation failure"); + } + + boolean altMetafactory = + cpKind == ClasspathKind.B7 && + !sources.contains(ClassKind.B) && + (pp == PreferPolicy.NEWER || !spKind.sources.contains(ClassKind.B)); + + if (altMetafactory != diagChecker.altMetafactory) { + throw new AssertionError("Bad metafactory detected - expected altMetafactory: " + altMetafactory + + "\ntest: " + testDir); + } + } + + static class DiagnosticChecker implements javax.tools.DiagnosticListener { + + boolean altMetafactory = false; + boolean errorFound = false; + + public void report(Diagnostic diagnostic) { + if (diagnostic.getKind() == Diagnostic.Kind.ERROR) { + errorFound = true; + } else if (statProcessor.matches(diagnostic)) { + statProcessor.process(diagnostic); + } + } + + abstract class DiagnosticProcessor { + + List codes; + Diagnostic.Kind kind; + + public DiagnosticProcessor(Kind kind, String... codes) { + this.codes = Arrays.asList(codes); + this.kind = kind; + } + + abstract void process(Diagnostic diagnostic); + + boolean matches(Diagnostic diagnostic) { + return (codes.isEmpty() || codes.contains(diagnostic.getCode())) && + diagnostic.getKind() == kind; + } + + JCDiagnostic asJCDiagnostic(Diagnostic diagnostic) { + if (diagnostic instanceof JCDiagnostic) { + return (JCDiagnostic)diagnostic; + } else if (diagnostic instanceof DiagnosticSourceUnwrapper) { + return ((DiagnosticSourceUnwrapper)diagnostic).d; + } else { + throw new AssertionError("Cannot convert diagnostic to JCDiagnostic: " + diagnostic.getClass().getName()); + } + } + } + + DiagnosticProcessor statProcessor = new DiagnosticProcessor(Kind.NOTE, + "compiler.note.lambda.stat", + "compiler.note.mref.stat", + "compiler.note.mref.stat.1") { + @Override + void process(Diagnostic diagnostic) { + JCDiagnostic diag = asJCDiagnostic(diagnostic); + if ((Boolean)diag.getArgs()[0]) { + altMetafactory = true; + } + } + }; + } +} diff --git a/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java index 9ee5c9308f2..ff1c209f01d 100644 --- a/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java +++ b/langtools/test/tools/javac/lambda/lambdaExpression/LambdaTest6.java @@ -105,7 +105,7 @@ public class LambdaTest6 { Class returnType = m.getReturnType(); assertTrue(types.remove(returnType.getName())); } - assertTrue(types.isEmpty()); + assertTrue(types.size() == 1); //there's a bridge } diff --git a/langtools/test/tools/javac/lambda/methodReference/BridgeMethod.java b/langtools/test/tools/javac/lambda/methodReference/BridgeMethod.java index e1df4bc8556..bf704321e64 100644 --- a/langtools/test/tools/javac/lambda/methodReference/BridgeMethod.java +++ b/langtools/test/tools/javac/lambda/methodReference/BridgeMethod.java @@ -112,6 +112,6 @@ public class BridgeMethod { Class returnType = m.getReturnType(); assertTrue(types.remove(returnType.getName())); } - assertTrue(types.isEmpty()); + assertTrue(types.size() == 1); //there's a bridge } } diff --git a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java index aad8cd37043..77500f255e9 100644 --- a/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java +++ b/langtools/test/tools/javac/lambdaShapes/org/openjdk/tests/vm/DefaultMethodsTest.java @@ -395,6 +395,7 @@ public class DefaultMethodsTest extends TestHarness { * TEST: C c = new C(); c.m() == 88; * TEST: I i = new C(); i.m() == 88; */ + @Test(enabled=false) public void testSelfFill() { // This test ensures that a concrete method overrides a default method // that matches at the language-level, but has a different method @@ -484,6 +485,7 @@ public class DefaultMethodsTest extends TestHarness { * TEST: J j = new C(); j.m("A","B","C") == 88; * TEST: K k = new C(); k.m("A","B","C") == 88; */ + @Test(enabled=false) public void testBridges() { DefaultMethod dm = new DefaultMethod("int", stdMethodName, "return 99;", new MethodParameter("T", "t"), new MethodParameter("V", "v"), @@ -672,6 +674,7 @@ public class DefaultMethodsTest extends TestHarness { * class S { Object foo() { return (new D()).m(); } // link sig: ()LInteger; * TEST: S s = new S(); s.foo() == new Integer(99) */ + @Test(enabled=false) public void testCovarBridge() { Interface I = new Interface("I", new DefaultMethod( "Integer", "m", "return new Integer(88);")); @@ -754,6 +757,7 @@ public class DefaultMethodsTest extends TestHarness { * Test that a erased-signature-matching method does not implement * non-language-level matching methods */ + @Test(enabled=false) public void testNonConcreteFill() { AbstractMethod ipm = new AbstractMethod("int", "m", new MethodParameter("T", "t"), From b3a5f0ec3878822c8c23d0c183702d7ce8d50217 Mon Sep 17 00:00:00 2001 From: Leonid Romanov Date: Thu, 11 Jul 2013 18:23:15 +0400 Subject: [PATCH 075/156] 8020038: [macosx] Incorrect usage of invokeLater() and likes in callbacks called via JNI from AppKit thread Reviewed-by: art, anthony --- .../com/apple/eawt/FullScreenHandler.java | 3 +- .../com/apple/eawt/_AppEventHandler.java | 100 ++++++++++++------ .../com/apple/eawt/event/GestureHandler.java | 4 +- .../classes/com/apple/laf/ScreenMenu.java | 9 +- .../sun/lwawt/macosx/CCheckboxMenuItem.java | 4 +- .../sun/lwawt/macosx/CViewEmbeddedFrame.java | 4 +- 6 files changed, 80 insertions(+), 44 deletions(-) diff --git a/jdk/src/macosx/classes/com/apple/eawt/FullScreenHandler.java b/jdk/src/macosx/classes/com/apple/eawt/FullScreenHandler.java index f5a843bcdbf..64e81b08a00 100644 --- a/jdk/src/macosx/classes/com/apple/eawt/FullScreenHandler.java +++ b/jdk/src/macosx/classes/com/apple/eawt/FullScreenHandler.java @@ -32,6 +32,7 @@ import java.util.List; import javax.swing.RootPaneContainer; import com.apple.eawt.AppEvent.FullScreenEvent; +import sun.awt.SunToolkit; import java.lang.annotation.Native; @@ -75,7 +76,7 @@ final class FullScreenHandler { static void handleFullScreenEventFromNative(final Window window, final int type) { if (!(window instanceof RootPaneContainer)) return; // handles null - EventQueue.invokeLater(new Runnable() { + SunToolkit.executeOnEventHandlerThread(window, new Runnable() { public void run() { final FullScreenHandler handler = getHandlerFor((RootPaneContainer)window); if (handler != null) handler.notifyListener(new FullScreenEvent(window), type); diff --git a/jdk/src/macosx/classes/com/apple/eawt/_AppEventHandler.java b/jdk/src/macosx/classes/com/apple/eawt/_AppEventHandler.java index a380e8412fd..b98d5739510 100644 --- a/jdk/src/macosx/classes/com/apple/eawt/_AppEventHandler.java +++ b/jdk/src/macosx/classes/com/apple/eawt/_AppEventHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,8 @@ import java.io.File; import java.net.*; import java.util.*; import java.util.List; +import sun.awt.AppContext; +import sun.awt.SunToolkit; import com.apple.eawt.AppEvent.*; @@ -269,11 +271,9 @@ class _AppEventHandler { } class _AppReOpenedDispatcher extends _AppEventMultiplexor { - void performOnListeners(final List listeners, final _NativeEvent event) { + void performOnListener(AppReOpenedListener listener, final _NativeEvent event) { final AppReOpenedEvent e = new AppReOpenedEvent(); - for (final AppReOpenedListener listener : listeners) { - listener.appReOpened(e); - } + listener.appReOpened(e); } } @@ -415,50 +415,67 @@ class _AppEventHandler { } abstract class _AppEventMultiplexor { - final List _listeners = new ArrayList(0); + private final Map listenerToAppContext = + new IdentityHashMap(); boolean nativeListenerRegistered; // called from AppKit Thread-0 void dispatch(final _NativeEvent event, final Object... args) { - // grab a local ref to the listeners - final List localListeners; + // grab a local ref to the listeners and its contexts as an array of the map's entries + final ArrayList> localEntries; synchronized (this) { - if (_listeners.size() == 0) return; - localListeners = new ArrayList(_listeners); + if (listenerToAppContext.size() == 0) { + return; + } + localEntries = new ArrayList>(listenerToAppContext.size()); + localEntries.addAll(listenerToAppContext.entrySet()); } - EventQueue.invokeLater(new Runnable() { - public void run() { - performOnListeners(localListeners, event); - } - }); + for (final Map.Entry e : localEntries) { + final L listener = e.getKey(); + final AppContext listenerContext = e.getValue(); + SunToolkit.invokeLaterOnAppContext(listenerContext, new Runnable() { + public void run() { + performOnListener(listener, event); + } + }); + } } synchronized void addListener(final L listener) { + setListenerContext(listener, AppContext.getAppContext()); + if (!nativeListenerRegistered) { registerNativeListener(); nativeListenerRegistered = true; } - _listeners.add(listener); } synchronized void removeListener(final L listener) { - _listeners.remove(listener); + listenerToAppContext.remove(listener); } - abstract void performOnListeners(final List listeners, final _NativeEvent event); + abstract void performOnListener(L listener, final _NativeEvent event); void registerNativeListener() { } + + private void setListenerContext(L listener, AppContext listenerContext) { + if (listenerContext == null) { + throw new RuntimeException( + "Attempting to add a listener from a thread group without AppContext"); + } + listenerToAppContext.put(listener, AppContext.getAppContext()); + } } abstract class _BooleanAppEventMultiplexor extends _AppEventMultiplexor { @Override - void performOnListeners(final List listeners, final _NativeEvent event) { + void performOnListener(L listener, final _NativeEvent event) { final boolean isTrue = Boolean.TRUE.equals(event.get(0)); final E e = createEvent(isTrue); if (isTrue) { - for (final L listener : listeners) performTrueEventOn(listener, e); + performTrueEventOn(listener, e); } else { - for (final L listener : listeners) performFalseEventOn(listener, e); + performFalseEventOn(listener, e); } } @@ -479,30 +496,34 @@ class _AppEventHandler { */ abstract class _AppEventDispatcher { H _handler; + AppContext handlerContext; // called from AppKit Thread-0 void dispatch(final _NativeEvent event) { - EventQueue.invokeLater(new Runnable() { - public void run() { - // grab a local ref to the handler - final H localHandler; - synchronized (_AppEventDispatcher.this) { - localHandler = _handler; - } + // grab a local ref to the handler + final H localHandler; + final AppContext localHandlerContext; + synchronized (_AppEventDispatcher.this) { + localHandler = _handler; + localHandlerContext = handlerContext; + } - // invoke the handler outside of the synchronized block - if (localHandler == null) { - performDefaultAction(event); - } else { + if (localHandler == null) { + performDefaultAction(event); + } else { + SunToolkit.invokeLaterOnAppContext(localHandlerContext, new Runnable() { + public void run() { performUsing(localHandler, event); } - } - }); + }); + } } synchronized void setHandler(final H handler) { this._handler = handler; + setHandlerContext(AppContext.getAppContext()); + // if a new handler is installed, block addition of legacy ApplicationListeners if (handler == legacyHandler) return; legacyHandler.blockLegacyAPI(); @@ -510,6 +531,15 @@ class _AppEventHandler { void performDefaultAction(final _NativeEvent event) { } // by default, do nothing abstract void performUsing(final H handler, final _NativeEvent event); + + protected void setHandlerContext(AppContext ctx) { + if (ctx == null) { + throw new RuntimeException( + "Attempting to set a handler from a thread group without AppContext"); + } + + handlerContext = ctx; + } } abstract class _QueuingAppEventDispatcher extends _AppEventDispatcher { @@ -531,6 +561,8 @@ class _AppEventHandler { synchronized void setHandler(final H handler) { this._handler = handler; + setHandlerContext(AppContext.getAppContext()); + // dispatch any events in the queue if (queuedEvents != null) { // grab a local ref to the queue, so the real one can be nulled out diff --git a/jdk/src/macosx/classes/com/apple/eawt/event/GestureHandler.java b/jdk/src/macosx/classes/com/apple/eawt/event/GestureHandler.java index 1378a2c808e..4514da90ca9 100644 --- a/jdk/src/macosx/classes/com/apple/eawt/event/GestureHandler.java +++ b/jdk/src/macosx/classes/com/apple/eawt/event/GestureHandler.java @@ -25,6 +25,8 @@ package com.apple.eawt.event; +import sun.awt.SunToolkit; + import java.awt.*; import java.util.*; import java.util.List; @@ -70,7 +72,7 @@ final class GestureHandler { static void handleGestureFromNative(final Window window, final int type, final double x, final double y, final double a, final double b) { if (window == null) return; // should never happen... - EventQueue.invokeLater(new Runnable() { + SunToolkit.executeOnEventHandlerThread(window, new Runnable() { public void run() { final Component component = SwingUtilities.getDeepestComponentAt(window, (int)x, (int)y); diff --git a/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java b/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java index 23c55c8d2a1..5f78ff6e061 100644 --- a/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java +++ b/jdk/src/macosx/classes/com/apple/laf/ScreenMenu.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,7 @@ import java.util.Hashtable; import javax.swing.*; +import sun.awt.SunToolkit; import sun.lwawt.LWToolkit; import sun.lwawt.macosx.*; @@ -144,7 +145,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S updateItems(); fItemBounds = new Rectangle[invoker.getMenuComponentCount()]; } - }, null); + }, invoker); } catch (final Exception e) { System.err.println(e); e.printStackTrace(); @@ -172,7 +173,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S fItemBounds = null; } - }, null); + }, invoker); } catch (final Exception e) { e.printStackTrace(); } @@ -200,7 +201,7 @@ class ScreenMenu extends Menu implements ContainerListener, ComponentListener, S if (kind == 0) return; if (fItemBounds == null) return; - SwingUtilities.invokeLater(new Runnable() { + SunToolkit.executeOnEventHandlerThread(fInvoker, new Runnable() { @Override public void run() { Component target = null; diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java index 9b59ceaef9b..da53c302ad5 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CCheckboxMenuItem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,7 @@ public class CCheckboxMenuItem extends CMenuItem implements CheckboxMenuItemPeer public void handleAction(final boolean state) { final CheckboxMenuItem target = (CheckboxMenuItem)getTarget(); - EventQueue.invokeLater(new Runnable() { + SunToolkit.executeOnEventHandlerThread(target, new Runnable() { public void run() { target.setState(state); } diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java index 306cfb1e12e..28acc26f6cc 100644 --- a/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java +++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,7 +96,7 @@ public class CViewEmbeddedFrame extends EmbeddedFrame { validate(); setVisible(true); } - }, null); + }, this); } catch (InterruptedException | InvocationTargetException ex) {} } } From 617386d568320f3b60b8882fb5f34c922bdbfbe8 Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Thu, 11 Jul 2013 15:37:02 +0100 Subject: [PATCH 076/156] 8013404: Unclear spec for target typing with conditional operator (?:) Fix previously ignored test Reviewed-by: jjg, vromero --- langtools/test/tools/javac/lambda/TargetType36.java | 7 +++---- langtools/test/tools/javac/lambda/TargetType36.out | 3 +++ 2 files changed, 6 insertions(+), 4 deletions(-) create mode 100644 langtools/test/tools/javac/lambda/TargetType36.out diff --git a/langtools/test/tools/javac/lambda/TargetType36.java b/langtools/test/tools/javac/lambda/TargetType36.java index 7740b5705e5..38f9c2add40 100644 --- a/langtools/test/tools/javac/lambda/TargetType36.java +++ b/langtools/test/tools/javac/lambda/TargetType36.java @@ -23,11 +23,10 @@ /* * @test - * @ignore 8013404: Test awaits spec clarification - * @bug 8003280 + * @bug 8003280 8013404 * @summary Add lambda tests - * check that target type of cast is propagated to conditional subexpressions - * @compile TargetType36.java + * check that target type of cast is not propagated to conditional subexpressions + * @compile/fail/ref=TargetType36.out -XDrawDiagnostics TargetType36.java */ class TargetType36 { //awaits spec wording on cast vs. poly diff --git a/langtools/test/tools/javac/lambda/TargetType36.out b/langtools/test/tools/javac/lambda/TargetType36.out new file mode 100644 index 00000000000..92542ddd182 --- /dev/null +++ b/langtools/test/tools/javac/lambda/TargetType36.out @@ -0,0 +1,3 @@ +TargetType36.java:40:30: compiler.err.unexpected.lambda +TargetType36.java:40:43: compiler.err.unexpected.lambda +2 errors From 4eb5c9e3a42cdda2c0bf7d79920844f8b8c9d1ee Mon Sep 17 00:00:00 2001 From: Attila Szegedi Date: Thu, 11 Jul 2013 18:33:33 +0200 Subject: [PATCH 077/156] 8013925: Remove symbol fields from nodes that don't need them Reviewed-by: jlaskey, lagergren --- .../jdk/nashorn/internal/codegen/Attr.java | 113 ++++----- .../internal/codegen/BranchOptimizer.java | 14 +- .../internal/codegen/CodeGenerator.java | 236 +++++++++--------- .../internal/codegen/CompilationPhase.java | 26 +- .../internal/codegen/FinalizeTypes.java | 81 +++--- .../internal/codegen/FoldConstants.java | 8 +- .../internal/codegen/FunctionSignature.java | 8 +- .../jdk/nashorn/internal/codegen/Lower.java | 69 ++--- .../internal/codegen/RangeAnalyzer.java | 11 +- .../internal/codegen/SpillObjectCreator.java | 17 +- .../nashorn/internal/codegen/Splitter.java | 6 +- .../nashorn/internal/codegen/WeighNodes.java | 7 +- .../jdk/nashorn/internal/ir/AccessNode.java | 8 +- .../jdk/nashorn/internal/ir/Assignment.java | 4 +- .../src/jdk/nashorn/internal/ir/BaseNode.java | 11 +- .../jdk/nashorn/internal/ir/BinaryNode.java | 26 +- .../src/jdk/nashorn/internal/ir/Block.java | 36 ++- .../nashorn/internal/ir/BlockStatement.java | 115 +++++++++ .../nashorn/internal/ir/BreakableNode.java | 47 +--- .../internal/ir/BreakableStatement.java | 91 +++++++ .../src/jdk/nashorn/internal/ir/CallNode.java | 57 +++-- .../src/jdk/nashorn/internal/ir/CaseNode.java | 12 +- .../jdk/nashorn/internal/ir/CatchNode.java | 12 +- .../jdk/nashorn/internal/ir/Expression.java | 99 ++++++++ ...cuteNode.java => ExpressionStatement.java} | 20 +- .../src/jdk/nashorn/internal/ir/ForNode.java | 28 +-- .../jdk/nashorn/internal/ir/FunctionNode.java | 17 +- .../jdk/nashorn/internal/ir/IdentNode.java | 3 +- .../src/jdk/nashorn/internal/ir/IfNode.java | 12 +- .../jdk/nashorn/internal/ir/IndexNode.java | 16 +- .../jdk/nashorn/internal/ir/LabelNode.java | 2 +- .../nashorn/internal/ir/LexicalContext.java | 9 +- .../internal/ir/LexicalContextExpression.java | 59 +++++ .../internal/ir/LexicalContextNode.java | 53 +--- .../internal/ir/LexicalContextStatement.java | 55 ++++ .../jdk/nashorn/internal/ir/LiteralNode.java | 28 +-- .../src/jdk/nashorn/internal/ir/LoopNode.java | 13 +- nashorn/src/jdk/nashorn/internal/ir/Node.java | 55 ---- .../jdk/nashorn/internal/ir/ObjectNode.java | 2 +- .../jdk/nashorn/internal/ir/PropertyNode.java | 16 +- .../jdk/nashorn/internal/ir/ReturnNode.java | 13 +- .../jdk/nashorn/internal/ir/RuntimeNode.java | 25 +- .../jdk/nashorn/internal/ir/SplitNode.java | 7 +- .../jdk/nashorn/internal/ir/SwitchNode.java | 15 +- .../nashorn/internal/ir/TemporarySymbols.java | 2 +- .../jdk/nashorn/internal/ir/TernaryNode.java | 120 ++++----- .../jdk/nashorn/internal/ir/ThrowNode.java | 12 +- .../jdk/nashorn/internal/ir/UnaryNode.java | 23 +- .../src/jdk/nashorn/internal/ir/VarNode.java | 22 +- .../jdk/nashorn/internal/ir/WhileNode.java | 12 +- .../src/jdk/nashorn/internal/ir/WithNode.java | 12 +- .../nashorn/internal/ir/debug/ASTWriter.java | 22 +- .../nashorn/internal/ir/debug/JSONWriter.java | 29 ++- .../internal/ir/debug/PrintVisitor.java | 16 +- .../ir/visitor/NodeOperatorVisitor.java | 2 - .../internal/ir/visitor/NodeVisitor.java | 39 ++- .../nashorn/internal/parser/JSONParser.java | 13 +- .../jdk/nashorn/internal/parser/Parser.java | 170 +++++++------ .../linker/NashornCallSiteDescriptor.java | 3 +- nashorn/test/script/trusted/JDK-8006529.js | 30 +-- 60 files changed, 1236 insertions(+), 853 deletions(-) create mode 100644 nashorn/src/jdk/nashorn/internal/ir/BlockStatement.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/BreakableStatement.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/Expression.java rename nashorn/src/jdk/nashorn/internal/ir/{ExecuteNode.java => ExpressionStatement.java} (78%) create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LexicalContextExpression.java create mode 100644 nashorn/src/jdk/nashorn/internal/ir/LexicalContextStatement.java diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java index e076825dfe0..f56a881def6 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java @@ -61,6 +61,7 @@ import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; +import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; @@ -72,7 +73,6 @@ import jdk.nashorn.internal.ir.LiteralNode; import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode; import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.ObjectNode; -import jdk.nashorn.internal.ir.PropertyNode; import jdk.nashorn.internal.ir.ReturnNode; import jdk.nashorn.internal.ir.RuntimeNode; import jdk.nashorn.internal.ir.RuntimeNode.Request; @@ -512,7 +512,6 @@ final class Attr extends NodeOperatorVisitor { assert nameSymbol != null; selfInit = selfInit.setName((IdentNode)name.setSymbol(lc, nameSymbol)); - selfInit = (VarNode)selfInit.setSymbol(lc, nameSymbol); newStatements.add(selfInit); newStatements.addAll(body.getStatements()); @@ -739,15 +738,9 @@ final class Attr extends NodeOperatorVisitor { return end(ensureSymbol(Type.OBJECT, objectNode)); } - @Override - public Node leavePropertyNode(final PropertyNode propertyNode) { - // assign a pseudo symbol to property name, see NASHORN-710 - return propertyNode.setSymbol(lc, new Symbol(propertyNode.getKeyName(), 0, Type.OBJECT)); - } - @Override public Node leaveReturnNode(final ReturnNode returnNode) { - final Node expr = returnNode.getExpression(); + final Expression expr = returnNode.getExpression(); final Type returnType; if (expr != null) { @@ -784,7 +777,7 @@ final class Attr extends NodeOperatorVisitor { final LiteralNode lit = (LiteralNode)test; if (lit.isNumeric() && !(lit.getValue() instanceof Integer)) { if (JSType.isRepresentableAsInt(lit.getNumber())) { - newCaseNode = caseNode.setTest(LiteralNode.newInstance(lit, lit.getInt32()).accept(this)); + newCaseNode = caseNode.setTest((Expression)LiteralNode.newInstance(lit, lit.getInt32()).accept(this)); } } } else { @@ -847,19 +840,18 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveVarNode(final VarNode varNode) { - VarNode newVarNode = varNode; + final Expression init = varNode.getInit(); + final IdentNode ident = varNode.getName(); + final String name = ident.getName(); - final Node init = newVarNode.getInit(); - final IdentNode ident = newVarNode.getName(); - final String name = ident.getName(); - - final Symbol symbol = findSymbol(lc.getCurrentBlock(), ident.getName()); + final Symbol symbol = findSymbol(lc.getCurrentBlock(), name); + assert ident.getSymbol() == symbol; if (init == null) { // var x; with no init will be treated like a use of x by // leaveIdentNode unless we remove the name from the localdef list. removeLocalDef(name); - return end(newVarNode.setSymbol(lc, symbol)); + return end(varNode); } addLocalDef(name); @@ -868,8 +860,7 @@ final class Attr extends NodeOperatorVisitor { final IdentNode newIdent = (IdentNode)ident.setSymbol(lc, symbol); - newVarNode = newVarNode.setName(newIdent); - newVarNode = (VarNode)newVarNode.setSymbol(lc, symbol); + final VarNode newVarNode = varNode.setName(newIdent); final boolean isScript = lc.getDefiningFunction(symbol).isProgram(); //see NASHORN-56 if ((init.getType().isNumeric() || init.getType().isBoolean()) && !isScript) { @@ -879,7 +870,7 @@ final class Attr extends NodeOperatorVisitor { newType(symbol, Type.OBJECT); } - assert newVarNode.hasType() : newVarNode + " has no type"; + assert newVarNode.getName().hasType() : newVarNode + " has no type"; return end(newVarNode); } @@ -907,11 +898,11 @@ final class Attr extends NodeOperatorVisitor { public Node leaveDELETE(final UnaryNode unaryNode) { final FunctionNode currentFunctionNode = lc.getCurrentFunction(); final boolean strictMode = currentFunctionNode.isStrict(); - final Node rhs = unaryNode.rhs(); - final Node strictFlagNode = LiteralNode.newInstance(unaryNode, strictMode).accept(this); + final Expression rhs = unaryNode.rhs(); + final Expression strictFlagNode = (Expression)LiteralNode.newInstance(unaryNode, strictMode).accept(this); Request request = Request.DELETE; - final List args = new ArrayList<>(); + final List args = new ArrayList<>(); if (rhs instanceof IdentNode) { // If this is a declared variable or a function parameter, delete always fails (except for globals). @@ -922,7 +913,7 @@ final class Attr extends NodeOperatorVisitor { if (failDelete && rhs.getSymbol().isThis()) { return LiteralNode.newInstance(unaryNode, true).accept(this); } - final Node literalNode = LiteralNode.newInstance(unaryNode, name).accept(this); + final Expression literalNode = (Expression)LiteralNode.newInstance(unaryNode, name).accept(this); if (!failDelete) { args.add(compilerConstant(SCOPE)); @@ -934,16 +925,17 @@ final class Attr extends NodeOperatorVisitor { request = Request.FAIL_DELETE; } } else if (rhs instanceof AccessNode) { - final Node base = ((AccessNode)rhs).getBase(); - final IdentNode property = ((AccessNode)rhs).getProperty(); + final Expression base = ((AccessNode)rhs).getBase(); + final IdentNode property = ((AccessNode)rhs).getProperty(); args.add(base); - args.add(LiteralNode.newInstance(unaryNode, property.getName()).accept(this)); + args.add((Expression)LiteralNode.newInstance(unaryNode, property.getName()).accept(this)); args.add(strictFlagNode); } else if (rhs instanceof IndexNode) { - final Node base = ((IndexNode)rhs).getBase(); - final Node index = ((IndexNode)rhs).getIndex(); + final IndexNode indexNode = (IndexNode)rhs; + final Expression base = indexNode.getBase(); + final Expression index = indexNode.getIndex(); args.add(base); args.add(index); @@ -998,15 +990,15 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveTYPEOF(final UnaryNode unaryNode) { - final Node rhs = unaryNode.rhs(); + final Expression rhs = unaryNode.rhs(); - List args = new ArrayList<>(); + List args = new ArrayList<>(); if (rhs instanceof IdentNode && !rhs.getSymbol().isParam() && !rhs.getSymbol().isVar()) { args.add(compilerConstant(SCOPE)); - args.add(LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null + args.add((Expression)LiteralNode.newInstance(rhs, ((IdentNode)rhs).getName()).accept(this)); //null } else { args.add(rhs); - args.add(LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this' + args.add((Expression)LiteralNode.newInstance(unaryNode).accept(this)); //null, do not reuse token of identifier rhs, it can be e.g. 'this' } RuntimeNode runtimeNode = new RuntimeNode(unaryNode, Request.TYPEOF, args); @@ -1040,8 +1032,8 @@ final class Attr extends NodeOperatorVisitor { */ @Override public Node leaveADD(final BinaryNode binaryNode) { - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); ensureTypeNotUnknown(lhs); ensureTypeNotUnknown(rhs); @@ -1096,8 +1088,8 @@ final class Attr extends NodeOperatorVisitor { private Node leaveAssignmentNode(final BinaryNode binaryNode) { BinaryNode newBinaryNode = binaryNode; - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); final Type type; if (rhs.getType().isNumeric()) { @@ -1133,8 +1125,8 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveASSIGN_ADD(final BinaryNode binaryNode) { - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); final Type widest = Type.widest(lhs.getType(), rhs.getType()); //Type.NUMBER if we can't prove that the add doesn't overflow. todo @@ -1413,13 +1405,13 @@ final class Attr extends NodeOperatorVisitor { @Override public Node leaveTernaryNode(final TernaryNode ternaryNode) { - final Node lhs = ternaryNode.rhs(); - final Node rhs = ternaryNode.third(); + final Expression trueExpr = ternaryNode.getTrueExpression(); + final Expression falseExpr = ternaryNode.getFalseExpression(); - ensureTypeNotUnknown(lhs); - ensureTypeNotUnknown(rhs); + ensureTypeNotUnknown(trueExpr); + ensureTypeNotUnknown(falseExpr); - final Type type = Type.widest(lhs.getType(), rhs.getType()); + final Type type = Type.widest(trueExpr.getType(), falseExpr.getType()); return end(ensureSymbol(type, ternaryNode)); } @@ -1537,7 +1529,7 @@ final class Attr extends NodeOperatorVisitor { } } - private static void ensureTypeNotUnknown(final Node node) { + private static void ensureTypeNotUnknown(final Expression node) { final Symbol symbol = node.getSymbol(); @@ -1594,13 +1586,13 @@ final class Attr extends NodeOperatorVisitor { * * @param assignmentDest the destination node of the assignment, e.g. lhs for binary nodes */ - private Node ensureAssignmentSlots(final Node assignmentDest) { + private Expression ensureAssignmentSlots(final Expression assignmentDest) { final LexicalContext attrLexicalContext = lc; - return assignmentDest.accept(new NodeVisitor(new LexicalContext()) { + return (Expression)assignmentDest.accept(new NodeVisitor(new LexicalContext()) { @Override public Node leaveIndexNode(final IndexNode indexNode) { assert indexNode.getSymbol().isTemp(); - final Node index = indexNode.getIndex(); + final Expression index = indexNode.getIndex(); //only temps can be set as needing slots. the others will self resolve //it is illegal to take a scope var and force it to be a slot, that breaks Symbol indexSymbol = index.getSymbol(); @@ -1642,7 +1634,7 @@ final class Attr extends NodeOperatorVisitor { changed.clear(); final FunctionNode newFunctionNode = (FunctionNode)currentFunctionNode.accept(new NodeVisitor(new LexicalContext()) { - private Node widen(final Node node, final Type to) { + private Expression widen(final Expression node, final Type to) { if (node instanceof LiteralNode) { return node; } @@ -1654,7 +1646,7 @@ final class Attr extends NodeOperatorVisitor { symbol = temporarySymbols.getTypedTemporarySymbol(to); } newType(symbol, to); - final Node newNode = node.setSymbol(lc, symbol); + final Expression newNode = node.setSymbol(lc, symbol); changed.add(newNode); return newNode; } @@ -1709,7 +1701,7 @@ final class Attr extends NodeOperatorVisitor { private Node leaveSelfModifyingAssignmentNode(final BinaryNode binaryNode, final Type destType) { //e.g. for -=, Number, no wider, destType (binaryNode.getWidestOperationType()) is the coerce type - final Node lhs = binaryNode.lhs(); + final Expression lhs = binaryNode.lhs(); newType(lhs.getSymbol(), destType); //may not narrow if dest is already wider than destType // ensureSymbol(destType, binaryNode); //for OP= nodes, the node can carry a narrower types than its lhs rhs. This is perfectly fine @@ -1717,9 +1709,9 @@ final class Attr extends NodeOperatorVisitor { return end(ensureSymbol(destType, ensureAssignmentSlots(binaryNode))); } - private Node ensureSymbol(final Type type, final Node node) { + private Expression ensureSymbol(final Type type, final Expression expr) { LOG.info("New TEMPORARY added to ", lc.getCurrentFunction().getName(), " type=", type); - return temporarySymbols.ensureSymbol(lc, type, node); + return temporarySymbols.ensureSymbol(lc, type, expr); } private Symbol newInternal(final String name, final Type type) { @@ -1841,11 +1833,11 @@ final class Attr extends NodeOperatorVisitor { return true; } - private Node end(final Node node) { + private T end(final T node) { return end(node, true); } - private Node end(final Node node, final boolean printNode) { + private T end(final T node, final boolean printNode) { if(node instanceof Statement) { // If we're done with a statement, all temporaries can be reused. temporarySymbols.reuse(); @@ -1860,10 +1852,13 @@ final class Attr extends NodeOperatorVisitor { append(" in '"). append(lc.getCurrentFunction().getName()); - if (node.getSymbol() == null) { - sb.append(" "); - } else { - sb.append(" '); + if(node instanceof Expression) { + final Symbol symbol = ((Expression)node).getSymbol(); + if (symbol == null) { + sb.append(" "); + } else { + sb.append(" '); + } } LOG.unindent(); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java index ee922115d15..02ea95f17e6 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/BranchOptimizer.java @@ -34,7 +34,7 @@ import static jdk.nashorn.internal.codegen.Condition.NE; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.BinaryNode; -import jdk.nashorn.internal.ir.Node; +import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.TernaryNode; import jdk.nashorn.internal.ir.UnaryNode; @@ -52,16 +52,16 @@ final class BranchOptimizer { this.method = method; } - void execute(final Node node, final Label label, final boolean state) { + void execute(final Expression node, final Label label, final boolean state) { branchOptimizer(node, label, state); } - private void load(final Node node) { + private void load(final Expression node) { codegen.load(node); } private void branchOptimizer(final UnaryNode unaryNode, final Label label, final boolean state) { - final Node rhs = unaryNode.rhs(); + final Expression rhs = unaryNode.rhs(); switch (unaryNode.tokenType()) { case NOT: @@ -88,8 +88,8 @@ final class BranchOptimizer { } private void branchOptimizer(final BinaryNode binaryNode, final Label label, final boolean state) { - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); switch (binaryNode.tokenType()) { case AND: @@ -173,7 +173,7 @@ final class BranchOptimizer { } } - private void branchOptimizer(final Node node, final Label label, final boolean state) { + private void branchOptimizer(final Expression node, final Label label, final boolean state) { if (!(node instanceof TernaryNode)) { if (node instanceof BinaryNode) { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java index b9d35682458..b6c6f3a13e9 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java @@ -69,6 +69,7 @@ import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; +import jdk.nashorn.internal.ir.BlockStatement; import jdk.nashorn.internal.ir.BreakNode; import jdk.nashorn.internal.ir.BreakableNode; import jdk.nashorn.internal.ir.CallNode; @@ -76,7 +77,8 @@ import jdk.nashorn.internal.ir.CaseNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.ContinueNode; import jdk.nashorn.internal.ir.EmptyNode; -import jdk.nashorn.internal.ir.ExecuteNode; +import jdk.nashorn.internal.ir.Expression; +import jdk.nashorn.internal.ir.ExpressionStatement; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; @@ -350,11 +352,11 @@ final class CodeGenerator extends NodeOperatorVisitor args) { + private int loadArgs(final List args) { return loadArgs(args, null, false, args.size()); } - private int loadArgs(final List args, final String signature, final boolean isVarArg, final int argCount) { + private int loadArgs(final List args, final String signature, final boolean isVarArg, final int argCount) { // arg have already been converted to objects here. if (isVarArg || argCount > LinkerCallSite.ARGLIMIT) { loadArgsArray(args); @@ -553,7 +555,7 @@ final class CodeGenerator extends NodeOperatorVisitor= argCount) { @@ -574,13 +576,13 @@ final class CodeGenerator extends NodeOperatorVisitor args = callNode.getArgs(); - final Node function = callNode.getFunction(); - final Block currentBlock = lc.getCurrentBlock(); + final List args = callNode.getArgs(); + final Expression function = callNode.getFunction(); + final Block currentBlock = lc.getCurrentBlock(); final CodeGeneratorLexicalContext codegenLexicalContext = lc; - final Type callNodeType = callNode.getType(); + final Type callNodeType = callNode.getType(); function.accept(new NodeVisitor(new LexicalContext()) { @@ -771,11 +773,19 @@ final class CodeGenerator extends NodeOperatorVisitor(init) { + new Store(init) { @Override protected void storeNonDiscard() { return; @@ -1047,7 +1051,7 @@ final class CodeGenerator extends NodeOperatorVisitor type = arrayType.getTypeClass(); @@ -1166,11 +1173,11 @@ final class CodeGenerator extends NodeOperatorVisitor args) { + private MethodEmitter loadArgsArray(final List args) { final Object[] array = new Object[args.size()]; loadConstant(array); @@ -1323,16 +1330,16 @@ final class CodeGenerator extends NodeOperatorVisitor elements = objectNode.getElements(); - final List keys = new ArrayList<>(); - final List symbols = new ArrayList<>(); - final List values = new ArrayList<>(); + final List keys = new ArrayList<>(); + final List symbols = new ArrayList<>(); + final List values = new ArrayList<>(); boolean hasGettersSetters = false; for (PropertyNode propertyNode: elements) { - final Node value = propertyNode.getValue(); + final Expression value = propertyNode.getValue(); final String key = propertyNode.getKeyName(); - final Symbol symbol = value == null ? null : propertyNode.getSymbol(); + final Symbol symbol = value == null ? null : propertyNode.getKey().getSymbol(); if (value == null) { hasGettersSetters = true; @@ -1346,9 +1353,9 @@ final class CodeGenerator extends NodeOperatorVisitor OBJECT_SPILL_THRESHOLD) { new SpillObjectCreator(this, keys, symbols, values).makeObject(method); } else { - new FieldObjectCreator(this, keys, symbols, values) { + new FieldObjectCreator(this, keys, symbols, values) { @Override - protected void loadValue(final Node node) { + protected void loadValue(final Expression node) { load(node); } @@ -1419,7 +1426,7 @@ final class CodeGenerator extends NodeOperatorVisitor && ((LiteralNode) node).isNull(); } - private boolean nullCheck(final RuntimeNode runtimeNode, final List args, final String signature) { + private boolean nullCheck(final RuntimeNode runtimeNode, final List args, final String signature) { final Request request = runtimeNode.getRequest(); if (!Request.isEQ(request) && !Request.isNE(request)) { @@ -1444,11 +1451,11 @@ final class CodeGenerator extends NodeOperatorVisitor args) { + private boolean specializationCheck(final RuntimeNode.Request request, final Expression node, final List args) { if (!request.canSpecialize()) { return false; } @@ -1555,10 +1562,11 @@ final class CodeGenerator extends NodeOperatorVisitor args = runtimeNode.getArgs(); if (runtimeNode.isPrimitive() && !runtimeNode.isFinal() && isReducible(runtimeNode.getRequest())) { - final Node lhs = runtimeNode.getArgs().get(0); - assert runtimeNode.getArgs().size() > 1 : runtimeNode + " must have two args"; - final Node rhs = runtimeNode.getArgs().get(1); + final Expression lhs = args.get(0); + assert args.size() > 1 : runtimeNode + " must have two args"; + final Expression rhs = args.get(1); final Type type = runtimeNode.getType(); final Symbol symbol = runtimeNode.getSymbol(); @@ -1595,9 +1603,6 @@ final class CodeGenerator extends NodeOperatorVisitor args = runtimeNode.getArgs(); - if (nullCheck(runtimeNode, args, new FunctionSignature(false, false, runtimeNode.getType(), args).toString())) { return false; } @@ -1606,7 +1611,7 @@ final class CodeGenerator extends NodeOperatorVisitor cases = switchNode.getCases(); @@ -1875,7 +1878,7 @@ final class CodeGenerator extends NodeOperatorVisitor(exception) { @Override @@ -2038,7 +2041,7 @@ final class CodeGenerator extends NodeOperatorVisitor args = callNode.getArgs(); + final List args = callNode.getArgs(); // Load function reference. load(callNode.getFunction()).convert(Type.OBJECT); // must detect type error @@ -2302,7 +2303,7 @@ final class CodeGenerator extends NodeOperatorVisitor */ - private abstract class SelfModifyingStore extends Store { - protected SelfModifyingStore(final T assignNode, final Node target) { + private abstract class SelfModifyingStore extends Store { + protected SelfModifyingStore(final T assignNode, final Expression target) { super(assignNode, target); } @@ -2939,13 +2939,13 @@ final class CodeGenerator extends NodeOperatorVisitor { + private abstract class Store { /** An assignment node, e.g. x += y */ protected final T assignNode; /** The target node to store to, e.g. x */ - private final Node target; + private final Expression target; /** How deep on the stack do the arguments go if this generates an indy call */ private int depth; @@ -2959,7 +2959,7 @@ final class CodeGenerator extends NodeOperatorVisitor { * strings etc as well. */ @Override - public Node leaveADD(final BinaryNode binaryNode) { - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + public Expression leaveADD(final BinaryNode binaryNode) { + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); final Type type = binaryNode.getType(); @@ -240,7 +241,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { return leaveASSIGN(binaryNode); } - private boolean symbolIsInteger(Node node) { + private boolean symbolIsInteger(final Expression node) { final Symbol symbol = node.getSymbol(); assert symbol != null && symbol.getSymbolType().isInteger() : "int coercion expected: " + Debug.id(symbol) + " " + symbol + " " + lc.getCurrentFunction().getSource(); return true; @@ -372,7 +373,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveCatchNode(final CatchNode catchNode) { - final Node exceptionCondition = catchNode.getExceptionCondition(); + final Expression exceptionCondition = catchNode.getExceptionCondition(); if (exceptionCondition != null) { return catchNode.setExceptionCondition(convert(exceptionCondition, Type.BOOLEAN)); } @@ -380,16 +381,16 @@ final class FinalizeTypes extends NodeOperatorVisitor { } @Override - public Node leaveExecuteNode(final ExecuteNode executeNode) { + public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) { temporarySymbols.reuse(); - return executeNode.setExpression(discard(executeNode.getExpression())); + return expressionStatement.setExpression(discard(expressionStatement.getExpression())); } @Override public Node leaveForNode(final ForNode forNode) { - final Node init = forNode.getInit(); - final Node test = forNode.getTest(); - final Node modify = forNode.getModify(); + final Expression init = forNode.getInit(); + final Expression test = forNode.getTest(); + final Expression modify = forNode.getModify(); if (forNode.isForIn()) { return forNode.setModify(lc, convert(forNode.getModify(), Type.OBJECT)); // NASHORN-400 @@ -439,13 +440,13 @@ final class FinalizeTypes extends NodeOperatorVisitor { public boolean enterLiteralNode(final LiteralNode literalNode) { if (literalNode instanceof ArrayLiteralNode) { final ArrayLiteralNode arrayLiteralNode = (ArrayLiteralNode)literalNode; - final Node[] array = arrayLiteralNode.getValue(); + final Expression[] array = arrayLiteralNode.getValue(); final Type elementType = arrayLiteralNode.getElementType(); for (int i = 0; i < array.length; i++) { final Node element = array[i]; if (element != null) { - array[i] = convert(element.accept(this), elementType); + array[i] = convert((Expression)element.accept(this), elementType); } } } @@ -455,7 +456,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveReturnNode(final ReturnNode returnNode) { - final Node expr = returnNode.getExpression(); + final Expression expr = returnNode.getExpression(); if (expr != null) { return returnNode.setExpression(convert(expr, lc.getCurrentFunction().getReturnType())); } @@ -464,8 +465,8 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveRuntimeNode(final RuntimeNode runtimeNode) { - final List args = runtimeNode.getArgs(); - for (final Node arg : args) { + final List args = runtimeNode.getArgs(); + for (final Expression arg : args) { assert !arg.getType().isUnknown(); } return runtimeNode; @@ -479,12 +480,12 @@ final class FinalizeTypes extends NodeOperatorVisitor { return switchNode; } - final Node expression = switchNode.getExpression(); + final Expression expression = switchNode.getExpression(); final List cases = switchNode.getCases(); final List newCases = new ArrayList<>(); for (final CaseNode caseNode : cases) { - final Node test = caseNode.getTest(); + final Expression test = caseNode.getTest(); newCases.add(test != null ? caseNode.setTest(convert(test, Type.OBJECT)) : caseNode); } @@ -495,7 +496,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveTernaryNode(final TernaryNode ternaryNode) { - return ternaryNode.setLHS(convert(ternaryNode.lhs(), Type.BOOLEAN)); + return ternaryNode.setTest(convert(ternaryNode.getTest(), Type.BOOLEAN)); } @Override @@ -505,16 +506,16 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveVarNode(final VarNode varNode) { - final Node init = varNode.getInit(); + final Expression init = varNode.getInit(); if (init != null) { final SpecializedNode specialized = specialize(varNode); final VarNode specVarNode = (VarNode)specialized.node; Type destType = specialized.type; if (destType == null) { - destType = specVarNode.getType(); + destType = specVarNode.getName().getType(); } - assert specVarNode.hasType() : specVarNode + " doesn't have a type"; - final Node convertedInit = convert(init, destType); + assert specVarNode.getName().hasType() : specVarNode + " doesn't have a type"; + final Expression convertedInit = convert(init, destType); temporarySymbols.reuse(); return specVarNode.setInit(convertedInit); } @@ -524,7 +525,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { @Override public Node leaveWhileNode(final WhileNode whileNode) { - final Node test = whileNode.getTest(); + final Expression test = whileNode.getTest(); if (test != null) { return whileNode.setTest(lc, convert(test, Type.BOOLEAN)); } @@ -599,8 +600,8 @@ final class FinalizeTypes extends NodeOperatorVisitor { */ @SuppressWarnings("fallthrough") private Node leaveCmp(final BinaryNode binaryNode, final RuntimeNode.Request request) { - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); Type widest = Type.widest(lhs.getType(), rhs.getType()); @@ -696,10 +697,10 @@ final class FinalizeTypes extends NodeOperatorVisitor { } } - SpecializedNode specialize(final Assignment assignment) { + SpecializedNode specialize(final Assignment assignment) { final Node node = ((Node)assignment); final T lhs = assignment.getAssignmentDest(); - final Node rhs = assignment.getAssignmentSource(); + final Expression rhs = assignment.getAssignmentSource(); if (!canHaveCallSiteType(lhs)) { return new SpecializedNode(node, null); @@ -718,8 +719,16 @@ final class FinalizeTypes extends NodeOperatorVisitor { } final Node newNode = assignment.setAssignmentDest(setTypeOverride(lhs, to)); - final Node typePropagatedNode = propagateType(newNode, to); - + final Node typePropagatedNode; + if(newNode instanceof Expression) { + typePropagatedNode = propagateType((Expression)newNode, to); + } else if(newNode instanceof VarNode) { + // VarNode, being a statement, doesn't have its own symbol; it uses the symbol of its name instead. + final VarNode varNode = (VarNode)newNode; + typePropagatedNode = varNode.setName((IdentNode)propagateType(varNode.getName(), to)); + } else { + throw new AssertionError(); + } return new SpecializedNode(typePropagatedNode, to); } @@ -759,7 +768,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { * @param to new type */ @SuppressWarnings("unchecked") - T setTypeOverride(final T node, final Type to) { + T setTypeOverride(final T node, final Type to) { final Type from = node.getType(); if (!node.getType().equals(to)) { LOG.info("Changing call override type for '", node, "' from ", node.getType(), " to ", to); @@ -788,7 +797,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { * @param to destination type * @return conversion node */ - private Node convert(final Node node, final Type to) { + private Expression convert(final Expression node, final Type to) { assert !to.isUnknown() : "unknown type for " + node + " class=" + node.getClass(); assert node != null : "node is null"; assert node.getSymbol() != null : "node " + node + " " + node.getClass() + " has no symbol! " + lc.getCurrentFunction(); @@ -804,7 +813,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { return node; } - Node resultNode = node; + Expression resultNode = node; if (node instanceof LiteralNode && !(node instanceof ArrayLiteralNode) && !to.isObject()) { final LiteralNode newNode = new LiteralNodeConstantEvaluator((LiteralNode)node, to).eval(); @@ -828,9 +837,9 @@ final class FinalizeTypes extends NodeOperatorVisitor { return temporarySymbols.ensureSymbol(lc, to, resultNode); } - private static Node discard(final Node node) { + private static Expression discard(final Expression node) { if (node.getSymbol() != null) { - final Node discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node); + final UnaryNode discard = new UnaryNode(Token.recast(node.getToken(), TokenType.DISCARD), node); //discard never has a symbol in the discard node - then it would be a nop assert !node.isTerminal(); return discard; @@ -853,7 +862,7 @@ final class FinalizeTypes extends NodeOperatorVisitor { * @param node * @param to */ - private Node propagateType(final Node node, final Type to) { + private Expression propagateType(final Expression node, final Type to) { Symbol symbol = node.getSymbol(); if (symbol.isTemp() && symbol.getSymbolType() != to) { symbol = symbol.setTypeOverrideShared(to, temporarySymbols); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java index 2331cf7570d..49dfbb324b7 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java @@ -28,8 +28,8 @@ package jdk.nashorn.internal.codegen; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; +import jdk.nashorn.internal.ir.BlockStatement; import jdk.nashorn.internal.ir.EmptyNode; -import jdk.nashorn.internal.ir.ExecuteNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; import jdk.nashorn.internal.ir.IfNode; @@ -91,7 +91,7 @@ final class FoldConstants extends NodeVisitor { if (test instanceof LiteralNode) { final Block shortCut = ((LiteralNode)test).isTrue() ? ifNode.getPass() : ifNode.getFail(); if (shortCut != null) { - return new ExecuteNode(shortCut.getLineNumber(), shortCut.getToken(), shortCut.getFinish(), shortCut); + return new BlockStatement(ifNode.getLineNumber(), shortCut); } return new EmptyNode(ifNode); } @@ -100,9 +100,9 @@ final class FoldConstants extends NodeVisitor { @Override public Node leaveTernaryNode(final TernaryNode ternaryNode) { - final Node test = ternaryNode.lhs(); + final Node test = ternaryNode.getTest(); if (test instanceof LiteralNode) { - return ((LiteralNode)test).isTrue() ? ternaryNode.rhs() : ternaryNode.third(); + return ((LiteralNode)test).isTrue() ? ternaryNode.getTrueExpression() : ternaryNode.getFalseExpression(); } return ternaryNode; } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java index 057d2d4e454..1c1b5f7469f 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/FunctionSignature.java @@ -31,8 +31,8 @@ import java.lang.invoke.MethodType; import java.util.ArrayList; import java.util.List; import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.FunctionNode; -import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.runtime.ScriptFunction; import jdk.nashorn.internal.runtime.linker.LinkerCallSite; @@ -63,7 +63,7 @@ public final class FunctionSignature { * @param retType what is the return type * @param args argument list of AST Nodes */ - public FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final List args) { + public FunctionSignature(final boolean hasSelf, final boolean hasCallee, final Type retType, final List args) { this(hasSelf, hasCallee, retType, FunctionSignature.typeArray(args)); } @@ -167,7 +167,7 @@ public final class FunctionSignature { * * @return the array of types */ - private static Type[] typeArray(final List args) { + private static Type[] typeArray(final List args) { if (args == null) { return null; } @@ -175,7 +175,7 @@ public final class FunctionSignature { final Type[] typeArray = new Type[args.size()]; int pos = 0; - for (final Node arg : args) { + for (final Expression arg : args) { typeArray[pos++] = arg.getType(); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java index 880fea67640..cc109695d38 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java @@ -37,12 +37,14 @@ import jdk.nashorn.internal.ir.BaseNode; import jdk.nashorn.internal.ir.BinaryNode; import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.BlockLexicalContext; +import jdk.nashorn.internal.ir.BlockStatement; import jdk.nashorn.internal.ir.BreakNode; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.ContinueNode; import jdk.nashorn.internal.ir.EmptyNode; -import jdk.nashorn.internal.ir.ExecuteNode; +import jdk.nashorn.internal.ir.Expression; +import jdk.nashorn.internal.ir.ExpressionStatement; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; @@ -138,7 +140,7 @@ final class Lower extends NodeOperatorVisitor { public boolean enterBlock(final Block block) { final FunctionNode function = lc.getCurrentFunction(); if (lc.isFunctionBody() && function.isProgram() && !function.hasDeclaredFunctions()) { - new ExecuteNode(block.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this); + new ExpressionStatement(function.getLineNumber(), block.getToken(), block.getFinish(), LiteralNode.newInstance(block, ScriptRuntime.UNDEFINED)).accept(this); } return true; } @@ -154,7 +156,7 @@ final class Lower extends NodeOperatorVisitor { final boolean isProgram = currentFunction.isProgram(); final Statement last = lc.getLastStatement(); final ReturnNode returnNode = new ReturnNode( - last == null ? block.getLineNumber() : last.getLineNumber(), //TODO? + last == null ? currentFunction.getLineNumber() : last.getLineNumber(), //TODO? currentFunction.getToken(), currentFunction.getFinish(), isProgram ? @@ -195,29 +197,32 @@ final class Lower extends NodeOperatorVisitor { } @Override - public Node leaveExecuteNode(final ExecuteNode executeNode) { - final Node expr = executeNode.getExpression(); - ExecuteNode node = executeNode; + public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) { + final Expression expr = expressionStatement.getExpression(); + ExpressionStatement node = expressionStatement; final FunctionNode currentFunction = lc.getCurrentFunction(); if (currentFunction.isProgram()) { - if (!(expr instanceof Block) || expr instanceof FunctionNode) { // it's not a block, but can be a function - if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) { - node = executeNode.setExpression( - new BinaryNode( - Token.recast( - executeNode.getToken(), - TokenType.ASSIGN), - compilerConstant(RETURN), - expr)); - } + if (!isInternalExpression(expr) && !isEvalResultAssignment(expr)) { + node = expressionStatement.setExpression( + new BinaryNode( + Token.recast( + expressionStatement.getToken(), + TokenType.ASSIGN), + compilerConstant(RETURN), + expr)); } } return addStatement(node); } + @Override + public Node leaveBlockStatement(BlockStatement blockStatement) { + return addStatement(blockStatement); + } + @Override public Node leaveForNode(final ForNode forNode) { ForNode newForNode = forNode; @@ -302,11 +307,11 @@ final class Lower extends NodeOperatorVisitor { final IdentNode exception = new IdentNode(token, finish, lc.getCurrentFunction().uniqueName("catch_all")); - final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW)). + final Block catchBody = new Block(token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW)). setIsTerminal(lc, true); //ends with throw, so terminal final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, CatchNode.IS_SYNTHETIC_RETHROW); - final Block catchAllBlock = new Block(lineNumber, token, finish, catchAllNode); + final Block catchAllBlock = new Block(token, finish, catchAllNode); //catchallblock -> catchallnode (catchnode) -> exception -> throw @@ -355,14 +360,14 @@ final class Lower extends NodeOperatorVisitor { if (!isTerminal(newStatements)) { newStatements.add(throwNode); } - return new Block(throwNode.getLineNumber(), throwNode.getToken(), throwNode.getFinish(), newStatements); + return BlockStatement.createReplacement(throwNode, newStatements); } return throwNode; } @Override public Node leaveBreakNode(final BreakNode breakNode) { - return copy(breakNode, Lower.this.lc.getBreakable(breakNode.getLabel())); + return copy(breakNode, (Node)Lower.this.lc.getBreakable(breakNode.getLabel())); } @Override @@ -372,15 +377,15 @@ final class Lower extends NodeOperatorVisitor { @Override public Node leaveReturnNode(final ReturnNode returnNode) { - final Node expr = returnNode.getExpression(); + final Expression expr = returnNode.getExpression(); final List newStatements = new ArrayList<>(); - final Node resultNode; + final Expression resultNode; if (expr != null) { //we need to evaluate the result of the return in case it is complex while //still in the try block, store it in a result value and return it afterwards resultNode = new IdentNode(Lower.this.compilerConstant(RETURN)); - newStatements.add(new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr))); + newStatements.add(new ExpressionStatement(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new BinaryNode(Token.recast(returnNode.getToken(), TokenType.ASSIGN), resultNode, expr))); } else { resultNode = null; } @@ -390,7 +395,7 @@ final class Lower extends NodeOperatorVisitor { newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode)); } - return new ExecuteNode(returnNode.getLineNumber(), returnNode.getToken(), returnNode.getFinish(), new Block(returnNode.getLineNumber(), returnNode.getToken(), lc.getCurrentBlock().getFinish(), newStatements)); + return BlockStatement.createReplacement(returnNode, lc.getCurrentBlock().getFinish(), newStatements); } private Node copy(final Statement endpoint, final Node targetNode) { @@ -399,7 +404,7 @@ final class Lower extends NodeOperatorVisitor { if (!isTerminal(newStatements)) { newStatements.add(endpoint); } - return new ExecuteNode(endpoint.getLineNumber(), endpoint.getToken(), endpoint.getFinish(), new Block(endpoint.getLineNumber(), endpoint.getToken(), finish, newStatements)); + return BlockStatement.createReplacement(endpoint, finish, newStatements); } return endpoint; } @@ -461,7 +466,7 @@ final class Lower extends NodeOperatorVisitor { if (tryNode.getCatchBlocks().isEmpty()) { newTryNode = tryNode.setFinallyBody(null); } else { - Block outerBody = new Block(tryNode.getLineNumber(), tryNode.getToken(), tryNode.getFinish(), new ArrayList(Arrays.asList(tryNode.setFinallyBody(null)))); + Block outerBody = new Block(tryNode.getToken(), tryNode.getFinish(), new ArrayList(Arrays.asList(tryNode.setFinallyBody(null)))); newTryNode = tryNode.setBody(outerBody).setCatchBlocks(null); } @@ -478,7 +483,7 @@ final class Lower extends NodeOperatorVisitor { public Node leaveVarNode(final VarNode varNode) { addStatement(varNode); if (varNode.getFlag(VarNode.IS_LAST_FUNCTION_DECLARATION) && lc.getCurrentFunction().isProgram()) { - new ExecuteNode(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this); + new ExpressionStatement(varNode.getLineNumber(), varNode.getToken(), varNode.getFinish(), new IdentNode(varNode.getName())).accept(this); } return varNode; } @@ -511,7 +516,7 @@ final class Lower extends NodeOperatorVisitor { * @param function function called by a CallNode * @return transformed node to marker function or identity if not ident/access/indexnode */ - private static Node markerFunction(final Node function) { + private static Expression markerFunction(final Expression function) { if (function instanceof IdentNode) { return ((IdentNode)function).setIsFunction(); } else if (function instanceof BaseNode) { @@ -553,15 +558,15 @@ final class Lower extends NodeOperatorVisitor { private CallNode checkEval(final CallNode callNode) { if (callNode.getFunction() instanceof IdentNode) { - final List args = callNode.getArgs(); - final IdentNode callee = (IdentNode)callNode.getFunction(); + final List args = callNode.getArgs(); + final IdentNode callee = (IdentNode)callNode.getFunction(); // 'eval' call with at least one argument if (args.size() >= 1 && EVAL.symbolName().equals(callee.getName())) { final FunctionNode currentFunction = lc.getCurrentFunction(); return callNode.setEvalArgs( new CallNode.EvalArgs( - ensureUniqueNamesIn(args.get(0)).accept(this), + (Expression)ensureUniqueNamesIn(args.get(0)).accept(this), compilerConstant(THIS), evalLocation(callee), currentFunction.isStrict())); @@ -630,7 +635,7 @@ final class Lower extends NodeOperatorVisitor { * @param expression expression to check for internal symbol * @return true if internal, false otherwise */ - private static boolean isInternalExpression(final Node expression) { + private static boolean isInternalExpression(final Expression expression) { final Symbol symbol = expression.getSymbol(); return symbol != null && symbol.isInternal(); } diff --git a/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java b/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java index ab61d374818..4056ec0c2bd 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java @@ -28,11 +28,11 @@ package jdk.nashorn.internal.codegen; import java.util.HashMap; import java.util.HashSet; import java.util.Map; - import jdk.nashorn.internal.codegen.types.Range; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.Assignment; import jdk.nashorn.internal.ir.BinaryNode; +import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.IdentNode; import jdk.nashorn.internal.ir.LexicalContext; @@ -87,7 +87,7 @@ final class RangeAnalyzer extends NodeOperatorVisitor { } //destination visited - private Symbol setRange(final Node dest, final Range range) { + private Symbol setRange(final Expression dest, final Range range) { if (range.isUnknown()) { return null; } @@ -352,7 +352,6 @@ final class RangeAnalyzer extends NodeOperatorVisitor { range = range.isUnknown() ? Range.createGenericRange() : range; setRange(node.getName(), range); - setRange(node, range); } return node; @@ -438,12 +437,12 @@ final class RangeAnalyzer extends NodeOperatorVisitor { * @return */ private static Symbol findLoopCounter(final LoopNode node) { - final Node test = node.getTest(); + final Expression test = node.getTest(); if (test != null && test.isComparison()) { final BinaryNode binaryNode = (BinaryNode)test; - final Node lhs = binaryNode.lhs(); - final Node rhs = binaryNode.rhs(); + final Expression lhs = binaryNode.lhs(); + final Expression rhs = binaryNode.rhs(); //detect ident cmp int_literal if (lhs instanceof IdentNode && rhs instanceof LiteralNode && ((LiteralNode)rhs).getType().isInteger()) { diff --git a/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java index 33e1d432ac3..08dfedf1a9f 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/SpillObjectCreator.java @@ -25,26 +25,25 @@ package jdk.nashorn.internal.codegen; +import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; +import static jdk.nashorn.internal.codegen.types.Type.OBJECT; + +import java.util.List; import jdk.nashorn.internal.codegen.types.Type; +import jdk.nashorn.internal.ir.Expression; import jdk.nashorn.internal.ir.LiteralNode; -import jdk.nashorn.internal.ir.Node; import jdk.nashorn.internal.ir.Symbol; import jdk.nashorn.internal.runtime.Property; import jdk.nashorn.internal.runtime.PropertyMap; import jdk.nashorn.internal.runtime.ScriptObject; import jdk.nashorn.internal.scripts.JO; -import java.util.List; - -import static jdk.nashorn.internal.codegen.CompilerConstants.constructorNoLookup; -import static jdk.nashorn.internal.codegen.types.Type.OBJECT; - /** * An object creator that uses spill properties. */ public class SpillObjectCreator extends ObjectCreator { - private final List values; + private final List values; /** * Constructor @@ -54,7 +53,7 @@ public class SpillObjectCreator extends ObjectCreator { * @param symbols symbols for fields in object * @param values list of values corresponding to keys */ - protected SpillObjectCreator(final CodeGenerator codegen, final List keys, final List symbols, final List values) { + protected SpillObjectCreator(final CodeGenerator codegen, final List keys, final List symbols, final List values) { super(codegen, keys, symbols, false, false); this.values = values; makeMap(); @@ -107,7 +106,7 @@ public class SpillObjectCreator extends ObjectCreator { for (int i = 0; i < length; i++) { final String key = keys.get(i); final Property property = propertyMap.findProperty(key); - final Node value = values.get(i); + final Expression value = values.get(i); if (property == null && value != null) { method.dup(); diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java index e724ce261c3..a35c6dfdcf1 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/Splitter.java @@ -31,7 +31,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; - import jdk.nashorn.internal.ir.Block; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.FunctionNode.CompilationState; @@ -221,14 +220,13 @@ final class Splitter extends NodeVisitor { * @return New split node. */ private SplitNode createBlockSplitNode(final Block parent, final FunctionNode function, final List statements, final long weight) { - final int lineNumber = parent.getLineNumber(); final long token = parent.getToken(); final int finish = parent.getFinish(); final String name = function.uniqueName(SPLIT_PREFIX.symbolName()); - final Block newBlock = new Block(lineNumber, token, finish, statements); + final Block newBlock = new Block(token, finish, statements); - return new SplitNode(lineNumber, name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT)); + return new SplitNode(name, newBlock, compiler.findUnit(weight + WeighNodes.FUNCTION_WEIGHT)); } @Override diff --git a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java index 1adef12bb3c..57b3bafa797 100644 --- a/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java +++ b/nashorn/src/jdk/nashorn/internal/codegen/WeighNodes.java @@ -27,7 +27,6 @@ package jdk.nashorn.internal.codegen; import java.util.List; import java.util.Map; - import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.AccessNode; import jdk.nashorn.internal.ir.BinaryNode; @@ -36,7 +35,7 @@ import jdk.nashorn.internal.ir.BreakNode; import jdk.nashorn.internal.ir.CallNode; import jdk.nashorn.internal.ir.CatchNode; import jdk.nashorn.internal.ir.ContinueNode; -import jdk.nashorn.internal.ir.ExecuteNode; +import jdk.nashorn.internal.ir.ExpressionStatement; import jdk.nashorn.internal.ir.ForNode; import jdk.nashorn.internal.ir.FunctionNode; import jdk.nashorn.internal.ir.IdentNode; @@ -158,8 +157,8 @@ final class WeighNodes extends NodeOperatorVisitor { } @Override - public Node leaveExecuteNode(final ExecuteNode executeNode) { - return executeNode; + public Node leaveExpressionStatement(final ExpressionStatement expressionStatement) { + return expressionStatement; } @Override diff --git a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java index eecc5713541..55b0aa3feb3 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/AccessNode.java @@ -45,12 +45,12 @@ public final class AccessNode extends BaseNode { * @param base base node * @param property property */ - public AccessNode(final long token, final int finish, final Node base, final IdentNode property) { + public AccessNode(final long token, final int finish, final Expression base, final IdentNode property) { super(token, finish, base, false, false); this.property = property.setIsPropertyName(); } - private AccessNode(final AccessNode accessNode, final Node base, final IdentNode property, final boolean isFunction, final boolean hasCallSiteType) { + private AccessNode(final AccessNode accessNode, final Expression base, final IdentNode property, final boolean isFunction, final boolean hasCallSiteType) { super(accessNode, base, isFunction, hasCallSiteType); this.property = property; } @@ -63,7 +63,7 @@ public final class AccessNode extends BaseNode { public Node accept(final NodeVisitor visitor) { if (visitor.enterAccessNode(this)) { return visitor.leaveAccessNode( - setBase(base.accept(visitor)). + setBase((Expression)base.accept(visitor)). setProperty((IdentNode)property.accept(visitor))); } return this; @@ -103,7 +103,7 @@ public final class AccessNode extends BaseNode { return property; } - private AccessNode setBase(final Node base) { + private AccessNode setBase(final Expression base) { if (this.base == base) { return this; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/Assignment.java b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java index 0c531bc2906..093b0d80a7d 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Assignment.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Assignment.java @@ -31,7 +31,7 @@ package jdk.nashorn.internal.ir; * * @param the destination type */ -public interface Assignment { +public interface Assignment { /** * Get assignment destination @@ -45,7 +45,7 @@ public interface Assignment { * * @return get the assignment source node */ - public Node getAssignmentSource(); + public Expression getAssignmentSource(); /** * Set assignment destination node. diff --git a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java index a1b7c0eed7d..f945ef35711 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/BaseNode.java @@ -26,6 +26,7 @@ package jdk.nashorn.internal.ir; import static jdk.nashorn.internal.codegen.ObjectClassGenerator.DEBUG_FIELDS; + import jdk.nashorn.internal.codegen.ObjectClassGenerator; import jdk.nashorn.internal.codegen.types.Type; import jdk.nashorn.internal.ir.annotations.Immutable; @@ -37,10 +38,10 @@ import jdk.nashorn.internal.ir.annotations.Immutable; * @see IndexNode */ @Immutable -public abstract class BaseNode extends Node implements FunctionCall, TypeOverride { +public abstract class BaseNode extends Expression implements FunctionCall, TypeOverride { /** Base Node. */ - protected final Node base; + protected final Expression base; private final boolean isFunction; @@ -55,7 +56,7 @@ public abstract class BaseNode extends Node implements FunctionCall, TypeOverrid * @param isFunction is this a function * @param hasCallSiteType does this access have a callsite type */ - public BaseNode(final long token, final int finish, final Node base, final boolean isFunction, final boolean hasCallSiteType) { + public BaseNode(final long token, final int finish, final Expression base, final boolean isFunction, final boolean hasCallSiteType) { super(token, base.getStart(), finish); this.base = base; this.isFunction = isFunction; @@ -69,7 +70,7 @@ public abstract class BaseNode extends Node implements FunctionCall, TypeOverrid * @param isFunction is this a function * @param hasCallSiteType does this access have a callsite type */ - protected BaseNode(final BaseNode baseNode, final Node base, final boolean isFunction, final boolean hasCallSiteType) { + protected BaseNode(final BaseNode baseNode, final Expression base, final boolean isFunction, final boolean hasCallSiteType) { super(baseNode); this.base = base; this.isFunction = isFunction; @@ -80,7 +81,7 @@ public abstract class BaseNode extends Node implements FunctionCall, TypeOverrid * Get the base node for this access * @return the base node */ - public Node getBase() { + public Expression getBase() { return base; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java index 4afa1945eae..1576fb9316e 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java +++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java @@ -34,11 +34,11 @@ import jdk.nashorn.internal.parser.TokenType; * BinaryNode nodes represent two operand operations. */ @Immutable -public final class BinaryNode extends Node implements Assignment { +public final class BinaryNode extends Expression implements Assignment { /** Left hand side argument. */ - private final Node lhs; + private final Expression lhs; - private final Node rhs; + private final Expression rhs; /** * Constructor @@ -47,13 +47,13 @@ public final class BinaryNode extends Node implements Assignment { * @param lhs left hand side * @param rhs right hand side */ - public BinaryNode(final long token, final Node lhs, final Node rhs) { + public BinaryNode(final long token, final Expression lhs, final Expression rhs) { super(token, lhs.getStart(), rhs.getFinish()); this.lhs = lhs; this.rhs = rhs; } - private BinaryNode(final BinaryNode binaryNode, final Node lhs, final Node rhs) { + private BinaryNode(final BinaryNode binaryNode, final Expression lhs, final Expression rhs) { super(binaryNode); this.lhs = lhs; this.rhs = rhs; @@ -141,17 +141,17 @@ public final class BinaryNode extends Node implements Assignment { } @Override - public Node getAssignmentDest() { + public Expression getAssignmentDest() { return isAssignment() ? lhs() : null; } @Override - public Node setAssignmentDest(Node n) { + public BinaryNode setAssignmentDest(Expression n) { return setLHS(n); } @Override - public Node getAssignmentSource() { + public Expression getAssignmentSource() { return rhs(); } @@ -162,7 +162,7 @@ public final class BinaryNode extends Node implements Assignment { @Override public Node accept(final NodeVisitor visitor) { if (visitor.enterBinaryNode(this)) { - return visitor.leaveBinaryNode(setLHS(lhs.accept(visitor)).setRHS(rhs.accept(visitor))); + return visitor.leaveBinaryNode(setLHS((Expression)lhs.accept(visitor)).setRHS((Expression)rhs.accept(visitor))); } return this; @@ -218,7 +218,7 @@ public final class BinaryNode extends Node implements Assignment { * Get the left hand side expression for this node * @return the left hand side expression */ - public Node lhs() { + public Expression lhs() { return lhs; } @@ -226,7 +226,7 @@ public final class BinaryNode extends Node implements Assignment { * Get the right hand side expression for this node * @return the left hand side expression */ - public Node rhs() { + public Expression rhs() { return rhs; } @@ -235,7 +235,7 @@ public final class BinaryNode extends Node implements Assignment { * @param lhs new left hand side expression * @return a node equivalent to this one except for the requested change. */ - public BinaryNode setLHS(final Node lhs) { + public BinaryNode setLHS(final Expression lhs) { if (this.lhs == lhs) { return this; } @@ -247,7 +247,7 @@ public final class BinaryNode extends Node implements Assignment { * @param rhs new left hand side expression * @return a node equivalent to this one except for the requested change. */ - public BinaryNode setRHS(final Node rhs) { + public BinaryNode setRHS(final Expression rhs) { if (this.rhs == rhs) { return this; } diff --git a/nashorn/src/jdk/nashorn/internal/ir/Block.java b/nashorn/src/jdk/nashorn/internal/ir/Block.java index 71692144167..c411401e710 100644 --- a/nashorn/src/jdk/nashorn/internal/ir/Block.java +++ b/nashorn/src/jdk/nashorn/internal/ir/Block.java @@ -38,11 +38,10 @@ import jdk.nashorn.internal.ir.annotations.Immutable; import jdk.nashorn.internal.ir.visitor.NodeVisitor; /** - * IR representation for a list of statements and functions. All provides the - * basis for script body. + * IR representation for a list of statements. */ @Immutable -public class Block extends BreakableNode implements Flags { +public class Block extends Node implements BreakableNode, Flags { /** List of statements */ protected final List statements; @@ -52,6 +51,9 @@ public class Block extends BreakableNode implements Flags { /** Entry label. */ protected final Label entryLabel; + /** Break label. */ + private final Label breakLabel; + /** Does the block/function need a new scope? */ protected final int flags; @@ -76,17 +78,17 @@ public class Block extends BreakableNode implements Flags { /** * Constructor * - * @param lineNumber line number * @param token token * @param finish finish * @param statements statements */ - public Block(final int lineNumber, final long token, final int finish, final Statement... statements) { - super(lineNumber, token, finish, new Label("block_break")); + public Block(final long token, final int finish, final Statement... statements) { + super(token, finish); this.statements = Arrays.asList(statements); this.symbols = new LinkedHashMap<>(); this.entryLabel = new Label("block_entry"); + this.breakLabel = new Label("block_break"); this.flags = 0; } @@ -98,8 +100,8 @@ public class Block extends BreakableNode implements Flags { * @param finish finish * @param statements statements */ - public Block(final int lineNumber, final long token, final int finish, final List statements) { - this(lineNumber, token, finish, statements.toArray(new Statement[statements.size()])); + public Block(final long token, final int finish, final List statements) { + this(token, finish, statements.toArray(new Statement[statements.size()])); } private Block(final Block block, final int finish, final List statements, final int flags, final Map symbols) { @@ -108,6 +110,7 @@ public class Block extends BreakableNode implements Flags { this.flags = flags; this.symbols = new LinkedHashMap<>(symbols); //todo - symbols have no dependencies on any IR node and can as far as we understand it be shallow copied now this.entryLabel = new Label(block.entryLabel); + this.breakLabel = new Label(block.breakLabel); this.finish = finish; } @@ -223,6 +226,11 @@ public class Block extends BreakableNode implements Flags { return entryLabel; } + @Override + public Label getBreakLabel() { + return breakLabel; + } + /** * Get the list of statements in this block * @@ -322,7 +330,17 @@ public class Block extends BreakableNode implements Flags { } @Override - protected boolean isBreakableWithoutLabel() { + public boolean isBreakableWithoutLabel() { return false; } + + @Override + public List