From e9f0b9af4a914228ab4bb70d779649010264763b Mon Sep 17 00:00:00 2001
From: Jungwoo Ha
Date: Wed, 16 Oct 2013 15:14:37 -0700
Subject: [PATCH 01/88] 8024954: CMS: CMSClassUnloadingMaxInterval is not
implemented correctly. This change is also part of the fix for 8024483
Reviewed-by: mgerdin, brutisso, tschatzl
---
.../concurrentMarkSweepGeneration.cpp | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index bf4ac21e346..97437bfafe2 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -594,9 +594,9 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
_verification_mark_bm(0, Mutex::leaf + 1, "CMS_verification_mark_bm_lock"),
_completed_initialization(false),
_collector_policy(cp),
- _should_unload_classes(false),
+ _should_unload_classes(CMSClassUnloadingEnabled),
_concurrent_cycles_since_last_unload(0),
- _roots_scanning_options(0),
+ _roots_scanning_options(SharedHeap::SO_None),
_inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
_intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding),
_gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) CMSTracer()),
@@ -788,14 +788,6 @@ CMSCollector::CMSCollector(ConcurrentMarkSweepGeneration* cmsGen,
&& _survivor_chunk_index == 0),
"Error");
- // Choose what strong roots should be scanned depending on verification options
- if (!CMSClassUnloadingEnabled) {
- // If class unloading is disabled we want to include all classes into the root set.
- add_root_scanning_option(SharedHeap::SO_AllClasses);
- } else {
- add_root_scanning_option(SharedHeap::SO_SystemClasses);
- }
-
NOT_PRODUCT(_overflow_counter = CMSMarkStackOverflowInterval;)
_gc_counters = new CollectorCounters("CMS", 1);
_completed_initialization = true;
@@ -3310,7 +3302,10 @@ void CMSCollector::setup_cms_unloading_and_verification_state() {
|| VerifyBeforeExit;
const int rso = SharedHeap::SO_Strings | SharedHeap::SO_CodeCache;
+ // We set the proper root for this CMS cycle here.
if (should_unload_classes()) { // Should unload classes this cycle
+ remove_root_scanning_option(SharedHeap::SO_AllClasses);
+ add_root_scanning_option(SharedHeap::SO_SystemClasses);
remove_root_scanning_option(rso); // Shrink the root set appropriately
set_verifying(should_verify); // Set verification state for this cycle
return; // Nothing else needs to be done at this time
@@ -3318,6 +3313,9 @@ void CMSCollector::setup_cms_unloading_and_verification_state() {
// Not unloading classes this cycle
assert(!should_unload_classes(), "Inconsitency!");
+ remove_root_scanning_option(SharedHeap::SO_SystemClasses);
+ add_root_scanning_option(SharedHeap::SO_AllClasses);
+
if ((!verifying() || unloaded_classes_last_cycle()) && should_verify) {
// Include symbols, strings and code cache elements to prevent their resurrection.
add_root_scanning_option(rso);
From 1123a5596ce984f13e4385cffbe246cd12fa67fa Mon Sep 17 00:00:00 2001
From: Jesper Wilhelmsson
Date: Mon, 21 Oct 2013 18:51:37 +0200
Subject: [PATCH 02/88] 8026851: Remove unnecessary code in GenRemSet
Removed the GenRemSet::rem_set_name() since we only have one remset.
Reviewed-by: stefank, mgerdin, tschatzl
---
hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp | 2 +-
hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp | 2 --
hotspot/src/share/vm/memory/collectorPolicy.cpp | 1 -
hotspot/src/share/vm/memory/collectorPolicy.hpp | 2 --
4 files changed, 1 insertion(+), 6 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index 92eee2e8eb9..ad1dce1750b 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -320,7 +320,7 @@ G1CollectorPolicy::G1CollectorPolicy() :
void G1CollectorPolicy::initialize_flags() {
_min_alignment = HeapRegion::GrainBytes;
- size_t card_table_alignment = GenRemSet::max_alignment_constraint(rem_set_name());
+ size_t card_table_alignment = GenRemSet::max_alignment_constraint(GenRemSet::CardTable);
size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size();
_max_alignment = MAX3(card_table_alignment, _min_alignment, page_size);
if (SurvivorRatio < 1) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index a497f2fa3b6..d5bdc08698f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -665,8 +665,6 @@ public:
BarrierSet::Name barrier_set_name() { return BarrierSet::G1SATBCTLogging; }
- GenRemSet::Name rem_set_name() { return GenRemSet::CardTable; }
-
bool need_to_start_conc_mark(const char* source, size_t alloc_word_size = 0);
// Record the start and end of an evacuation pause.
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index a3c466327ef..d6c4afe2f01 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -105,7 +105,6 @@ bool CollectorPolicy::use_should_clear_all_soft_refs(bool v) {
GenRemSet* CollectorPolicy::create_rem_set(MemRegion whole_heap,
int max_covered_regions) {
- assert(rem_set_name() == GenRemSet::CardTable, "unrecognized GenRemSet::Name");
return new CardTableRS(whole_heap, max_covered_regions);
}
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp
index 42976b34563..a86f45c54d7 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.hpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp
@@ -151,7 +151,6 @@ class CollectorPolicy : public CHeapObj {
virtual BarrierSet::Name barrier_set_name() = 0;
- virtual GenRemSet::Name rem_set_name() = 0;
// Create the remembered set (to cover the given reserved region,
// allowing breaking up into at most "max_covered_regions").
@@ -303,7 +302,6 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
int number_of_generations() { return 2; }
BarrierSet::Name barrier_set_name() { return BarrierSet::CardTableModRef; }
- GenRemSet::Name rem_set_name() { return GenRemSet::CardTable; }
virtual CollectorPolicy::Name kind() {
return CollectorPolicy::TwoGenerationCollectorPolicyKind;
From 5976b6915a7936491afed94515031cded77e83c2 Mon Sep 17 00:00:00 2001
From: Jesper Wilhelmsson
Date: Mon, 21 Oct 2013 18:52:13 +0200
Subject: [PATCH 03/88] 8026852: Use restricted_align_down in collector policy
code
Moved restricted_align_down to globalDefinitions and renamed it align_size_down_bounded
Reviewed-by: stefank, mgerdin, tschatzl
---
hotspot/src/share/vm/memory/collectorPolicy.cpp | 14 +++-----------
hotspot/src/share/vm/memory/metaspace.cpp | 15 +++++----------
.../src/share/vm/utilities/globalDefinitions.hpp | 7 +++++++
3 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index d6c4afe2f01..585c7d06cab 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -146,11 +146,7 @@ size_t CollectorPolicy::compute_max_alignment() {
// GenCollectorPolicy methods.
size_t GenCollectorPolicy::scale_by_NewRatio_aligned(size_t base_size) {
- size_t x = base_size / (NewRatio+1);
- size_t new_gen_size = x > _min_alignment ?
- align_size_down(x, _min_alignment) :
- _min_alignment;
- return new_gen_size;
+ return align_size_down_bounded(base_size / (NewRatio + 1), _min_alignment);
}
size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
@@ -410,15 +406,11 @@ bool TwoGenerationCollectorPolicy::adjust_gen0_sizes(size_t* gen0_size_ptr,
if ((heap_size < (*gen0_size_ptr + min_gen1_size)) &&
(heap_size >= min_gen1_size + _min_alignment)) {
// Adjust gen0 down to accommodate min_gen1_size
- *gen0_size_ptr = heap_size - min_gen1_size;
- *gen0_size_ptr =
- MAX2((uintx)align_size_down(*gen0_size_ptr, _min_alignment), _min_alignment);
+ *gen0_size_ptr = align_size_down_bounded(heap_size - min_gen1_size, _min_alignment);
assert(*gen0_size_ptr > 0, "Min gen0 is too large");
result = true;
} else {
- *gen1_size_ptr = heap_size - *gen0_size_ptr;
- *gen1_size_ptr =
- MAX2((uintx)align_size_down(*gen1_size_ptr, _min_alignment), _min_alignment);
+ *gen1_size_ptr = align_size_down_bounded(heap_size - *gen0_size_ptr, _min_alignment);
}
}
return result;
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 1877967408d..7ab68dd1ea7 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -2965,11 +2965,6 @@ void Metaspace::initialize_class_space(ReservedSpace rs) {
#endif
-// Align down. If the aligning result in 0, return 'alignment'.
-static size_t restricted_align_down(size_t size, size_t alignment) {
- return MAX2(alignment, align_size_down_(size, alignment));
-}
-
void Metaspace::ergo_initialize() {
if (DumpSharedSpaces) {
// Using large pages when dumping the shared archive is currently not implemented.
@@ -2992,13 +2987,13 @@ void Metaspace::ergo_initialize() {
// Ideally, we would be able to set the default value of MaxMetaspaceSize in
// globals.hpp to the aligned value, but this is not possible, since the
// alignment depends on other flags being parsed.
- MaxMetaspaceSize = restricted_align_down(MaxMetaspaceSize, _reserve_alignment);
+ MaxMetaspaceSize = align_size_down_bounded(MaxMetaspaceSize, _reserve_alignment);
if (MetaspaceSize > MaxMetaspaceSize) {
MetaspaceSize = MaxMetaspaceSize;
}
- MetaspaceSize = restricted_align_down(MetaspaceSize, _commit_alignment);
+ MetaspaceSize = align_size_down_bounded(MetaspaceSize, _commit_alignment);
assert(MetaspaceSize <= MaxMetaspaceSize, "MetaspaceSize should be limited by MaxMetaspaceSize");
@@ -3006,10 +3001,10 @@ void Metaspace::ergo_initialize() {
vm_exit_during_initialization("Too small initial Metaspace size");
}
- MinMetaspaceExpansion = restricted_align_down(MinMetaspaceExpansion, _commit_alignment);
- MaxMetaspaceExpansion = restricted_align_down(MaxMetaspaceExpansion, _commit_alignment);
+ MinMetaspaceExpansion = align_size_down_bounded(MinMetaspaceExpansion, _commit_alignment);
+ MaxMetaspaceExpansion = align_size_down_bounded(MaxMetaspaceExpansion, _commit_alignment);
- CompressedClassSpaceSize = restricted_align_down(CompressedClassSpaceSize, _reserve_alignment);
+ CompressedClassSpaceSize = align_size_down_bounded(CompressedClassSpaceSize, _reserve_alignment);
set_class_metaspace_size(CompressedClassSpaceSize);
}
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index 06a32dc9037..c558574ebbd 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -458,6 +458,13 @@ inline void* align_pointer_up(const void* addr, size_t size) {
return (void*) align_size_up_((uintptr_t)addr, size);
}
+// Align down with a lower bound. If the aligning results in 0, return 'alignment'.
+
+inline size_t align_size_down_bounded(size_t size, size_t alignment) {
+ size_t aligned_size = align_size_down_(size, alignment);
+ return aligned_size > 0 ? aligned_size : alignment;
+}
+
// Clamp an address to be within a specific page
// 1. If addr is on the page it is returned as is
// 2. If addr is above the page_address the start of the *next* page will be returned
From 9705a6e3f94aee2f8862d84d71df4a94b9c3d3f8 Mon Sep 17 00:00:00 2001
From: Jesper Wilhelmsson
Date: Mon, 21 Oct 2013 18:56:20 +0200
Subject: [PATCH 04/88] 8026853: Prepare GC code for collector policy
regression fix
Cleanup related to the NewSize and MaxNewSize bugs
Reviewed-by: tschatzl, jcoomes, ehelin
---
.../g1/g1CollectorPolicy.hpp | 1 -
.../vm/gc_implementation/g1/g1RemSet.cpp | 5 ----
.../parallelScavenge/asPSOldGen.cpp | 3 --
.../parallelScavenge/asPSYoungGen.cpp | 3 --
.../parallelScavenge/parallelScavengeHeap.hpp | 28 +++++++++----------
.../parallelScavenge/psAdaptiveSizePolicy.cpp | 3 +-
.../src/share/vm/memory/collectorPolicy.cpp | 15 +++++-----
.../src/share/vm/memory/collectorPolicy.hpp | 17 +++++++----
.../src/share/vm/memory/genCollectedHeap.cpp | 6 ----
.../src/share/vm/memory/genCollectedHeap.hpp | 4 ---
hotspot/src/share/vm/memory/universe.cpp | 2 +-
hotspot/src/share/vm/runtime/arguments.cpp | 7 +++--
12 files changed, 39 insertions(+), 55 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index d5bdc08698f..037876e07e7 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -217,7 +217,6 @@ private:
return _during_marking;
}
-private:
enum PredictionConstants {
TruncatedSeqLength = 10
};
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
index 0ed37e6c5a5..a11be17ef53 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
@@ -377,11 +377,6 @@ void G1RemSet::prepare_for_oops_into_collection_set_do() {
DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
dcqs.concatenate_logs();
- if (G1CollectedHeap::use_parallel_gc_threads()) {
- // Don't set the number of workers here. It will be set
- // when the task is run
- // _seq_task->set_n_termination((int)n_workers());
- }
guarantee( _cards_scanned == NULL, "invariant" );
_cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers(), mtGC);
for (uint i = 0; i < n_workers(); ++i) {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp
index 39f5835ffe5..6f7026e5a0c 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSOldGen.cpp
@@ -54,7 +54,6 @@ ASPSOldGen::ASPSOldGen(size_t initial_size,
int level) :
PSOldGen(initial_size, min_size, size_limit, gen_name, level),
_gen_size_limit(size_limit)
-
{}
ASPSOldGen::ASPSOldGen(PSVirtualSpace* vs,
@@ -65,13 +64,11 @@ ASPSOldGen::ASPSOldGen(PSVirtualSpace* vs,
int level) :
PSOldGen(initial_size, min_size, size_limit, gen_name, level),
_gen_size_limit(size_limit)
-
{
_virtual_space = vs;
}
void ASPSOldGen::initialize_work(const char* perf_data_name, int level) {
-
PSOldGen::initialize_work(perf_data_name, level);
// The old gen can grow to gen_size_limit(). _reserve reflects only
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp
index 73b63043b71..a7b2eb28ef2 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/asPSYoungGen.cpp
@@ -70,7 +70,6 @@ void ASPSYoungGen::initialize(ReservedSpace rs, size_t alignment) {
}
size_t ASPSYoungGen::available_for_expansion() {
-
size_t current_committed_size = virtual_space()->committed_size();
assert((gen_size_limit() >= current_committed_size),
"generation size limit is wrong");
@@ -85,7 +84,6 @@ size_t ASPSYoungGen::available_for_expansion() {
// Future implementations could check the survivors and if to_space is in the
// right place (below from_space), take a chunk from to_space.
size_t ASPSYoungGen::available_for_contraction() {
-
size_t uncommitted_bytes = virtual_space()->uncommitted_size();
if (uncommitted_bytes != 0) {
return uncommitted_bytes;
@@ -121,7 +119,6 @@ size_t ASPSYoungGen::available_for_contraction() {
gclog_or_tty->print_cr(" gen_avail %d K", gen_avail/K);
}
return result_aligned;
-
}
return 0;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
index 4e458efa903..2ef42c86660 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
@@ -35,7 +35,6 @@
#include "utilities/ostream.hpp"
class AdjoiningGenerations;
-class CollectorPolicy;
class GCHeapSummary;
class GCTaskManager;
class GenerationSizer;
@@ -50,8 +49,8 @@ class ParallelScavengeHeap : public CollectedHeap {
static PSOldGen* _old_gen;
// Sizing policy for entire heap
- static PSAdaptiveSizePolicy* _size_policy;
- static PSGCAdaptivePolicyCounters* _gc_policy_counters;
+ static PSAdaptiveSizePolicy* _size_policy;
+ static PSGCAdaptivePolicyCounters* _gc_policy_counters;
static ParallelScavengeHeap* _psh;
@@ -67,7 +66,8 @@ class ParallelScavengeHeap : public CollectedHeap {
AdjoiningGenerations* _gens;
unsigned int _death_march_count;
- static GCTaskManager* _gc_task_manager; // The task manager.
+ // The task manager
+ static GCTaskManager* _gc_task_manager;
void trace_heap(GCWhen::Type when, GCTracer* tracer);
@@ -80,15 +80,14 @@ class ParallelScavengeHeap : public CollectedHeap {
HeapWord* mem_allocate_old_gen(size_t size);
public:
- ParallelScavengeHeap() : CollectedHeap() {
- _death_march_count = 0;
+ ParallelScavengeHeap() : CollectedHeap(), _death_march_count(0) {
set_alignment(_young_gen_alignment, intra_heap_alignment());
set_alignment(_old_gen_alignment, intra_heap_alignment());
}
// Return the (conservative) maximum heap alignment
static size_t conservative_max_heap_alignment() {
- return intra_heap_alignment();
+ return GenCollectorPolicy::intra_heap_alignment();
}
// For use by VM operations
@@ -103,8 +102,8 @@ class ParallelScavengeHeap : public CollectedHeap {
virtual CollectorPolicy* collector_policy() const { return (CollectorPolicy*) _collector_policy; }
- static PSYoungGen* young_gen() { return _young_gen; }
- static PSOldGen* old_gen() { return _old_gen; }
+ static PSYoungGen* young_gen() { return _young_gen; }
+ static PSOldGen* old_gen() { return _old_gen; }
virtual PSAdaptiveSizePolicy* size_policy() { return _size_policy; }
@@ -127,7 +126,7 @@ class ParallelScavengeHeap : public CollectedHeap {
// The alignment used for eden and survivors within the young gen
// and for boundary between young gen and old gen.
- static size_t intra_heap_alignment() { return 64 * K * HeapWordSize; }
+ size_t intra_heap_alignment() { return GenCollectorPolicy::intra_heap_alignment(); }
size_t capacity() const;
size_t used() const;
@@ -157,16 +156,15 @@ class ParallelScavengeHeap : public CollectedHeap {
virtual bool is_in_partial_collection(const void *p);
#endif
- bool is_in_young(oop p); // reserved part
- bool is_in_old(oop p); // reserved part
+ bool is_in_young(oop p); // reserved part
+ bool is_in_old(oop p); // reserved part
// Memory allocation. "gc_time_limit_was_exceeded" will
// be set to true if the adaptive size policy determine that
// an excessive amount of time is being spent doing collections
// and caused a NULL to be returned. If a NULL is not returned,
// "gc_time_limit_was_exceeded" has an undefined meaning.
- HeapWord* mem_allocate(size_t size,
- bool* gc_overhead_limit_was_exceeded);
+ HeapWord* mem_allocate(size_t size, bool* gc_overhead_limit_was_exceeded);
// Allocation attempt(s) during a safepoint. It should never be called
// to allocate a new TLAB as this allocation might be satisfied out
@@ -257,7 +255,7 @@ class ParallelScavengeHeap : public CollectedHeap {
// Call these in sequential code around the processing of strong roots.
class ParStrongRootsScope : public MarkingCodeBlobClosure::MarkScope {
- public:
+ public:
ParStrongRootsScope();
~ParStrongRootsScope();
};
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
index 8d411811b3c..1ffdf64e2aa 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
@@ -46,8 +46,7 @@ PSAdaptiveSizePolicy::PSAdaptiveSizePolicy(size_t init_eden_size,
init_survivor_size,
gc_pause_goal_sec,
gc_cost_ratio),
- _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin/
- 100.0),
+ _collection_cost_margin_fraction(AdaptiveSizePolicyCollectionCostMargin / 100.0),
_intra_generation_alignment(intra_generation_alignment),
_live_at_last_full_gc(init_promo_size),
_gc_minor_pause_goal_sec(gc_minor_pause_goal_sec),
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.cpp b/hotspot/src/share/vm/memory/collectorPolicy.cpp
index 585c7d06cab..8cd11de6ef2 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.cpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.cpp
@@ -160,7 +160,7 @@ size_t GenCollectorPolicy::bound_minus_alignment(size_t desired_size,
void GenCollectorPolicy::initialize_size_policy(size_t init_eden_size,
size_t init_promo_size,
size_t init_survivor_size) {
- const double max_gc_pause_sec = ((double) MaxGCPauseMillis)/1000.0;
+ const double max_gc_pause_sec = ((double) MaxGCPauseMillis) / 1000.0;
_size_policy = new AdaptiveSizePolicy(init_eden_size,
init_promo_size,
init_survivor_size,
@@ -192,6 +192,7 @@ void GenCollectorPolicy::initialize_flags() {
// make sure there room for eden and two survivor spaces
vm_exit_during_initialization("Too small new size specified");
}
+
if (SurvivorRatio < 1 || NewRatio < 1) {
vm_exit_during_initialization("Invalid young gen ratio specified");
}
@@ -465,7 +466,7 @@ void TwoGenerationCollectorPolicy::initialize_size_info() {
"generation sizes: using minimum heap = " SIZE_FORMAT,
_min_heap_byte_size);
}
- if ((OldSize > _max_gen1_size)) {
+ if (OldSize > _max_gen1_size) {
warning("Inconsistency between maximum heap size and maximum "
"generation sizes: using maximum heap = " SIZE_FORMAT
" -XX:OldSize flag is being ignored",
@@ -596,9 +597,7 @@ HeapWord* GenCollectorPolicy::mem_allocate_work(size_t size,
gc_count_before = Universe::heap()->total_collections();
}
- VM_GenCollectForAllocation op(size,
- is_tlab,
- gc_count_before);
+ VM_GenCollectForAllocation op(size, is_tlab, gc_count_before);
VMThread::execute(&op);
if (op.prologue_succeeded()) {
result = op.result();
@@ -833,8 +832,9 @@ MarkSweepPolicy::MarkSweepPolicy() {
void MarkSweepPolicy::initialize_generations() {
_generations = NEW_C_HEAP_ARRAY3(GenerationSpecPtr, number_of_generations(), mtGC, 0, AllocFailStrategy::RETURN_NULL);
- if (_generations == NULL)
+ if (_generations == NULL) {
vm_exit_during_initialization("Unable to allocate gen spec");
+ }
if (UseParNewGC) {
_generations[0] = new GenerationSpec(Generation::ParNew, _initial_gen0_size, _max_gen0_size);
@@ -843,8 +843,9 @@ void MarkSweepPolicy::initialize_generations() {
}
_generations[1] = new GenerationSpec(Generation::MarkSweepCompact, _initial_gen1_size, _max_gen1_size);
- if (_generations[0] == NULL || _generations[1] == NULL)
+ if (_generations[0] == NULL || _generations[1] == NULL) {
vm_exit_during_initialization("Unable to allocate gen spec");
+ }
}
void MarkSweepPolicy::initialize_gc_policy_counters() {
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp
index a86f45c54d7..bbfccdd644c 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.hpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp
@@ -79,6 +79,7 @@ class CollectorPolicy : public CHeapObj {
// Set to true when policy wants soft refs cleared.
// Reset to false by gc after it clears all soft refs.
bool _should_clear_all_soft_refs;
+
// Set to true by the GC if the just-completed gc cleared all
// softrefs. This is set to true whenever a gc clears all softrefs, and
// set to false each time gc returns to the mutator. For example, in the
@@ -101,8 +102,8 @@ class CollectorPolicy : public CHeapObj {
// Return maximum heap alignment that may be imposed by the policy
static size_t compute_max_alignment();
- size_t min_alignment() { return _min_alignment; }
- size_t max_alignment() { return _max_alignment; }
+ size_t min_alignment() { return _min_alignment; }
+ size_t max_alignment() { return _max_alignment; }
size_t initial_heap_byte_size() { return _initial_heap_byte_size; }
size_t max_heap_byte_size() { return _max_heap_byte_size; }
@@ -248,7 +249,7 @@ class GenCollectorPolicy : public CollectorPolicy {
virtual int number_of_generations() = 0;
- virtual GenerationSpec **generations() {
+ virtual GenerationSpec **generations() {
assert(_generations != NULL, "Sanity check");
return _generations;
}
@@ -273,6 +274,12 @@ class GenCollectorPolicy : public CollectorPolicy {
virtual void initialize_size_policy(size_t init_eden_size,
size_t init_promo_size,
size_t init_survivor_size);
+
+ // The alignment used for eden and survivors within the young gen
+ // and for boundary between young gen and old gen.
+ static size_t intra_heap_alignment() {
+ return 64 * K * HeapWordSize;
+ }
};
// All of hotspot's current collectors are subtypes of this
@@ -300,8 +307,8 @@ class TwoGenerationCollectorPolicy : public GenCollectorPolicy {
// Inherited methods
TwoGenerationCollectorPolicy* as_two_generation_policy() { return this; }
- int number_of_generations() { return 2; }
- BarrierSet::Name barrier_set_name() { return BarrierSet::CardTableModRef; }
+ int number_of_generations() { return 2; }
+ BarrierSet::Name barrier_set_name() { return BarrierSet::CardTableModRef; }
virtual CollectorPolicy::Name kind() {
return CollectorPolicy::TwoGenerationCollectorPolicyKind;
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
index 3a5ab210c83..2b84542ef48 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
@@ -1053,12 +1053,6 @@ void GenCollectedHeap::save_marks() {
}
}
-void GenCollectedHeap::compute_new_generation_sizes(int collectedGen) {
- for (int i = 0; i <= collectedGen; i++) {
- _gens[i]->compute_new_size();
- }
-}
-
GenCollectedHeap* GenCollectedHeap::heap() {
assert(_gch != NULL, "Uninitialized access to GenCollectedHeap::heap()");
assert(_gch->kind() == CollectedHeap::GenCollectedHeap, "not a generational heap");
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
index 8f814132a78..5cd8a71280a 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
@@ -86,10 +86,6 @@ public:
NOT_PRODUCT(static size_t _skip_header_HeapWords;)
protected:
- // Directs each generation up to and including "collectedGen" to recompute
- // its desired size.
- void compute_new_generation_sizes(int collectedGen);
-
// Helper functions for allocation
HeapWord* attempt_allocation(size_t size,
bool is_tlab,
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 1f632ae478f..18c9733076c 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -1021,7 +1021,7 @@ bool universe_post_init() {
Universe::_virtual_machine_error_instance =
InstanceKlass::cast(k)->allocate_instance(CHECK_false);
- Universe::_vm_exception = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
+ Universe::_vm_exception = InstanceKlass::cast(k)->allocate_instance(CHECK_false);
if (!DumpSharedSpaces) {
// These are the only Java fields that are currently set during shared space dumping.
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 8060dae0377..1e82e5bdca8 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -1408,7 +1408,7 @@ uintx Arguments::max_heap_for_compressed_oops() {
// NULL page is located before the heap, we pad the NULL page to the conservative
// maximum alignment that the GC may ever impose upon the heap.
size_t displacement_due_to_null_page = align_size_up_(os::vm_page_size(),
- Arguments::conservative_max_heap_alignment());
+ _conservative_max_heap_alignment);
LP64_ONLY(return OopEncodingHeapMax - displacement_due_to_null_page);
NOT_LP64(ShouldNotReachHere(); return 0);
@@ -2681,9 +2681,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
describe_range_error(errcode);
return JNI_EINVAL;
}
- FLAG_SET_CMDLINE(uintx, InitialHeapSize, (uintx)long_initial_heap_size);
+ set_min_heap_size((uintx)long_initial_heap_size);
// Currently the minimum size and the initial heap sizes are the same.
- set_min_heap_size(InitialHeapSize);
+ // Can be overridden with -XX:InitialHeapSize.
+ FLAG_SET_CMDLINE(uintx, InitialHeapSize, (uintx)long_initial_heap_size);
// -Xmx
} else if (match_option(option, "-Xmx", &tail) || match_option(option, "-XX:MaxHeapSize=", &tail)) {
julong long_max_heap_size = 0;
From 0b4ed553d6a3fd8237e7711ab59688da657d1ba5 Mon Sep 17 00:00:00 2001
From: Mikael Gerdin
Date: Wed, 30 Oct 2013 15:35:25 +0100
Subject: [PATCH 05/88] 8027252: Crash in interpreter because
get_unsigned_2_byte_index_at_bcp reads 4 bytes
Use 2-byte loads to load indexes from the byte code stream to avoid out of bounds reads.
Reviewed-by: coleenp, sspitsyn
---
hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp | 2 +-
hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp | 2 +-
hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp | 8 ++++++--
hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp | 8 ++++++--
4 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
index fcadd2ee9a3..b6f2438db83 100644
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
@@ -196,7 +196,7 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread)
void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) {
assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
- movl(reg, Address(rsi, bcp_offset));
+ load_unsigned_short(reg, Address(rsi, bcp_offset));
bswapl(reg);
shrl(reg, 16);
}
diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
index 7758d8fbcb5..520c872a604 100644
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
@@ -192,7 +192,7 @@ void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(
Register reg,
int bcp_offset) {
assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode");
- movl(reg, Address(r13, bcp_offset));
+ load_unsigned_short(reg, Address(r13, bcp_offset));
bswapl(reg);
shrl(reg, 16);
}
diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
index 6e6033b02b6..387ed67f008 100644
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
@@ -558,7 +558,7 @@ void TemplateTable::aload() {
void TemplateTable::locals_index_wide(Register reg) {
- __ movl(reg, at_bcp(2));
+ __ load_unsigned_short(reg, at_bcp(2));
__ bswapl(reg);
__ shrl(reg, 16);
__ negptr(reg);
@@ -1552,7 +1552,11 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
InvocationCounter::counter_offset();
// Load up EDX with the branch displacement
- __ movl(rdx, at_bcp(1));
+ if (is_wide) {
+ __ movl(rdx, at_bcp(1));
+ } else {
+ __ load_signed_short(rdx, at_bcp(1));
+ }
__ bswapl(rdx);
if (!is_wide) __ sarl(rdx, 16);
LP64_ONLY(__ movslq(rdx, rdx));
diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
index 8c49726e5ff..64001398d55 100644
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
@@ -568,7 +568,7 @@ void TemplateTable::aload() {
}
void TemplateTable::locals_index_wide(Register reg) {
- __ movl(reg, at_bcp(2));
+ __ load_unsigned_short(reg, at_bcp(2));
__ bswapl(reg);
__ shrl(reg, 16);
__ negptr(reg);
@@ -1575,7 +1575,11 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) {
InvocationCounter::counter_offset();
// Load up edx with the branch displacement
- __ movl(rdx, at_bcp(1));
+ if (is_wide) {
+ __ movl(rdx, at_bcp(1));
+ } else {
+ __ load_signed_short(rdx, at_bcp(1));
+ }
__ bswapl(rdx);
if (!is_wide) {
From ca92769602e3a3c9070ebb53635f5a21df74ee22 Mon Sep 17 00:00:00 2001
From: Karen Kinnear
Date: Wed, 30 Oct 2013 09:11:04 -0700
Subject: [PATCH 06/88] 8027304: Lambda: inheriting abstract + 1 default ->
default, not ICCE
Reviewed-by: hseigel, zgu
---
hotspot/src/share/vm/classfile/defaultMethods.cpp | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp
index 6b3c910d67c..c05c58748d8 100644
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp
@@ -392,10 +392,16 @@ class MethodFamily : public ResourceObj {
}
GrowableArray qualified_methods;
+ int num_defaults = 0;
+ int default_index = -1;
for (int i = 0; i < _members.length(); ++i) {
Pair entry = _members.at(i);
if (entry.second == QUALIFIED) {
qualified_methods.append(entry.first);
+ default_index++;
+ if (entry.first->is_default_method()) {
+ num_defaults++;
+ }
}
}
@@ -408,6 +414,9 @@ class MethodFamily : public ResourceObj {
if (!method->is_abstract()) {
_selected_target = qualified_methods.at(0);
}
+ // If only one qualified method is default, select that
+ } else if (num_defaults == 1) {
+ _selected_target = qualified_methods.at(default_index);
} else {
_exception_message = generate_conflicts_message(&qualified_methods,CHECK);
_exception_name = vmSymbols::java_lang_IncompatibleClassChangeError();
From 535b489554879dec71bec6412f1f909a08f1060f Mon Sep 17 00:00:00 2001
From: Coleen Phillimore
Date: Thu, 31 Oct 2013 14:11:02 -0400
Subject: [PATCH 07/88] 8027616: Off by one error in putback for compressed
oops nashorn performance improvement
Should compare bounds greater than or equal 4G when deciding if shift is needed or CDS area + compressed class space are within 4G of each other.
Reviewed-by: stefank, hseigel, zgu
---
hotspot/src/share/vm/memory/metaspace.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 8df4e32c355..f9e3385eb22 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -2869,7 +2869,7 @@ void Metaspace::set_narrow_klass_base_and_shift(address metaspace_base, address
Universe::set_narrow_klass_base(lower_base);
- if ((uint64_t)(higher_address - lower_base) < UnscaledClassSpaceMax) {
+ if ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax) {
Universe::set_narrow_klass_shift(0);
} else {
assert(!UseSharedSpaces, "Cannot shift with UseSharedSpaces");
@@ -2885,7 +2885,7 @@ bool Metaspace::can_use_cds_with_metaspace_addr(char* metaspace_base, address cd
address lower_base = MIN2((address)metaspace_base, cds_base);
address higher_address = MAX2((address)(cds_base + FileMapInfo::shared_spaces_size()),
(address)(metaspace_base + compressed_class_space_size()));
- return ((uint64_t)(higher_address - lower_base) < UnscaledClassSpaceMax);
+ return ((uint64_t)(higher_address - lower_base) <= UnscaledClassSpaceMax);
}
// Try to allocate the metaspace at the requested addr.
From 1dbd6b18552c581f788ac9899c13ec2c8a3ad667 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Fri, 1 Nov 2013 19:54:48 +0530
Subject: [PATCH 08/88] 8027700: function redeclaration checks missing for
declaration binding instantiation
Reviewed-by: jlaskey, lagergren
---
.../jdk/nashorn/internal/codegen/Attr.java | 1 +
.../nashorn/internal/codegen/MapCreator.java | 4 ++
.../src/jdk/nashorn/internal/ir/Symbol.java | 20 +++++++
.../nashorn/internal/runtime/Property.java | 31 +++++++----
.../internal/runtime/ScriptObject.java | 13 ++++-
nashorn/test/script/basic/JDK-8015355.js | 4 --
nashorn/test/script/basic/JDK-8027700.js | 54 +++++++++++++++++++
7 files changed, 111 insertions(+), 16 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8027700.js
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
index 5415a06df41..d4e378cfd8b 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Attr.java
@@ -271,6 +271,7 @@ final class Attr extends NodeOperatorVisitor {
functionNode.addDeclaredSymbol(symbol);
if (varNode.isFunctionDeclaration()) {
newType(symbol, FunctionNode.FUNCTION_TYPE);
+ symbol.setIsFunctionDeclaration();
}
return varNode.setName((IdentNode)ident.setSymbol(lc, symbol));
}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
index 2921ea9ecbc..8012adf5065 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MapCreator.java
@@ -134,6 +134,10 @@ public class MapCreator {
flags |= Property.CAN_BE_UNDEFINED;
}
+ if (symbol.isFunctionDeclaration()) {
+ flags |= Property.IS_FUNCTION_DECLARATION;
+ }
+
return flags;
}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
index 69e98ac6b3d..2906893f1ee 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
@@ -75,6 +75,8 @@ public final class Symbol implements Comparable {
public static final int IS_SPECIALIZED_PARAM = 1 << 13;
/** Is this symbol a shared temporary? */
public static final int IS_SHARED = 1 << 14;
+ /** Is this a function declaration? */
+ public static final int IS_FUNCTION_DECLARATION = 1 << 15;
/** Null or name identifying symbol. */
private final String name;
@@ -359,6 +361,14 @@ public final class Symbol implements Comparable {
return (flags & IS_SHARED) == IS_SHARED;
}
+ /**
+ * Check if this symbol is a function declaration
+ * @return true if a function declaration
+ */
+ public boolean isFunctionDeclaration() {
+ return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
+ }
+
/**
* Creates an unshared copy of a symbol. The symbol must be currently shared.
* @param newName the name for the new symbol.
@@ -395,6 +405,16 @@ public final class Symbol implements Comparable {
}
+ /**
+ * Mark this symbol as a function declaration.
+ */
+ public void setIsFunctionDeclaration() {
+ if (!isFunctionDeclaration()) {
+ trace("SET IS FUNCTION DECLARATION");
+ flags |= IS_FUNCTION_DECLARATION;
+ }
+ }
+
/**
* Check if this symbol is a variable
* @return true if variable
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
index e735ed11ea5..d1dbe2adb4b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -56,33 +56,36 @@ public abstract class Property {
public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000;
/** ECMA 8.6.1 - Is this property not writable? */
- public static final int NOT_WRITABLE = 0b0000_0000_0001;
+ public static final int NOT_WRITABLE = 1 << 0;
/** ECMA 8.6.1 - Is this property not enumerable? */
- public static final int NOT_ENUMERABLE = 0b0000_0000_0010;
+ public static final int NOT_ENUMERABLE = 1 << 1;
/** ECMA 8.6.1 - Is this property not configurable? */
- public static final int NOT_CONFIGURABLE = 0b0000_0000_0100;
+ public static final int NOT_CONFIGURABLE = 1 << 2;
- private static final int MODIFY_MASK = 0b0000_0000_1111;
+ private static final int MODIFY_MASK = (NOT_WRITABLE | NOT_ENUMERABLE | NOT_CONFIGURABLE);
/** Is this a spill property? See {@link AccessorProperty} */
- public static final int IS_SPILL = 0b0000_0001_0000;
+ public static final int IS_SPILL = 1 << 3;
/** Is this a function parameter? */
- public static final int IS_PARAMETER = 0b0000_0010_0000;
+ public static final int IS_PARAMETER = 1 << 4;
/** Is parameter accessed thru arguments? */
- public static final int HAS_ARGUMENTS = 0b0000_0100_0000;
+ public static final int HAS_ARGUMENTS = 1 << 5;
/** Is this property always represented as an Object? See {@link ObjectClassGenerator} and dual fields flag. */
- public static final int IS_ALWAYS_OBJECT = 0b0000_1000_0000;
+ public static final int IS_ALWAYS_OBJECT = 1 << 6;
/** Can this property be primitive? */
- public static final int CAN_BE_PRIMITIVE = 0b0001_0000_0000;
+ public static final int CAN_BE_PRIMITIVE = 1 << 7;
/** Can this property be undefined? */
- public static final int CAN_BE_UNDEFINED = 0b0010_0000_0000;
+ public static final int CAN_BE_UNDEFINED = 1 << 8;
+
+ /* Is this a function declaration property ? */
+ public static final int IS_FUNCTION_DECLARATION = 1 << 9;
/** Property key. */
private final String key;
@@ -522,4 +525,12 @@ public abstract class Property {
public boolean canBeUndefined() {
return (flags & CAN_BE_UNDEFINED) == CAN_BE_UNDEFINED;
}
+
+ /**
+ * Check whether this property represents a function declaration.
+ * @return whether this property is a function declaration or not.
+ */
+ public boolean isFunctionDeclaration() {
+ return (flags & IS_FUNCTION_DECLARATION) == IS_FUNCTION_DECLARATION;
+ }
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
index 5d1fbcd67f1..c7c8202775f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -226,14 +226,23 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
for (final Property property : properties) {
final String key = property.getKey();
-
- if (newMap.findProperty(key) == null) {
+ final Property oldProp = newMap.findProperty(key);
+ if (oldProp == null) {
if (property instanceof UserAccessorProperty) {
final UserAccessorProperty prop = this.newUserAccessors(key, property.getFlags(), property.getGetterFunction(source), property.getSetterFunction(source));
newMap = newMap.addProperty(prop);
} else {
newMap = newMap.addPropertyBind((AccessorProperty)property, source);
}
+ } else {
+ // See ECMA section 10.5 Declaration Binding Instantiation
+ // step 5 processing each function declaration.
+ if (property.isFunctionDeclaration() && !oldProp.isConfigurable()) {
+ if (oldProp instanceof UserAccessorProperty ||
+ !(oldProp.isWritable() && oldProp.isEnumerable())) {
+ throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
+ }
+ }
}
}
diff --git a/nashorn/test/script/basic/JDK-8015355.js b/nashorn/test/script/basic/JDK-8015355.js
index bc39d8d981c..aa1a39de3a7 100644
--- a/nashorn/test/script/basic/JDK-8015355.js
+++ b/nashorn/test/script/basic/JDK-8015355.js
@@ -28,10 +28,6 @@
* @run
*/
-function fail(msg) {
- print(msg);
-}
-
function check(callback) {
try {
callback();
diff --git a/nashorn/test/script/basic/JDK-8027700.js b/nashorn/test/script/basic/JDK-8027700.js
new file mode 100644
index 00000000000..4c5445d8429
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8027700.js
@@ -0,0 +1,54 @@
+/*
+ * 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-8027700: function redeclaration checks missing for declaration binding instantiation
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(this,"x", {
+ value:0,
+ writable:true,
+ enumerable:false
+})
+
+try {
+ eval("function x() {}");
+ fail("should have thrown TypeError");
+} catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("TypeError expected but got " + e);
+ }
+}
+
+Object.defineProperty(this, "foo", { value:0 })
+try {
+ eval("function foo() {}");
+ fail("should have thrown TypeError");
+} catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("TypeError expected but got " + e);
+ }
+}
From b1689ab022bc9a9a7dfc9ed9774e116e54a34abb Mon Sep 17 00:00:00 2001
From: Coleen Phillimore
Date: Fri, 1 Nov 2013 10:32:36 -0400
Subject: [PATCH 09/88] 8026946: JvmtiEnv::SetBreakpoint and
JvmtiEnv::ClearBreakpoint should use MethodHandle 8026948:
JvmtiEnv::SetBreakpoint and JvmtiEnv::ClearBreakpoint might not work with
anonymous classes
Walk methods in breakpoints for marking on stack so they aren't deallocated by redefine classes. Use class_holder rather than class_loader to keep GC from reclaiming class owning the method.
Reviewed-by: sspitsyn, ehelin, sla
---
.../vm/classfile/metadataOnStackMark.cpp | 2 +
hotspot/src/share/vm/prims/jvmtiImpl.cpp | 41 +++++++++++++++----
hotspot/src/share/vm/prims/jvmtiImpl.hpp | 19 +++++++--
3 files changed, 51 insertions(+), 11 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
index 1f24042f5cb..20404879adb 100644
--- a/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
+++ b/hotspot/src/share/vm/classfile/metadataOnStackMark.cpp
@@ -27,6 +27,7 @@
#include "code/codeCache.hpp"
#include "compiler/compileBroker.hpp"
#include "oops/metadata.hpp"
+#include "prims/jvmtiImpl.hpp"
#include "runtime/synchronizer.hpp"
#include "runtime/thread.hpp"
#include "utilities/growableArray.hpp"
@@ -48,6 +49,7 @@ MetadataOnStackMark::MetadataOnStackMark() {
Threads::metadata_do(Metadata::mark_on_stack);
CodeCache::alive_nmethods_do(nmethod::mark_on_stack);
CompileBroker::mark_on_stack();
+ JvmtiCurrentBreakpoints::metadata_do(Metadata::mark_on_stack);
}
MetadataOnStackMark::~MetadataOnStackMark() {
diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp
index 5d560f56a2d..ad90eeb9435 100644
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp
@@ -210,6 +210,14 @@ void GrowableCache::oops_do(OopClosure* f) {
}
}
+void GrowableCache::metadata_do(void f(Metadata*)) {
+ int len = _elements->length();
+ for (int i=0; iat(i);
+ e->metadata_do(f);
+ }
+}
+
void GrowableCache::gc_epilogue() {
int len = _elements->length();
for (int i=0; imethod_holder()->class_loader_data()->class_loader();
+ _class_holder = _method->method_holder()->klass_holder();
#ifdef CHECK_UNHANDLED_OOPS
- // _class_loader can't be wrapped in a Handle, because JvmtiBreakpoint:s are
- // eventually allocated on the heap.
+ // _class_holder can't be wrapped in a Handle, because JvmtiBreakpoints are
+ // sometimes allocated on the heap.
//
- // The code handling JvmtiBreakpoint:s allocated on the stack can't be
- // interrupted by a GC until _class_loader is reachable by the GC via the
+ // The code handling JvmtiBreakpoints allocated on the stack can't be
+ // interrupted by a GC until _class_holder is reachable by the GC via the
// oops_do method.
- Thread::current()->allow_unhandled_oop(&_class_loader);
+ Thread::current()->allow_unhandled_oop(&_class_holder);
#endif // CHECK_UNHANDLED_OOPS
assert(_method != NULL, "_method != NULL");
_bci = (int) location;
@@ -247,7 +255,7 @@ JvmtiBreakpoint::JvmtiBreakpoint(Method* m_method, jlocation location) {
void JvmtiBreakpoint::copy(JvmtiBreakpoint& bp) {
_method = bp._method;
_bci = bp._bci;
- _class_loader = bp._class_loader;
+ _class_holder = bp._class_holder;
}
bool JvmtiBreakpoint::lessThan(JvmtiBreakpoint& bp) {
@@ -365,6 +373,13 @@ void VM_ChangeBreakpoints::oops_do(OopClosure* f) {
}
}
+void VM_ChangeBreakpoints::metadata_do(void f(Metadata*)) {
+ // Walk metadata in breakpoints to keep from being deallocated with RedefineClasses
+ if (_bp != NULL) {
+ _bp->metadata_do(f);
+ }
+}
+
//
// class JvmtiBreakpoints
//
@@ -381,6 +396,10 @@ void JvmtiBreakpoints::oops_do(OopClosure* f) {
_bps.oops_do(f);
}
+void JvmtiBreakpoints::metadata_do(void f(Metadata*)) {
+ _bps.metadata_do(f);
+}
+
void JvmtiBreakpoints::gc_epilogue() {
_bps.gc_epilogue();
}
@@ -499,6 +518,12 @@ void JvmtiCurrentBreakpoints::oops_do(OopClosure* f) {
}
}
+void JvmtiCurrentBreakpoints::metadata_do(void f(Metadata*)) {
+ if (_jvmti_breakpoints != NULL) {
+ _jvmti_breakpoints->metadata_do(f);
+ }
+}
+
void JvmtiCurrentBreakpoints::gc_epilogue() {
if (_jvmti_breakpoints != NULL) {
_jvmti_breakpoints->gc_epilogue();
diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.hpp b/hotspot/src/share/vm/prims/jvmtiImpl.hpp
index c7beb176215..fc502c7387d 100644
--- a/hotspot/src/share/vm/prims/jvmtiImpl.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.hpp
@@ -69,6 +69,7 @@ public:
virtual bool lessThan(GrowableElement *e)=0;
virtual GrowableElement *clone() =0;
virtual void oops_do(OopClosure* f) =0;
+ virtual void metadata_do(void f(Metadata*)) =0;
};
class GrowableCache VALUE_OBJ_CLASS_SPEC {
@@ -115,6 +116,8 @@ public:
void clear();
// apply f to every element and update the cache
void oops_do(OopClosure* f);
+ // walk metadata to preserve for RedefineClasses
+ void metadata_do(void f(Metadata*));
// update the cache after a full gc
void gc_epilogue();
};
@@ -148,6 +151,7 @@ public:
void remove (int index) { _cache.remove(index); }
void clear() { _cache.clear(); }
void oops_do(OopClosure* f) { _cache.oops_do(f); }
+ void metadata_do(void f(Metadata*)) { _cache.metadata_do(f); }
void gc_epilogue() { _cache.gc_epilogue(); }
};
@@ -169,7 +173,7 @@ private:
Method* _method;
int _bci;
Bytecodes::Code _orig_bytecode;
- oop _class_loader;
+ oop _class_holder; // keeps _method memory from being deallocated
public:
JvmtiBreakpoint();
@@ -191,9 +195,15 @@ public:
bool lessThan(GrowableElement* e) { Unimplemented(); return false; }
bool equals(GrowableElement* e) { return equals((JvmtiBreakpoint&) *e); }
void oops_do(OopClosure* f) {
- // Mark the method loader as live
- f->do_oop(&_class_loader);
+ // Mark the method loader as live so the Method* class loader doesn't get
+ // unloaded and Method* memory reclaimed.
+ f->do_oop(&_class_holder);
}
+ void metadata_do(void f(Metadata*)) {
+ // walk metadata to preserve for RedefineClasses
+ f(_method);
+ }
+
GrowableElement *clone() {
JvmtiBreakpoint *bp = new JvmtiBreakpoint();
bp->copy(*this);
@@ -239,6 +249,7 @@ public:
int length();
void oops_do(OopClosure* f);
+ void metadata_do(void f(Metadata*));
void print();
int set(JvmtiBreakpoint& bp);
@@ -288,6 +299,7 @@ public:
static inline bool is_breakpoint(address bcp);
static void oops_do(OopClosure* f);
+ static void metadata_do(void f(Metadata*));
static void gc_epilogue();
};
@@ -332,6 +344,7 @@ public:
VMOp_Type type() const { return VMOp_ChangeBreakpoints; }
void doit();
void oops_do(OopClosure* f);
+ void metadata_do(void f(Metadata*));
};
From 80f2daae7bcddd73801e7b803c2fe5de4004b774 Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Fri, 1 Nov 2013 15:36:33 +0100
Subject: [PATCH 10/88] 8027236: Ensure ScriptObject and ConsString aren't
visible to Java
Reviewed-by: lagergren, sundar
---
.../api/scripting/ScriptObjectMirror.java | 17 ++-
.../jdk/nashorn/internal/objects/Global.java | 8 +-
.../internal/objects/NativeObject.java | 4 +-
.../nashorn/internal/runtime/ConsString.java | 16 +--
.../jdk/nashorn/internal/runtime/JSType.java | 11 +-
.../internal/runtime/linker/Bootstrap.java | 2 +-
.../linker/BoundDynamicMethodLinker.java | 2 +-
.../linker/JavaSuperAdapterLinker.java | 5 +-
.../runtime/linker/NashornBeansLinker.java | 127 ++++++++++++++++++
.../linker/NashornStaticClassLinker.java | 2 +-
nashorn/test/script/basic/JDK-8027236.js | 37 +++++
.../test/script/basic/JDK-8027236.js.EXPECTED | 1 +
.../api/javaaccess/ConsStringTest.java | 99 ++++++++++++++
13 files changed, 305 insertions(+), 26 deletions(-)
create mode 100644 nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
create mode 100644 nashorn/test/script/basic/JDK-8027236.js
create mode 100644 nashorn/test/script/basic/JDK-8027236.js.EXPECTED
create mode 100644 nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java
diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index ee287a2e088..6b88668921b 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -41,6 +41,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.Callable;
import javax.script.Bindings;
+import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.JSType;
@@ -594,14 +595,20 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
}
/**
- * Make a script object mirror on given object if needed.
+ * Make a script object mirror on given object if needed. Also converts ConsString instances to Strings.
*
- * @param obj object to be wrapped
- * @param homeGlobal global to which this object belongs
- * @return wrapped object
+ * @param obj object to be wrapped/converted
+ * @param homeGlobal global to which this object belongs. Not used for ConsStrings.
+ * @return wrapped/converted object
*/
public static Object wrap(final Object obj, final ScriptObject homeGlobal) {
- return (obj instanceof ScriptObject && homeGlobal != null) ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
+ if(obj instanceof ScriptObject) {
+ return homeGlobal != null ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
+ }
+ if(obj instanceof ConsString) {
+ return obj.toString();
+ }
+ return obj;
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/objects/Global.java b/nashorn/src/jdk/nashorn/internal/objects/Global.java
index a0df10b0aa4..0a09370aac9 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java
@@ -53,19 +53,19 @@ import jdk.nashorn.internal.runtime.GlobalFunctions;
import jdk.nashorn.internal.runtime.GlobalObject;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.NativeJavaPackage;
-import jdk.nashorn.internal.runtime.PropertyMap;
-import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.PropertyDescriptor;
-import jdk.nashorn.internal.runtime.arrays.ArrayData;
-import jdk.nashorn.internal.runtime.regexp.RegExpResult;
+import jdk.nashorn.internal.runtime.PropertyMap;
import jdk.nashorn.internal.runtime.Scope;
+import jdk.nashorn.internal.runtime.ScriptEnvironment;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
import jdk.nashorn.internal.runtime.ScriptingFunctions;
import jdk.nashorn.internal.runtime.Source;
+import jdk.nashorn.internal.runtime.arrays.ArrayData;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
import jdk.nashorn.internal.runtime.linker.InvokeByName;
+import jdk.nashorn.internal.runtime.regexp.RegExpResult;
import jdk.nashorn.internal.scripts.JO;
/**
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
index 94e3bef2d48..c7db39a5a24 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java
@@ -60,6 +60,7 @@ 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;
+import jdk.nashorn.internal.runtime.linker.NashornBeansLinker;
/**
* ECMA 15.2 Object objects
@@ -729,8 +730,7 @@ public final class NativeObject {
final MethodType methodType, final Object source) {
final GuardedInvocation inv;
try {
- inv = linker.getGuardedInvocation(createLinkRequest(operation, methodType, source),
- Bootstrap.getLinkerServices());
+ inv = NashornBeansLinker.getGuardedInvocation(linker, createLinkRequest(operation, methodType, source), Bootstrap.getLinkerServices());
assert passesGuard(source, inv.getGuard());
} catch(RuntimeException|Error e) {
throw e;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java b/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java
index 9cf51552f94..8f764f4bdda 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ConsString.java
@@ -57,10 +57,7 @@ public final class ConsString implements CharSequence {
@Override
public String toString() {
- if (!flat) {
- flatten();
- }
- return (String) left;
+ return (String) flattened();
}
@Override
@@ -70,18 +67,19 @@ public final class ConsString implements CharSequence {
@Override
public char charAt(final int index) {
- if (!flat) {
- flatten();
- }
- return left.charAt(index);
+ return flattened().charAt(index);
}
@Override
public CharSequence subSequence(final int start, final int end) {
+ return flattened().subSequence(start, end);
+ }
+
+ private CharSequence flattened() {
if (!flat) {
flatten();
}
- return left.subSequence(start, end);
+ return left;
}
private void flatten() {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
index e1b913022c0..aeeb336f65a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
@@ -883,7 +883,7 @@ public enum JSType {
*/
public static Object toJavaArray(final Object obj, final Class> componentType) {
if (obj instanceof ScriptObject) {
- return convertArray(((ScriptObject)obj).getArray().asObjectArray(), componentType);
+ return ((ScriptObject)obj).getArray().asArrayOfType(componentType);
} else if (obj instanceof JSObject) {
final ArrayLikeIterator> itr = ArrayLikeIterator.arrayLikeIterator(obj);
final int len = (int) itr.getLength();
@@ -908,6 +908,15 @@ public enum JSType {
* @return converted Java array
*/
public static Object convertArray(final Object[] src, final Class> componentType) {
+ if(componentType == Object.class) {
+ for(int i = 0; i < src.length; ++i) {
+ final Object e = src[i];
+ if(e instanceof ConsString) {
+ src[i] = e.toString();
+ }
+ }
+ }
+
final int l = src.length;
final Object dst = Array.newInstance(componentType, l);
final MethodHandle converter = Bootstrap.getLinkerServices().getTypeConverter(Object.class, componentType);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
index f725817af4b..0d5f68a1e2f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/Bootstrap.java
@@ -63,7 +63,7 @@ public final class Bootstrap {
final DynamicLinkerFactory factory = new DynamicLinkerFactory();
factory.setPrioritizedLinkers(new NashornLinker(), new NashornPrimitiveLinker(), new NashornStaticClassLinker(),
new BoundDynamicMethodLinker(), new JavaSuperAdapterLinker(), new JSObjectLinker(), new ReflectionCheckLinker());
- factory.setFallbackLinkers(new BeansLinker(), new NashornBottomLinker());
+ factory.setFallbackLinkers(new NashornBeansLinker(), new NashornBottomLinker());
factory.setSyncOnRelink(true);
final int relinkThreshold = Options.getIntProperty("nashorn.unstable.relink.threshold", -1);
if (relinkThreshold > -1) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java
index ccd497d741b..77c1618b822 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/BoundDynamicMethodLinker.java
@@ -72,7 +72,7 @@ final class BoundDynamicMethodLinker implements TypeBasedGuardingDynamicLinker {
type.changeParameterType(0, dynamicMethodClass).changeParameterType(1, boundThis.getClass()));
// Delegate to BeansLinker
- final GuardedInvocation inv = BeansLinker.getLinkerForClass(dynamicMethodClass).getGuardedInvocation(
+ final GuardedInvocation inv = NashornBeansLinker.getGuardedInvocation(BeansLinker.getLinkerForClass(dynamicMethodClass),
linkRequest.replaceArguments(newDescriptor, args), linkerServices);
if(inv == null) {
return null;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java
index 8e40805a746..c42af1d81f8 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaSuperAdapterLinker.java
@@ -100,8 +100,9 @@ final class JavaSuperAdapterLinker implements TypeBasedGuardingDynamicLinker {
type.changeParameterType(0, adapterClass), 0);
// Delegate to BeansLinker
- final GuardedInvocation guardedInv = BeansLinker.getLinkerForClass(adapterClass).getGuardedInvocation(
- linkRequest.replaceArguments(newDescriptor, args), linkerServices);
+ final GuardedInvocation guardedInv = NashornBeansLinker.getGuardedInvocation(
+ BeansLinker.getLinkerForClass(adapterClass), linkRequest.replaceArguments(newDescriptor, args),
+ linkerServices);
final MethodHandle guard = IS_ADAPTER_OF_CLASS.bindTo(adapterClass);
if(guardedInv == null) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
new file mode 100644
index 00000000000..e2db2b11cc9
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornBeansLinker.java
@@ -0,0 +1,127 @@
+/*
+ * 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.linker;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import jdk.internal.dynalink.beans.BeansLinker;
+import jdk.internal.dynalink.linker.ConversionComparator.Comparison;
+import jdk.internal.dynalink.linker.GuardedInvocation;
+import jdk.internal.dynalink.linker.GuardingDynamicLinker;
+import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.linker.LinkerServices;
+import jdk.internal.dynalink.support.Lookup;
+import jdk.nashorn.internal.runtime.ConsString;
+
+/**
+ * This linker delegates to a {@code BeansLinker} but passes it a special linker services object that has a modified
+ * {@code asType} method that will ensure that we never pass internal engine objects that should not be externally
+ * observable (currently only ConsString) to Java APIs, but rather that we flatten it into a String. We can't just add
+ * this functionality as custom converters via {@code GuaardingTypeConverterFactory}, since they are not consulted when
+ * the target method handle parameter signature is {@code Object}.
+ */
+public class NashornBeansLinker implements GuardingDynamicLinker {
+ private static final MethodHandle EXPORT_ARGUMENT = new Lookup(MethodHandles.lookup()).findOwnStatic("exportArgument", Object.class, Object.class);
+
+ private final BeansLinker beansLinker = new BeansLinker();
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ return getGuardedInvocation(beansLinker, linkRequest, linkerServices);
+ }
+
+ /**
+ * Delegates to the specified linker but injects its linker services wrapper so that it will apply all special
+ * conversions that this class does.
+ * @param delegateLinker the linker to which the actual work is delegated to.
+ * @param linkRequest the delegated link request
+ * @param linkerServices the original link services that will be augmented with special conversions
+ * @return the guarded invocation from the delegate, possibly augmented with special conversions
+ * @throws Exception if the delegate throws an exception
+ */
+ public static GuardedInvocation getGuardedInvocation(final GuardingDynamicLinker delegateLinker, final LinkRequest linkRequest, final LinkerServices linkerServices) throws Exception {
+ return delegateLinker.getGuardedInvocation(linkRequest, new NashornBeansLinkerServices(linkerServices));
+ }
+
+ @SuppressWarnings("unused")
+ private static Object exportArgument(final Object arg) {
+ return arg instanceof ConsString ? arg.toString() : arg;
+ }
+
+ private static class NashornBeansLinkerServices implements LinkerServices {
+ private final LinkerServices linkerServices;
+
+ NashornBeansLinkerServices(final LinkerServices linkerServices) {
+ this.linkerServices = linkerServices;
+ }
+
+ @Override
+ public MethodHandle asType(final MethodHandle handle, final MethodType fromType) {
+ final MethodHandle typed = linkerServices.asType(handle, fromType);
+
+ final MethodType handleType = handle.type();
+ final int paramCount = handleType.parameterCount();
+ assert fromType.parameterCount() == handleType.parameterCount();
+
+ MethodHandle[] filters = null;
+ for(int i = 0; i < paramCount; ++i) {
+ if(shouldConvert(handleType.parameterType(i), fromType.parameterType(i))) {
+ if(filters == null) {
+ filters = new MethodHandle[paramCount];
+ }
+ filters[i] = EXPORT_ARGUMENT;
+ }
+ }
+
+ return filters != null ? MethodHandles.filterArguments(typed, 0, filters) : typed;
+ }
+
+ private static boolean shouldConvert(final Class> handleType, final Class> fromType) {
+ return handleType == Object.class && fromType == Object.class;
+ }
+
+ @Override
+ public MethodHandle getTypeConverter(final Class> sourceType, final Class> targetType) {
+ return linkerServices.getTypeConverter(sourceType, targetType);
+ }
+
+ @Override
+ public boolean canConvert(final Class> from, final Class> to) {
+ return linkerServices.canConvert(from, to);
+ }
+
+ @Override
+ public GuardedInvocation getGuardedInvocation(final LinkRequest linkRequest) throws Exception {
+ return linkerServices.getGuardedInvocation(linkRequest);
+ }
+
+ @Override
+ public Comparison compareConversion(final Class> sourceType, final Class> targetType1, final Class> targetType2) {
+ return linkerServices.compareConversion(sourceType, targetType1, targetType2);
+ }
+ }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
index ce60d790f57..72ed97666d0 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornStaticClassLinker.java
@@ -93,7 +93,7 @@ final class NashornStaticClassLinker implements TypeBasedGuardingDynamicLinker {
}
private static GuardedInvocation delegate(LinkerServices linkerServices, final LinkRequest request) throws Exception {
- return staticClassLinker.getGuardedInvocation(request, linkerServices);
+ return NashornBeansLinker.getGuardedInvocation(staticClassLinker, request, linkerServices);
}
private static GuardedInvocation checkNullConstructor(final GuardedInvocation ctorInvocation, final Class> receiverClass) {
diff --git a/nashorn/test/script/basic/JDK-8027236.js b/nashorn/test/script/basic/JDK-8027236.js
new file mode 100644
index 00000000000..02f9e8d8e97
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8027236.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-8027236: Ensure ScriptObject and ConsString aren't visible to Java
+ *
+ * @test
+ * @run
+ */
+
+// Check that ConsString is flattened
+var m = new java.util.HashMap()
+var x = "f"
+x += "oo"
+m.put(x, "bar")
+print(m.get("foo"))
+// Note: many more tests are run by the JavaExportImportTest TestNG class.
diff --git a/nashorn/test/script/basic/JDK-8027236.js.EXPECTED b/nashorn/test/script/basic/JDK-8027236.js.EXPECTED
new file mode 100644
index 00000000000..5716ca5987c
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8027236.js.EXPECTED
@@ -0,0 +1 @@
+bar
diff --git a/nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java b/nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java
new file mode 100644
index 00000000000..1eadfb77112
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/api/javaaccess/ConsStringTest.java
@@ -0,0 +1,99 @@
+/*
+ * 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.api.javaaccess;
+
+import static org.testng.AssertJUnit.assertEquals;
+
+import java.util.HashMap;
+import java.util.Map;
+import javax.script.Bindings;
+import javax.script.ScriptContext;
+import javax.script.ScriptEngine;
+import javax.script.ScriptEngineManager;
+import javax.script.ScriptException;
+import jdk.nashorn.api.scripting.JSObject;
+import org.testng.TestNG;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+public class ConsStringTest {
+ private static ScriptEngine e = null;
+
+ public static void main(final String[] args) {
+ TestNG.main(args);
+ }
+
+ @BeforeClass
+ public static void setUpClass() throws ScriptException {
+ e = new ScriptEngineManager().getEngineByName("nashorn");
+ }
+
+ @AfterClass
+ public static void tearDownClass() {
+ e = null;
+ }
+
+ @Test
+ public void testConsStringFlattening() throws ScriptException {
+ final Bindings b = e.getBindings(ScriptContext.ENGINE_SCOPE);
+ final Map
*
- * @param extensionName key in the attibute list
+ * @param extensionName key in the attribute list
* @param attr manifest file attributes
* @param file installed extension jar file to compare the requested
* extension against.
diff --git a/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java b/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java
index a9649c7fca9..6b997e42647 100644
--- a/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java
+++ b/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java
@@ -1132,7 +1132,7 @@ public class RMIGenerator implements RMIConstants, Generator {
throws IOException
{
if (types.length != names.length) {
- throw new Error("paramter type and name arrays different sizes");
+ throw new Error("parameter type and name arrays different sizes");
}
for (int i = 0; i < types.length; i++) {
@@ -1213,7 +1213,7 @@ public class RMIGenerator implements RMIConstants, Generator {
throws IOException
{
if (types.length != names.length) {
- throw new Error("paramter type and name arrays different sizes");
+ throw new Error("parameter type and name arrays different sizes");
}
boolean readObject = false;
diff --git a/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java b/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java
index c15ddd23529..7b34ff83914 100644
--- a/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java
+++ b/jdk/src/share/classes/sun/security/jgss/krb5/InitialToken.java
@@ -192,7 +192,7 @@ abstract class InitialToken extends Krb5Token {
if (krbCredMessage.length > 0x0000ffff)
throw new GSSException(GSSException.FAILURE, -1,
- "Incorrect messsage length");
+ "Incorrect message length");
writeLittleEndian(krbCredMessage.length, temp);
checksumBytes[pos++] = temp[0];
diff --git a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
index 0312a1fbf76..1acc3a9a06b 100644
--- a/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
+++ b/jdk/src/share/classes/sun/security/jgss/spnego/SpNegoContext.java
@@ -360,7 +360,7 @@ public class SpNegoContext implements GSSContextSpi {
if (internal_mech == null) {
// return wth failure
throw new GSSException(errorCode, -1,
- "supported mechansim from server is null");
+ "supported mechanism from server is null");
}
// get the negotiated result
@@ -911,7 +911,7 @@ public class SpNegoContext implements GSSContextSpi {
return mechContext.isEstablished();
} else {
if (DEBUG) {
- System.out.println("The underlying mechansim context has " +
+ System.out.println("The underlying mechanism context has " +
"not been initialized");
}
return false;
@@ -1024,7 +1024,7 @@ public class SpNegoContext implements GSSContextSpi {
return peerName;
} else {
if (DEBUG) {
- System.out.println("The underlying mechansim context has " +
+ System.out.println("The underlying mechanism context has " +
"not been initialized");
}
return null;
@@ -1040,7 +1040,7 @@ public class SpNegoContext implements GSSContextSpi {
return myName;
} else {
if (DEBUG) {
- System.out.println("The underlying mechansim context has " +
+ System.out.println("The underlying mechanism context has " +
"not been initialized");
}
return null;
diff --git a/jdk/src/share/demo/jfc/FileChooserDemo/FileChooserDemo.java b/jdk/src/share/demo/jfc/FileChooserDemo/FileChooserDemo.java
index e492e09e032..24c5533f9a1 100644
--- a/jdk/src/share/demo/jfc/FileChooserDemo/FileChooserDemo.java
+++ b/jdk/src/share/demo/jfc/FileChooserDemo/FileChooserDemo.java
@@ -450,9 +450,9 @@ public class FileChooserDemo extends JPanel implements ActionListener {
"User cancelled operation. No file was chosen.");
} else if (retval == ERROR_OPTION) {
JOptionPane.showMessageDialog(frame,
- "An error occured. No file was chosen.");
+ "An error occurred. No file was chosen.");
} else {
- JOptionPane.showMessageDialog(frame, "Unknown operation occured.");
+ JOptionPane.showMessageDialog(frame, "Unknown operation occurred.");
}
}
diff --git a/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c
index 8889f740d0e..79d5250390d 100644
--- a/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c
+++ b/jdk/src/share/native/sun/security/pkcs11/wrapper/p11_util.c
@@ -598,16 +598,16 @@ void jAttributeArrayToCKAttributeArray(JNIEnv *env, jobjectArray jArray, CK_ATTR
throwOutOfMemoryError(env, 0);
return;
}
- TRACE1(", converting %d attibutes", jLength);
+ TRACE1(", converting %d attributes", jLength);
for (i=0; i<(*ckpLength); i++) {
- TRACE1(", getting %d. attibute", i);
+ TRACE1(", getting %d. attribute", i);
jAttribute = (*env)->GetObjectArrayElement(env, jArray, i);
if ((*env)->ExceptionCheck(env)) {
freeCKAttributeArray(*ckpArray, i);
return;
}
TRACE1(", jAttribute = %d", jAttribute);
- TRACE1(", converting %d. attibute", i);
+ TRACE1(", converting %d. attribute", i);
(*ckpArray)[i] = jAttributeToCKAttribute(env, jAttribute);
if ((*env)->ExceptionCheck(env)) {
freeCKAttributeArray(*ckpArray, i);
diff --git a/jdk/src/share/sample/nio/chatserver/ClientReader.java b/jdk/src/share/sample/nio/chatserver/ClientReader.java
index de7f639e81b..822125a946c 100644
--- a/jdk/src/share/sample/nio/chatserver/ClientReader.java
+++ b/jdk/src/share/sample/nio/chatserver/ClientReader.java
@@ -58,7 +58,7 @@ class ClientReader {
}
/**
- * Runs a cycle of doing a beforeRead action and then inquiring a new
+ * Runs a cycle of doing a beforeRead action and then enqueuing a new
* read on the client. Handles closed channels and errors while reading.
* If the client is still connected a new round of actions are called.
*/
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
index e61273dc4d4..912a951f374 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
@@ -1173,7 +1173,7 @@ abstract class XDecoratedPeer extends XWindowPeer {
}
if (target == activeWindow && target != focusedWindow) {
// Happens when an owned window is currently focused
- focusLog.fine("Focus is on child window - transfering it back to the owner");
+ focusLog.fine("Focus is on child window - transferring it back to the owner");
handleWindowFocusInSync(-1);
return true;
}
diff --git a/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java b/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
index 725e66f8bec..d84712ba97c 100644
--- a/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
+++ b/jdk/src/windows/classes/sun/nio/ch/WindowsSelectorImpl.java
@@ -266,7 +266,7 @@ final class WindowsSelectorImpl extends SelectorImpl {
private void checkForException() throws IOException {
if (exception == null)
return;
- StringBuffer message = new StringBuffer("An exception occured" +
+ StringBuffer message = new StringBuffer("An exception occurred" +
" during the execution of select(): \n");
message.append(exception);
message.append('\n');
diff --git a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java
index ce0e3e7fb5d..566b0bee12c 100644
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Klist.java
@@ -336,7 +336,7 @@ public class Klist {
System.out.println(" name\t name of credentials cache or " +
" keytab with the prefix. File-based cache or "
+ "keytab's prefix is FILE:.");
- System.out.println(" -c specifes that credential cache is to be " +
+ System.out.println(" -c specifies that credential cache is to be " +
"listed");
System.out.println(" -k specifies that key tab is to be listed");
System.out.println(" options for credentials caches:");
diff --git a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java
index eeeb848e6e5..bf09016136f 100644
--- a/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java
+++ b/jdk/src/windows/classes/sun/security/krb5/internal/tools/Ktab.java
@@ -381,12 +381,12 @@ public class Ktab {
}
}
} catch (KrbException e) {
- System.err.println("Error occured while deleting the entry. "+
+ System.err.println("Error occurred while deleting the entry. "+
"Deletion failed.");
e.printStackTrace();
System.exit(-1);
} catch (IOException e) {
- System.err.println("Error occured while deleting the entry. "+
+ System.err.println("Error occurred while deleting the entry. "+
" Deletion failed.");
e.printStackTrace();
System.exit(-1);
From 96d9e95176c6471b21ced8991be7cbe5f99c6ad0 Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Fri, 1 Nov 2013 19:08:56 +0000
Subject: [PATCH 14/88] 8027660: javac crash while creating LVT entry for a
local variable defined in an inner block
Co-authored-by: Jan Lahoda
Reviewed-by: jjg
---
.../classes/com/sun/tools/javac/jvm/Code.java | 10 ++++-
.../test/tools/javac/flow/LVTHarness.java | 6 ++-
.../flow/tests/TestCaseLocalInInnerBlock.java | 41 +++++++++++++++++++
3 files changed, 53 insertions(+), 4 deletions(-)
create mode 100644 langtools/test/tools/javac/flow/tests/TestCaseLocalInInnerBlock.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
index 6276a24ad2f..fceaff23445 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/Code.java
@@ -1790,8 +1790,9 @@ public class Code {
void markInitialized(UninitializedType old) {
Type newtype = old.initializedType();
- for (int i=0; i
Date: Fri, 1 Nov 2013 21:43:27 +0100
Subject: [PATCH 15/88] 8027310: Annotation Processor crashes with NPE
JCAnnotation.attribute is null when annotation type is unavailable
Reviewed-by: jjg, jfranck
---
.../com/sun/tools/javac/comp/Attr.java | 3 +-
.../Processor.java | 208 ++++++++++++++++++
.../CrashOnNonExistingAnnotation/Source.java | 74 +++++++
3 files changed, 284 insertions(+), 1 deletion(-)
create mode 100644 langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java
create mode 100644 langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Source.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 e8af8251c6f..9a744951136 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
@@ -2254,7 +2254,8 @@ public class Attr extends JCTree.Visitor {
// empty annotations, if only declaration annotations were given.
// This method will raise an error for such a type.
for (JCAnnotation ai : annotations) {
- if (typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
+ if (!ai.type.isErroneous() &&
+ typeAnnotations.annotationType(ai.attribute, sym) == TypeAnnotations.AnnotationType.DECLARATION) {
log.error(ai.pos(), "annotation.type.not.applicable");
}
}
diff --git a/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java b/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java
new file mode 100644
index 00000000000..c89149265bf
--- /dev/null
+++ b/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Processor.java
@@ -0,0 +1,208 @@
+/*
+ * 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.io.File;
+import java.io.IOException;
+import java.io.Writer;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+import java.util.TreeMap;
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedOptions;
+import javax.lang.model.element.TypeElement;
+import javax.tools.Diagnostic;
+import javax.tools.DiagnosticCollector;
+import javax.tools.DiagnosticListener;
+import javax.tools.FileObject;
+import javax.tools.ForwardingJavaFileManager;
+import javax.tools.JavaFileManager;
+import javax.tools.JavaFileObject;
+import javax.tools.JavaFileObject.Kind;
+import javax.tools.SimpleJavaFileObject;
+import com.sun.source.tree.AnnotationTree;
+import com.sun.source.tree.CompilationUnitTree;
+import com.sun.source.tree.LiteralTree;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TreeScanner;
+import com.sun.source.util.Trees;
+import com.sun.tools.javac.api.JavacTool;
+import com.sun.tools.javac.file.JavacFileManager;
+import com.sun.tools.javac.util.Assert;
+
+@SupportedAnnotationTypes("*")
+@SupportedOptions("target")
+public class Processor extends AbstractProcessor {
+
+ private int round = 0;
+ @Override
+ public boolean process(Set extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ if (round++ == 0) {
+ try (Writer out = processingEnv.getFiler()
+ .createSourceFile("Anno.java")
+ .openWriter()) {
+ String target = processingEnv.getOptions().get("target");
+ String code = "import java.lang.annotation.ElementType;\n" +
+ "import java.lang.annotation.Target;\n" +
+ "@Target(ElementType." + target + ")\n" +
+ "@interface Anno { public String value(); }\n";
+ out.write(code);
+ } catch (IOException exc) {
+ throw new IllegalStateException(exc);
+ }
+ }
+ return true;
+ }
+
+ public static void main(String... args) throws IOException, URISyntaxException {
+ if (args.length != 1) throw new IllegalStateException("Must provide class name!");
+ String testContent = null;
+ File testSrc = new File(System.getProperty("test.src"));
+ File testFile = new File(testSrc, args[0]);
+ if (!testFile.canRead()) throw new IllegalStateException("Cannot read the test source");
+ JavacTool compiler = JavacTool.create();
+ JavacFileManager fm = compiler.getStandardFileManager(null, null, null);
+ testContent = fm.getRegularFile(testFile).getCharContent(true).toString();
+ JavaFileObject testFileObject = new TestFO(new URI("mem://" + args[0]), testContent);
+ TestFM testFileManager = new TestFM(fm);
+ JavacTask task = compiler.getTask(null,
+ testFileManager,
+ new DiagnosticCollector(),
+ null,
+ null,
+ Arrays.asList(testFileObject));
+ final Trees trees = Trees.instance(task);
+ final CompilationUnitTree cut = task.parse().iterator().next();
+
+ final Map annotation2Target = new TreeMap<>(new Comparator() {
+ @Override public int compare(int[] o1, int[] o2) {
+ return o2[0] - o1[0];
+ }
+ });
+
+ new TreeScanner() {
+ @Override
+ public Void visitAnnotation(AnnotationTree node, Void p) {
+ int endPos = (int) trees.getSourcePositions().getEndPosition(cut, node);
+
+ Assert.check(endPos >= 0);
+
+ int startPos = (int) trees.getSourcePositions().getStartPosition(cut, node);
+ String target = ((LiteralTree) node.getArguments().get(0)).getValue().toString();
+
+ annotation2Target.put(new int[] {startPos, endPos}, target);
+
+ return super.visitAnnotation(node, p);
+ }
+ }.scan(cut.getTypeDecls().get(0), null);
+
+ DiagnosticListener noErrors = new DiagnosticListener() {
+ @Override public void report(Diagnostic extends JavaFileObject> diagnostic) {
+ if (diagnostic.getKind() == Diagnostic.Kind.ERROR) {
+ throw new IllegalStateException(diagnostic.toString());
+ }
+ }
+ };
+
+ for (Entry e : annotation2Target.entrySet()) {
+ StringBuilder updatedContent = new StringBuilder();
+ int last = testContent.length();
+
+ for (int[] toRemove : annotation2Target.keySet()) {
+ if (toRemove == e.getKey()) continue;
+ updatedContent.insert(0, testContent.substring(toRemove[1], last));
+ last = toRemove[0];
+ }
+
+ updatedContent.insert(0, testContent.substring(0, last));
+
+ JavaFileObject updatedFile = new TestFO(new URI("mem://" + args[0]),
+ updatedContent.toString());
+ JavacTask testTask = compiler.getTask(null,
+ testFileManager,
+ noErrors,
+ Arrays.asList("-processor", "Processor",
+ "-Atarget=" + e.getValue()),
+ null,
+ Arrays.asList(updatedFile));
+
+ try {
+ testTask.analyze();
+ } catch (Throwable exc) {
+ System.out.println("error while processing:");
+ System.out.println(updatedContent);
+ throw exc;
+ }
+
+ JavacTask testTask2 = compiler.getTask(null,
+ testFileManager,
+ new DiagnosticCollector(),
+ null,
+ null,
+ Arrays.asList(updatedFile));
+
+ try {
+ testTask2.analyze();
+ } catch (Throwable exc) {
+ System.out.println("error while processing:");
+ System.out.println(updatedContent);
+ throw exc;
+ }
+ }
+ }
+
+ private static final class TestFO extends SimpleJavaFileObject {
+ private final String content;
+ public TestFO(URI uri, String content) {
+ super(uri, Kind.SOURCE);
+ this.content = content;
+ }
+
+ @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+ return content;
+ }
+
+ @Override public boolean isNameCompatible(String simpleName, Kind kind) {
+ return true;
+ }
+ }
+
+ private static final class TestFM extends ForwardingJavaFileManager {
+
+ public TestFM(JavaFileManager fileManager) {
+ super(fileManager);
+ }
+
+ @Override
+ public boolean isSameFile(FileObject a, FileObject b) {
+ return a.equals(b);
+ }
+
+ }
+}
diff --git a/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Source.java b/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Source.java
new file mode 100644
index 00000000000..9995fa6734e
--- /dev/null
+++ b/langtools/test/tools/javac/processing/errors/CrashOnNonExistingAnnotation/Source.java
@@ -0,0 +1,74 @@
+/*
+ * 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 /nodynamiccopyright/
+ * @bug 8027310
+ * @summary Ensure no exceptions on unresolvable annotations
+ * @build Processor
+ * @run main Processor Source.java
+ */
+
+import java.util.List;
+
+@Anno("TYPE")
+public class Source {
+ @Anno("TYPE")
+ class Inner {
+ class InnerInner {
+ public @Anno("CONSTRUCTOR") InnerInner(@Anno("TYPE_USE") Source. @Anno("TYPE_USE") Inner Inner.this,
+ @Anno("PARAMETER") java.lang. @Anno("TYPE_USE") Runnable p) {
+ Runnable r = () -> {
+ @Anno("TYPE_USE") Object tested = null;
+ @Anno("TYPE_USE") boolean isAnnotated = tested instanceof @Anno("TYPE_USE") String;
+ };
+
+ @Anno("TYPE_USE") Object tested = (@Anno("TYPE_USE") String @Anno("TYPE_USE") []) null;
+ @Anno("TYPE_USE") boolean isAnnotated = tested instanceof@Anno("TYPE_USE") String;
+
+ tested = new java.lang. @Anno("TYPE_USE") Object();
+ tested = new @Anno("TYPE_USE") Object();
+ }
+ }
+ }
+
+ {
+ Runnable r = () -> {
+ @Anno("TYPE_USE") Object tested = null;
+ @Anno("TYPE_USE") boolean isAnnotated = tested instanceof @Anno("TYPE_USE") String;
+ };
+
+ @Anno("TYPE_USE") Object tested = (@Anno("TYPE_USE") String @Anno("TYPE_USE") []) null;
+ @Anno("TYPE_USE") boolean isAnnotated = tested instanceof@Anno("TYPE_USE") String;
+
+ tested = new java.lang. @Anno("TYPE_USE") Object();
+ tested = new @Anno("TYPE_USE") Object();
+ }
+
+ @Anno("TYPE")
+ @Anno("ANNOTATION_TYPE")
+ @interface A { }
+ abstract class Parameterized<@Anno("TYPE_PARAMETER") T extends @Anno("TYPE_USE") CharSequence &
+ @Anno("TYPE_USE") Runnable>
+ implements @Anno("TYPE_USE") List<@Anno("TYPE_USE") Runnable> { }
+}
From 897e6d41f6906668fa51c1ef8eac31ff17ebb858 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Rickard=20B=C3=A4ckman?=
Date: Mon, 4 Nov 2013 10:44:46 +0100
Subject: [PATCH 16/88] 8027622: java.time.Instant.create failing since
hs25-b56
Reviewed-by: kvn, iveresov
---
hotspot/src/share/vm/opto/compile.cpp | 17 ++++--
.../intrinsics/mathexact/CompareTest.java | 61 +++++++++++++++++++
2 files changed, 72 insertions(+), 6 deletions(-)
create mode 100644 hotspot/test/compiler/intrinsics/mathexact/CompareTest.java
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index a896532f5d3..e0fd34d9819 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -3018,12 +3018,17 @@ void Compile::final_graph_reshaping_impl( Node *n, Final_Reshape_Counts &frc) {
// Phi nodes shouldn't be moved. They would only match below if they
// had the same control as the MathExactNode. The only time that
// would happen is if the Phi is also an input to the MathExact
- if (!out->is_Phi()) {
- if (out->in(0) == NULL) {
- out->set_req(0, non_throwing);
- } else if (out->in(0) == ctrl) {
- out->set_req(0, non_throwing);
- }
+ //
+ // Cmp nodes shouldn't have control set at all.
+ if (out->is_Phi() ||
+ out->is_Cmp()) {
+ continue;
+ }
+
+ if (out->in(0) == NULL) {
+ out->set_req(0, non_throwing);
+ } else if (out->in(0) == ctrl) {
+ out->set_req(0, non_throwing);
}
}
}
diff --git a/hotspot/test/compiler/intrinsics/mathexact/CompareTest.java b/hotspot/test/compiler/intrinsics/mathexact/CompareTest.java
new file mode 100644
index 00000000000..f6785c07c69
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/mathexact/CompareTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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 8026722
+ * @summary Verify that the compare after addExact is a signed compare
+ * @compile CompareTest.java
+ * @run main CompareTest
+ *
+ */
+
+public class CompareTest {
+ public static long store = 0;
+ public static long addValue = 1231;
+
+ public static void main(String[] args) {
+ for (int i = 0; i < 20000; ++i) {
+ runTest(i, i);
+ runTest(i-1, i);
+ }
+ }
+
+ public static long create(long value, int v) {
+ if ((value | v) == 0) {
+ return 0;
+ }
+
+ // C2 turned this test into unsigned test when a control edge was set on the Cmp
+ if (value < -31557014167219200L || value > 31556889864403199L) {
+ throw new RuntimeException("error");
+ }
+
+ return value;
+ }
+
+ public static void runTest(long value, int value2) {
+ long res = Math.addExact(value, addValue);
+ store = create(res, Math.floorMod(value2, 100000));
+ }
+}
From d3e3eead180ffb56fc98c90cc5dc327536a5ae4c Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Mon, 4 Nov 2013 18:52:22 +0530
Subject: [PATCH 17/88] 8027753: Support ScriptObject to JSObject,
ScriptObjectMirror, Map, Bindings auto-conversion as well as explicit wrap,
unwrap
Reviewed-by: jlaskey, hannesw, attila
---
.../api/scripting/ScriptObjectMirror.java | 10 ++--
.../nashorn/api/scripting/ScriptUtils.java | 57 +++++++++++++++++++
.../runtime/linker/NashornLinker.java | 39 +++++++++++--
nashorn/test/script/basic/JDK-8027753.js | 50 ++++++++++++++++
.../test/script/basic/JDK-8027753.js.EXPECTED | 3 +
.../api/scripting/ScriptEngineTest.java | 12 ++++
.../src/jdk/nashorn/api/scripting/Window.java | 19 +++++++
7 files changed, 180 insertions(+), 10 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8027753.js
create mode 100644 nashorn/test/script/basic/JDK-8027753.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index 6b88668921b..764c8da30fb 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -601,9 +601,9 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
* @param homeGlobal global to which this object belongs. Not used for ConsStrings.
* @return wrapped/converted object
*/
- public static Object wrap(final Object obj, final ScriptObject homeGlobal) {
+ public static Object wrap(final Object obj, final Object homeGlobal) {
if(obj instanceof ScriptObject) {
- return homeGlobal != null ? new ScriptObjectMirror((ScriptObject)obj, homeGlobal) : obj;
+ return homeGlobal instanceof ScriptObject ? new ScriptObjectMirror((ScriptObject)obj, (ScriptObject)homeGlobal) : obj;
}
if(obj instanceof ConsString) {
return obj.toString();
@@ -618,7 +618,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
* @param homeGlobal global to which this object belongs
* @return unwrapped object
*/
- public static Object unwrap(final Object obj, final ScriptObject homeGlobal) {
+ public static Object unwrap(final Object obj, final Object homeGlobal) {
if (obj instanceof ScriptObjectMirror) {
final ScriptObjectMirror mirror = (ScriptObjectMirror)obj;
return (mirror.global == homeGlobal)? mirror.sobj : obj;
@@ -634,7 +634,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
* @param homeGlobal global to which this object belongs
* @return wrapped array
*/
- public static Object[] wrapArray(final Object[] args, final ScriptObject homeGlobal) {
+ public static Object[] wrapArray(final Object[] args, final Object homeGlobal) {
if (args == null || args.length == 0) {
return args;
}
@@ -655,7 +655,7 @@ public final class ScriptObjectMirror extends AbstractJSObject implements Bindin
* @param homeGlobal global to which this object belongs
* @return unwrapped array
*/
- public static Object[] unwrapArray(final Object[] args, final ScriptObject homeGlobal) {
+ public static Object[] unwrapArray(final Object[] args, final Object homeGlobal) {
if (args == null || args.length == 0) {
return args;
}
diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java
index 48045e1f336..fd0a7beefbb 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptUtils.java
@@ -25,7 +25,9 @@
package jdk.nashorn.api.scripting;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptFunction;
+import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
/**
@@ -71,4 +73,59 @@ public final class ScriptUtils {
return func.makeSynchronizedFunction(sync);
}
+ /**
+ * Make a script object mirror on given object if needed.
+ *
+ * @param obj object to be wrapped
+ * @return wrapped object
+ */
+ public static Object wrap(final Object obj) {
+ if (obj instanceof ScriptObject) {
+ return ScriptObjectMirror.wrap(obj, Context.getGlobal());
+ }
+
+ return obj;
+ }
+
+ /**
+ * Unwrap a script object mirror if needed.
+ *
+ * @param obj object to be unwrapped
+ * @return unwrapped object
+ */
+ public static Object unwrap(final Object obj) {
+ if (obj instanceof ScriptObjectMirror) {
+ return ScriptObjectMirror.unwrap(obj, Context.getGlobal());
+ }
+
+ return obj;
+ }
+
+ /**
+ * Wrap an array of object to script object mirrors if needed.
+ *
+ * @param args array to be unwrapped
+ * @return wrapped array
+ */
+ public static Object[] wrapArray(final Object[] args) {
+ if (args == null || args.length == 0) {
+ return args;
+ }
+
+ return ScriptObjectMirror.wrapArray(args, Context.getGlobal());
+ }
+
+ /**
+ * Unwrap an array of script object mirrors if needed.
+ *
+ * @param args array to be unwrapped
+ * @return unwrapped array
+ */
+ public static Object[] unwrapArray(final Object[] args) {
+ if (args == null || args.length == 0) {
+ return args;
+ }
+
+ return ScriptObjectMirror.unwrapArray(args, Context.getGlobal());
+ }
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
index a760c604d46..27e4573f572 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/NashornLinker.java
@@ -32,6 +32,8 @@ import java.lang.invoke.MethodHandles;
import java.lang.reflect.Modifier;
import java.util.Deque;
import java.util.List;
+import java.util.Map;
+import javax.script.Bindings;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.ConversionComparator;
import jdk.internal.dynalink.linker.GuardedInvocation;
@@ -40,7 +42,11 @@ import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.linker.LinkerServices;
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.api.scripting.JSObject;
+import jdk.nashorn.api.scripting.ScriptObjectMirror;
+import jdk.nashorn.api.scripting.ScriptUtils;
import jdk.nashorn.internal.objects.NativeArray;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
@@ -115,9 +121,14 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp
return new GuardedInvocation(mh, canLinkTypeStatic(sourceType) ? null : IS_NASHORN_OR_UNDEFINED_TYPE);
}
- GuardedInvocation inv = getArrayConverter(sourceType, targetType);
- if(inv != null) {
- return inv;
+ final GuardedInvocation arrayConverter = getArrayConverter(sourceType, targetType);
+ if(arrayConverter != null) {
+ return arrayConverter;
+ }
+
+ final GuardedInvocation mirrorConverter = getMirrorConverter(sourceType, targetType);
+ if(mirrorConverter != null) {
+ return mirrorConverter;
}
return getSamTypeConverter(sourceType, targetType);
@@ -181,6 +192,18 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp
return MH.asType(converter, converter.type().changeReturnType(type));
}
+ private static GuardedInvocation getMirrorConverter(Class> sourceType, Class> targetType) {
+ // Could've also used (targetType.isAssignableFrom(ScriptObjectMirror.class) && targetType != Object.class) but
+ // it's probably better to explicitly spell out the supported target types
+ if (targetType == Map.class || targetType == Bindings.class || targetType == JSObject.class || targetType == ScriptObjectMirror.class) {
+ if(ScriptObject.class.isAssignableFrom(sourceType)) {
+ return new GuardedInvocation(CREATE_MIRROR, null);
+ }
+ return new GuardedInvocation(CREATE_MIRROR, IS_SCRIPT_OBJECT);
+ }
+ return null;
+ }
+
private static boolean isAutoConvertibleFromFunction(final Class> clazz) {
return isAbstractClass(clazz) && !ScriptObject.class.isAssignableFrom(clazz) &&
JavaAdapterFactory.isAutoConvertibleFromFunction(clazz);
@@ -235,17 +258,23 @@ final class NashornLinker implements TypeBasedGuardingDynamicLinker, GuardingTyp
return clazz == List.class || clazz == Deque.class;
}
+ private static final MethodHandle IS_SCRIPT_OBJECT = Guards.isInstance(ScriptObject.class, MH.type(Boolean.TYPE, Object.class));
private static final MethodHandle IS_SCRIPT_FUNCTION = Guards.isInstance(ScriptFunction.class, MH.type(Boolean.TYPE, Object.class));
private static final MethodHandle IS_NATIVE_ARRAY = Guards.isOfClass(NativeArray.class, MH.type(Boolean.TYPE, Object.class));
- private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined",
- Boolean.TYPE, Object.class);
+ private static final MethodHandle IS_NASHORN_OR_UNDEFINED_TYPE = findOwnMH("isNashornTypeOrUndefined", Boolean.TYPE, Object.class);
+ private static final MethodHandle CREATE_MIRROR = findOwnMH("createMirror", Object.class, Object.class);
@SuppressWarnings("unused")
private static boolean isNashornTypeOrUndefined(final Object obj) {
return obj instanceof ScriptObject || obj instanceof Undefined;
}
+ @SuppressWarnings("unused")
+ private static Object createMirror(final Object obj) {
+ return ScriptUtils.wrap(obj);
+ }
+
private static MethodHandle findOwnMH(final String name, final Class> rtype, final Class>... types) {
return MH.findStatic(MethodHandles.lookup(), NashornLinker.class, name, MH.type(rtype, types));
}
diff --git a/nashorn/test/script/basic/JDK-8027753.js b/nashorn/test/script/basic/JDK-8027753.js
new file mode 100644
index 00000000000..2af0baad4cd
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8027753.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-8027753: Support ScriptObject to JSObject, ScriptObjectMirror, Map, Bindings auto-conversion as well as explicit wrap, unwrap
+ *
+ * @test
+ * @run
+ */
+
+var ScriptUtils = Java.type("jdk.nashorn.api.scripting.ScriptUtils");
+var ScriptObjectMirror = Java.type("jdk.nashorn.api.scripting.ScriptObjectMirror");
+
+var obj = { foo: 34, bar: 'hello' };
+
+var wrapped = ScriptUtils.wrap(obj);
+if (! (wrapped instanceof ScriptObjectMirror)) {
+ fail("ScriptUtils.wrap does not return a ScriptObjectMirror");
+}
+
+print("wrapped.foo = " + wrapped.foo);
+print("wrapped.bar = " + wrapped.bar);
+
+var unwrapped = ScriptUtils.unwrap(wrapped);
+if (! (unwrapped instanceof Object)) {
+ fail("ScriptUtils.unwrap does not return a ScriptObject");
+}
+
+// same object unwrapped?
+print(unwrapped === obj);
diff --git a/nashorn/test/script/basic/JDK-8027753.js.EXPECTED b/nashorn/test/script/basic/JDK-8027753.js.EXPECTED
new file mode 100644
index 00000000000..30a8779e98c
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8027753.js.EXPECTED
@@ -0,0 +1,3 @@
+wrapped.foo = 34
+wrapped.bar = hello
+true
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
index 99207de0d6e..55aacb3409f 100644
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
@@ -523,6 +523,18 @@ public class ScriptEngineTest {
assertEquals(sw.toString(), println("34 true hello"));
}
+ @Test
+ public void scriptObjectAutoConversionTest() throws ScriptException {
+ final ScriptEngineManager m = new ScriptEngineManager();
+ final ScriptEngine e = m.getEngineByName("nashorn");
+ e.eval("obj = { foo: 'hello' }");
+ e.put("Window", e.eval("Packages.jdk.nashorn.api.scripting.Window"));
+ assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
+ assertEquals(e.eval("Window.funcScriptObjectMirror(obj)"), "hello");
+ assertEquals(e.eval("Window.funcMap(obj)"), "hello");
+ assertEquals(e.eval("Window.funcJSObject(obj)"), "hello");
+ }
+
private static final String LINE_SEPARATOR = System.getProperty("line.separator");
// Returns String that would be the result of calling PrintWriter.println
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/Window.java b/nashorn/test/src/jdk/nashorn/api/scripting/Window.java
index bde2394119f..510c5daec75 100644
--- a/nashorn/test/src/jdk/nashorn/api/scripting/Window.java
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/Window.java
@@ -25,6 +25,9 @@
package jdk.nashorn.api.scripting;
+import java.util.Map;
+import javax.script.Bindings;
+
public class Window {
private String location = "http://localhost:8080/window";
@@ -63,4 +66,20 @@ public class Window {
System.out.println("window.setTimeout: " + delay + ", code: " + code);
return 0;
}
+
+ public static Object funcJSObject(final JSObject jsobj) {
+ return jsobj.getMember("foo");
+ }
+
+ public static Object funcScriptObjectMirror(final ScriptObjectMirror sobj) {
+ return sobj.get("foo");
+ }
+
+ public static Object funcMap(final Map,?> map) {
+ return map.get("foo");
+ }
+
+ public static Object funcBindings(final Bindings bindings) {
+ return bindings.get("foo");
+ }
}
From c8757a5edd29a16cd60b15ea972b23b403a52c59 Mon Sep 17 00:00:00 2001
From: Roland Westrelin
Date: Mon, 4 Nov 2013 21:59:54 +0100
Subject: [PATCH 18/88] 8027445: SIGSEGV at
TestFloatingDecimal.testAppendToDouble()I
String.equals() intrinsic shouldn't use integer length input in pointer arithmetic without an i2l.
Reviewed-by: kvn, twisti
---
hotspot/src/cpu/sparc/vm/sparc.ad | 6 ++
.../TestStringEqualsBadLength.java | 82 +++++++++++++++++++
2 files changed, 88 insertions(+)
create mode 100644 hotspot/test/compiler/intrinsics/stringequals/TestStringEqualsBadLength.java
diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad
index eadb0a8b60f..9d3856245f2 100644
--- a/hotspot/src/cpu/sparc/vm/sparc.ad
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad
@@ -2916,6 +2916,9 @@ enc_class Fast_Unlock(iRegP oop, iRegP box, o7RegP scratch, iRegP scratch2) %{
__ bind(LSkip2);
}
+ // We have no guarantee that on 64 bit the higher half of limit_reg is 0
+ __ signx(limit_reg);
+
__ subcc(limit_reg, 1 * sizeof(jchar), chr1_reg);
__ br(Assembler::equal, true, Assembler::pn, Ldone);
__ delayed()->mov(O7, result_reg); // result is difference in lengths
@@ -2973,6 +2976,9 @@ enc_class enc_String_Equals(o0RegP str1, o1RegP str2, g3RegI cnt, notemp_iRegI r
Register chr1_reg = result_reg;
Register chr2_reg = tmp1_reg;
+ // We have no guarantee that on 64 bit the higher half of limit_reg is 0
+ __ signx(limit_reg);
+
//check for alignment and position the pointers to the ends
__ or3(str1_reg, str2_reg, chr1_reg);
__ andcc(chr1_reg, 0x3, chr1_reg);
diff --git a/hotspot/test/compiler/intrinsics/stringequals/TestStringEqualsBadLength.java b/hotspot/test/compiler/intrinsics/stringequals/TestStringEqualsBadLength.java
new file mode 100644
index 00000000000..0de5175d286
--- /dev/null
+++ b/hotspot/test/compiler/intrinsics/stringequals/TestStringEqualsBadLength.java
@@ -0,0 +1,82 @@
+/*
+ * 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 8027445
+ * @summary String.equals() may be called with a length whose upper bits are not cleared
+ * @run main/othervm -XX:-UseOnStackReplacement -XX:-BackgroundCompilation TestStringEqualsBadLength
+ *
+ */
+
+import java.util.Arrays;
+
+public class TestStringEqualsBadLength {
+
+ int v1;
+ int v2;
+
+ boolean m(String s1) {
+ int l = v2 - v1; // 0 - (-1) = 1. On 64 bit: 0xffffffff00000001
+ char[] arr = new char[l];
+ arr[0] = 'a';
+ String s2 = new String(arr);
+ // The string length is not reloaded but the value computed is
+ // reused so pointer computation must not use
+ // 0xffffffff00000001
+ return s2.equals(s1);
+ }
+
+ // Same thing with String.compareTo()
+ int m2(String s1) {
+ int l = v2 - v1;
+ char[] arr = new char[l+1];
+ arr[0] = 'a';
+ arr[1] = 'b';
+ String s2 = new String(arr);
+ return s2.compareTo(s1);
+ }
+
+ // Same thing with equals() for arrays
+ boolean m3(char[] arr1) {
+ int l = v2 - v1; // 0 - (-1) = 1. On 64 bit: 0xffffffff00000001
+ char[] arr2 = new char[l];
+ arr2[0] = 'a';
+ return Arrays.equals(arr2, arr1);
+ }
+
+ static public void main(String[] args) {
+ TestStringEqualsBadLength tse = new TestStringEqualsBadLength();
+ tse.v1 = -1;
+ tse.v2 = 0;
+ char[] arr = new char[1];
+ arr[0] = 'a';
+ for (int i = 0; i < 20000; i++) {
+ tse.m("a");
+ tse.m2("ab");
+ tse.m3(arr);
+ }
+
+ System.out.println("TEST PASSED");
+ }
+}
From 989860b8c3aba2b674ac3f6cb1ad32194dd9f97d Mon Sep 17 00:00:00 2001
From: Christine Lu
Date: Mon, 4 Nov 2013 17:38:38 -0800
Subject: [PATCH 19/88] 8025844: Need test to provide coverage for new
DocumentationTool.Location enum
Reviewed-by: jjg
---
.../basic/DocumentationToolLocationTest.java | 73 +++++++++++++++++++
1 file changed, 73 insertions(+)
create mode 100644 langtools/test/tools/javadoc/api/basic/DocumentationToolLocationTest.java
diff --git a/langtools/test/tools/javadoc/api/basic/DocumentationToolLocationTest.java b/langtools/test/tools/javadoc/api/basic/DocumentationToolLocationTest.java
new file mode 100644
index 00000000000..c3334688cb0
--- /dev/null
+++ b/langtools/test/tools/javadoc/api/basic/DocumentationToolLocationTest.java
@@ -0,0 +1,73 @@
+/*
+ * 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 8025844
+ * @summary test DocumentationTool.Location methods
+ * @build APITest
+ * @run main DocumentationToolLocationTest
+ */
+
+import javax.tools.DocumentationTool;
+import java.util.Objects;
+
+/**
+ * Test for DocumentationTool.Location methods.
+ */
+public class DocumentationToolLocationTest extends APITest {
+ public static void main(String[] args) throws Exception {
+ new DocumentationToolLocationTest().run();
+ }
+
+ /**
+ * Test getName() method
+ */
+ @Test
+ public void testGetName() throws Exception {
+ // getName() returns name(). This is for test coverage of getName.
+ for (DocumentationTool.Location dl: DocumentationTool.Location.values()) {
+ String expect = dl.name();
+ String found = dl.getName();
+ if (!Objects.equals(expect, found))
+ throw new Exception("mismatch for " + dl + "; expected " + expect + ", found " + found);
+ }
+ }
+
+ /**
+ * Test generated enum methods values() and valueOf()
+ */
+ @Test
+ public void testEnumMethods() throws Exception {
+ DocumentationTool.Location[] values = DocumentationTool.Location.values();
+ if (values.length != 3)
+ throw new Exception("unexpected number of values returned");
+
+ for (DocumentationTool.Location dl: values) {
+ DocumentationTool.Location expect = dl;
+ DocumentationTool.Location found = DocumentationTool.Location.valueOf(dl.name());
+ if (!Objects.equals(expect, found))
+ throw new Exception("mismatch for " + dl + "; expected " + expect + ", found " + found);
+ }
+ }
+}
From 14c3c8b4fbc14a5fd8cfbe31bb173c4fd474ff9b Mon Sep 17 00:00:00 2001
From: Christine Lu
Date: Mon, 4 Nov 2013 18:04:34 -0800
Subject: [PATCH 20/88] 8027411: javap tonga tests cleanup: write a java
program to test invalid options -h and -b
Reviewed-by: jjg
---
.../test/tools/javap/InvalidOptions.java | 78 +++++++++++++++++++
1 file changed, 78 insertions(+)
create mode 100644 langtools/test/tools/javap/InvalidOptions.java
diff --git a/langtools/test/tools/javap/InvalidOptions.java b/langtools/test/tools/javap/InvalidOptions.java
new file mode 100644
index 00000000000..d92f644ba85
--- /dev/null
+++ b/langtools/test/tools/javap/InvalidOptions.java
@@ -0,0 +1,78 @@
+/*
+ * 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 8027411
+ * @summary test invalid options -h and -b
+ */
+
+import java.io.*;
+import java.util.zip.*;
+
+public class InvalidOptions {
+ int errorCount;
+ String log;
+
+ public static void main(String[] args) throws Exception {
+ new InvalidOptions().run();
+ }
+
+ void run() throws Exception {
+ test(2, "-h", "Error: -h is no longer available - use the javah program");
+ test(2, "-b", "Error: unknown option: -b",
+ "Usage: javap ",
+ "use -help for a list of possible options");
+ if (errorCount > 0)
+ throw new Exception(errorCount + " errors received");
+ }
+
+ void test(int expect, String option, String ... expectedOutput) {
+ String output = runJavap(expect, option);
+ verify(output, expectedOutput);
+ }
+
+ String runJavap(int expect, String... option) {
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ int rc = com.sun.tools.javap.Main.run(option, pw);
+ pw.close();
+ System.out.println("javap prints:");
+ System.out.println(sw);
+ if (rc != expect)
+ throw new Error("Expect to return " + expect + ", but return " + rc);
+ return sw.toString();
+ }
+
+ void verify(String output, String... expects) {
+ for (String expect: expects) {
+ if (!output.contains(expect))
+ error(expect + " not found");
+ }
+ }
+
+ void error(String msg) {
+ System.err.println(msg);
+ errorCount++;
+ }
+}
From 12da1db3d7dc86a538d6c357b429ed4c48e4db18 Mon Sep 17 00:00:00 2001
From: Christine Lu
Date: Mon, 4 Nov 2013 18:51:56 -0800
Subject: [PATCH 21/88] 8027530: javap tonga tests cleanup: test -public,
-protected, -package, -private options
Reviewed-by: jjg
---
.../test/tools/javap/AccessModifiers.java | 120 ++++++++++++++++++
1 file changed, 120 insertions(+)
create mode 100644 langtools/test/tools/javap/AccessModifiers.java
diff --git a/langtools/test/tools/javap/AccessModifiers.java b/langtools/test/tools/javap/AccessModifiers.java
new file mode 100644
index 00000000000..1791536c3d0
--- /dev/null
+++ b/langtools/test/tools/javap/AccessModifiers.java
@@ -0,0 +1,120 @@
+/*
+ * 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 8027530
+ * @summary test -public, -protected, -package, -private options
+ */
+
+import java.io.*;
+import java.util.*;
+import java.lang.StringBuilder;
+
+public class AccessModifiers {
+ public int errorCount;
+ protected String protectedField;
+ String packageField;
+ private String privateField;
+
+ public static void main(String[] args) throws Exception {
+ new AccessModifiers().run();
+ }
+
+ private void run() throws Exception {
+ List pubMembers = new ArrayList();
+ pubMembers.add("public int errorCount");
+ pubMembers.add("public AccessModifiers");
+ pubMembers.add("public static void main");
+
+ List proMembers = new ArrayList();
+ proMembers.add("protected java.lang.String protectedField");
+ proMembers.add("protected java.lang.String runJavap");
+
+ List pkgMembers = new ArrayList();
+ pkgMembers.add("java.lang.String packageField");
+ pkgMembers.add("boolean verify");
+ pkgMembers.add("void error");
+
+ List priMembers = new ArrayList();
+ priMembers.add("private java.lang.String privateField");
+ priMembers.add("private void run() throws java.lang.Exception");
+ priMembers.add("private void test");
+
+ List expectedList = new ArrayList();
+
+ expectedList.addAll(pubMembers);
+ test("-public", expectedList);
+
+ expectedList.addAll(proMembers);
+ test("-protected", expectedList);
+
+ expectedList.addAll(pkgMembers);
+ test("-package", expectedList);
+
+ expectedList.addAll(priMembers);
+ test("-private", expectedList);
+
+ if (errorCount > 0)
+ throw new Exception(errorCount + " errors received");
+ }
+
+ private void test(String option, List expectedStrs) throws Exception {
+ String output = runJavap(0, option);
+ if (verify(output, expectedStrs))
+ System.out.println(option + " test passed");
+ }
+
+ protected String runJavap(int expect, String... options) {
+ // convert the varargs to a list in order to add class name
+ List optlist = new ArrayList();
+ optlist.addAll(Arrays.asList(options));
+ optlist.add("AccessModifiers");
+ String[] newoptions = optlist.toArray(new String[optlist.size()]);
+ StringWriter sw = new StringWriter();
+ PrintWriter pw = new PrintWriter(sw);
+ System.out.printf("\nRun javap " + optlist + "\n\n");
+ int rc = com.sun.tools.javap.Main.run(newoptions, pw);
+ pw.close();
+ System.out.println(sw);
+ if (rc != expect)
+ throw new Error("Expect to return " + expect + ", but return " + rc);
+ return sw.toString();
+ }
+
+ boolean verify(String output, List expects) {
+ boolean pass = true;
+ for (String expect: expects) {
+ if (!output.contains(expect)) {
+ error(expect + " not found");
+ pass = false;
+ }
+ }
+ return pass;
+ }
+
+ void error(String msg) {
+ System.err.println(msg);
+ errorCount++;
+ }
+}
From 7899a729a95a8d9466cc0fb59d2c22cae790609c Mon Sep 17 00:00:00 2001
From: Igor Veresov
Date: Tue, 5 Nov 2013 00:59:30 -0800
Subject: [PATCH 22/88] 8027751: C1 crashes in Weblogic with G1 enabled
Keep T_OBJECT operands in registers for logical operations on x64
Reviewed-by: kvn, roland
---
hotspot/src/share/vm/c1/c1_LinearScan.cpp | 6 ++-
.../regalloc/C1ObjectSpillInLogicOp.java | 45 +++++++++++++++++++
2 files changed, 49 insertions(+), 2 deletions(-)
create mode 100644 hotspot/test/compiler/regalloc/C1ObjectSpillInLogicOp.java
diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp
index b7c04dbe825..52dff2642c1 100644
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp
@@ -1138,8 +1138,10 @@ IntervalUseKind LinearScan::use_kind_of_input_operand(LIR_Op* op, LIR_Opr opr) {
}
}
}
-
- } else if (opr_type != T_LONG) {
+ // We want to sometimes use logical operations on pointers, in particular in GC barriers.
+ // Since 64bit logical operations do not current support operands on stack, we have to make sure
+ // T_OBJECT doesn't get spilled along with T_LONG.
+ } else if (opr_type != T_LONG LP64_ONLY(&& opr_type != T_OBJECT)) {
// integer instruction (note: long operands must always be in register)
switch (op->code()) {
case lir_cmp:
diff --git a/hotspot/test/compiler/regalloc/C1ObjectSpillInLogicOp.java b/hotspot/test/compiler/regalloc/C1ObjectSpillInLogicOp.java
new file mode 100644
index 00000000000..d6976bd3bdf
--- /dev/null
+++ b/hotspot/test/compiler/regalloc/C1ObjectSpillInLogicOp.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.
+ */
+
+/*
+ * @test
+ * @bug 8027751
+ * @summary C1 crashes generating G1 post-barrier in Unsafe.getAndSetObject() intrinsic because of the new value spill
+ * @run main/othervm -XX:+UseG1GC C1ObjectSpillInLogicOp
+ *
+ * G1 barriers use logical operators (xor) on T_OBJECT mixed with T_LONG or T_INT.
+ * The current implementation of logical operations on x86 in C1 doesn't allow for long operands to be on stack.
+ * There is a special code in the register allocator that forces long arguments in registers on x86. However T_OBJECT
+ * can be spilled just fine, and in that case the xor emission will fail.
+ */
+
+import java.util.concurrent.atomic.*;
+class C1ObjectSpillInLogicOp {
+ static public void main(String[] args) {
+ AtomicReferenceArray x = new AtomicReferenceArray(128);
+ Integer y = new Integer(0);
+ for (int i = 0; i < 50000; i++) {
+ x.getAndSet(i % x.length(), y);
+ }
+ }
+}
From f78f47b98dff55aecec8020c194025b612aa1a8b Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Tue, 5 Nov 2013 13:09:40 +0400
Subject: [PATCH 23/88] 8027708: NASHORN TEST: Create Nashorn test that draws
image step-by-step using JavaFX canvas
Reviewed-by: jlaskey, lagergren
---
nashorn/make/build.xml | 7 +
nashorn/make/project.properties | 2 +-
nashorn/test/script/jfx.js | 37 ++-
nashorn/test/script/jfx/flyingimage.js | 33 +--
.../script/jfx/flyingimage/flyingimage.png | Bin 439 -> 1278 bytes
.../script/jfx/flyingimage/golden/linux.png | Bin 14754 -> 68179 bytes
.../script/jfx/flyingimage/golden/macosx.png | Bin 12298 -> 68361 bytes
.../script/jfx/flyingimage/golden/windows.png | Bin 9849 -> 68588 bytes
nashorn/test/script/jfx/kaleidoscope.js | 59 ++---
.../script/jfx/kaleidoscope/golden/linux.png | Bin 185802 -> 192428 bytes
.../script/jfx/kaleidoscope/golden/macosx.png | Bin 202995 -> 202987 bytes
.../jfx/kaleidoscope/golden/windows.png | Bin 202946 -> 192428 bytes
nashorn/test/script/jfx/spread.js | 222 ++++++++++++++++++
.../test/script/jfx/spread/golden/linux.png | Bin 0 -> 201159 bytes
.../test/script/jfx/spread/golden/macosx.png | Bin 0 -> 199251 bytes
.../test/script/jfx/spread/golden/windows.png | Bin 0 -> 201159 bytes
16 files changed, 303 insertions(+), 57 deletions(-)
create mode 100644 nashorn/test/script/jfx/spread.js
create mode 100644 nashorn/test/script/jfx/spread/golden/linux.png
create mode 100644 nashorn/test/script/jfx/spread/golden/macosx.png
create mode 100644 nashorn/test/script/jfx/spread/golden/windows.png
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index c90cdd6fe71..7d1f42aea0c 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -372,6 +372,12 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
+
+
+
+
+
+
@@ -380,6 +386,7 @@ grant codeBase "file:/${basedir}/test/script/basic/classloader.js" {
+
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index 33c94780249..c3ffca4ec68 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -230,7 +230,7 @@ testjfx.run.test.classpath=\
${file.reference.jemmyawtinput.jar}${path.separator}\
${file.reference.testng.jar}${path.separator}\
${nashorn.internal.tests.jar}${path.separator}\
- ${nashorn.api.tests.jar}
+ ${nashorn.api.tests.jar}
# testjfx VM options for script tests with @fork option
testjfx-test-sys-prop.test.fork.jvm.options=${run.test.jvmargs.main} -Xmx${run.test.xmx} -cp ${testjfx.run.test.classpath}
diff --git a/nashorn/test/script/jfx.js b/nashorn/test/script/jfx.js
index 26f97873456..5962b5d05ba 100644
--- a/nashorn/test/script/jfx.js
+++ b/nashorn/test/script/jfx.js
@@ -37,13 +37,24 @@ var ByWindowType = Java.type("org.jemmy.fx.ByWindowType");
var Scene = Java.type("javafx.scene.Scene");
var Stage = Java.type("javafx.stage.Stage");
var File = Java.type("java.io.File");
-var Timer = Java.type("java.util.Timer");
-var TimerTask = Java.type("java.util.TimerTask");
var OSInfo = Java.type("sun.awt.OSInfo");
var OSType = Java.type("sun.awt.OSInfo.OSType");
var StringBuffer = Java.type("java.lang.StringBuffer");
+var Paint = Java.type("javafx.scene.paint.Paint");
+var Color = Java.type("javafx.scene.paint.Color");
+var Image = Java.type("javafx.scene.image.Image");
+var Canvas = Java.type("javafx.scene.canvas.Canvas");
+var BorderPane = Java.type("javafx.scene.layout.BorderPane");
+var StackPane = Java.type("javafx.scene.layout.StackPane");
+var StrokeLineCap = Java.type("javafx.scene.shape.StrokeLineCap");
+var Platform = Java.type("javafx.application.Platform");
+var Runnable = Java.type("java.lang.Runnable");
+var RunnableExtend = Java.extend(Runnable);
+var AnimationTimer = Java.type("javafx.animation.AnimationTimer");
+var AnimationTimerExtend = Java.extend(AnimationTimer);
+var Timer = Java.type("java.util.Timer");
+var TimerTask = Java.type("java.util.TimerTask");
-var WAIT = 2000;
var TESTNAME = "test";
var fsep = System.getProperty("file.separator");
@@ -53,14 +64,16 @@ function checkImageAndExit() {
run: function run() {
var tmpdir = System.getProperty("java.io.tmpdir");
var timenow = (new Date()).getTime();
- makeScreenShot(tmpdir + fsep + "screenshot" + timenow +".png");
- var dupImg = isDuplicateImages(tmpdir + fsep + "screenshot" + timenow +".png", __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden");
- (new File(mpdir + fsep + "screenshot" + timenow +".png")).delete();
- if (!dupImg) System.err.println("ERROR: screenshot does not match golden image");
+ var scrShotTmp = tmpdir + fsep + "screenshot" + timenow +".png";
+ var goldenImageDir = __DIR__ + "jfx" + fsep + TESTNAME + fsep + "golden";
+ makeScreenShot(scrShotTmp);
+ var dupImg = isDuplicateImages(scrShotTmp, goldenImageDir);
+ (new File(scrShotTmp)).delete();
+ if (!dupImg) System.err.println("ERROR: screenshot does not match the golden image");
exit(0);
}
};
- raceTimer.schedule(timerTask, WAIT);
+ raceTimer.schedule(timerTask, 100);
}
function makeScreenShot(shootToImg) {
@@ -70,10 +83,10 @@ function makeScreenShot(shootToImg) {
imageJemmy.save(shootToImg);
}
-function isDuplicateImages(file1, file2) {
- var f1 = new File(file1);
+function isDuplicateImages(screenShot, goldenDir) {
+ var f1 = new File(screenShot);
var f2;
- var sb = new StringBuffer(file2);
+ var sb = new StringBuffer(goldenDir);
if (OSInfo.getOSType() == OSType.WINDOWS) {
f2 = new File(sb.append(fsep + "windows.png").toString());
} else if (OSInfo.getOSType() == OSType.LINUX) {
@@ -81,8 +94,6 @@ function isDuplicateImages(file1, file2) {
} else if (OSInfo.getOSType() == OSType.MACOSX) {
f2 = new File(sb.append(fsep + "macosx.png").toString());
}
- print(f1.getAbsolutePath());
- print(f2.getAbsolutePath());
if (f1.exists() && f2.exists()) {
var image1 = new AWTImage(PNGDecoder.decode(f1.getAbsolutePath()));
var image2 = new AWTImage(PNGDecoder.decode(f2.getAbsolutePath()));
diff --git a/nashorn/test/script/jfx/flyingimage.js b/nashorn/test/script/jfx/flyingimage.js
index 4cf3f7fcab0..844a0fc3c37 100644
--- a/nashorn/test/script/jfx/flyingimage.js
+++ b/nashorn/test/script/jfx/flyingimage.js
@@ -31,15 +31,6 @@
TESTNAME = "flyingimage";
-var Image = Java.type("javafx.scene.image.Image");
-var Color = Java.type("javafx.scene.paint.Color");
-var Canvas = Java.type("javafx.scene.canvas.Canvas");
-var BorderPane = Java.type("javafx.scene.layout.BorderPane");
-var StackPane = Java.type("javafx.scene.layout.StackPane");
-var Font = Java.type("javafx.scene.text.Font");
-var FontSmoothingType = Java.type("javafx.scene.text.FontSmoothingType");
-var Text = Java.type("javafx.scene.text.Text");
-
var WIDTH = 800;
var HEIGHT = 600;
var canvas = new Canvas(WIDTH, HEIGHT);
@@ -48,10 +39,9 @@ function fileToURL(file) {
}
var imageUrl = fileToURL(__DIR__ + "flyingimage/flyingimage.png");
var img = new Image(imageUrl);
-var font = new Font("Arial", 16);
-var t = 0;
var isFrameRendered = false;
function renderFrame() {
+ var t = frame;
var gc = canvas.graphicsContext2D;
gc.setFill(Color.web("#cccccc"));
gc.fillRect(0, 0, WIDTH, HEIGHT);
@@ -61,7 +51,7 @@ function renderFrame() {
var c = 200;
var msc= 0.5 * HEIGHT / img.height;
var sp0 = 0.003;
- for (var h = 0; h < c; h++, t++) {
+ for (var h = 0; h < c; h++) {
gc.setTransform(1, 0, 0, 1, 0, 0);
var yh = h / (c - 1);
gc.translate((0.5 + Math.sin(t * sp0 + h * 0.1) / 3) * WIDTH, 25 + (HEIGHT * 3 / 4 - 40) * (yh * yh));
@@ -69,15 +59,26 @@ function renderFrame() {
gc.rotate(90 * Math.sin(t * sp0 + h * 0.1 + Math.PI));
gc.scale(sc, sc);
gc.drawImage(img, -img.width / 2, -img.height / 2);
- }
+ }
gc.setTransform(1, 0, 0, 1, 0, 0);
isFrameRendered = true;
}
var stack = new StackPane();
var pane = new BorderPane();
-
pane.setCenter(canvas);
stack.getChildren().add(pane);
$STAGE.scene = new Scene(stack);
-renderFrame();
-checkImageAndExit();
+var frame = 0;
+var timer = new AnimationTimerExtend() {
+ handle: function handle(now) {
+ if (frame < 200) {
+ renderFrame();
+ frame++;
+ } else {
+ checkImageAndExit();
+ timer.stop();
+ }
+ }
+};
+timer.start();
+
diff --git a/nashorn/test/script/jfx/flyingimage/flyingimage.png b/nashorn/test/script/jfx/flyingimage/flyingimage.png
index ecd98a1445aa07983ac7a7caa73042d1d9840dbb..afc44dd3b9684ed3cbfcee573369d76afc46ff95 100644
GIT binary patch
literal 1278
zcmeAS@N?(olHy`uVBq!ia0vp^Ux4@~2OE$Smz5O*QjEnx?oJHr&dIz4a#+$GeH|GX
zHuiJ>Nn{1`ISV`@iy0XBj({-ZRBb+Kpqj~^E{-7;ac^%P418iB;u<(3AYvjz#BC0n;kn}>Me~~8-MCcX
zZTY{J)9OkXV|=pwHq{pj?wvn`c3+&gz`FcPhyF(O+$nFG{de*|DJj@{tme}1@AD7v
z?%n)_;mx@!RqID>_bzg5pDA4(-E{9@=1KRcFBj|X*>YAnFV^3-;kNJ>H=R%Fn={-m
z^zNK`&Um^R%iRgBd(ZW}5-L#^E4ACa%KZXw#D$`?u=WMoR=P`%#+>_eO}Io=Y@^)f
z7{3dm5eI&qDUozspYrjR;q9WPxPynbrXNdX**n4Yc3`UZ#NkA2Pwo3IFe5zT9QTx4d?35>5_
z;&}~^i{0*X&U)ARYw`m94JuzeE(o|>NZ&E{_v15mp!ob{fA7oRqOztojixq*rhkXl
z=lqra%fkwfM%$0yi~A;?4+3d}BNwT!&4!Nu9}DLNp`{7z++XvrFW>&MQ)KbHl?xO*
z5J=rlLb-84r}3xLkx;|qe^~FTUp#*yRL%d#*WcAy0{trDIRBxq|9Tc*7X63(P5TZs
zT~KzsY^#6Yzv*AA>q7IUW!Z7N?sNX);x3Lk_e>oeHV@P+FGA+b>+A$h}p5^M1bz+z~o`UKdIZdY8yK>ZcssmVE6qXBBJrwRw`$1;2QS
zt&`oXtNwyZC$2VaSI+|NjSXLCJS}QkcS31hdfRJ`U7IdDMV%^o28>+kjdMQF47F{_
zJFzG(-K~^!*T&0-qHfJUvy|5{|H!90qwX@6y$dhqFTGg*PnV;LU0HA2gzbtiWP3L}
zQQo)bTL~zm+1bWFaoF||lytwI-FGE)lX%_>=9hoXUjO~=|Derohg@Fn?~7q4`8ak7
zyK~?6%W=QZe8Z^7dV{*4nkx{XbS_fG8QGP`Qb@dg;!
N44$rjF6*2UngEk$ff@h+
diff --git a/nashorn/test/script/jfx/flyingimage/golden/linux.png b/nashorn/test/script/jfx/flyingimage/golden/linux.png
index 4f678853fe9bf3c5491992a106deb6ff4a9f258d..4a668a6d0e9e539c7011918536288e78deaeba39 100644
GIT binary patch
literal 68179
zcmYIvRa6~K7c8#9-QC>-1PSi$dT{8B
zLZhOhLj8+YYJS_|`<%1#CDpIEV&Qh*i;UECyuEEX({Hbi>+3_8$3N+B|Nr@UwD?#xKjHr*=;j45Of9FOFooG{GSZuHpki!%Rvw-~0Rw4shyGYn4U
z{n;CnxTyq}6p5d+1P-$oK|GqJswTWP`
zIZnDGrTE0?-YT#%F|zRR{>2P+t;Baq37w!6~vwdr!J8|hNuH9(rqS4?sCCl2XQopxLayl#Ul(sNn0vH
zL9~@|Xqsc55iZD4?XwzPT7X}Y|3hgL^bE2y6nNl{avvyKNDv-M+$vDh}vWnA2U
z>rQM?a)O#-6LwY^E>TY^xV$0bS-OFKzTzmc7RJ2~H6r3i`stMXq349tum}oD>vJ-5
z8OLGhE2ouPMWg(ZqBvuZIK{50)Hs-RNAfE9JJZfX(dl&4
zVkz@P_V|T{E_E4P_x8CoV4WeGSYuykK8
zMRa#4yw*l5eL>=;9k0;#>y*fLXQUhAncjz1lEMxogUgis_dL|yQfJ7&1-7=b=+Xb7
zK)yRZo0Y3=6WTUB=58Jm5+olQHrTZ-CKJ8W@3$46*m$-wkHZ`))tVTxQ9$0BUb6j9
z(WZq|iu;&vOi?A0csBJHG7(NjgDyAugP%Cf?tugU6hbksS}UjCNRS8jnk{#H0+m=n
zfn+P(4{F~|f+2m_B@tmL8wN;usN`qYLR}bW&DN{H+TTJk@=qmLiu_oDocOf8D}tZ7
zGGMW&GiJ!!@UguUk4y@>t@I`GU1U{xp7aZX{#N3&ea#|(R+?u9eP0wGM42P3uM=jt
zP}xKkv{WTa@w*tSUu1Gi!mOqS4J&Kw1xG})T{9Y$xl3BZDJt60>uSS+QoIc}W
z>w7<@FlUF4EsCb9c|ZEg-tE|1Z10L$P6t$YE)tPkT>g)mnokdUZY{1QhpIwy)NUVc
z=CWUQ2pNC1P7x{@I8qEW@;K(pKkDODSA<#MYWyba;dIuK-QMoi@{Rk=t$zLpFshf5
zw=1G+asMVZzbJeJ|0Y=I$ltHeGy2f}kggwT6D{4I<0D|rW_4#YIKB|Adr|eouZzow
zgef$uz!AZ;SMf#zZ=7B90})q(YexK~jh+-T`g@(&{gY8jSfTXYKCe!&66vO
zh@C+F9PwIXvLep%Q*%MgUTEzz&I%v#c#n%zK9jfr2Cg2ft`=5ntd)mH!?3Ny=Vd-C
zn2Xq{B$iWdbw`gnI?$3FPF34drq2ylq@?;NcU3VjyK(B}>Qai@BDYS}D-Neal-R+QOeTRjb+bh?@N|b7{yv#yQ@tU3^St68hkZ#$%PGL2sJFe*Wq-D=o+tm
z+hL#-i*sY@5W<9UYS2AjtUz5tnnvuVt8GM23Bl6qctf?(?;=`>2HY$|>9s&jvT$#Dq=(iJ){y#K~1a
zMwx`JO$m{87vtPy@_QxPAaSQicTlaeGf4bdcBl$VYV?oR!?i?F<3252uWh5=@`>CM
zdmru6(67s}p`v1rlj&)*bec<{SdGKiIqr!2L#~R6rXFm;n8bcWV>$J%{aH8SBK20F
z<;G-O_+(A3#G^{bx|lRF%2L1}P-?~)73An-xz4N!S@|kt7se4CN-|@#+
z4fv3#LQmf;J22->PVD>F`9R@jhK!Jm9H!y>R`r^dg^f)K)wQR9Z@)@1$|$Zoh{AFt
zFTF@B+RPulKw~E`g@hFPz|+*`hPZvpj}|PJi24RAX+&T6C6%D}TnO*Yqp+QfzBq^S
z_7kea`9+;UM(i?JJn^0-Mz)$7(Bdc`2n
zw*uy|AR`<|1r~Ah>Imgi77)C%XHR_cc|bdj*lxxaG$^cnqE0=IC}0$3s?3lKY_5fQ
zTjdyTtup*oYSXAdrzJ%Cja#=%wSJG>Aq}qT#i8Ou-DEWx<)ZURno(OBe?oJ#xa+jK
zUV;?;=hnQ}c(v6to1@zWn8LuYDC7#+rO_+_dBAIHE5uNnA?
zUjZp?SV@hG&q)mAW^qzJ`y-(wH}}*T1$Rxicuh_-__mz^uwfMcZIfc?{)9G-#am|2X43bRKz@uZ+E8@6NX~Lf%qZJ0OzFYhn7b(ej^!;
z(hIpp(y&O&=G?YJSxuagfOuBZQs~R<63B^hfGo&L!%AI=it5U0rks&_?DI~Y07Qvp
zv=z^Ye{kBF$=HGbWS@zVFSE@Gba5>{80O73*v$NTwO3pdxmmvGReRl~7i2DFuUus9
zp97j)GxK%dbr?$A;Zrp0d5}e?)4)T5x1Xqp`EFVl(y-QGi65sTDOs_41YbbG#c8@Bk88YsRV5%sOJce3PVkCX)3)7Koo<+HqVz88wPD?|}Sg=c#UYB4J%
zhljV)faZygm(NnMISdPacS#5daRliW9C(bHgRB$!vD*Y4(wNbFu0KU7EV_oBYH);p
zw|+@FTY*ZsZOx*HZL*j(0~%Psyf~!Y$uo>}H)H*8t7B{piV0N0`xzYXH%o0!Kfh(+
zkaeIuWc2V^!wGfU1ujYUkW7vo%DIX-oTf-R_>1)UCZZUerUhG>j{KQPDq0bk80WcB
zQhmj)1Vv7GZS2$tF_%jMR0Eur%@DZTuQ_qrmG6gA2(Nl3lYd53>^Vd6q}c6?>mO8*
zL|W%(bi<|3h#NfB`>DHXFL^=>(Q`Nk#}8Gkd7q7nU;R{w@9^}9mYtGX%nO4e@p{y<(Oott-G(@X>ZAtIzp%z`k@)D36c1Ya
zVE;q+Vb@*HD5-X_TbfE>3^Q0yzF1Fqhld;NZZ$%K4_{IpW7Pef=|XMenB#?>85z_q|UFqvMa3EDnL(6{<<^X-WVJ6Q#^I
z2d@QG(mR`9qi