From 2e5f47375207983e0a0e03435fd35f11df864862 Mon Sep 17 00:00:00 2001
From: Roland Westrelin
Date: Thu, 30 May 2013 11:21:01 +0200
Subject: [PATCH 001/206] 8015585: Missing regression test for 8011771
Missing regression test
Reviewed-by: kvn
---
.../test/compiler/8011771/Test8011771.java | 77 +++++++++++++++++++
1 file changed, 77 insertions(+)
create mode 100644 hotspot/test/compiler/8011771/Test8011771.java
diff --git a/hotspot/test/compiler/8011771/Test8011771.java b/hotspot/test/compiler/8011771/Test8011771.java
new file mode 100644
index 00000000000..7827150cb24
--- /dev/null
+++ b/hotspot/test/compiler/8011771/Test8011771.java
@@ -0,0 +1,77 @@
+/*
+ * 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 8011771
+ * @summary Array bound check elimination's in block motion doesn't always reset its data structures from one step to the other.
+ * @run main/othervm -XX:-BackgroundCompilation Test8011771
+ *
+ */
+
+public class Test8011771 {
+
+ static void m(int[] a, int[] b, int j) {
+ // Array bound check elimination inserts a predicate before
+ // the loop. We'll have the predicate fail, so the method is
+ // recompiled without optimistic optimizations
+ for (int i = 0; i < 10; i++) {
+ a[i] = i;
+ }
+
+ // The test itself
+ a[j] = 0;
+ a[j+5] = 0;
+ b[j+4] = 0; // this range check shouldn't be eliminated
+ }
+
+ static public void main(String[] args) {
+ int[] arr1 = new int[10], arr2 = new int[10];
+ // force compilation:
+ for (int i = 0; i < 5000; i++) {
+ m(arr1, arr2, 0);
+ }
+
+ try {
+ m(new int[1], null, 0); // force predicate failure
+ } catch(ArrayIndexOutOfBoundsException e) {}
+
+ // force compilation again (no optimistic opts):
+ for (int i = 0; i < 5000; i++) {
+ m(arr1, arr2, 0);
+ }
+
+ // Check that the range check on the second array wasn't optimized out
+ boolean success = false;
+ try {
+ m(arr1, new int[1], 0);
+ } catch(ArrayIndexOutOfBoundsException e) {
+ success = true;
+ }
+ if (success) {
+ System.out.println("TEST PASSED");
+ } else {
+ throw new RuntimeException("TEST FAILED: erroneous bound check elimination");
+ }
+ }
+}
From 337a9c1432aed56e04c020f541c183aa3b54e55d Mon Sep 17 00:00:00 2001
From: Christian Thalinger
Date: Thu, 30 May 2013 08:37:08 -0700
Subject: [PATCH 002/206] 8015266: fix some -Wsign-compare warnings in adlc
Reviewed-by: kvn
---
hotspot/src/share/vm/adlc/archDesc.cpp | 4 +-
hotspot/src/share/vm/adlc/dict2.cpp | 18 +++---
hotspot/src/share/vm/adlc/formssel.cpp | 83 ++++++++++++++------------
hotspot/src/share/vm/adlc/formssel.hpp | 16 ++---
hotspot/src/share/vm/adlc/output_c.cpp | 35 ++++++-----
5 files changed, 85 insertions(+), 71 deletions(-)
diff --git a/hotspot/src/share/vm/adlc/archDesc.cpp b/hotspot/src/share/vm/adlc/archDesc.cpp
index 7e272e4d028..412a728228a 100644
--- a/hotspot/src/share/vm/adlc/archDesc.cpp
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp
@@ -29,8 +29,8 @@
static FILE *errfile = stderr;
//--------------------------- utility functions -----------------------------
-inline char toUpper(char lower) {
- return (('a' <= lower && lower <= 'z') ? (lower + ('A'-'a')) : lower);
+inline char toUpper(char lower) {
+ return (('a' <= lower && lower <= 'z') ? ((char) (lower + ('A'-'a'))) : lower);
}
char *toUpper(const char *str) {
char *upper = new char[strlen(str)+1];
diff --git a/hotspot/src/share/vm/adlc/dict2.cpp b/hotspot/src/share/vm/adlc/dict2.cpp
index c7797c74223..24d7fcba023 100644
--- a/hotspot/src/share/vm/adlc/dict2.cpp
+++ b/hotspot/src/share/vm/adlc/dict2.cpp
@@ -64,18 +64,18 @@ void Dict::init() {
int i;
// Precompute table of null character hashes
- if( !initflag ) { // Not initializated yet?
- xsum[0] = (1<Amalloc_4(sizeof(bucket)*_size);
- memset(_bin,0,sizeof(bucket)*_size);
+ _bin = (bucket*)_arena->Amalloc_4(sizeof(bucket) * _size);
+ memset(_bin, 0, sizeof(bucket) * _size);
}
//------------------------------~Dict------------------------------------------
@@ -287,11 +287,11 @@ int hashstr(const void *t) {
register int sum = 0;
register const char *s = (const char *)t;
- while( ((c = s[k]) != '\0') && (k < MAXID-1) ) { // Get characters till nul
- c = (c<<1)+1; // Characters are always odd!
- sum += c + (c<> 1); // Hash key, un-modulo'd table size
}
diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp
index 42f1e3fad6f..27651dc68d7 100644
--- a/hotspot/src/share/vm/adlc/formssel.cpp
+++ b/hotspot/src/share/vm/adlc/formssel.cpp
@@ -796,11 +796,11 @@ uint InstructForm::num_opnds() {
return num_opnds;
}
-const char *InstructForm::opnd_ident(int idx) {
+const char* InstructForm::opnd_ident(int idx) {
return _components.at(idx)->_name;
}
-const char *InstructForm::unique_opnd_ident(int idx) {
+const char* InstructForm::unique_opnd_ident(uint idx) {
uint i;
for (i = 1; i < num_opnds(); ++i) {
if (unique_opnds_idx(i) == idx) {
@@ -1315,36 +1315,36 @@ void InstructForm::rep_var_format(FILE *fp, const char *rep_var) {
// Seach through operands to determine parameters unique positions.
void InstructForm::set_unique_opnds() {
uint* uniq_idx = NULL;
- int nopnds = num_opnds();
+ uint nopnds = num_opnds();
uint num_uniq = nopnds;
- int i;
+ uint i;
_uniq_idx_length = 0;
- if ( nopnds > 0 ) {
+ if (nopnds > 0) {
// Allocate index array. Worst case we're mapping from each
// component back to an index and any DEF always goes at 0 so the
// length of the array has to be the number of components + 1.
_uniq_idx_length = _components.count() + 1;
- uniq_idx = (uint*) malloc(sizeof(uint)*(_uniq_idx_length));
- for( i = 0; i < _uniq_idx_length; i++ ) {
+ uniq_idx = (uint*) malloc(sizeof(uint) * _uniq_idx_length);
+ for (i = 0; i < _uniq_idx_length; i++) {
uniq_idx[i] = i;
}
}
// Do it only if there is a match rule and no expand rule. With an
// expand rule it is done by creating new mach node in Expand()
// method.
- if ( nopnds > 0 && _matrule != NULL && _exprule == NULL ) {
+ if (nopnds > 0 && _matrule != NULL && _exprule == NULL) {
const char *name;
uint count;
bool has_dupl_use = false;
_parameters.reset();
- while( (name = _parameters.iter()) != NULL ) {
+ while ((name = _parameters.iter()) != NULL) {
count = 0;
- int position = 0;
- int uniq_position = 0;
+ uint position = 0;
+ uint uniq_position = 0;
_components.reset();
Component *comp = NULL;
- if( sets_result() ) {
+ if (sets_result()) {
comp = _components.iter();
position++;
}
@@ -1352,11 +1352,11 @@ void InstructForm::set_unique_opnds() {
for (; (comp = _components.iter()) != NULL; ++position) {
// When the first component is not a DEF,
// leave space for the result operand!
- if ( position==0 && (! comp->isa(Component::DEF)) ) {
+ if (position==0 && (!comp->isa(Component::DEF))) {
++position;
}
- if( strcmp(name, comp->_name)==0 ) {
- if( ++count > 1 ) {
+ if (strcmp(name, comp->_name) == 0) {
+ if (++count > 1) {
assert(position < _uniq_idx_length, "out of bounds");
uniq_idx[position] = uniq_position;
has_dupl_use = true;
@@ -1364,22 +1364,25 @@ void InstructForm::set_unique_opnds() {
uniq_position = position;
}
}
- if( comp->isa(Component::DEF)
- && comp->isa(Component::USE) ) {
+ if (comp->isa(Component::DEF) && comp->isa(Component::USE)) {
++position;
- if( position != 1 )
+ if (position != 1)
--position; // only use two slots for the 1st USE_DEF
}
}
}
- if( has_dupl_use ) {
- for( i = 1; i < nopnds; i++ )
- if( i != uniq_idx[i] )
+ if (has_dupl_use) {
+ for (i = 1; i < nopnds; i++) {
+ if (i != uniq_idx[i]) {
break;
- int j = i;
- for( ; i < nopnds; i++ )
- if( i == uniq_idx[i] )
+ }
+ }
+ uint j = i;
+ for (; i < nopnds; i++) {
+ if (i == uniq_idx[i]) {
uniq_idx[i] = j++;
+ }
+ }
num_uniq = j;
}
}
@@ -2216,21 +2219,27 @@ RegClass* OperandForm::get_RegClass() const {
bool OperandForm::is_bound_register() const {
- RegClass *reg_class = get_RegClass();
- if (reg_class == NULL) return false;
+ RegClass* reg_class = get_RegClass();
+ if (reg_class == NULL) {
+ return false;
+ }
- const char * name = ideal_type(globalAD->globalNames());
- if (name == NULL) return false;
+ const char* name = ideal_type(globalAD->globalNames());
+ if (name == NULL) {
+ return false;
+ }
- int size = 0;
- if (strcmp(name,"RegFlags")==0) size = 1;
- if (strcmp(name,"RegI")==0) size = 1;
- if (strcmp(name,"RegF")==0) size = 1;
- if (strcmp(name,"RegD")==0) size = 2;
- if (strcmp(name,"RegL")==0) size = 2;
- if (strcmp(name,"RegN")==0) size = 1;
- if (strcmp(name,"RegP")==0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
- if (size == 0) return false;
+ uint size = 0;
+ if (strcmp(name, "RegFlags") == 0) size = 1;
+ if (strcmp(name, "RegI") == 0) size = 1;
+ if (strcmp(name, "RegF") == 0) size = 1;
+ if (strcmp(name, "RegD") == 0) size = 2;
+ if (strcmp(name, "RegL") == 0) size = 2;
+ if (strcmp(name, "RegN") == 0) size = 1;
+ if (strcmp(name, "RegP") == 0) size = globalAD->get_preproc_def("_LP64") ? 2 : 1;
+ if (size == 0) {
+ return false;
+ }
return size == reg_class->size();
}
diff --git a/hotspot/src/share/vm/adlc/formssel.hpp b/hotspot/src/share/vm/adlc/formssel.hpp
index 6f2975fc3a3..622d8902f45 100644
--- a/hotspot/src/share/vm/adlc/formssel.hpp
+++ b/hotspot/src/share/vm/adlc/formssel.hpp
@@ -106,7 +106,7 @@ public:
const char *_ins_pipe; // Instruction Scheduling description class
uint *_uniq_idx; // Indexes of unique operands
- int _uniq_idx_length; // Length of _uniq_idx array
+ uint _uniq_idx_length; // Length of _uniq_idx array
uint _num_uniq; // Number of unique operands
ComponentList _components; // List of Components matches MachNode's
// operand structure
@@ -272,14 +272,14 @@ public:
void set_unique_opnds();
uint num_unique_opnds() { return _num_uniq; }
uint unique_opnds_idx(int idx) {
- if( _uniq_idx != NULL && idx > 0 ) {
- assert(idx < _uniq_idx_length, "out of bounds");
- return _uniq_idx[idx];
- } else {
- return idx;
- }
+ if (_uniq_idx != NULL && idx > 0) {
+ assert((uint)idx < _uniq_idx_length, "out of bounds");
+ return _uniq_idx[idx];
+ } else {
+ return idx;
+ }
}
- const char *unique_opnd_ident(int idx); // Name of operand at unique idx.
+ const char *unique_opnd_ident(uint idx); // Name of operand at unique idx.
// Operands which are only KILLs aren't part of the input array and
// require special handling in some cases. Their position in this
diff --git a/hotspot/src/share/vm/adlc/output_c.cpp b/hotspot/src/share/vm/adlc/output_c.cpp
index f86dd21fc3b..a9bd95177eb 100644
--- a/hotspot/src/share/vm/adlc/output_c.cpp
+++ b/hotspot/src/share/vm/adlc/output_c.cpp
@@ -463,8 +463,9 @@ static int pipeline_res_mask_initializer(
uint resources_used_exclusively = 0;
for (pipeclass->_resUsage.reset();
- (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; )
+ (piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
element_count++;
+ }
// Pre-compute the string length
int templen;
@@ -482,8 +483,8 @@ static int pipeline_res_mask_initializer(
for (i = rescount; i > 0; i /= 10)
maskdigit++;
- static const char * pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
- static const char * pipeline_use_element = "Pipeline_Use_Element";
+ static const char* pipeline_use_cycle_mask = "Pipeline_Use_Cycle_Mask";
+ static const char* pipeline_use_element = "Pipeline_Use_Element";
templen = 1 +
(int)(strlen(pipeline_use_cycle_mask) + (int)strlen(pipeline_use_element) +
@@ -496,11 +497,12 @@ static int pipeline_res_mask_initializer(
templen = 0;
for (pipeclass->_resUsage.reset();
- (piperesource = (const PipeClassResourceForm *)pipeclass->_resUsage.iter()) != NULL; ) {
+ (piperesource = (const PipeClassResourceForm*)pipeclass->_resUsage.iter()) != NULL; ) {
int used_mask = pipeline->_resdict[piperesource->_resource]->is_resource()->mask();
- if (!used_mask)
+ if (!used_mask) {
fprintf(stderr, "*** used_mask is 0 ***\n");
+ }
resources_used |= used_mask;
@@ -509,8 +511,9 @@ static int pipeline_res_mask_initializer(
for (lb = 0; (used_mask & (1 << lb)) == 0; lb++);
for (ub = 31; (used_mask & (1 << ub)) == 0; ub--);
- if (lb == ub)
+ if (lb == ub) {
resources_used_exclusively |= used_mask;
+ }
int formatlen =
sprintf(&resource_mask[templen], " %s(0x%0*x, %*d, %*d, %s %s(",
@@ -526,7 +529,7 @@ static int pipeline_res_mask_initializer(
int cycles = piperesource->_cycles;
uint stage = pipeline->_stages.index(piperesource->_stage);
- if (NameList::Not_in_list == stage) {
+ if ((uint)NameList::Not_in_list == stage) {
fprintf(stderr,
"pipeline_res_mask_initializer: "
"semantic error: "
@@ -534,8 +537,8 @@ static int pipeline_res_mask_initializer(
piperesource->_stage);
exit(1);
}
- uint upper_limit = stage+cycles-1;
- uint lower_limit = stage-1;
+ uint upper_limit = stage + cycles - 1;
+ uint lower_limit = stage - 1;
uint upper_idx = upper_limit >> 5;
uint lower_idx = lower_limit >> 5;
uint upper_position = upper_limit & 0x1f;
@@ -543,7 +546,7 @@ static int pipeline_res_mask_initializer(
uint mask = (((uint)1) << upper_position) - 1;
- while ( upper_idx > lower_idx ) {
+ while (upper_idx > lower_idx) {
res_mask[upper_idx--] |= mask;
mask = (uint)-1;
}
@@ -565,8 +568,9 @@ static int pipeline_res_mask_initializer(
}
resource_mask[templen] = 0;
- if (last_comma)
+ if (last_comma) {
last_comma[0] = ' ';
+ }
// See if the same string is in the table
int ndx = pipeline_res_mask.index(resource_mask);
@@ -580,7 +584,7 @@ static int pipeline_res_mask_initializer(
fprintf(fp_cpp, "static const Pipeline_Use_Element pipeline_res_mask_%03d[%d] = {\n%s};\n\n",
ndx+1, element_count, resource_mask);
- char * args = new char [9 + 2*masklen + maskdigit];
+ char* args = new char [9 + 2*masklen + maskdigit];
sprintf(args, "0x%0*x, 0x%0*x, %*d",
masklen, resources_used,
@@ -589,8 +593,9 @@ static int pipeline_res_mask_initializer(
pipeline_res_args.addName(args);
}
- else
+ else {
delete [] resource_mask;
+ }
delete [] res_mask;
//delete [] res_masks;
@@ -1787,7 +1792,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
// Skip first unique operands.
for( i = 1; i < cur_num_opnds; i++ ) {
comp = node->_components.iter();
- if( (int)i != node->unique_opnds_idx(i) ) {
+ if (i != node->unique_opnds_idx(i)) {
break;
}
new_num_opnds++;
@@ -1795,7 +1800,7 @@ void ArchDesc::defineExpand(FILE *fp, InstructForm *node) {
// Replace not unique operands with next unique operands.
for( ; i < cur_num_opnds; i++ ) {
comp = node->_components.iter();
- int j = node->unique_opnds_idx(i);
+ uint j = node->unique_opnds_idx(i);
// unique_opnds_idx(i) is unique if unique_opnds_idx(j) is not unique.
if( j != node->unique_opnds_idx(j) ) {
fprintf(fp," set_opnd_array(%d, opnd_array(%d)->clone(C)); // %s\n",
From 6a17746b6cbb6d30cb42cf1e115e99d7789f3b5b Mon Sep 17 00:00:00 2001
From: Roland Westrelin
Date: Fri, 31 May 2013 14:40:26 +0200
Subject: [PATCH 003/206] 8009981: nashorn tests fail with -XX:+VerifyStack
Nmethod::preserve_callee_argument_oops() must take appendix into account.
Reviewed-by: kvn, twisti
---
hotspot/src/share/vm/code/nmethod.cpp | 7 +++----
hotspot/src/share/vm/runtime/deoptimization.cpp | 15 ++++++++++-----
hotspot/src/share/vm/runtime/frame.cpp | 16 +++++++++++-----
hotspot/src/share/vm/runtime/frame.hpp | 2 +-
hotspot/src/share/vm/runtime/sharedRuntime.cpp | 7 ++++++-
hotspot/src/share/vm/runtime/sharedRuntime.hpp | 2 +-
6 files changed, 32 insertions(+), 17 deletions(-)
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 597a7ac548e..53f8cd07be8 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -1976,11 +1976,10 @@ void nmethod::preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map
if (!method()->is_native()) {
SimpleScopeDesc ssd(this, fr.pc());
Bytecode_invoke call(ssd.method(), ssd.bci());
- // compiled invokedynamic call sites have an implicit receiver at
- // resolution time, so make sure it gets GC'ed.
- bool has_receiver = !call.is_invokestatic();
+ bool has_receiver = call.has_receiver();
+ bool has_appendix = call.has_appendix();
Symbol* signature = call.signature();
- fr.oops_compiled_arguments_do(signature, has_receiver, reg_map, f);
+ fr.oops_compiled_arguments_do(signature, has_receiver, has_appendix, reg_map, f);
}
#endif // !SHARK
}
diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp
index 4a8d52b1284..7f71c2d8b76 100644
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp
@@ -635,18 +635,22 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
// at an uncommon trap for an invoke (where the compiler
// generates debug info before the invoke has executed)
Bytecodes::Code cur_code = str.next();
- if (cur_code == Bytecodes::_invokevirtual ||
- cur_code == Bytecodes::_invokespecial ||
- cur_code == Bytecodes::_invokestatic ||
- cur_code == Bytecodes::_invokeinterface) {
+ if (cur_code == Bytecodes::_invokevirtual ||
+ cur_code == Bytecodes::_invokespecial ||
+ cur_code == Bytecodes::_invokestatic ||
+ cur_code == Bytecodes::_invokeinterface ||
+ cur_code == Bytecodes::_invokedynamic) {
Bytecode_invoke invoke(mh, iframe->interpreter_frame_bci());
Symbol* signature = invoke.signature();
ArgumentSizeComputer asc(signature);
cur_invoke_parameter_size = asc.size();
- if (cur_code != Bytecodes::_invokestatic) {
+ if (invoke.has_receiver()) {
// Add in receiver
++cur_invoke_parameter_size;
}
+ if (i != 0 && !invoke.is_invokedynamic() && MethodHandles::has_member_arg(invoke.klass(), invoke.name())) {
+ callee_size_of_parameters++;
+ }
}
if (str.bci() < max_bci) {
Bytecodes::Code bc = str.next();
@@ -661,6 +665,7 @@ JRT_LEAF(BasicType, Deoptimization::unpack_frames(JavaThread* thread, int exec_m
case Bytecodes::_invokespecial:
case Bytecodes::_invokestatic:
case Bytecodes::_invokeinterface:
+ case Bytecodes::_invokedynamic:
case Bytecodes::_athrow:
break;
default: {
diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp
index e1913829702..e5caf604d98 100644
--- a/hotspot/src/share/vm/runtime/frame.cpp
+++ b/hotspot/src/share/vm/runtime/frame.cpp
@@ -1008,6 +1008,7 @@ class CompiledArgumentOopFinder: public SignatureInfo {
OopClosure* _f;
int _offset; // the current offset, incremented with each argument
bool _has_receiver; // true if the callee has a receiver
+ bool _has_appendix; // true if the call has an appendix
frame _fr;
RegisterMap* _reg_map;
int _arg_size;
@@ -1027,19 +1028,20 @@ class CompiledArgumentOopFinder: public SignatureInfo {
}
public:
- CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, OopClosure* f, frame fr, const RegisterMap* reg_map)
+ CompiledArgumentOopFinder(Symbol* signature, bool has_receiver, bool has_appendix, OopClosure* f, frame fr, const RegisterMap* reg_map)
: SignatureInfo(signature) {
// initialize CompiledArgumentOopFinder
_f = f;
_offset = 0;
_has_receiver = has_receiver;
+ _has_appendix = has_appendix;
_fr = fr;
_reg_map = (RegisterMap*)reg_map;
- _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0);
+ _arg_size = ArgumentSizeComputer(signature).size() + (has_receiver ? 1 : 0) + (has_appendix ? 1 : 0);
int arg_size;
- _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, &arg_size);
+ _regs = SharedRuntime::find_callee_arguments(signature, has_receiver, has_appendix, &arg_size);
assert(arg_size == _arg_size, "wrong arg size");
}
@@ -1049,12 +1051,16 @@ class CompiledArgumentOopFinder: public SignatureInfo {
_offset++;
}
iterate_parameters();
+ if (_has_appendix) {
+ handle_oop_offset();
+ _offset++;
+ }
}
};
-void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f) {
+void frame::oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f) {
ResourceMark rm;
- CompiledArgumentOopFinder finder(signature, has_receiver, f, *this, reg_map);
+ CompiledArgumentOopFinder finder(signature, has_receiver, has_appendix, f, *this, reg_map);
finder.oops_do();
}
diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp
index 2e27430f7fb..1baa38fb6c3 100644
--- a/hotspot/src/share/vm/runtime/frame.hpp
+++ b/hotspot/src/share/vm/runtime/frame.hpp
@@ -411,7 +411,7 @@ class frame VALUE_OBJ_CLASS_SPEC {
oop* oopmapreg_to_location(VMReg reg, const RegisterMap* regmap) const;
// Oops-do's
- void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
+ void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, bool has_appendix, const RegisterMap* reg_map, OopClosure* f);
void oops_interpreted_do(OopClosure* f, CLDToOopClosure* cld_f, const RegisterMap* map, bool query_oop_map_cache = true);
private:
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index 114f27d20a8..fe55e8b0e6b 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -2726,7 +2726,7 @@ VMReg SharedRuntime::name_for_receiver() {
return regs.first();
}
-VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, int* arg_size) {
+VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int* arg_size) {
// This method is returning a data structure allocating as a
// ResourceObject, so do not put any ResourceMarks in here.
char *s = sig->as_C_string();
@@ -2770,6 +2770,11 @@ VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver,
default : ShouldNotReachHere();
}
}
+
+ if (has_appendix) {
+ sig_bt[cnt++] = T_OBJECT;
+ }
+
assert( cnt < 256, "grow table size" );
int comp_args_on_stack;
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp
index e6867645ae6..a7f0d92a1fb 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp
@@ -410,7 +410,7 @@ class SharedRuntime: AllStatic {
// Convert a sig into a calling convention register layout
// and find interesting things about it.
- static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, int *arg_size);
+ static VMRegPair* find_callee_arguments(Symbol* sig, bool has_receiver, bool has_appendix, int *arg_size);
static VMReg name_for_receiver();
// "Top of Stack" slots that may be unused by the calling convention but must
From ff008d061551555640074f1acbfcadf3ef23cf1e Mon Sep 17 00:00:00 2001
From: Vladimir Kozlov
Date: Fri, 31 May 2013 13:54:47 -0700
Subject: [PATCH 004/206] 8015441: runThese crashed with assert(opcode ==
Op_ConP || opcode == Op_ThreadLocal || opcode == Op_CastX2P ..) failed:
sanity
Relax the assert to accept any raw ptr types.
Reviewed-by: roland
---
hotspot/src/share/vm/opto/escape.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index f29f82b3539..96f0011b3b2 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -2202,7 +2202,7 @@ Node* ConnectionGraph::get_addp_base(Node *addp) {
int opcode = uncast_base->Opcode();
assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
opcode == Op_CastX2P || uncast_base->is_DecodeNarrowPtr() ||
- (uncast_base->is_Mem() && uncast_base->bottom_type() == TypeRawPtr::NOTNULL) ||
+ (uncast_base->is_Mem() && (uncast_base->bottom_type()->isa_rawptr() != NULL)) ||
(uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
}
return base;
From 34f8be0bc97c236d84fdd528c7ba63a3bd168e4b Mon Sep 17 00:00:00 2001
From: Albert Noll
Date: Fri, 31 May 2013 06:41:50 +0200
Subject: [PATCH 005/206] 8013496: Code cache management command line options
work only in special order. Another order of arguments does not deliver the
second parameter to the jvm
Moved check that ReservedCodeCacheSize >= InitialCodeCacheSize to Arguments::check_vm_args_consistency(). As a result, the ordering in which the two parameters are given to the VM is not relevant. Added a regression test.
Reviewed-by: kvn, twisti
---
hotspot/src/share/vm/runtime/arguments.cpp | 14 +++--
hotspot/test/compiler/8013496/Test8013496.sh | 55 ++++++++++++++++++++
2 files changed, 64 insertions(+), 5 deletions(-)
create mode 100644 hotspot/test/compiler/8013496/Test8013496.sh
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 83f4660a0c7..7cfd7a42eb7 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -2217,6 +2217,13 @@ bool Arguments::check_vm_args_consistency() {
status = false;
}
+ if (ReservedCodeCacheSize < InitialCodeCacheSize) {
+ jio_fprintf(defaultStream::error_stream(),
+ "Invalid ReservedCodeCacheSize: %dK. Should be greater than InitialCodeCacheSize=%dK\n",
+ ReservedCodeCacheSize/K, InitialCodeCacheSize/K);
+ status = false;
+ }
+
return status;
}
@@ -2619,13 +2626,10 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args,
} else if (match_option(option, "-Xmaxjitcodesize", &tail) ||
match_option(option, "-XX:ReservedCodeCacheSize=", &tail)) {
julong long_ReservedCodeCacheSize = 0;
- ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize,
- (size_t)InitialCodeCacheSize);
+ ArgsRange errcode = parse_memory_size(tail, &long_ReservedCodeCacheSize, 1);
if (errcode != arg_in_range) {
jio_fprintf(defaultStream::error_stream(),
- "Invalid maximum code cache size: %s. Should be greater than InitialCodeCacheSize=%dK\n",
- option->optionString, InitialCodeCacheSize/K);
- describe_range_error(errcode);
+ "Invalid maximum code cache size: %s.\n", option->optionString);
return JNI_EINVAL;
}
FLAG_SET_CMDLINE(uintx, ReservedCodeCacheSize, (uintx)long_ReservedCodeCacheSize);
diff --git a/hotspot/test/compiler/8013496/Test8013496.sh b/hotspot/test/compiler/8013496/Test8013496.sh
new file mode 100644
index 00000000000..ae1d1fe34ff
--- /dev/null
+++ b/hotspot/test/compiler/8013496/Test8013496.sh
@@ -0,0 +1,55 @@
+#!/bin/sh
+#
+# 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 8013496
+# @summary Test checks that the order in which ReversedCodeCacheSize and
+# InitialCodeCacheSize are passed to the VM is irrelevant.
+# @run shell Test8013496.sh
+#
+#
+## some tests require path to find test source dir
+if [ "${TESTSRC}" = "" ]
+then
+ TESTSRC=${PWD}
+ echo "TESTSRC not set. Using "${TESTSRC}" as default"
+fi
+echo "TESTSRC=${TESTSRC}"
+## Adding common setup Variables for running shell tests.
+. ${TESTSRC}/../../test_env.sh
+set -x
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:ReservedCodeCacheSize=2m -XX:InitialCodeCacheSize=500K -version > 1.out 2>&1
+${TESTJAVA}/bin/java ${TESTVMOPTS} -XX:InitialCodeCacheSize=500K -XX:ReservedCodeCacheSize=2m -version > 2.out 2>&1
+
+diff 1.out 2.out
+
+result=$?
+if [ $result -eq 0 ] ; then
+ echo "Test Passed"
+ exit 0
+else
+ echo "Test Failed"
+ exit 1
+fi
From 6ae26f2e9424d37ab38a051ab2a75cba46f0e9d0 Mon Sep 17 00:00:00 2001
From: Roland Westrelin
Date: Wed, 24 Apr 2013 11:49:38 +0200
Subject: [PATCH 006/206] 8010460: Interpreter on some platforms loads
ConstMethod::_max_stack and misses extra stack slots for JSR 292
ConstMethod::max_stack() doesn't account for JSR 292 appendix.
Reviewed-by: kvn
---
.../src/cpu/sparc/vm/cppInterpreter_sparc.cpp | 11 +++-------
.../src/cpu/sparc/vm/interp_masm_sparc.cpp | 2 +-
.../sparc/vm/templateInterpreter_sparc.cpp | 3 +--
hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp | 15 +++++---------
.../cpu/x86/vm/templateInterpreter_x86_32.cpp | 3 +--
.../cpu/x86/vm/templateInterpreter_x86_64.cpp | 3 +--
.../vm/interpreter/bytecodeInterpreter.cpp | 20 ++++++++++++++++++-
hotspot/src/share/vm/oops/method.hpp | 14 +++++++------
hotspot/src/share/vm/opto/matcher.cpp | 10 ----------
9 files changed, 39 insertions(+), 42 deletions(-)
diff --git a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
index 8a71d0923ab..5750e5f587f 100644
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
@@ -1065,7 +1065,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
const int slop_factor = 2*wordSize;
const int fixed_size = ((sizeof(BytecodeInterpreter) + slop_factor) >> LogBytesPerWord) + // what is the slop factor?
- //6815692//Method::extra_stack_words() + // extra push slots for MH adapters
+ Method::extra_stack_entries() + // extra stack for jsr 292
frame::memory_parameter_word_sp_offset + // register save area + param window
(native ? frame::interpreter_frame_extra_outgoing_argument_words : 0); // JNI, class
@@ -1221,9 +1221,7 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
// Full size expression stack
__ ld_ptr(constMethod, O3);
__ lduh(O3, in_bytes(ConstMethod::max_stack_offset()), O3);
- guarantee(!EnableInvokeDynamic, "no support yet for java.lang.invoke.MethodHandle"); //6815692
- //6815692//if (EnableInvokeDynamic)
- //6815692// __ inc(O3, Method::extra_stack_entries());
+ __ inc(O3, Method::extra_stack_entries());
__ sll(O3, LogBytesPerWord, O3);
__ sub(O2, O3, O3);
// __ sub(O3, wordSize, O3); // so prepush doesn't look out of bounds
@@ -2084,9 +2082,7 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo
const int fixed_size = sizeof(BytecodeInterpreter)/wordSize + // interpreter state object
frame::memory_parameter_word_sp_offset; // register save area + param window
- const int extra_stack = 0; //6815692//Method::extra_stack_entries();
return (round_to(max_stack +
- extra_stack +
slop_factor +
fixed_size +
monitor_size +
@@ -2173,8 +2169,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
// Need +1 here because stack_base points to the word just above the first expr stack entry
// and stack_limit is supposed to point to the word just below the last expr stack entry.
// See generate_compute_interpreter_state.
- int extra_stack = 0; //6815692//Method::extra_stack_entries();
- to_fill->_stack_limit = stack_base - (method->max_stack() + 1 + extra_stack);
+ to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
// sparc specific
diff --git a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
index d4f8b9b2341..9775d2f871a 100644
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
@@ -521,7 +521,7 @@ void InterpreterMacroAssembler::empty_expression_stack() {
// Compute max expression stack+register save area
ld_ptr(Lmethod, in_bytes(Method::const_offset()), Gframe_size);
lduh(Gframe_size, in_bytes(ConstMethod::max_stack_offset()), Gframe_size); // Load max stack.
- add( Gframe_size, frame::memory_parameter_word_sp_offset, Gframe_size );
+ add(Gframe_size, frame::memory_parameter_word_sp_offset+Method::extra_stack_entries(), Gframe_size );
//
// now set up a stack frame with the size computed above
diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index d8281cadaec..135760ec0b4 100644
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -507,7 +507,7 @@ void TemplateInterpreterGenerator::generate_fixed_frame(bool native_call) {
const int extra_space =
rounded_vm_local_words + // frame local scratch space
- //6815692//Method::extra_stack_words() + // extra push slots for MH adapters
+ Method::extra_stack_entries() + // extra stack for jsr 292
frame::memory_parameter_word_sp_offset + // register save area
(native_call ? frame::interpreter_frame_extra_outgoing_argument_words : 0);
@@ -1558,7 +1558,6 @@ static int size_activation_helper(int callee_extra_locals, int max_stack, int mo
round_to(callee_extra_locals * Interpreter::stackElementWords, WordsPerLong);
const int max_stack_words = max_stack * Interpreter::stackElementWords;
return (round_to((max_stack_words
- //6815692//+ Method::extra_stack_words()
+ rounded_vm_local_words
+ frame::memory_parameter_word_sp_offset), WordsPerLong)
// already rounded
diff --git a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
index 08db8e074d0..1eef095b9a5 100644
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
@@ -539,12 +539,11 @@ void CppInterpreterGenerator::generate_compute_interpreter_state(const Register
// compute full expression stack limit
- const int extra_stack = 0; //6815692//Method::extra_stack_words();
__ movptr(rdx, Address(rbx, Method::const_offset()));
__ load_unsigned_short(rdx, Address(rdx, ConstMethod::max_stack_offset())); // get size of expression stack in words
__ negptr(rdx); // so we can subtract in next step
// Allocate expression stack
- __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -extra_stack));
+ __ lea(rsp, Address(rsp, rdx, Address::times_ptr, -Method::extra_stack_words()));
__ movptr(STATE(_stack_limit), rsp);
}
@@ -692,10 +691,9 @@ void InterpreterGenerator::generate_stack_overflow_check(void) {
// Always give one monitor to allow us to start interp if sync method.
// Any additional monitors need a check when moving the expression stack
const int one_monitor = frame::interpreter_frame_monitor_size() * wordSize;
- const int extra_stack = 0; //6815692//Method::extra_stack_entries();
__ movptr(rax, Address(rbx, Method::const_offset()));
__ load_unsigned_short(rax, Address(rax, ConstMethod::max_stack_offset())); // get size of expression stack in words
- __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), extra_stack + one_monitor));
+ __ lea(rax, Address(noreg, rax, Interpreter::stackElementScale(), one_monitor+Method::extra_stack_words()));
__ lea(rax, Address(rax, rdx, Interpreter::stackElementScale(), overhead_size));
#ifdef ASSERT
@@ -2265,8 +2263,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
const int overhead_size = sizeof(BytecodeInterpreter)/wordSize +
( frame::sender_sp_offset - frame::link_offset) + 2;
- const int extra_stack = 0; //6815692//Method::extra_stack_entries();
- const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
+ const int method_stack = (method->max_locals() + method->max_stack()) *
Interpreter::stackElementWords;
return overhead_size + method_stack + stub_code;
}
@@ -2331,8 +2328,7 @@ void BytecodeInterpreter::layout_interpreterState(interpreterState to_fill,
// Need +1 here because stack_base points to the word just above the first expr stack entry
// and stack_limit is supposed to point to the word just below the last expr stack entry.
// See generate_compute_interpreter_state.
- int extra_stack = 0; //6815692//Method::extra_stack_entries();
- to_fill->_stack_limit = stack_base - (method->max_stack() + extra_stack + 1);
+ to_fill->_stack_limit = stack_base - (method->max_stack() + 1);
to_fill->_monitor_base = (BasicObjectLock*) monitor_base;
to_fill->_self_link = to_fill;
@@ -2380,8 +2376,7 @@ int AbstractInterpreter::layout_activation(Method* method,
monitor_size);
// Now with full size expression stack
- int extra_stack = 0; //6815692//Method::extra_stack_entries();
- int full_frame_size = short_frame_size + (method->max_stack() + extra_stack) * BytesPerWord;
+ int full_frame_size = short_frame_size + method->max_stack() * BytesPerWord;
// and now with only live portion of the expression stack
short_frame_size = short_frame_size + tempcount * BytesPerWord;
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
index ca3ab92f2d0..3908a8c09da 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -1565,8 +1565,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
// be sure to change this if you add/subtract anything to/from the overhead area
const int overhead_size = -frame::interpreter_frame_initial_sp_offset;
- const int extra_stack = Method::extra_stack_entries();
- const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
+ const int method_stack = (method->max_locals() + method->max_stack()) *
Interpreter::stackElementWords;
return overhead_size + method_stack + stub_code;
}
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 4ad577ca4c9..50bb8a968f6 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -1574,8 +1574,7 @@ int AbstractInterpreter::size_top_interpreter_activation(Method* method) {
-(frame::interpreter_frame_initial_sp_offset) + entry_size;
const int stub_code = frame::entry_frame_after_call_words;
- const int extra_stack = Method::extra_stack_entries();
- const int method_stack = (method->max_locals() + method->max_stack() + extra_stack) *
+ const int method_stack = (method->max_locals() + method->max_stack()) *
Interpreter::stackElementWords;
return (overhead_size + method_stack + stub_code);
}
diff --git a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
index 1b9a7d2fd9a..8f0ec849cca 100644
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
@@ -468,7 +468,25 @@ BytecodeInterpreter::run(interpreterState istate) {
#ifdef ASSERT
if (istate->_msg != initialize) {
- assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
+ // We have a problem here if we are running with a pre-hsx24 JDK (for example during bootstrap)
+ // because in that case, EnableInvokeDynamic is true by default but will be later switched off
+ // if java_lang_invoke_MethodHandle::compute_offsets() detects that the JDK only has the classes
+ // for the old JSR292 implementation.
+ // This leads to a situation where 'istate->_stack_limit' always accounts for
+ // methodOopDesc::extra_stack_entries() because it is computed in
+ // CppInterpreterGenerator::generate_compute_interpreter_state() which was generated while
+ // EnableInvokeDynamic was still true. On the other hand, istate->_method->max_stack() doesn't
+ // account for extra_stack_entries() anymore because at the time when it is called
+ // EnableInvokeDynamic was already set to false.
+ // So we have a second version of the assertion which handles the case where EnableInvokeDynamic was
+ // switched off because of the wrong classes.
+ if (EnableInvokeDynamic || FLAG_IS_CMDLINE(EnableInvokeDynamic)) {
+ assert(abs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + 1), "bad stack limit");
+ } else {
+ const int extra_stack_entries = Method::extra_stack_entries_for_indy;
+ assert(labs(istate->_stack_base - istate->_stack_limit) == (istate->_method->max_stack() + extra_stack_entries
+ + 1), "bad stack limit");
+ }
#ifndef SHARK
IA32_ONLY(assert(istate->_stack_limit == istate->_thread->last_Java_sp() + 1, "wrong"));
#endif // !SHARK
diff --git a/hotspot/src/share/vm/oops/method.hpp b/hotspot/src/share/vm/oops/method.hpp
index 54c2647b790..250d5c0d65f 100644
--- a/hotspot/src/share/vm/oops/method.hpp
+++ b/hotspot/src/share/vm/oops/method.hpp
@@ -671,13 +671,15 @@ class Method : public Metadata {
Symbol* signature, //anything at all
TRAPS);
static Klass* check_non_bcp_klass(Klass* klass);
- // these operate only on invoke methods:
+
+ // How many extra stack entries for invokedynamic when it's enabled
+ static const int extra_stack_entries_for_jsr292 = 1;
+
+ // this operates only on invoke methods:
// presize interpreter frames for extra interpreter stack entries, if needed
- // method handles want to be able to push a few extra values (e.g., a bound receiver), and
- // invokedynamic sometimes needs to push a bootstrap method, call site, and arglist,
- // all without checking for a stack overflow
- static int extra_stack_entries() { return EnableInvokeDynamic ? 2 : 0; }
- static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize()
+ // Account for the extra appendix argument for invokehandle/invokedynamic
+ static int extra_stack_entries() { return EnableInvokeDynamic ? extra_stack_entries_for_jsr292 : 0; }
+ static int extra_stack_words(); // = extra_stack_entries() * Interpreter::stackElementSize
// RedefineClasses() support:
bool is_old() const { return access_flags().is_old(); }
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index ffd3cc28346..91b4448c9bc 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -1282,16 +1282,6 @@ MachNode *Matcher::match_sfpt( SafePointNode *sfpt ) {
mcall->_argsize = out_arg_limit_per_call - begin_out_arg_area;
}
- if (is_method_handle_invoke) {
- // Kill some extra stack space in case method handles want to do
- // a little in-place argument insertion.
- // FIXME: Is this still necessary?
- int regs_per_word = NOT_LP64(1) LP64_ONLY(2); // %%% make a global const!
- out_arg_limit_per_call += Method::extra_stack_entries() * regs_per_word;
- // Do not update mcall->_argsize because (a) the extra space is not
- // pushed as arguments and (b) _argsize is dead (not used anywhere).
- }
-
// Compute the max stack slot killed by any call. These will not be
// available for debug info, and will be used to adjust FIRST_STACK_mask
// after all call sites have been visited.
From df78dbbf736d02540793c9aff47fed1a3b465228 Mon Sep 17 00:00:00 2001
From: James Laskey
Date: Tue, 14 May 2013 11:15:12 -0300
Subject: [PATCH 007/206] 8014512: Exclude testing and infrastructure packages
from code coverage
Reviewed-by: sundar
---
nashorn/make/code_coverage.xml | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/nashorn/make/code_coverage.xml b/nashorn/make/code_coverage.xml
index 33980bdfdf6..457f6308154 100644
--- a/nashorn/make/code_coverage.xml
+++ b/nashorn/make/code_coverage.xml
@@ -139,6 +139,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
From ca08772ec8f1f3b62f03dba6b9617c944c2c2d45 Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Tue, 14 May 2013 19:18:17 +0200
Subject: [PATCH 008/206] 8011718: binding already bound function with extra
arguments fails
Reviewed-by: jlaskey, sundar
---
.../internal/runtime/ScriptFunctionData.java | 9 ++--
nashorn/test/script/basic/JDK-8011718.js | 46 +++++++++++++++++++
.../test/script/basic/JDK-8011718.js.EXPECTED | 2 +
3 files changed, 53 insertions(+), 4 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8011718.js
create mode 100644 nashorn/test/script/basic/JDK-8011718.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
index f83cfa2c954..1e899be5805 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@@ -25,14 +25,13 @@
package jdk.nashorn.internal.runtime;
+import static jdk.nashorn.internal.lookup.Lookup.MH;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
-import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
-
import jdk.nashorn.internal.runtime.linker.JavaAdapterFactory;
/**
@@ -389,7 +388,9 @@ public abstract class ScriptFunctionData {
boundInvoker = noArgBoundInvoker;
}
} else {
- final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount(), args.length + (isTargetBound ? 0 : (needsCallee ? 2 : 1)))];
+ // If target is already bound, insert additional bound arguments after "this" argument, at position 1.
+ final int argInsertPos = isTargetBound ? 1 : 0;
+ final Object[] boundArgs = new Object[Math.min(originalInvoker.type().parameterCount() - argInsertPos, args.length + (isTargetBound ? 0 : (needsCallee ? 2 : 1)))];
int next = 0;
if (!isTargetBound) {
if (needsCallee) {
@@ -403,7 +404,7 @@ public abstract class ScriptFunctionData {
// "this" will get dropped anyway by the target invoker. We previously asserted that already bound functions
// don't take a callee parameter, so we can know that the signature is (this[, args...]) therefore args
// start at position 1. If the function is not bound, we start inserting arguments at position 0.
- boundInvoker = MH.insertArguments(originalInvoker, isTargetBound ? 1 : 0, boundArgs);
+ boundInvoker = MH.insertArguments(originalInvoker, argInsertPos, boundArgs);
}
if (isTargetBound) {
diff --git a/nashorn/test/script/basic/JDK-8011718.js b/nashorn/test/script/basic/JDK-8011718.js
new file mode 100644
index 00000000000..7cb24f24f10
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8011718.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8011718: binding already bound function with extra arguments fails.
+ *
+ * @test
+ * @run
+ */
+
+var obj = {
+ hello:"From obj",
+};
+var obj2 = {
+ hello:"From obj2",
+};
+
+function doit(cb){
+ cb();
+ var cb2 = cb.bind(obj2, "This one is not acccepted");
+ cb2();
+}
+
+doit(function(){
+ print(this.hello);
+ }.bind(obj));
diff --git a/nashorn/test/script/basic/JDK-8011718.js.EXPECTED b/nashorn/test/script/basic/JDK-8011718.js.EXPECTED
new file mode 100644
index 00000000000..58a7d55629a
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8011718.js.EXPECTED
@@ -0,0 +1,2 @@
+From obj
+From obj
From 41f972c2ed5411b7d1862048268a9d265da16241 Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Tue, 14 May 2013 19:56:35 +0200
Subject: [PATCH 009/206] 8014426: Original exception no longer thrown away
when a finally rethrows
Reviewed-by: attila, jlaskey
---
.../internal/codegen/CodeGenerator.java | 12 ++++-
.../jdk/nashorn/internal/codegen/Lower.java | 4 +-
.../jdk/nashorn/internal/ir/CatchNode.java | 30 ++++++++++--
.../jdk/nashorn/internal/ir/ThrowNode.java | 24 +++++++--
.../jdk/nashorn/internal/parser/Parser.java | 4 +-
nashorn/test/script/basic/JDK-8014426.js | 49 +++++++++++++++++++
.../test/script/basic/JDK-8014426.js.EXPECTED | 1 +
7 files changed, 111 insertions(+), 13 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8014426.js
create mode 100644 nashorn/test/script/basic/JDK-8014426.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index 1fae129468d..617b5ab8474 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -2028,6 +2028,13 @@ final class CodeGenerator extends NodeOperatorVisitor {
public boolean enterThrowNode(final ThrowNode throwNode) {
lineNumber(throwNode);
+ if (throwNode.isSyntheticRethrow()) {
+ //do not wrap whatever this is in an ecma exception, just rethrow it
+ load(throwNode.getExpression());
+ method.athrow();
+ return false;
+ }
+
method._new(ECMAException.class).dup();
final Source source = getLexicalContext().getCurrentFunction().getSource();
@@ -2096,13 +2103,16 @@ final class CodeGenerator extends NodeOperatorVisitor {
}
@Override
protected void evaluate() {
+ if (catchNode.isSyntheticRethrow()) {
+ method.load(symbol);
+ return;
+ }
/*
* If caught object is an instance of ECMAException, then
* bind obj.thrown to the script catch var. Or else bind the
* caught object itself to the script catch var.
*/
final Label notEcmaException = new Label("no_ecma_exception");
-
method.load(symbol).dup()._instanceof(ECMAException.class).ifeq(notEcmaException);
method.checkcast(ECMAException.class); //TODO is this necessary?
method.getField(ECMAException.THROWN);
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
index 23e91b63026..a602ddf512c 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
@@ -288,10 +288,10 @@ final class Lower extends NodeOperatorVisitor {
final IdentNode exception = new IdentNode(token, finish, getLexicalContext().getCurrentFunction().uniqueName("catch_all"));
- final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception))).
+ final Block catchBody = new Block(lineNumber, token, finish, new ThrowNode(lineNumber, token, finish, new IdentNode(exception), ThrowNode.IS_SYNTHETIC_RETHROW)).
setIsTerminal(getLexicalContext(), true); //ends with throw, so terminal
- final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody);
+ final CatchNode catchAllNode = new CatchNode(lineNumber, token, finish, new IdentNode(exception), null, catchBody, CatchNode.IS_SYNTHETIC_RETHROW);
final Block catchAllBlock = new Block(lineNumber, token, finish, catchAllNode);
//catchallblock -> catchallnode (catchnode) -> exception -> throw
diff --git a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
index c4551492ed8..67da65f4041 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/CatchNode.java
@@ -42,6 +42,11 @@ public final class CatchNode extends Statement {
/** Catch body. */
private final Block body;
+ private final int flags;
+
+ /** Is this block a synthethic rethrow created by finally inlining? */
+ public static final int IS_SYNTHETIC_RETHROW = 1;
+
/**
* Constructors
*
@@ -51,19 +56,22 @@ public final class CatchNode extends Statement {
* @param exception variable name of exception
* @param exceptionCondition exception condition
* @param body catch body
+ * @param flags flags
*/
- public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body) {
+ public CatchNode(final int lineNumber, final long token, final int finish, final IdentNode exception, final Node exceptionCondition, final Block body, final int flags) {
super(lineNumber, token, finish);
this.exception = exception;
this.exceptionCondition = exceptionCondition;
this.body = body;
+ this.flags = flags;
}
- private CatchNode(final CatchNode catchNode, final IdentNode exception, final Node exceptionCondition, final Block body) {
+ private CatchNode(final CatchNode catchNode, final IdentNode exception, final Node exceptionCondition, final Block body, final int flags) {
super(catchNode);
this.exception = exception;
this.exceptionCondition = exceptionCondition;
this.body = body;
+ this.flags = flags;
}
/**
@@ -124,7 +132,7 @@ public final class CatchNode extends Statement {
if (this.exceptionCondition == exceptionCondition) {
return this;
}
- return new CatchNode(this, exception, exceptionCondition, body);
+ return new CatchNode(this, exception, exceptionCondition, body, flags);
}
/**
@@ -144,13 +152,25 @@ public final class CatchNode extends Statement {
if (this.exception == exception) {
return this;
}
- return new CatchNode(this, exception, exceptionCondition, body);
+ return new CatchNode(this, exception, exceptionCondition, body, flags);
}
private CatchNode setBody(final Block body) {
if (this.body == body) {
return this;
}
- return new CatchNode(this, exception, exceptionCondition, body);
+ return new CatchNode(this, exception, exceptionCondition, body, flags);
}
+
+ /**
+ * Is this catch block a non-JavaScript constructor, for example created as
+ * part of the rethrow mechanism of a finally block in Lower? Then we just
+ * pass the exception on and need not unwrap whatever is in the ECMAException
+ * object catch symbol
+ * @return true if a finally synthetic rethrow
+ */
+ public boolean isSyntheticRethrow() {
+ return (flags & IS_SYNTHETIC_RETHROW) == IS_SYNTHETIC_RETHROW;
+ }
+
}
diff --git a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
index e37302e6902..70d385733be 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/ThrowNode.java
@@ -36,6 +36,11 @@ public final class ThrowNode extends Statement {
/** Exception expression. */
private final Node expression;
+ private final int flags;
+
+ /** Is this block a synthethic rethrow created by finally inlining? */
+ public static final int IS_SYNTHETIC_RETHROW = 1;
+
/**
* Constructor
*
@@ -43,15 +48,18 @@ public final class ThrowNode extends Statement {
* @param token token
* @param finish finish
* @param expression expression to throw
+ * @param flags flags
*/
- public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression) {
+ public ThrowNode(final int lineNumber, final long token, final int finish, final Node expression, final int flags) {
super(lineNumber, token, finish);
this.expression = expression;
+ this.flags = flags;
}
- private ThrowNode(final ThrowNode node, final Node expression) {
+ private ThrowNode(final ThrowNode node, final Node expression, final int flags) {
super(node);
this.expression = expression;
+ this.flags = flags;
}
@Override
@@ -98,7 +106,17 @@ public final class ThrowNode extends Statement {
if (this.expression == expression) {
return this;
}
- return new ThrowNode(this, expression);
+ return new ThrowNode(this, expression, flags);
+ }
+
+ /**
+ * Is this a throw a synthetic rethrow in a synthetic catch-all block
+ * created when inlining finally statements? In that case we never
+ * wrap whatever is thrown into an ECMAException, just rethrow it.
+ * @return true if synthetic throw node
+ */
+ public boolean isSyntheticRethrow() {
+ return (flags & IS_SYNTHETIC_RETHROW) == IS_SYNTHETIC_RETHROW;
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/parser/Parser.java b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
index efb7a391586..03f65b86e11 100644
--- a/nashorn/src/jdk/nashorn/internal/parser/Parser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/Parser.java
@@ -1537,7 +1537,7 @@ loop:
endOfLine();
- appendStatement(new ThrowNode(throwLine, throwToken, finish, expression));
+ appendStatement(new ThrowNode(throwLine, throwToken, finish, expression, 0));
}
/**
@@ -1597,7 +1597,7 @@ loop:
try {
// Get CATCH body.
final Block catchBody = getBlock(true);
- final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody);
+ final CatchNode catchNode = new CatchNode(catchLine, catchToken, finish, exception, ifExpression, catchBody, 0);
appendStatement(catchNode);
} finally {
catchBlock = restoreBlock(catchBlock);
diff --git a/nashorn/test/script/basic/JDK-8014426.js b/nashorn/test/script/basic/JDK-8014426.js
new file mode 100644
index 00000000000..220aa7f3683
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014426.js
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/**
+ * Ensure catchall exceptions from finally inlining are rethrown as is
+ *
+ * @test
+ * @run
+ */
+
+function runScriptEngine() {
+ var fac = new Packages.jdk.nashorn.api.scripting.NashornScriptEngineFactory();
+ var engine = fac.getScriptEngine();
+ engine.eval(
+"try {\n\
+ doIt();\n\
+} finally { \n\
+ var x = 17;\n\
+}\n\
+function doIt() {\n\
+ throw new TypeError('en stor graa noshoerning!');\n\
+}\n");
+}
+
+try {
+ runScriptEngine();
+} catch(e) {
+ print(e);
+}
diff --git a/nashorn/test/script/basic/JDK-8014426.js.EXPECTED b/nashorn/test/script/basic/JDK-8014426.js.EXPECTED
new file mode 100644
index 00000000000..8a8b2a06ae3
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014426.js.EXPECTED
@@ -0,0 +1 @@
+javax.script.ScriptException: TypeError: en stor graa noshoerning! in at line number 7 at column number 2
From 3710d6fcf605500bc62ef1ec1de87b8b3647542a Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Wed, 15 May 2013 10:28:18 +0200
Subject: [PATCH 010/206] 8014639: Remove debug flag from test runs
Reviewed-by: hannesw, lagergren
---
nashorn/make/project.properties | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index 2d66dfef6fb..9ed8125e14a 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -216,7 +216,7 @@ run.test.xms=2G
# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
# add '-Dtest.js.outofprocess' to run each test in a new sub-process
-run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dnashorn.debug=true -Dfile.encoding=UTF-8
+run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8
#-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
From a3e2765ce8d04539669fab63099bc821fd36c6cb Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Wed, 15 May 2013 14:54:28 +0200
Subject: [PATCH 011/206] 8014646: Update the Java interop documentation in the
Java Scripting Programmer's Guide
Reviewed-by: jlaskey, hannesw, lagergren
---
.../docs/JavaScriptingProgrammersGuide.html | 234 ++++++++++++++++--
1 file changed, 216 insertions(+), 18 deletions(-)
diff --git a/nashorn/docs/JavaScriptingProgrammersGuide.html b/nashorn/docs/JavaScriptingProgrammersGuide.html
index 811b29c9d51..a9af9612271 100644
--- a/nashorn/docs/JavaScriptingProgrammersGuide.html
+++ b/nashorn/docs/JavaScriptingProgrammersGuide.html
@@ -71,9 +71,20 @@ Classes
Arrays
-Note that the name of the type is always a string for a fully qualified name. You can use any of these types to create new instances, e.g.:
+Note that the name of the type is always a string for a fully qualified name. You can use any of these expressions to create new instances, e.g.:
- var anArrayList = new Java.type("java.util.ArrayList")
+ var anArrayList = new (Java.type("java.util.ArrayList"))
or
@@ -496,6 +507,37 @@ However, once you retrieved the outer class, you can access the inner class as a
You can access both static and non-static inner classes. If you want to create an instance of a non-static inner class, remember to pass an instance of its outer class as the first argument to the constructor.
+
+In addition to creating new instances, the type objects returned from Java.type calls can also be used to access the
+static fields and methods of the classes:
+
+ var File = Java.type("java.io.File")
+ File.createTempFile("nashorn", ".tmp")
+
+
+Methods with names of the form isXxx(), getXxx(), and setXxx() can also be used as properties, for both instances and statics.
+
+
+A type object returned from Java.type is distinct from a java.lang.Class object. You can obtain one from the other using properties class and static on them.
+
+ var ArrayList = Java.type("java.util.ArrayList")
+ var a = new ArrayList
+
+ // All of the following print true:
+ print("Type acts as target of instanceof: " + (a instanceof ArrayList))
+ print("Class doesn't act as target of instanceof: " + !(a instanceof a.getClass()))
+ print("Type is not same as instance's getClass(): " + (a.getClass() !== ArrayList))
+ print("Type's `class` property is same as instance getClass(): " + (a.getClass() === ArrayList.class))
+ print("Type is same as instance getClass()'s `static` property: " + (a.getClass().static === ArrayList))
+
+
+You can think of the type object as similar to the class names as used in Java source code: you use them as the
+arguments to the new and instanceof operators and as the namespace for the static fields
+and methods, but they are different than the runtime Class objects returned by getClass() calls.
+Syntactically and semantically, this separation produces code that is most similar to Java code, where a distinction
+between compile-time class expressions and runtime class objects also exists. (Also, Java can't have the equivalent of static
+property on a Class object since compile-time class expressions are never reified as objects).
+
Importing Java Packages, Classes
@@ -558,10 +600,7 @@ with (SwingGui) {
Creating, Converting and Using Java Arrays
-Array element access or length access is
-the same as in Java. Also, a script array can be used when a Java
-method expects a Java array (auto conversion). So in most cases we
-don't have to create Java arrays explicitly.
+Array element access or length access is the same as in Java.
// javaarray.js
@@ -587,7 +626,11 @@ Given a JavaScript array and a Java type, Java.toJavaArray returns
print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
-Given a Java array or Collection, Java.toJavaScriptArray returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.i
+You can use either a string or a type object returned from Java.type() to specify the component type of the array.
+You can also omit the array type, in which case a Object[] will be created.
+
+
+Given a Java array or Collection, Java.toJavaScriptArray returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
var File = Java.type("java.io.File");
@@ -597,7 +640,7 @@ print(jsList);
-
Implementing Java Interfaces
+
Implementing Java interfaces
A Java interface can be implemented in JavaScript by using a
Java anonymous class-like syntax:
@@ -631,8 +674,8 @@ th.join();
-
-
Extending Java classes
+
+
Extending Abstract Java Classes
If a Java class is abstract, you can instantiate an anonymous subclass of it using an argument list that is applicable to any of its public or protected constructors, but inserting a JavaScript object with functions properties that provide JavaScript implementations of the abstract methods. If method names are overloaded, the JavaScript function will provide implementation for all overloads. E.g.:
@@ -671,6 +714,9 @@ The use of functions can be taken even further; if you are invoking a Java metho
Here, Timer.schedule() expects a TimerTask as its argument, so Nashorn creates an instance of a TimerTask subclass and uses the passed function to implement its only abstract method, run(). In this usage though, you can't use non-default constructors; the type must be either an interface, or must have a protected or public no-arg constructor.
+
+
+
Extending Concrete Java Classes
To extend a concrete Java class, you have to use Java.extend function.
Java.extend returns a type object for a subclass of the specified Java class (or implementation of the specified interface) that acts as a script-to-Java adapter for it.
@@ -695,26 +741,178 @@ var printAddInvokedArrayList = new ArrayListExtender() {
printSizeInvokedArrayList.size();
printAddInvokedArrayList.add(33, 33);
+
+The reason you must use Java.extend() with concrete classes is that with concrete classes, there can be a
+syntactic ambiguity if you just invoke their constructor. Consider this example:
+
+
+var t = new java.lang.Thread({ run: function() { print("Hello!") } })
+
+
+If we allowed subclassing of concrete classes with constructor syntax, Nashorn couldn't tell if you're creating a new
+Thread and passing it a Runnable at this point, or you are subclassing Thread and
+passing it a new implementation for its own run() method.
+
+
+
+
Implementing Multiple Interfaces
+
+Java.extend can in fact take a list of multiple types. At most one of the types can be a class, and the rest must
+be interfaces (the class doesn't have to be the first in the list). You will get back an object that extends the class and
+implements all the interfaces. (Obviously, if you only specify interfaces and no class, the object will extend java.lang.Object).
+
+
+
Class-Bound Implementations
+
+The methods shown so far for extending Java classes and implementing interfaces – passing an implementation JavaScript object
+or function to a constructor, or using Java.extend with new – all produce classes that take an
+extra JavaScript object parameter in their constructors that specifies the implementation. The implementation is therefore always bound
+to the actual instance being created with new, and not to the whole class. This has some advantages, for example in the
+memory footprint of the runtime, as Nashorn can just create a single "universal adapter" for every combination of types being implemented.
+In reality, the below code shows that different instantiations of, say, Runnable have the same class regardless of them having
+different JavaScript implementation objects:
+
+
+var Runnable = java.lang.Runnable;
+var r1 = new Runnable(function() { print("I'm runnable 1!") })
+var r2 = new Runnable(function() { print("I'm runnable 2!") })
+r1.run()
+r2.run()
+print("We share the same class: " + (r1.class === r2.class))
+
+
+prints:
+
+
+I'm runnable 1!
+I'm runnable 2!
+We share the same class: true
+
+
+Sometimes, however, you'll want to extend a Java class or implement an interface with implementation bound to the class, not to
+its instances. Such a need arises, for example, when you need to pass the class for instantiation to an external API; prime example
+of this is the JavaFX framework where you need to pass an Application class to the FX API and let it instantiate it.
+
+
+Fortunately, there's a solution for that: Java.extend() – aside from being able to take any number of type parameters
+denoting a class to extend and interfaces to implement – can also take one last argument that has to be a JavaScript object
+that serves as the implementation for the methods. In this case, Java.extend() will create a class that has the same
+constructors as the original class had, as they don't need to take an an extra implementation object parameter. The example below
+shows how you can create class-bound implementations, and shows that in this case, the implementation classes for different invocations
+are indeed different:
+
+I'm runnable 1!
+I'm runnable 2!
+We share the same class: false
+
+
+As you can see, the major difference here is that we moved the implementation object into the invocation of Java.extend
+from the constructor invocations – indeed the constructor invocations now don't even need to take an extra parameter! Since
+the implementations are bound to a class, the two classes obviously can't be the same, and we indeed see that the two runnables no
+longer share the same class – every invocation of Java.extend() with a class-specific implementation object triggers
+the creation of a new Java adapter class.
+
+
+Finally, the adapter classes with class-bound implementations can still take an additional constructor parameter to further
+override the behavior on a per-instance basis. Thus, you can even combine the two approaches: you can provide part of the implementation
+in a class-based JavaScript implementation object passed to Java.extend, and part in another object passed to the constructor.
+Whatever functions are provided by the constructor-passed object will override the functions in the class-bound object.
+
+
+var RunnableImpl = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
+var r1 = new RunnableImpl()
+var r2 = new RunnableImpl(function() { print("I'm runnable 2!") })
+r1.run()
+r2.run()
+print("We share the same class: " + (r1.class === r2.class))
+
+
+prints:
+
+
+I'm runnable 1!
+I'm runnable 2!
+We share the same class: true
+
Overload Resolution
Java methods can be overloaded by argument types. In Java,
overload resolution occurs at compile time (performed by javac).
-When calling Java methods from a script, the script
-interpreter/compiler needs to select the appropriate method. With
-the JavaScript engine, you do not need to do anything special - the
-correct Java method overload variant is selected based on the
-argument types. But, sometimes you may want (or have) to explicitly
-select a particular overload variant.
+When calling Java methods from Nashorn, the appropriate method will be
+selected based on the argument types at invocation time. You do not need
+to do anything special – the correct Java method overload variant
+is selected based automatically. You still have the option of explicitly
+specifying a particular overload variant. Reasons for this include
+either running into a genuine ambiguity with actual argument types, or
+rarely reasons of performance – if you specify the actual overload
+then the engine doesn't have to perform resolution during invocation.
+Individual overloads of a Java methods are exposed as special properties
+with the name of the method followed with its signature in parentheses.
+You can invoke them like this:
// overload.js
var out = java.lang.System.out;
// select a particular print function
-out["println(java.lang.Object)"]("hello");
+out["println(Object)"]("hello");
+
+Note that you normally don't even have to use qualified class names in
+the signatures as long as the unqualified name of the type is sufficient
+for uniquely identifying the signature. In practice this means that only
+in the extremely unlikely case that two overloads only differ in
+parameter types that have identical unqualified names but come from
+different packages would you need to use the fully qualified name of the
+class.
+
+
+
+
Mapping of Data Types Between Java and JavaScript
+
+We have previously shown some of the data type mappings between Java and JavaScript.
+We saw that arrays need to be explicitly converted. We have also shown that JavaScript functions
+are automatically converted to SAM types when passed as parameters to Java methods. Most other
+conversions work as you would expect.
+
+
+Every JavaScript object is also a java.util.Map so APIs receiving maps will receive them directly.
+
+
+When numbers are passed to a Java API, they will be converted to the expected target numeric type, either boxed or
+primitive, but if the target type is less specific, say Number or Object, you can only
+count on them being a Number, and have to test specifically for whether it's a boxed Double,
+Integer, Long, etc. – it can be any of these due to internal optimizations. Also, you
+can pass any JavaScript value to a Java API expecting either a boxed or primitive number; the JavaScript specification's
+ToNumber conversion algorithm will be applied to the value.
+
+
+In a similar vein, if a Java method expects a String or a Boolean, the values will be
+converted using all conversions allowed by the JavaScript specification's ToString and ToBoolean
+conversions.
+
+
+Finally, a word of caution about strings. Due to internal performance optimizations of string operations, JavaScript strings are
+not always necessarily of type java.lang.String, but they will always be of type java.lang.CharSequence.
+If you pass them to a Java method that expects a java.lang.String parameter, then you will naturally receive a Java
+String, but if the signature of your method is more generic, i.e. it receives a java.lang.Object parameter, you can
+end up with an object of private engine implementation class that implements CharSequence but is not a Java String.
+
Implementing Your Own Script Engine
From 8bbf3e9b524c0bd260da5294218e7623f24229e7 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Wed, 15 May 2013 19:45:16 +0530
Subject: [PATCH 012/206] 8012305: Function.bind can't be called on prototype
function inside constructor
Reviewed-by: lagergren, attila
---
nashorn/test/script/basic/JDK-8012305.js | 39 +++++++++++++++++++
.../test/script/basic/JDK-8012305.js.EXPECTED | 1 +
2 files changed, 40 insertions(+)
create mode 100644 nashorn/test/script/basic/JDK-8012305.js
create mode 100644 nashorn/test/script/basic/JDK-8012305.js.EXPECTED
diff --git a/nashorn/test/script/basic/JDK-8012305.js b/nashorn/test/script/basic/JDK-8012305.js
new file mode 100644
index 00000000000..d08502defb1
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8012305.js
@@ -0,0 +1,39 @@
+/*
+ * 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-8012305: Function.bind can't be called on prototype function inside constructor
+ *
+ * @test
+ * @run
+ */
+
+function MyObject() {
+ // If the call to bind is removed, then the function is properly printed.
+ print("function " + this._process);
+ this._process = this._process.bind(this);
+}
+
+MyObject.prototype._process = function() { print("Message "); }
+
+var s = new MyObject();
diff --git a/nashorn/test/script/basic/JDK-8012305.js.EXPECTED b/nashorn/test/script/basic/JDK-8012305.js.EXPECTED
new file mode 100644
index 00000000000..b509e0c1051
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8012305.js.EXPECTED
@@ -0,0 +1 @@
+function function() { print("Message "); }
From e5be7a02eaf8f90d5c7f84338af5854c2e164e7f Mon Sep 17 00:00:00 2001
From: James Laskey
Date: Wed, 15 May 2013 12:09:38 -0300
Subject: [PATCH 013/206] 8014648: Exclude testing and infrastructure packages
from code coverage, round two
Reviewed-by: sundar
---
nashorn/make/code_coverage.xml | 12 ++++
.../internal/runtime/options/Option.java | 4 --
.../internal/runtime/options/Options.java | 2 -
.../internal/runtime/options/ValueOption.java | 59 -------------------
nashorn/test/script/basic/allgettersetters.js | 3 +
5 files changed, 15 insertions(+), 65 deletions(-)
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java
diff --git a/nashorn/make/code_coverage.xml b/nashorn/make/code_coverage.xml
index 457f6308154..3e2860f8d9d 100644
--- a/nashorn/make/code_coverage.xml
+++ b/nashorn/make/code_coverage.xml
@@ -153,6 +153,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java
index ddbeba184d4..feaff1f1805 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Option.java
@@ -42,10 +42,6 @@ public class Option {
this.value = value;
}
- void setValue(final T value) {
- this.value = value;
- }
-
/**
* Return the value of an option
* @return the option value
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
index 286feec907b..52864a6652a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
@@ -501,8 +501,6 @@ public final class Options {
return new Option<>(TimeZone.getTimeZone(value));
case "keyvalues":
return new KeyValueOption(value);
- case "values":
- return new ValueOption(value);
case "log":
final KeyValueOption kv = new KeyValueOption(value);
Logging.initialize(kv.getValues());
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java b/nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java
deleted file mode 100644
index 2f4461f44ca..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/ValueOption.java
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.options;
-
-import java.util.Collection;
-import java.util.Collections;
-import java.util.LinkedHashSet;
-import java.util.StringTokenizer;
-
-/**
- * This option represents a collection of comma separated values
- */
-public class ValueOption extends Option {
-
- private Collection values;
-
- ValueOption(final String value) {
- super(value);
- if (value != null) {
- values = new LinkedHashSet<>();
- final StringTokenizer st = new StringTokenizer(getValue(), ",");
- while (st.hasMoreElements()) {
- values.add(st.nextToken());
- }
- }
- }
-
- /**
- * Get the values in the option
- * @return collection of strings
- */
- public Collection getValues() {
- return Collections.unmodifiableCollection(values);
- }
-
-}
diff --git a/nashorn/test/script/basic/allgettersetters.js b/nashorn/test/script/basic/allgettersetters.js
index 0f6753c23a4..1cb956239e5 100644
--- a/nashorn/test/script/basic/allgettersetters.js
+++ b/nashorn/test/script/basic/allgettersetters.js
@@ -34,6 +34,9 @@ function checkGetterSetter(obj, expectError) {
for (var i in properties) {
var prop = properties[i];
try {
+ if (!/\d.*/.test(prop)) {
+ eval("obj." + prop + " = " + "obj." + prop + ";");
+ }
obj[prop] = obj[prop];
} catch (e) {
if (!expectError || !(e instanceof TypeError)) {
From 18bdc5fd42353d59f803b64377033e4d76af90af Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Wed, 15 May 2013 20:21:59 +0200
Subject: [PATCH 014/206] 8014647: Allow class-based overrides to be
initialized with a ScriptFunction
Reviewed-by: hannesw, jlaskey, sundar
---
.../linker/JavaAdapterBytecodeGenerator.java | 32 ++++++++++++++-
nashorn/test/script/basic/JDK-8014647.js | 40 +++++++++++++++++++
.../test/script/basic/JDK-8014647.js.EXPECTED | 5 +++
3 files changed, 76 insertions(+), 1 deletion(-)
create mode 100644 nashorn/test/script/basic/JDK-8014647.js
create mode 100644 nashorn/test/script/basic/JDK-8014647.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java
index 37786b1e685..1fe76954391 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java
@@ -310,7 +310,34 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
Type.getMethodDescriptor(Type.VOID_TYPE), null, null));
mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getClassOverrides", GET_CLASS_INITIALIZER_DESCRIPTOR);
- // Assign MethodHandle fields through invoking getHandle()
+ final Label initGlobal;
+ if(samName != null) {
+ // If the class is a SAM, allow having a ScriptFunction passed as class overrides
+ final Label notAFunction = new Label();
+ mv.dup();
+ mv.instanceOf(SCRIPT_FUNCTION_TYPE);
+ mv.ifeq(notAFunction);
+ mv.checkcast(SCRIPT_FUNCTION_TYPE);
+
+ // Assign MethodHandle fields through invoking getHandle() for a ScriptFunction, only assigning the SAM
+ // method(s).
+ for (final MethodInfo mi : methodInfos) {
+ if(mi.getName().equals(samName)) {
+ mv.dup();
+ mv.aconst(Type.getMethodType(mi.type.toMethodDescriptorString()));
+ mv.invokestatic(SERVICES_CLASS_TYPE_NAME, "getHandle", GET_HANDLE_FUNCTION_DESCRIPTOR);
+ } else {
+ mv.visitInsn(ACONST_NULL);
+ }
+ mv.putstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
+ }
+ initGlobal = new Label();
+ mv.goTo(initGlobal);
+ mv.visitLabel(notAFunction);
+ } else {
+ initGlobal = null;
+ }
+ // Assign MethodHandle fields through invoking getHandle() for a ScriptObject
for (final MethodInfo mi : methodInfos) {
mv.dup();
mv.aconst(mi.getName());
@@ -319,6 +346,9 @@ final class JavaAdapterBytecodeGenerator extends JavaAdapterGeneratorBase {
mv.putstatic(generatedClassName, mi.methodHandleClassFieldName, METHOD_HANDLE_TYPE_DESCRIPTOR);
}
+ if(initGlobal != null) {
+ mv.visitLabel(initGlobal);
+ }
// Assign "staticGlobal = Context.getGlobal()"
invokeGetGlobalWithNullCheck(mv);
mv.putstatic(generatedClassName, STATIC_GLOBAL_FIELD_NAME, SCRIPT_OBJECT_TYPE_DESCRIPTOR);
diff --git a/nashorn/test/script/basic/JDK-8014647.js b/nashorn/test/script/basic/JDK-8014647.js
new file mode 100644
index 00000000000..8ecc21101d5
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014647.js
@@ -0,0 +1,40 @@
+/*
+ * 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-8014647: Allow class-based overrides to be initialized with a ScriptFunction
+ *
+ * @test
+ * @run
+ */
+
+var RunnableImpl1 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 1!") })
+var RunnableImpl2 = Java.extend(java.lang.Runnable, function() { print("I'm runnable 2!") })
+var r1 = new RunnableImpl1()
+var r2 = new RunnableImpl2()
+var r3 = new RunnableImpl2(function() { print("I'm runnable 3!") })
+r1.run()
+r2.run()
+r3.run()
+print("r1.class === r2.class: " + (r1.class === r2.class))
+print("r2.class === r3.class: " + (r2.class === r3.class))
diff --git a/nashorn/test/script/basic/JDK-8014647.js.EXPECTED b/nashorn/test/script/basic/JDK-8014647.js.EXPECTED
new file mode 100644
index 00000000000..641a13b1d45
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014647.js.EXPECTED
@@ -0,0 +1,5 @@
+I'm runnable 1!
+I'm runnable 2!
+I'm runnable 3!
+r1.class === r2.class: false
+r2.class === r3.class: true
From 6e9157648062e24fa6a84bb0d06f32e5674c88bd Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Thu, 16 May 2013 14:52:48 +0530
Subject: [PATCH 015/206] 8009141: Avoid netscape.javascript.JSObject in
nashorn code
Reviewed-by: lagergren, hannesw
---
.../nashorn/api/scripting}/JSObject.java | 18 ++----------------
.../api/scripting/ScriptObjectMirror.java | 1 -
.../runtime/linker/JSObjectLinker.java | 2 +-
.../api/scripting/ScriptEngineTest.java | 1 -
4 files changed, 3 insertions(+), 19 deletions(-)
rename nashorn/src/{netscape/javascript => jdk/nashorn/api/scripting}/JSObject.java (87%)
diff --git a/nashorn/src/netscape/javascript/JSObject.java b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java
similarity index 87%
rename from nashorn/src/netscape/javascript/JSObject.java
rename to nashorn/src/jdk/nashorn/api/scripting/JSObject.java
index 23054c6321d..583e8f7a199 100644
--- a/nashorn/src/netscape/javascript/JSObject.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/JSObject.java
@@ -23,26 +23,12 @@
* questions.
*/
-package netscape.javascript;
-
-import java.applet.Applet;
+package jdk.nashorn.api.scripting;
/**
- * Stub for JSObject to get compilation going.
+ * netscape.javascript.JSObject-like interface for nashorn script objects.
*/
public abstract class JSObject {
-
- /**
- * Get the window for an {@link Applet}. Not supported
- * by Nashorn
- *
- * @param a applet
- * @return the window instance
- */
- public static JSObject getWindow(final Applet a) {
- throw new UnsupportedOperationException("getWindow");
- }
-
/**
* Call a JavaScript method
*
diff --git a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
index 266ce87f48d..e53903d3c3f 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java
@@ -42,7 +42,6 @@ import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.ScriptFunction;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
-import netscape.javascript.JSObject;
/**
* Mirror object that wraps a given ScriptObject instance. User can
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
index df9c47ff623..edd75e4dafd 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JSObjectLinker.java
@@ -38,7 +38,7 @@ import jdk.internal.dynalink.linker.LinkerServices;
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
import jdk.nashorn.internal.runtime.JSType;
-import netscape.javascript.JSObject;
+import jdk.nashorn.api.scripting.JSObject;
/**
* A Dynalink linker to handle web browser built-in JS (DOM etc.) objects as well
diff --git a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
index d12c9057246..a6c015a1e54 100644
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java
@@ -47,7 +47,6 @@ import javax.script.ScriptEngineFactory;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import javax.script.SimpleScriptContext;
-import netscape.javascript.JSObject;
import org.testng.Assert;
import org.testng.annotations.Test;
From aeda283b752d5e8b74cf849bdaf151540ce503a0 Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Thu, 16 May 2013 13:44:25 +0200
Subject: [PATCH 016/206] 8013919: Original exception no longer thrown away
when a finally rethrows
Reviewed-by: jlaskey, sundar
---
.../jdk/nashorn/internal/codegen/Lower.java | 32 ++++++++-------
.../jdk/nashorn/internal/ir/FunctionNode.java | 38 ++++++++++++------
nashorn/test/script/basic/JDK-8013919.js | 39 +++++++++++++++++++
.../test/script/basic/JDK-8013919.js.EXPECTED | 2 +
4 files changed, 87 insertions(+), 24 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8013919.js
create mode 100644 nashorn/test/script/basic/JDK-8013919.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
index a602ddf512c..a7089674d82 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Lower.java
@@ -261,19 +261,25 @@ final class Lower extends NodeOperatorVisitor {
return throwNode;
}
- private static Node ensureUniqueLabelsIn(final Node node) {
+ private static Node ensureUniqueNamesIn(final LexicalContext lc, final Node node) {
return node.accept(new NodeVisitor() {
- @Override
- public Node leaveDefault(final Node labelledNode) {
- return labelledNode.ensureUniqueLabels(getLexicalContext());
- }
+ @Override
+ public Node leaveFunctionNode(final FunctionNode functionNode) {
+ final String name = functionNode.getName();
+ return functionNode.setName(getLexicalContext(), lc.getCurrentFunction().uniqueName(name));
+ }
+
+ @Override
+ public Node leaveDefault(final Node labelledNode) {
+ return labelledNode.ensureUniqueLabels(getLexicalContext());
+ }
});
}
- private static List copyFinally(final Block finallyBody) {
+ private static List copyFinally(final LexicalContext lc, final Block finallyBody) {
final List newStatements = new ArrayList<>();
for (final Statement statement : finallyBody.getStatements()) {
- newStatements.add((Statement)ensureUniqueLabelsIn(statement));
+ newStatements.add((Statement)ensureUniqueNamesIn(lc, statement));
if (statement.hasTerminalFlags()) {
return newStatements;
}
@@ -316,9 +322,9 @@ final class Lower extends NodeOperatorVisitor {
* @return new try node after splicing finally code (same if nop)
*/
private Node spliceFinally(final TryNode tryNode, final List rethrows, final Block finallyBody) {
- final int finish = tryNode.getFinish();
-
assert tryNode.getFinallyBody() == null;
+ final int finish = tryNode.getFinish();
+ final LexicalContext lc = getLexicalContext();
final TryNode newTryNode = (TryNode)tryNode.accept(new NodeVisitor() {
final List insideTry = new ArrayList<>();
@@ -338,7 +344,7 @@ final class Lower extends NodeOperatorVisitor {
@Override
public Node leaveThrowNode(final ThrowNode throwNode) {
if (rethrows.contains(throwNode)) {
- final List newStatements = copyFinally(finallyBody);
+ final List newStatements = copyFinally(lc, finallyBody);
if (!isTerminal(newStatements)) {
newStatements.add(throwNode);
}
@@ -372,7 +378,7 @@ final class Lower extends NodeOperatorVisitor {
resultNode = null;
}
- newStatements.addAll(copyFinally(finallyBody));
+ newStatements.addAll(copyFinally(lc, finallyBody));
if (!isTerminal(newStatements)) {
newStatements.add(expr == null ? returnNode : returnNode.setExpression(resultNode));
}
@@ -382,7 +388,7 @@ final class Lower extends NodeOperatorVisitor {
private Node copy(final Statement endpoint, final Node targetNode) {
if (!insideTry.contains(targetNode)) {
- final List newStatements = copyFinally(finallyBody);
+ final List newStatements = copyFinally(lc, finallyBody);
if (!isTerminal(newStatements)) {
newStatements.add(endpoint);
}
@@ -548,7 +554,7 @@ final class Lower extends NodeOperatorVisitor {
final FunctionNode currentFunction = getLexicalContext().getCurrentFunction();
return callNode.setEvalArgs(
new CallNode.EvalArgs(
- ensureUniqueLabelsIn(args.get(0)).accept(this),
+ ensureUniqueNamesIn(getLexicalContext(), args.get(0)).accept(this),
compilerConstant(THIS),
evalLocation(callee),
currentFunction.isStrict()));
diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
index 2b6d19bf501..715d4507ac3 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
@@ -250,6 +250,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags compilationState,
@@ -260,6 +261,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags newState = EnumSet.copyOf(this.compilationState);
newState.add(state);
- return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, returnType, compileUnit, newState, body, parameters, snapshot, hints));
+ return Node.replaceInLexicalContext(lc, this, new FunctionNode(this, lastToken, flags, name, returnType, compileUnit, newState, body, parameters, snapshot, hints));
}
/**
@@ -410,7 +411,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags
Date: Thu, 16 May 2013 19:52:39 +0200
Subject: [PATCH 017/206] 8012359: Increase code coverage in Joni
Reviewed-by: jlaskey, lagergren
---
nashorn/make/build.xml | 2 +
.../{DefaultRegExp.java => JdkRegExp.java} | 4 +-
.../internal/runtime/regexp/JoniRegExp.java | 2 +-
.../runtime/regexp/RegExpFactory.java | 6 +-
.../runtime/regexp/joni/Analyser.java | 837 +-----------------
.../runtime/regexp/joni/ArrayCompiler.java | 410 ++-------
.../runtime/regexp/joni/AsmCompiler.java | 109 ---
.../regexp/joni/AsmCompilerSupport.java | 267 ------
.../internal/runtime/regexp/joni/BitSet.java | 8 -
.../runtime/regexp/joni/BitStatus.java | 7 +-
.../runtime/regexp/joni/ByteCodeMachine.java | 263 ------
.../runtime/regexp/joni/ByteCodePrinter.java | 237 ++++-
.../runtime/regexp/joni/CaptureTreeNode.java | 74 --
.../runtime/regexp/joni/Compiler.java | 28 +-
.../internal/runtime/regexp/joni/Config.java | 17 +-
.../runtime/regexp/joni/EncodingHelper.java | 14 -
.../internal/runtime/regexp/joni/Lexer.java | 376 +-------
.../internal/runtime/regexp/joni/Matcher.java | 18 -
.../runtime/regexp/joni/NameEntry.java | 97 --
.../runtime/regexp/joni/NativeMachine.java | 27 -
.../internal/runtime/regexp/joni/Parser.java | 195 +---
.../internal/runtime/regexp/joni/Regex.java | 139 +--
.../internal/runtime/regexp/joni/Region.java | 19 -
.../runtime/regexp/joni/ScanEnvironment.java | 10 -
.../runtime/regexp/joni/ScannerSupport.java | 4 +-
.../runtime/regexp/joni/StackMachine.java | 104 ---
.../internal/runtime/regexp/joni/Syntax.java | 2 +-
.../runtime/regexp/joni/UnsetAddrList.java | 69 --
.../runtime/regexp/joni/ast/CClassNode.java | 40 +-
.../runtime/regexp/joni/ast/CTypeNode.java | 50 --
.../runtime/regexp/joni/ast/CallNode.java | 86 --
.../runtime/regexp/joni/ast/EncloseNode.java | 38 +-
.../regexp/joni/ast/QuantifierNode.java | 44 +-
.../runtime/regexp/joni/ast/StateNode.java | 65 --
.../regexp/joni/bench/AbstractBench.java | 49 -
.../joni/bench/BenchGreedyBacktrack.java | 7 -
.../regexp/joni/bench/BenchRailsRegs.java | 31 -
.../joni/bench/BenchSeveralRegexps.java | 17 -
.../runtime/regexp/joni/constants/OPCode.java | 235 -----
.../runtime/regexp/joni/constants/Reduce.java | 61 --
.../regexp/joni/encoding/AsciiTables.java | 157 ----
.../runtime/regexp/joni/encoding/ObjPtr.java | 1 -
.../regexp/joni/encoding/PosixBracket.java | 77 --
.../runtime/regexp/joni/encoding/Ptr.java | 35 -
.../regexp/joni/exception/ErrorMessages.java | 29 +-
.../regexp/joni/exception/ValueException.java | 4 -
.../runtime/regexp/JdkRegExpTest.java | 61 ++
.../runtime/regexp/joni/JoniTest.java | 52 ++
48 files changed, 531 insertions(+), 3953 deletions(-)
rename nashorn/src/jdk/nashorn/internal/runtime/regexp/{DefaultRegExp.java => JdkRegExp.java} (97%)
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CTypeNode.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/CallNode.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchGreedyBacktrack.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchRailsRegs.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/BenchSeveralRegexps.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/constants/Reduce.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/AsciiTables.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java
delete mode 100644 nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/Ptr.java
create mode 100644 nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java
create mode 100644 nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index d884b2fe009..c647ba4b922 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -305,6 +305,8 @@
+
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java
similarity index 97%
rename from nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
rename to nashorn/src/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java
index e3157ba5cb8..9250331deda 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/DefaultRegExp.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JdkRegExp.java
@@ -41,7 +41,7 @@ import java.util.regex.PatternSyntaxException;
* Note that this class is not thread-safe as it stores the current match result
* and the string being matched in instance fields.
*/
-public class DefaultRegExp extends RegExp {
+public class JdkRegExp extends RegExp {
/** Java regexp pattern to use for match. We compile to one of these */
private Pattern pattern;
@@ -56,7 +56,7 @@ public class DefaultRegExp extends RegExp {
* @param flags RegExp flag string
* @throws ParserException if flags is invalid or source string has syntax error.
*/
- public DefaultRegExp(final String source, final String flags) throws ParserException {
+ public JdkRegExp(final String source, final String flags) throws ParserException {
super(source, flags);
int intFlags = 0;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
index 1047221af69..f797b051adc 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/JoniRegExp.java
@@ -113,7 +113,7 @@ public class JoniRegExp extends RegExp {
public static class Factory extends RegExpFactory {
@Override
- protected RegExp compile(final String pattern, final String flags) throws ParserException {
+ public RegExp compile(final String pattern, final String flags) throws ParserException {
return new JoniRegExp(pattern, flags);
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
index 4a7ac11bc99..08168b63779 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpFactory.java
@@ -29,7 +29,7 @@ import jdk.nashorn.internal.runtime.ParserException;
import jdk.nashorn.internal.runtime.options.Options;
/**
- * Factory class for regular expressions. This class creates instances of {@link DefaultRegExp}.
+ * Factory class for regular expressions. This class creates instances of {@link JdkRegExp}.
* An alternative factory can be installed using the {@code nashorn.regexp.impl} system property.
*/
public class RegExpFactory {
@@ -62,8 +62,8 @@ public class RegExpFactory {
* @return new RegExp
* @throws ParserException if flags is invalid or pattern string has syntax error.
*/
- protected RegExp compile(final String pattern, final String flags) throws ParserException {
- return new DefaultRegExp(pattern, flags);
+ public RegExp compile(final String pattern, final String flags) throws ParserException {
+ return new JdkRegExp(pattern, flags);
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
index 49a2a925ec8..c0dbf0d8740 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java
@@ -21,10 +21,7 @@ package jdk.nashorn.internal.runtime.regexp.joni;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAll;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
-import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsClear;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAt;
-import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
-import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isFindCondition;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isMultiline;
@@ -36,8 +33,6 @@ import java.util.HashSet;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@@ -49,9 +44,7 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.NodeType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
import jdk.nashorn.internal.runtime.regexp.joni.constants.StackPopLevel;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.ObjPtr;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
final class Analyser extends Parser {
@@ -74,38 +67,9 @@ final class Analyser extends Parser {
//regex.repeatRangeAlloc = 0;
regex.repeatRangeLo = null;
regex.repeatRangeHi = null;
- regex.numCombExpCheck = 0;
-
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) regex.numCombExpCheck = 0;
parse();
- if (Config.USE_NAMED_GROUP) {
- /* mixed use named group and no-named group */
- if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(regex.options)) {
- if (env.numNamed != env.numMem) {
- root = disableNoNameGroupCapture(root);
- } else {
- numberedRefCheck(root);
- }
- }
- } // USE_NAMED_GROUP
-
- if (Config.USE_NAMED_GROUP) {
- if (env.numCall > 0) {
- env.unsetAddrList = new UnsetAddrList(env.numCall);
- setupSubExpCall(root);
- // r != 0 ???
- subexpRecursiveCheckTrav(root);
- // r < 0 -< err, FOUND_CALLED_NODE = 1
- subexpInfRecursiveCheckTrav(root);
- // r != 0 recursion infinite ???
- regex.numCall = env.numCall;
- } else {
- regex.numCall = 0;
- }
- } // USE_NAMED_GROUP
-
if (Config.DEBUG_PARSE_TREE_RAW && Config.DEBUG_PARSE_TREE) {
Config.log.println("");
Config.log.println(root + "\n");
@@ -129,27 +93,6 @@ final class Analyser extends Parser {
regex.btMemEnd |= regex.captureHistory;
}
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (env.backrefedMem == 0 || (Config.USE_SUBEXP_CALL && env.numCall == 0)) {
- setupCombExpCheck(root, 0);
-
- if (Config.USE_SUBEXP_CALL && env.hasRecursion) {
- env.numCombExpCheck = 0;
- } else { // USE_SUBEXP_CALL
- if (env.combExpMaxRegNum > 0) {
- for (int i=1; ic)/
- node = noNameDisableMap(node, map, counter);
- }
- } else {
- //en.target = noNameDisableMap(en.target, map, counter);
- en.setTarget(noNameDisableMap(en.target, map, counter)); // ???
- }
- return node;
- }
-
- private void noNameDisableMapFor_anchor(Node node, int[]map, Ptr counter) {
- AnchorNode an = (AnchorNode)node;
- switch (an.type) {
- case AnchorNode.PREC_READ:
- case AnchorNode.PREC_READ_NOT:
- case AnchorNode.LOOK_BEHIND:
- case AnchorNode.LOOK_BEHIND_NOT:
- an.setTarget(noNameDisableMap(an.target, map, counter));
- }
- }
-
- private Node noNameDisableMap(Node node, int[]map, Ptr counter) {
- switch (node.getType()) {
- case NodeType.LIST:
- case NodeType.ALT:
- noNameDisableMapFor_cosAlt(node, map, counter);
- break;
- case NodeType.QTFR:
- noNameDisableMapFor_quantifier(node, map, counter);
- break;
- case NodeType.ENCLOSE:
- node = noNameDisableMapFor_enclose(node, map, counter);
- break;
- case NodeType.ANCHOR:
- noNameDisableMapFor_anchor(node, map, counter);
- break;
- } // switch
- return node;
- }
-
- private void renumberByMap(Node node, int[]map) {
- switch (node.getType()) {
- case NodeType.LIST:
- case NodeType.ALT:
- ConsAltNode can = (ConsAltNode)node;
- do {
- renumberByMap(can.car, map);
- } while ((can = can.cdr) != null);
- break;
-
- case NodeType.QTFR:
- renumberByMap(((QuantifierNode)node).target, map);
- break;
-
- case NodeType.ENCLOSE:
- renumberByMap(((EncloseNode)node).target, map);
- break;
-
- case NodeType.BREF:
- ((BackRefNode)node).renumber(map);
- break;
- } // switch
- }
-
- protected final void numberedRefCheck(Node node) {
- switch (node.getType()) {
- case NodeType.LIST:
- case NodeType.ALT:
- ConsAltNode can = (ConsAltNode)node;
- do {
- numberedRefCheck(can.car);
- } while ((can = can.cdr) != null);
- break;
-
- case NodeType.QTFR:
- numberedRefCheck(((QuantifierNode)node).target);
- break;
-
- case NodeType.ENCLOSE:
- numberedRefCheck(((EncloseNode)node).target);
- break;
-
- case NodeType.BREF:
- BackRefNode br = (BackRefNode)node;
- if (!br.isNameRef()) newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
- break;
- } // switch
- }
-
- protected final Node disableNoNameGroupCapture(Node root) {
- int[]map = new int[env.numMem + 1];
-
- for (int i=1; i<=env.numMem; i++) map[i] = 0;
-
- root = noNameDisableMap(root, map, new Ptr(0));
- renumberByMap(root, map);
-
- for (int i=1, pos=1; i<=env.numMem; i++) {
- if (map[i] > 0) {
- env.memNodes[pos] = env.memNodes[i];
- pos++;
- }
- }
-
- int loc = env.captureHistory;
- env.captureHistory = bsClear();
-
- for (int i=1; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
- if (bsAt(loc, i)) {
- env.captureHistory = bsOnAtSimple(env.captureHistory, map[i]);
- }
- }
-
- env.numMem = env.numNamed;
- regex.numMem = env.numNamed;
-
- regex.renumberNameTable(map);
-
- return root;
- }
-
private void swap(Node a, Node b) {
a.swap(b);
@@ -352,17 +143,6 @@ final class Analyser extends Parser {
} while ((can = can.cdr) != null);
break;
- case NodeType.CALL:
- if (Config.USE_SUBEXP_CALL) {
- CallNode cn = (CallNode)node;
- if (cn.isRecursion()) {
- return TargetInfo.IS_EMPTY_REC; /* tiny version */
- } else {
- info = quantifiersMemoryInfo(cn.target);
- }
- } // USE_SUBEXP_CALL
- break;
-
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.upper != 0) {
@@ -417,18 +197,6 @@ final class Analyser extends Parser {
}
break;
- case NodeType.CALL:
- if (Config.USE_SUBEXP_CALL) {
- CallNode cn = (CallNode)node;
- if (cn.isRecursion()) {
- EncloseNode en = (EncloseNode)cn.target;
- if (en.isMinFixed()) min = en.minLength;
- } else {
- min = getMinMatchLength(cn.target);
- }
- } // USE_SUBEXP_CALL
- break;
-
case NodeType.LIST:
ConsAltNode can = (ConsAltNode)node;
do {
@@ -474,15 +242,13 @@ final class Analyser extends Parser {
EncloseNode en = (EncloseNode)node;
switch (en.type) {
case EncloseType.MEMORY:
- if (Config.USE_SUBEXP_CALL) {
- if (en.isMinFixed()) {
- min = en.minLength;
- } else {
- min = getMinMatchLength(en.target);
- en.minLength = min;
- en.setMinFixed();
- }
- } // USE_SUBEXP_CALL
+ if (en.isMinFixed()) {
+ min = en.minLength;
+ } else {
+ min = getMinMatchLength(en.target);
+ en.minLength = min;
+ en.setMinFixed();
+ }
break;
case EncloseType.OPTION:
@@ -547,17 +313,6 @@ final class Analyser extends Parser {
}
break;
- case NodeType.CALL:
- if (Config.USE_SUBEXP_CALL) {
- CallNode cn = (CallNode)node;
- if (!cn.isRecursion()) {
- max = getMaxMatchLength(cn.target);
- } else {
- max = MinMaxLen.INFINITE_DISTANCE;
- }
- } // USE_SUBEXP_CALL
- break;
-
case NodeType.QTFR:
QuantifierNode qn = (QuantifierNode)node;
if (qn.upper != 0) {
@@ -576,15 +331,13 @@ final class Analyser extends Parser {
EncloseNode en = (EncloseNode)node;
switch (en.type) {
case EncloseType.MEMORY:
- if (Config.USE_SUBEXP_CALL) {
- if (en.isMaxFixed()) {
- max = en.maxLength;
- } else {
- max = getMaxMatchLength(en.target);
- en.maxLength = max;
- en.setMaxFixed();
- }
- } // USE_SUBEXP_CALL
+ if (en.isMaxFixed()) {
+ max = en.maxLength;
+ } else {
+ max = getMaxMatchLength(en.target);
+ en.maxLength = max;
+ en.setMaxFixed();
+ }
break;
case EncloseType.OPTION:
@@ -663,17 +416,6 @@ final class Analyser extends Parser {
}
break;
- case NodeType.CALL:
- if (Config.USE_SUBEXP_CALL) {
- CallNode cn = (CallNode)node;
- if (!cn.isRecursion()) {
- len = getCharLengthTree(cn.target, level);
- } else {
- returnCode = GET_CHAR_LEN_VARLEN;
- }
- } // USE_SUBEXP_CALL
- break;
-
case NodeType.CTYPE:
len = 1;
@@ -686,17 +428,15 @@ final class Analyser extends Parser {
EncloseNode en = (EncloseNode)node;
switch(en.type) {
case EncloseType.MEMORY:
- if (Config.USE_SUBEXP_CALL) {
- if (en.isCLenFixed()) {
- len = en.charLength;
- } else {
- len = getCharLengthTree(en.target, level);
- if (returnCode == 0) {
- en.charLength = len;
- en.setCLenFixed();
- }
+ if (en.isCLenFixed()) {
+ len = en.charLength;
+ } else {
+ len = getCharLengthTree(en.target, level);
+ if (returnCode == 0) {
+ en.charLength = len;
+ en.setCLenFixed();
}
- } // USE_SUBEXP_CALL
+ }
break;
case EncloseType.OPTION:
@@ -727,10 +467,6 @@ final class Analyser extends Parser {
switch(x.getType()) {
case NodeType.CTYPE:
switch(yType) {
- case NodeType.CTYPE:
- CTypeNode cny = (CTypeNode)y;
- CTypeNode cnx = (CTypeNode)x;
- return cny.ctype == cnx.ctype && cny.not != cnx.not;
case NodeType.CCLASS:
// !swap:!
@@ -756,37 +492,6 @@ final class Analyser extends Parser {
CClassNode xc = (CClassNode)x;
switch(yType) {
- case NodeType.CTYPE:
- switch(((CTypeNode)y).ctype) {
- case CharacterType.WORD:
- if (!((CTypeNode)y).not) {
- if (xc.mbuf == null && !xc.isNot()) {
- for (int i=0; i 0) newValueException(ERR_NEVER_ENDING_RECURSION);
- en.clearMark1();
- }
- r = subexpInfRecursiveCheckTrav(en.target);
- break;
-
- default:
- break;
- } // switch
-
- return r;
- }
-
- private int subexpRecursiveCheck(Node node) {
- int r = 0;
-
- switch (node.getType()) {
- case NodeType.LIST:
- case NodeType.ALT:
- ConsAltNode can = (ConsAltNode)node;
- do {
- r |= subexpRecursiveCheck(can.car);
- } while ((can = can.cdr) != null);
- break;
-
- case NodeType.QTFR:
- r = subexpRecursiveCheck(((QuantifierNode)node).target);
- break;
-
- case NodeType.ANCHOR:
- AnchorNode an = (AnchorNode)node;
- switch (an.type) {
- case AnchorType.PREC_READ:
- case AnchorType.PREC_READ_NOT:
- case AnchorType.LOOK_BEHIND:
- case AnchorType.LOOK_BEHIND_NOT:
- r = subexpRecursiveCheck(an.target);
- break;
- } // inner switch
- break;
-
- case NodeType.CALL:
- CallNode cn = (CallNode)node;
- r = subexpRecursiveCheck(cn.target);
- if (r != 0) cn.setRecursion();
- break;
-
- case NodeType.ENCLOSE:
- EncloseNode en = (EncloseNode)node;
- if (en.isMark2()) {
- return 0;
- } else if (en.isMark1()) {
- return 1; /* recursion */
- } else {
- en.setMark2();
- r = subexpRecursiveCheck(en.target);
- en.clearMark2();
- }
- break;
-
- default:
- break;
- } // switch
-
- return r;
- }
-
- private static final int FOUND_CALLED_NODE = 1;
- protected final int subexpRecursiveCheckTrav(Node node) {
- int r = 0;
-
- switch (node.getType()) {
- case NodeType.LIST:
- case NodeType.ALT:
- ConsAltNode can = (ConsAltNode)node;
- do {
- int ret = subexpRecursiveCheckTrav(can.car);
- if (ret == FOUND_CALLED_NODE) {
- r = FOUND_CALLED_NODE;
- }
- // else if (ret < 0) return ret; ???
- } while ((can = can.cdr) != null);
- break;
-
- case NodeType.QTFR:
- QuantifierNode qn = (QuantifierNode)node;
- r = subexpRecursiveCheckTrav(qn.target);
- if (qn.upper == 0) {
- if (r == FOUND_CALLED_NODE) qn.isRefered = true;
- }
- break;
-
- case NodeType.ANCHOR:
- AnchorNode an = (AnchorNode)node;
- switch (an.type) {
- case AnchorType.PREC_READ:
- case AnchorType.PREC_READ_NOT:
- case AnchorType.LOOK_BEHIND:
- case AnchorType.LOOK_BEHIND_NOT:
- r = subexpRecursiveCheckTrav(an.target);
- break;
- } // inner switch
- break;
-
- case NodeType.ENCLOSE:
- EncloseNode en = (EncloseNode)node;
- if (!en.isRecursion()) {
- if (en.isCalled()) {
- en.setMark1();
- r = subexpRecursiveCheck(en.target);
- if (r != 0) en.setRecursion();
- en.clearMark1();
- }
- }
- r = subexpRecursiveCheckTrav(en.target);
- if (en.isCalled()) r |= FOUND_CALLED_NODE;
- break;
-
- default:
- break;
- } // switch
-
- return r;
- }
-
- private void setCallAttr(CallNode cn) {
- cn.target = env.memNodes[cn.groupNum]; // no setTarget in call nodes!
- if (cn.target == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
-
- ((EncloseNode)cn.target).setCalled();
- env.btMemStart = BitStatus.bsOnAt(env.btMemStart, cn.groupNum);
- cn.unsetAddrList = env.unsetAddrList;
- }
-
- protected final void setupSubExpCall(Node node) {
-
- switch(node.getType()) {
- case NodeType.LIST:
- ConsAltNode ln = (ConsAltNode)node;
- do {
- setupSubExpCall(ln.car);
- } while ((ln = ln.cdr) != null);
- break;
-
- case NodeType.ALT:
- ConsAltNode can = (ConsAltNode)node;
- do {
- setupSubExpCall(can.car);
- } while ((can = can.cdr) != null);
- break;
-
- case NodeType.QTFR:
- setupSubExpCall(((QuantifierNode)node).target);
- break;
-
- case NodeType.ENCLOSE:
- setupSubExpCall(((EncloseNode)node).target);
- break;
-
- case NodeType.CALL:
- CallNode cn = (CallNode)node;
-
- if (cn.groupNum != 0) {
- int gNum = cn.groupNum;
-
- if (Config.USE_NAMED_GROUP) {
- if (env.numNamed > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(env.option)) {
- newValueException(ERR_NUMBERED_BACKREF_OR_CALL_NOT_ALLOWED);
- }
- } // USE_NAMED_GROUP
- if (gNum > env.numMem) newValueException(ERR_UNDEFINED_GROUP_REFERENCE, cn.nameP, cn.nameEnd);
- setCallAttr(cn);
- } else {
- if (Config.USE_NAMED_GROUP) {
- NameEntry ne = regex.nameToGroupNumbers(cn.name, cn.nameP, cn.nameEnd);
-
- if (ne == null) {
- newValueException(ERR_UNDEFINED_NAME_REFERENCE, cn.nameP, cn.nameEnd);
- } else if (ne.backNum > 1) {
- newValueException(ERR_MULTIPLEX_DEFINITION_NAME_CALL, cn.nameP, cn.nameEnd);
- } else {
- cn.groupNum = ne.backRef1; // ne.backNum == 1 ? ne.backRef1 : ne.backRefs[0]; // ??? need to check ?
- setCallAttr(cn);
- }
- }
- }
- break;
-
- case NodeType.ANCHOR:
- AnchorNode an = (AnchorNode)node;
- switch (an.type) {
- case AnchorType.PREC_READ:
- case AnchorType.PREC_READ_NOT:
- case AnchorType.LOOK_BEHIND:
- case AnchorType.LOOK_BEHIND_NOT:
- setupSubExpCall(an.target);
- break;
- }
- break;
-
- } // switch
- }
-
/* divide different length alternatives in look-behind.
(?<=A|B) ==> (?<=A)|(?<=B)
(? (?= 0 && (ln = ln.cdr) != null);
- break;
-
- case NodeType.ALT:
- ConsAltNode an = (ConsAltNode)node;
- do {
- ret = setupCombExpCheck(an.car, state);
- r |= ret;
- } while (ret >= 0 && (an = an.cdr) != null);
- break;
-
- case NodeType.QTFR:
- QuantifierNode qn = (QuantifierNode)node;
- int childState = state;
- int addState = 0;
- int varNum;
-
- if (!isRepeatInfinite(qn.upper)) {
- if (qn.upper > 1) {
- /* {0,1}, {1,1} are allowed */
- childState |= CEC_IN_FINITE_REPEAT;
-
- /* check (a*){n,m}, (a+){n,m} => (a*){n,n}, (a+){n,n} */
- if (env.backrefedMem == 0) {
- if (qn.target.getType() == NodeType.ENCLOSE) {
- EncloseNode en = (EncloseNode)qn.target;
- if (en.type == EncloseType.MEMORY) {
- if (en.target.getType() == NodeType.QTFR) {
- QuantifierNode q = (QuantifierNode)en.target;
- if (isRepeatInfinite(q.upper) && q.greedy == qn.greedy) {
- qn.upper = qn.lower == 0 ? 1 : qn.lower;
- if (qn.upper == 1) childState = state;
- }
- }
- }
- }
- }
- }
- }
-
- if ((state & CEC_IN_FINITE_REPEAT) != 0) {
- qn.combExpCheckNum = -1;
- } else {
- if (isRepeatInfinite(qn.upper)) {
- varNum = CEC_INFINITE_NUM;
- childState |= CEC_IN_INFINITE_REPEAT;
- } else {
- varNum = qn.upper - qn.lower;
- }
-
- if (varNum >= CEC_THRES_NUM_BIG_REPEAT) addState |= CEC_CONT_BIG_REPEAT;
-
- if (((state & CEC_IN_INFINITE_REPEAT) != 0 && varNum != 0) ||
- ((state & CEC_CONT_BIG_REPEAT) != 0 && varNum >= CEC_THRES_NUM_BIG_REPEAT)) {
- if (qn.combExpCheckNum == 0) {
- env.numCombExpCheck++;
- qn.combExpCheckNum = env.numCombExpCheck;
- if (env.currMaxRegNum > env.combExpMaxRegNum) {
- env.combExpMaxRegNum = env.currMaxRegNum;
- }
- }
- }
- }
- r = setupCombExpCheck(qn.target, childState);
- r |= addState;
- break;
-
- case NodeType.ENCLOSE:
- EncloseNode en = (EncloseNode)node;
- switch( en.type) {
- case EncloseNode.MEMORY:
- if (env.currMaxRegNum < en.regNum) {
- env.currMaxRegNum = en.regNum;
- }
- r = setupCombExpCheck(en.target, state);
- break;
-
- default:
- r = setupCombExpCheck(en.target, state);
- } // inner switch
- break;
-
- case NodeType.CALL:
- if (Config.USE_SUBEXP_CALL) {
- CallNode cn = (CallNode)node;
- if (cn.isRecursion()) {
- env.hasRecursion = true;
- } else {
- r = setupCombExpCheck(cn.target, state);
- }
- } // USE_SUBEXP_CALL
- break;
-
- default:
- break;
-
- } // switch
-
- return r;
- }
-
private static final int IN_ALT = (1<<0);
private static final int IN_NOT = (1<<1);
private static final int IN_REPEAT = (1<<2);
@@ -1691,20 +953,12 @@ final class Analyser extends Parser {
case NodeType.CANY:
break;
- case NodeType.CALL: // if (Config.USE_SUBEXP_CALL) ?
- break;
-
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
for (int i=0; i env.numMem) newValueException(ERR_INVALID_BACKREF);
env.backrefedMem = bsOnAt(env.backrefedMem, br.back[i]);
env.btMemStart = bsOnAt(env.btMemStart, br.back[i]);
- if (Config.USE_BACKREF_WITH_LEVEL) {
- if (br.isNestLevel()) {
- env.btMemEnd = bsOnAt(env.btMemEnd, br.back[i]);
- }
- } // USE_BACKREF_AT_LEVEL
((EncloseNode)env.memNodes[br.back[i]]).setMemBackrefed();
}
break;
@@ -1916,37 +1170,6 @@ final class Analyser extends Parser {
break;
}
- case NodeType.CTYPE: {
- int min;
- int max = 1;
- if (max == 1) {
- min = 1;
- CTypeNode cn = (CTypeNode)node;
-
- switch (cn.ctype) {
- case CharacterType.WORD:
- if (cn.not) {
- for (int i=0; i MAX_NODE_OPT_INFO_REF_COUNT) {
+ if (++en.optCount > MAX_NODE_OPT_INFO_REF_COUNT) {
int min = 0;
int max = MinMaxLen.INFINITE_DISTANCE;
if (en.isMinFixed()) min = en.minLength;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java
index b55991698b6..f348a205289 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ArrayCompiler.java
@@ -28,8 +28,6 @@ import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.isRepe
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@@ -71,11 +69,6 @@ final class ArrayCompiler extends Compiler {
regex.templates = templates;
regex.templateNum = templateNum;
regex.factory = MatcherFactory.DEFAULT;
-
- if (Config.USE_SUBEXP_CALL && analyser.env.unsetAddrList != null) {
- analyser.env.unsetAddrList.fix(regex);
- analyser.env.unsetAddrList = null;
- }
}
@Override
@@ -119,7 +112,7 @@ final class ArrayCompiler extends Compiler {
return isNeedStrLenOpExact(op);
}
- private int selectStrOpcode(int mbLength, int strLength, boolean ignoreCase) {
+ private int selectStrOpcode(int strLength, boolean ignoreCase) {
int op;
if (ignoreCase) {
@@ -128,31 +121,14 @@ final class ArrayCompiler extends Compiler {
default:op = OPCode.EXACTN_IC; break;
} // switch
} else {
- switch (mbLength) {
- case 1:
- switch (strLength) {
- case 1: op = OPCode.EXACT1; break;
- case 2: op = OPCode.EXACT2; break;
- case 3: op = OPCode.EXACT3; break;
- case 4: op = OPCode.EXACT4; break;
- case 5: op = OPCode.EXACT5; break;
- default:op = OPCode.EXACTN; break;
- } // inner switch
- break;
- case 2:
- switch (strLength) {
- case 1: op = OPCode.EXACTMB2N1; break;
- case 2: op = OPCode.EXACTMB2N2; break;
- case 3: op = OPCode.EXACTMB2N3; break;
- default:op = OPCode.EXACTMB2N; break;
- } // inner switch
- break;
- case 3:
- op = OPCode.EXACTMB3N;
- break;
- default:
- op = OPCode.EXACTMBN;
- } // switch
+ switch (strLength) {
+ case 1: op = OPCode.EXACT1; break;
+ case 2: op = OPCode.EXACT2; break;
+ case 3: op = OPCode.EXACT3; break;
+ case 4: op = OPCode.EXACT4; break;
+ case 5: op = OPCode.EXACT5; break;
+ default:op = OPCode.EXACTN; break;
+ } // inner switch
}
return op;
}
@@ -185,8 +161,8 @@ final class ArrayCompiler extends Compiler {
}
}
- private int addCompileStringlength(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
- int op = selectStrOpcode(mbLength, strLength, ignoreCase);
+ private int addCompileStringlength(char[] chars, int p, int strLength, boolean ignoreCase) {
+ int op = selectStrOpcode(strLength, ignoreCase);
int len = OPSize.OPCODE;
if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
@@ -194,25 +170,21 @@ final class ArrayCompiler extends Compiler {
len += OPSize.LENGTH + OPSize.INDEX + OPSize.INDEX;
} else {
if (isNeedStrLenOpExact(op)) len += OPSize.LENGTH;
- len += mbLength * strLength;
+ len += strLength;
}
if (op == OPCode.EXACTMBN) len += OPSize.LENGTH;
return len;
}
@Override
- protected final void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
- int op = selectStrOpcode(mbLength, strLength, ignoreCase);
+ protected final void addCompileString(char[] chars, int p, int strLength, boolean ignoreCase) {
+ int op = selectStrOpcode(strLength, ignoreCase);
addOpcode(op);
- if (op == OPCode.EXACTMBN) addLength(mbLength);
+ if (op == OPCode.EXACTMBN) addLength(1);
if (isNeedStrLenOpExact(op)) {
- if (op == OPCode.EXACTN_IC || op == OPCode.EXACTN_IC_SB) {
- addLength(mbLength * strLength);
- } else {
- addLength(strLength);
- }
+ addLength(strLength);
}
if (Config.USE_STRING_TEMPLATES && opTemplated(op)) {
@@ -220,7 +192,7 @@ final class ArrayCompiler extends Compiler {
addInt(p);
addTemplate(chars);
} else {
- addChars(chars, p, mbLength * strLength);
+ addChars(chars, p, strLength);
}
}
@@ -242,14 +214,14 @@ final class ArrayCompiler extends Compiler {
slen++;
p++;
}
- int r = addCompileStringlength(chars, prev, 1, slen, ambig);
+ int r = addCompileStringlength(chars, prev, slen, ambig);
rlen += r;
return rlen;
}
private int compileLengthStringRawNode(StringNode sn) {
if (sn.length() <= 0) return 0;
- return addCompileStringlength(sn.chars, sn.p, 1 /*sb*/, sn.length(), false);
+ return addCompileStringlength(sn.chars, sn.p, sn.length(), false);
}
private void addMultiByteCClass(CodeRangeBuffer mbuf) {
@@ -311,26 +283,6 @@ final class ArrayCompiler extends Compiler {
}
}
- @Override
- protected void compileCTypeNode(CTypeNode node) {
- CTypeNode cn = node;
- int op;
- switch (cn.ctype) {
- case CharacterType.WORD:
- if (cn.not) {
- op = OPCode.NOT_WORD;
- } else {
- op = OPCode.WORD;
- }
- break;
-
- default:
- newInternalException(ERR_PARSER_BUG);
- return; // not reached
- } // inner switch
- addOpcode(op);
- }
-
@Override
protected void compileAnyCharNode() {
if (isMultiline(regex.options)) {
@@ -340,31 +292,16 @@ final class ArrayCompiler extends Compiler {
}
}
- @Override
- protected void compileCallNode(CallNode node) {
- addOpcode(OPCode.CALL);
- node.unsetAddrList.add(codeLength, node.target);
- addAbsAddr(0); /*dummy addr.*/
- }
-
@Override
protected void compileBackrefNode(BackRefNode node) {
BackRefNode br = node;
- if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
- addOpcode(OPCode.BACKREF_WITH_LEVEL);
- addOption(regex.options & Option.IGNORECASE);
- addLength(br.nestLevel);
- // !goto add_bacref_mems;!
- addLength(br.backNum);
- for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
- return;
- } else { // USE_BACKREF_AT_LEVEL
- if (br.backNum == 1) {
- if (isIgnoreCase(regex.options)) {
- addOpcode(OPCode.BACKREFN_IC);
- addMemNum(br.back[0]);
- } else {
- switch (br.back[0]) {
+ // USE_BACKREF_AT_LEVEL
+ if (br.backNum == 1) {
+ if (isIgnoreCase(regex.options)) {
+ addOpcode(OPCode.BACKREFN_IC);
+ addMemNum(br.back[0]);
+ } else {
+ switch (br.back[0]) {
case 1:
addOpcode(OPCode.BACKREF1);
break;
@@ -375,18 +312,17 @@ final class ArrayCompiler extends Compiler {
addOpcode(OPCode.BACKREFN);
addOpcode(br.back[0]);
break;
- } // switch
- }
- } else {
- if (isIgnoreCase(regex.options)) {
- addOpcode(OPCode.BACKREF_MULTI_IC);
- } else {
- addOpcode(OPCode.BACKREF_MULTI);
- }
- // !add_bacref_mems:!
- addLength(br.backNum);
- for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
+ } // switch
}
+ } else {
+ if (isIgnoreCase(regex.options)) {
+ addOpcode(OPCode.BACKREF_MULTI_IC);
+ } else {
+ addOpcode(OPCode.BACKREF_MULTI);
+ }
+ // !add_bacref_mems:!
+ addLength(br.backNum);
+ for (int i=br.backNum-1; i>=0; i--) addMemNum(br.back[i]);
}
}
@@ -419,7 +355,7 @@ final class ArrayCompiler extends Compiler {
compileTreeEmptyCheck(qn.target, emptyInfo);
- if ((Config.USE_SUBEXP_CALL && regex.numCall > 0) || qn.isInRepeat()) {
+ if (qn.isInRepeat()) {
addOpcode(qn.greedy ? OPCode.REPEAT_INC_SG : OPCode.REPEAT_INC_NG_SG);
} else {
addOpcode(qn.greedy ? OPCode.REPEAT_INC : OPCode.REPEAT_INC_NG);
@@ -434,193 +370,6 @@ final class ArrayCompiler extends Compiler {
return ckn > 0;
}
- private int compileCECLengthQuantifierNode(QuantifierNode qn) {
- boolean infinite = isRepeatInfinite(qn.upper);
- int emptyInfo = qn.targetEmptyInfo;
-
- int tlen = compileLengthTree(qn.target);
- int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
- int cklen = cknOn(ckn) ? OPSize.STATE_CHECK_NUM : 0;
-
- /* anychar repeat */
- if (qn.target.getType() == NodeType.CANY) {
- if (qn.greedy && infinite) {
- if (qn.nextHeadExact != null && !cknOn(ckn)) {
- return OPSize.ANYCHAR_STAR_PEEK_NEXT + tlen * qn.lower + cklen;
- } else {
- return OPSize.ANYCHAR_STAR + tlen * qn.lower + cklen;
- }
- }
- }
-
- int modTLen;
- if (emptyInfo != 0) {
- modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
- } else {
- modTLen = tlen;
- }
-
- int len;
- if (infinite && qn.lower <= 1) {
- if (qn.greedy) {
- if (qn.lower == 1) {
- len = OPSize.JUMP;
- } else {
- len = 0;
- }
- len += OPSize.PUSH + cklen + modTLen + OPSize.JUMP;
- } else {
- if (qn.lower == 0) {
- len = OPSize.JUMP;
- } else {
- len = 0;
- }
- len += modTLen + OPSize.PUSH + cklen;
- }
- } else if (qn.upper == 0) {
- if (qn.isRefered) { /* /(?..){0}/ */
- len = OPSize.JUMP + tlen;
- } else {
- len = 0;
- }
- } else if (qn.upper == 1 && qn.greedy) {
- if (qn.lower == 0) {
- if (cknOn(ckn)) {
- len = OPSize.STATE_CHECK_PUSH + tlen;
- } else {
- len = OPSize.PUSH + tlen;
- }
- } else {
- len = tlen;
- }
- } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0) { /* '??' */
- len = OPSize.PUSH + cklen + OPSize.JUMP + tlen;
- } else {
- len = OPSize.REPEAT_INC + modTLen + OPSize.OPCODE + OPSize.RELADDR + OPSize.MEMNUM;
-
- if (cknOn(ckn)) {
- len += OPSize.STATE_CHECK;
- }
- }
- return len;
- }
-
- @Override
- protected void compileCECQuantifierNode(QuantifierNode qn) {
- boolean infinite = isRepeatInfinite(qn.upper);
- int emptyInfo = qn.targetEmptyInfo;
-
- int tlen = compileLengthTree(qn.target);
-
- int ckn = regex.numCombExpCheck > 0 ? qn.combExpCheckNum : 0;
-
- if (qn.isAnyCharStar()) {
- compileTreeNTimes(qn.target, qn.lower);
- if (qn.nextHeadExact != null && !cknOn(ckn)) {
- if (isMultiline(regex.options)) {
- addOpcode(OPCode.ANYCHAR_ML_STAR_PEEK_NEXT);
- } else {
- addOpcode(OPCode.ANYCHAR_STAR_PEEK_NEXT);
- }
- if (cknOn(ckn)) {
- addStateCheckNum(ckn);
- }
- StringNode sn = (StringNode)qn.nextHeadExact;
- addChars(sn.chars, sn.p, 1);
- return;
- } else {
- if (isMultiline(regex.options)) {
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK_ANYCHAR_ML_STAR);
- } else {
- addOpcode(OPCode.ANYCHAR_ML_STAR);
- }
- } else {
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK_ANYCHAR_STAR);
- } else {
- addOpcode(OPCode.ANYCHAR_STAR);
- }
- }
- if (cknOn(ckn)) {
- addStateCheckNum(ckn);
- }
- return;
- }
- }
-
- int modTLen;
- if (emptyInfo != 0) {
- modTLen = tlen + (OPSize.NULL_CHECK_START + OPSize.NULL_CHECK_END);
- } else {
- modTLen = tlen;
- }
- if (infinite && qn.lower <= 1) {
- if (qn.greedy) {
- if (qn.lower == 1) {
- addOpcodeRelAddr(OPCode.JUMP, cknOn(ckn) ? OPSize.STATE_CHECK_PUSH :
- OPSize.PUSH);
- }
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK_PUSH);
- addStateCheckNum(ckn);
- addRelAddr(modTLen + OPSize.JUMP);
- } else {
- addOpcodeRelAddr(OPCode.PUSH, modTLen + OPSize.JUMP);
- }
- compileTreeEmptyCheck(qn.target, emptyInfo);
- addOpcodeRelAddr(OPCode.JUMP, -(modTLen + OPSize.JUMP + (cknOn(ckn) ?
- OPSize.STATE_CHECK_PUSH :
- OPSize.PUSH)));
- } else {
- if (qn.lower == 0) {
- addOpcodeRelAddr(OPCode.JUMP, modTLen);
- }
- compileTreeEmptyCheck(qn.target, emptyInfo);
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK_PUSH_OR_JUMP);
- addStateCheckNum(ckn);
- addRelAddr(-(modTLen + OPSize.STATE_CHECK_PUSH_OR_JUMP));
- } else {
- addOpcodeRelAddr(OPCode.PUSH, -(modTLen + OPSize.PUSH));
- }
- }
- } else if (qn.upper == 0) {
- if (qn.isRefered) { /* /(?..){0}/ */
- addOpcodeRelAddr(OPCode.JUMP, tlen);
- compileTree(qn.target);
- } // else r=0 ???
- } else if (qn.upper == 1 && qn.greedy) {
- if (qn.lower == 0) {
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK_PUSH);
- addStateCheckNum(ckn);
- addRelAddr(tlen);
- } else {
- addOpcodeRelAddr(OPCode.PUSH, tlen);
- }
- }
- compileTree(qn.target);
- } else if (!qn.greedy && qn.upper == 1 && qn.lower == 0){ /* '??' */
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK_PUSH);
- addStateCheckNum(ckn);
- addRelAddr(OPSize.JUMP);
- } else {
- addOpcodeRelAddr(OPCode.PUSH, OPSize.JUMP);
- }
-
- addOpcodeRelAddr(OPCode.JUMP, tlen);
- compileTree(qn.target);
- } else {
- compileRangeRepeatNode(qn, modTLen, emptyInfo);
- if (cknOn(ckn)) {
- addOpcode(OPCode.STATE_CHECK);
- addStateCheckNum(ckn);
- }
- }
- }
-
private int compileNonCECLengthQuantifierNode(QuantifierNode qn) {
boolean infinite = isRepeatInfinite(qn.upper);
int emptyInfo = qn.targetEmptyInfo;
@@ -821,21 +570,12 @@ final class ArrayCompiler extends Compiler {
int len;
switch (node.type) {
case EncloseType.MEMORY:
- if (Config.USE_SUBEXP_CALL && node.isCalled()) {
- len = OPSize.MEMORY_START_PUSH + tlen + OPSize.CALL + OPSize.JUMP + OPSize.RETURN;
- if (bsAt(regex.btMemEnd, node.regNum)) {
- len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
- } else {
- len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
- }
- } else { // USE_SUBEXP_CALL
- if (bsAt(regex.btMemStart, node.regNum)) {
- len = OPSize.MEMORY_START_PUSH;
- } else {
- len = OPSize.MEMORY_START;
- }
- len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
+ if (bsAt(regex.btMemStart, node.regNum)) {
+ len = OPSize.MEMORY_START_PUSH;
+ } else {
+ len = OPSize.MEMORY_START;
}
+ len += tlen + (bsAt(regex.btMemEnd, node.regNum) ? OPSize.MEMORY_END_PUSH : OPSize.MEMORY_END);
break;
case EncloseType.STOP_BACKTRACK:
@@ -860,23 +600,6 @@ final class ArrayCompiler extends Compiler {
int len;
switch (node.type) {
case EncloseType.MEMORY:
- if (Config.USE_SUBEXP_CALL) {
- if (node.isCalled()) {
- addOpcode(OPCode.CALL);
- node.callAddr = codeLength + OPSize.ABSADDR + OPSize.JUMP;
- node.setAddrFixed();
- addAbsAddr(node.callAddr);
- len = compileLengthTree(node.target);
- len += OPSize.MEMORY_START_PUSH + OPSize.RETURN;
- if (bsAt(regex.btMemEnd, node.regNum)) {
- len += node.isRecursion() ? OPSize.MEMORY_END_PUSH_REC : OPSize.MEMORY_END_PUSH;
- } else {
- len += node.isRecursion() ? OPSize.MEMORY_END_REC : OPSize.MEMORY_END;
- }
- addOpcodeRelAddr(OPCode.JUMP, len);
- }
- } // USE_SUBEXP_CALL
-
if (bsAt(regex.btMemStart, node.regNum)) {
addOpcode(OPCode.MEMORY_START_PUSH);
} else {
@@ -886,22 +609,12 @@ final class ArrayCompiler extends Compiler {
addMemNum(node.regNum);
compileTree(node.target);
- if (Config.USE_SUBEXP_CALL && node.isCalled()) {
- if (bsAt(regex.btMemEnd, node.regNum)) {
- addOpcode(node.isRecursion() ? OPCode.MEMORY_END_PUSH_REC : OPCode.MEMORY_END_PUSH);
- } else {
- addOpcode(node.isRecursion() ? OPCode.MEMORY_END_REC : OPCode.MEMORY_END);
- }
- addMemNum(node.regNum);
- addOpcode(OPCode.RETURN);
- } else { // USE_SUBEXP_CALL
- if (bsAt(regex.btMemEnd, node.regNum)) {
- addOpcode(OPCode.MEMORY_END_PUSH);
- } else {
- addOpcode(OPCode.MEMORY_END);
- }
- addMemNum(node.regNum);
+ if (bsAt(regex.btMemEnd, node.regNum)) {
+ addOpcode(OPCode.MEMORY_END_PUSH);
+ } else {
+ addOpcode(OPCode.MEMORY_END);
}
+ addMemNum(node.regNum);
break;
case EncloseType.STOP_BACKTRACK:
@@ -1078,32 +791,17 @@ final class ArrayCompiler extends Compiler {
case NodeType.BREF:
BackRefNode br = (BackRefNode)node;
- if (Config.USE_BACKREF_WITH_LEVEL && br.isNestLevel()) {
- len = OPSize.OPCODE + OPSize.OPTION + OPSize.LENGTH +
- OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
- } else { // USE_BACKREF_AT_LEVEL
- if (br.backNum == 1) {
- len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
- ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
- } else {
- len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
- }
+ // USE_BACKREF_AT_LEVEL
+ if (br.backNum == 1) {
+ len = ((!isIgnoreCase(regex.options) && br.back[0] <= 2)
+ ? OPSize.OPCODE : (OPSize.OPCODE + OPSize.MEMNUM));
+ } else {
+ len = OPSize.OPCODE + OPSize.LENGTH + (OPSize.MEMNUM * br.backNum);
}
break;
- case NodeType.CALL:
- if (Config.USE_SUBEXP_CALL) {
- len = OPSize.CALL;
- break;
- } // USE_SUBEXP_CALL
- break;
-
case NodeType.QTFR:
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- len = compileCECLengthQuantifierNode((QuantifierNode)node);
- } else {
- len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
- }
+ len = compileNonCECLengthQuantifierNode((QuantifierNode)node);
break;
case NodeType.ENCLOSE:
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java
deleted file mode 100644
index 475d6595bcd..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompiler.java
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni;
-
-import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode;
-
-final class AsmCompiler extends AsmCompilerSupport {
-
- public AsmCompiler(Analyser analyser) {
- super(analyser);
- }
-
- @Override
- protected void prepare() {
- REG_NUM++;
- prepareMachine();
- prepareMachineInit();
- prepareMachineMatch();
-
- prepareFactory();
- prepareFactoryInit();
- }
-
- @Override
- protected void finish() {
- setupFactoryInit();
-
- setupMachineInit();
- setupMachineMatch();
-
- setupClasses();
- }
-
- @Override
- protected void compileAltNode(ConsAltNode node) {
- }
-
- @Override
- protected void addCompileString(char[] chars, int p, int mbLength, int strLength, boolean ignoreCase) {
- String template = installTemplate(chars, p, strLength);
- }
-
- @Override
- protected void compileCClassNode(CClassNode node) {
- if (node.bs != null) {
- String bitsetName = installBitSet(node.bs.bits);
- }
- }
-
- @Override
- protected void compileCTypeNode(CTypeNode node) {
- }
-
- @Override
- protected void compileAnyCharNode() {
- }
-
- @Override
- protected void compileBackrefNode(BackRefNode node) {
- }
-
- @Override
- protected void compileCallNode(CallNode node) {
- }
-
- @Override
- protected void compileCECQuantifierNode(QuantifierNode node) {
- }
-
- @Override
- protected void compileNonCECQuantifierNode(QuantifierNode node) {
- }
-
- @Override
- protected void compileOptionNode(EncloseNode node) {
- }
-
- @Override
- protected void compileEncloseNode(EncloseNode node) {
- }
-
- @Override
- protected void compileAnchorNode(AnchorNode node) {
- }
-}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java
deleted file mode 100644
index 06ca21a9b06..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/AsmCompilerSupport.java
+++ /dev/null
@@ -1,267 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni;
-
-import java.io.FileOutputStream;
-import java.io.IOException;
-
-import jdk.nashorn.internal.runtime.regexp.joni.constants.AsmConstants;
-import jdk.internal.org.objectweb.asm.ClassWriter;
-import jdk.internal.org.objectweb.asm.MethodVisitor;
-import jdk.internal.org.objectweb.asm.Opcodes;
-
-abstract class AsmCompilerSupport extends Compiler implements Opcodes, AsmConstants {
- protected ClassWriter factory; // matcher allocator, also bit set, code rage and string template container
- protected MethodVisitor factoryInit;// factory constructor
- protected String factoryName;
-
- protected ClassWriter machine; // matcher
- protected MethodVisitor machineInit;// matcher constructor
- protected MethodVisitor match; // actual matcher implementation (the matchAt method)
- protected String machineName;
-
- // we will? try to manage visitMaxs ourselves for efficiency
- protected int maxStack = 1;
- protected int maxVars = LAST_INDEX;
-
- // for field generation
- protected int bitsets, ranges, templates;
-
- // simple class name postfix scheme for now
- static int REG_NUM = 0;
-
- // dummy class loader for now
- private static final class DummyClassLoader extends ClassLoader {
- public Class> defineClass(String name, byte[] bytes) {
- return super.defineClass(name, bytes, 0, bytes.length);
- }
- };
-
- private static final DummyClassLoader loader = new DummyClassLoader();
-
- AsmCompilerSupport(Analyser analyser) {
- super(analyser);
- }
-
- protected final void prepareFactory() {
- factory = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- factoryName = "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory" + REG_NUM;
-
- factory.visit(V1_4, ACC_PUBLIC + ACC_FINAL, factoryName, null, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", null);
-
- MethodVisitor create = factory.visitMethod(ACC_SYNTHETIC, "create", "(Lorg/joni/Regex;[BII)Lorg/joni/Matcher;", null, null);
- create.visitTypeInsn(NEW, machineName);
- create.visitInsn(DUP); // instance
- create.visitVarInsn(ALOAD, 1); // Regex
- create.visitVarInsn(ALOAD, 2); // bytes[]
- create.visitVarInsn(ILOAD, 3); // p
- create.visitVarInsn(ILOAD, 4); // end
- create.visitMethodInsn(INVOKESPECIAL, machineName, "", "(Lorg/joni/Regex;[BII)V");
- create.visitInsn(ARETURN);
- create.visitMaxs(0, 0);
- //create.visitMaxs(6, 5);
- create.visitEnd();
- }
-
- protected final void prepareFactoryInit() {
- factoryInit = factory.visitMethod(ACC_PUBLIC, "", "()V", null, null);
- factoryInit.visitVarInsn(ALOAD, 0);
- factoryInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/MatcherFactory", "", "()V");
- }
-
- protected final void setupFactoryInit() {
- factoryInit.visitInsn(RETURN);
- factoryInit.visitMaxs(0, 0);
- //init.visitMaxs(1, 1);
- factoryInit.visitEnd();
- }
-
- protected final void prepareMachine() {
- machine = new ClassWriter(ClassWriter.COMPUTE_MAXS);
- machineName = "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine" + REG_NUM;
- }
-
- protected final void prepareMachineInit() {
- machine.visit(V1_4, ACC_PUBLIC + ACC_FINAL, machineName, null, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", null);
- machineInit = machine.visitMethod(ACC_PROTECTED, "", "(Lorg/joni/Regex;[BII)V", null, null);
- machineInit.visitVarInsn(ALOAD, THIS); // this
- machineInit.visitVarInsn(ALOAD, 1); // Regex
- machineInit.visitVarInsn(ALOAD, 2); // bytes[]
- machineInit.visitVarInsn(ILOAD, 3); // p
- machineInit.visitVarInsn(ILOAD, 4); // end
- machineInit.visitMethodInsn(INVOKESPECIAL, "jdk/nashorn/internal/runtime/regexp/joni/NativeMachine", "", "(Lorg/joni/Regex;[BII)V");
- }
-
- protected final void setupMachineInit() {
- if (bitsets + ranges + templates > 0) { // ok, some of these are in use, we'd like to cache the factory
- machine.visitField(ACC_PRIVATE + ACC_FINAL, "factory", "L" + factoryName + ";", null, null);
- machineInit.visitVarInsn(ALOAD, THIS); // this
- machineInit.visitVarInsn(ALOAD, 1); // this, Regex
- machineInit.visitFieldInsn(GETFIELD, "jdk/nashorn/internal/runtime/regexp/joni/Regex", "factory", "Lorg/joni/MatcherFactory;"); // this, factory
- machineInit.visitTypeInsn(CHECKCAST, factoryName);
- machineInit.visitFieldInsn(PUTFIELD, machineName, "factory", "L" + factoryName + ";"); // []
- }
-
- machineInit.visitInsn(RETURN);
- machineInit.visitMaxs(0, 0);
- //init.visitMaxs(5, 5);
- machineInit.visitEnd();
- }
-
- protected final void prepareMachineMatch() {
- match = machine.visitMethod(ACC_SYNTHETIC, "matchAt", "(III)I", null, null);
- move(S, SSTART); // s = sstart
- load("bytes", "[B"); //
- astore(BYTES); // byte[]bytes = this.bytes
- }
-
- protected final void setupMachineMatch() {
- match.visitInsn(ICONST_M1);
- match.visitInsn(IRETURN);
-
- match.visitMaxs(maxStack, maxVars);
- match.visitEnd();
- }
-
- protected final void setupClasses() {
- byte[]factoryCode = factory.toByteArray();
- byte[]machineCode = machine.toByteArray();
-
- if (Config.DEBUG_ASM) {
- try {
- FileOutputStream fos;
- fos = new FileOutputStream(factoryName.substring(factoryName.lastIndexOf('/') + 1) + ".class");
- fos.write(factoryCode);
- fos.close();
- fos = new FileOutputStream(machineName.substring(machineName.lastIndexOf('/') + 1) + ".class");
- fos.write(machineCode);
- fos.close();
- } catch (IOException ioe) {
- ioe.printStackTrace(Config.err);
- }
- }
-
- loader.defineClass(machineName.replace('/', '.'), machineCode);
- Class> cls = loader.defineClass(factoryName.replace('/', '.'), factoryCode);
- try {
- regex.factory = (MatcherFactory)cls.newInstance();
- } catch(Exception e) {
- e.printStackTrace(Config.err);
- }
- }
-
- protected final void aload(int var) {
- match.visitVarInsn(ALOAD, var);
- }
-
- protected final void astore(int var) {
- match.visitVarInsn(ASTORE, var);
- }
-
- protected final void loadThis() {
- match.visitVarInsn(ALOAD, THIS);
- }
-
- protected final void load(int var) {
- match.visitVarInsn(ILOAD, var);
- }
-
- protected final void store(int var) {
- match.visitVarInsn(ISTORE, var);
- }
-
- protected final void move(int to, int from) {
- load(from);
- store(to);
- }
-
- protected final void load(String field, String singature) {
- loadThis();
- match.visitFieldInsn(GETFIELD, machineName, field, singature);
- }
-
- protected final void load(String field) {
- load(field, "I");
- }
-
- protected final void store(String field, String singature) {
- loadThis();
- match.visitFieldInsn(PUTFIELD, machineName, field, singature);
- }
-
- protected final void store(String field) {
- store(field, "I");
- }
-
- protected final String installTemplate(char[] arr, int p, int length) {
- String templateName = TEMPLATE + ++templates;
- installArray(templateName, arr, p, length);
- return templateName;
- }
-
- protected final String installCodeRange(int[]arr) {
- String coreRangeName = CODERANGE + ++ranges;
- installArray(coreRangeName, arr);
- return coreRangeName;
- }
-
- protected final String installBitSet(int[]arr) {
- String bitsetName = BITSET + ++bitsets;
- installArray(bitsetName, arr);
- return bitsetName;
- }
-
- private void installArray(String name, int[]arr) {
- factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[I", null, null);
- factoryInit.visitVarInsn(ALOAD, THIS); // this;
- loadInt(factoryInit, arr.length); // this, length
- factoryInit.visitIntInsn(NEWARRAY, T_INT); // this, arr
- for (int i=0;i < arr.length; i++) buildArray(i, arr[i], IASTORE);
- factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[I");
- }
-
- private void installArray(String name, char[]arr, int p, int length) {
- factory.visitField(ACC_PRIVATE + ACC_FINAL, name, "[B", null, null);
- factoryInit.visitVarInsn(ALOAD, THIS); // this;
- loadInt(factoryInit, arr.length); // this, length
- factoryInit.visitIntInsn(NEWARRAY, T_BYTE); // this, arr
- for (int i=p, j=0; i < p + length; i++, j++) buildArray(j, arr[i] & 0xff, BASTORE);
- factoryInit.visitFieldInsn(PUTFIELD, factoryName, name, "[B");
- }
-
- private void buildArray(int index, int value, int type) {
- factoryInit.visitInsn(DUP); // ... arr, arr
- loadInt(factoryInit, index); // ... arr, arr, index
- loadInt(factoryInit, value); // ... arr, arr, index, value
- factoryInit.visitInsn(type); // ... arr
- }
-
- private void loadInt(MethodVisitor mv, int value) {
- if (value >= -1 && value <= 5) {
- mv.visitInsn(value + ICONST_0); // ICONST_0 == 3
- } else if (value >= 6 && value <= 127 || value >= -128 && value <= -2) {
- mv.visitIntInsn(BIPUSH, value);
- } else if (value >= 128 && value <= 32767 || value >= -32768 && value <= -129) {
- mv.visitIntInsn(SIPUSH, value);
- } else {
- mv.visitLdcInsn(new Integer(value));
- }
- }
-}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java
index bf715987428..5f98fe6411b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/BitSet.java
@@ -51,10 +51,6 @@ public final class BitSet {
bits[pos >>> ROOM_SHIFT] &= ~bit(pos);
}
- public void invert(int pos) {
- bits[pos >>> ROOM_SHIFT] ^= bit(pos);
- }
-
public void clear() {
for (int i=0; i range) {opFail(); return;}
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- sprev = sbegin; // break;
- }
-
- private void opExactMB2N2() {
- if (s + 4 > range) {opFail(); return;}
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- sprev = s;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- }
-
- private void opExactMB2N3() {
- if (s + 6 > range) {opFail(); return;}
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- sprev = s;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- }
-
- private void opExactMB2N() {
- int tlen = code[ip++];
- if (s + tlen * 2 > range) {opFail(); return;}
-
- if (Config.USE_STRING_TEMPLATES) {
- char[] bs = regex.templates[code[ip++]];
- int ps = code[ip++];
-
- while(tlen-- > 0) {
- if (bs[ps] != chars[s]) {opFail(); return;}
- ps++; s++;
- if (bs[ps] != chars[s]) {opFail(); return;}
- ps++; s++;
- }
- } else {
- while(tlen-- > 0) {
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- }
- }
- sprev = s - 2;
- }
-
- private void opExactMB3N() {
- int tlen = code[ip++];
- if (s + tlen * 3 > range) {opFail(); return;}
-
- if (Config.USE_STRING_TEMPLATES) {
- char[] bs = regex.templates[code[ip++]];
- int ps = code[ip++];
-
- while (tlen-- > 0) {
- if (bs[ps] != chars[s]) {opFail(); return;}
- ps++; s++;
- if (bs[ps] != chars[s]) {opFail(); return;}
- ps++; s++;
- if (bs[ps] != chars[s]) {opFail(); return;}
- ps++; s++;
- }
- } else {
- while (tlen-- > 0) {
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- }
- }
-
- sprev = s - 3;
- }
-
- private void opExactMBN() {
- int tlen = code[ip++]; /* mb-len */
- int tlen2= code[ip++]; /* string len */
-
- tlen2 *= tlen;
- if (s + tlen2 > range) {opFail(); return;}
-
- if (Config.USE_STRING_TEMPLATES) {
- char[] bs = regex.templates[code[ip++]];
- int ps = code[ip++];
-
- while (tlen2-- > 0) {
- if (bs[ps] != chars[s]) {opFail(); return;}
- ps++; s++;
- }
- } else {
- while (tlen2-- > 0) {
- if (code[ip] != chars[s]) {opFail(); return;}
- ip++; s++;
- }
- }
-
- sprev = s - tlen;
- }
-
private void opExact1IC() {
if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;}
ip++;
@@ -748,34 +558,6 @@ class ByteCodeMachine extends StackMachine {
sprev = sbegin; // break;
}
- // CEC
- private void opStateCheckAnyCharStar() {
- int mem = code[ip++];
- final char[] chars = this.chars;
-
- while (s < range) {
- if (stateCheckVal(s, mem)) {opFail(); return;}
- pushAltWithStateCheck(ip, s, sprev, mem);
- if (chars[s] == EncodingHelper.NEW_LINE) {opFail(); return;}
- sprev = s;
- s++;
- }
- sprev = sbegin; // break;
- }
-
- // CEC
- private void opStateCheckAnyCharMLStar() {
- int mem = code[ip++];
-
- while (s < range) {
- if (stateCheckVal(s, mem)) {opFail(); return;}
- pushAltWithStateCheck(ip, s, sprev, mem);
- sprev = s;
- s++;
- }
- sprev = sbegin; // break;
- }
-
private void opWord() {
if (s >= range || !EncodingHelper.isWord(chars[s])) {opFail(); return;}
s++;
@@ -1223,33 +1005,6 @@ class ByteCodeMachine extends StackMachine {
pushAlt(ip + addr, s, sprev);
}
- // CEC
- private void opStateCheckPush() {
- int mem = code[ip++];
- if (stateCheckVal(s, mem)) {opFail(); return;}
- int addr = code[ip++];
- pushAltWithStateCheck(ip + addr, s, sprev, mem);
- }
-
- // CEC
- private void opStateCheckPushOrJump() {
- int mem = code[ip++];
- int addr= code[ip++];
-
- if (stateCheckVal(s, mem)) {
- ip += addr;
- } else {
- pushAltWithStateCheck(ip + addr, s, sprev, mem);
- }
- }
-
- // CEC
- private void opStateCheck() {
- int mem = code[ip++];
- if (stateCheckVal(s, mem)) {opFail(); return;}
- pushStateCheck(s, mem);
- }
-
private void opPop() {
popOne();
}
@@ -1425,17 +1180,6 @@ class ByteCodeMachine extends StackMachine {
opFail();
}
- private void opCall() {
- int addr = code[ip++];
- pushCallFrame(ip);
- ip = addr; // absolute address
- }
-
- private void opReturn() {
- ip = sreturn();
- pushReturn();
- }
-
private void opFail() {
if (stack == null) {
ip = regex.codeLength - 1;
@@ -1447,13 +1191,6 @@ class ByteCodeMachine extends StackMachine {
ip = e.getStatePCode();
s = e.getStatePStr();
sprev = e.getStatePStrPrev();
-
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.getStateCheck() != 0) {
- e.type = STATE_CHECK_MARK;
- stk++;
- }
- }
}
private int finish() {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java
index 86a558b0e0c..d56164d116f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodePrinter.java
@@ -34,6 +34,239 @@ class ByteCodePrinter {
int operantCount;
WarnCallback warnings;
+ private final static String OpCodeNames[] = new String[] {
+ "finish", /*OP_FINISH*/
+ "end", /*OP_END*/
+ "exact1", /*OP_EXACT1*/
+ "exact2", /*OP_EXACT2*/
+ "exact3", /*OP_EXACT3*/
+ "exact4", /*OP_EXACT4*/
+ "exact5", /*OP_EXACT5*/
+ "exactn", /*OP_EXACTN*/
+ "exactmb2-n1", /*OP_EXACTMB2N1*/
+ "exactmb2-n2", /*OP_EXACTMB2N2*/
+ "exactmb2-n3", /*OP_EXACTMB2N3*/
+ "exactmb2-n", /*OP_EXACTMB2N*/
+ "exactmb3n", /*OP_EXACTMB3N*/
+ "exactmbn", /*OP_EXACTMBN*/
+ "exact1-ic", /*OP_EXACT1_IC*/
+ "exactn-ic", /*OP_EXACTN_IC*/
+ "cclass", /*OP_CCLASS*/
+ "cclass-mb", /*OP_CCLASS_MB*/
+ "cclass-mix", /*OP_CCLASS_MIX*/
+ "cclass-not", /*OP_CCLASS_NOT*/
+ "cclass-mb-not", /*OP_CCLASS_MB_NOT*/
+ "cclass-mix-not", /*OP_CCLASS_MIX_NOT*/
+ "cclass-node", /*OP_CCLASS_NODE*/
+ "anychar", /*OP_ANYCHAR*/
+ "anychar-ml", /*OP_ANYCHAR_ML*/
+ "anychar*", /*OP_ANYCHAR_STAR*/
+ "anychar-ml*", /*OP_ANYCHAR_ML_STAR*/
+ "anychar*-peek-next", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+ "anychar-ml*-peek-next", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+ "word", /*OP_WORD*/
+ "not-word", /*OP_NOT_WORD*/
+ "word-bound", /*OP_WORD_BOUND*/
+ "not-word-bound", /*OP_NOT_WORD_BOUND*/
+ "word-begin", /*OP_WORD_BEGIN*/
+ "word-end", /*OP_WORD_END*/
+ "begin-buf", /*OP_BEGIN_BUF*/
+ "end-buf", /*OP_END_BUF*/
+ "begin-line", /*OP_BEGIN_LINE*/
+ "end-line", /*OP_END_LINE*/
+ "semi-end-buf", /*OP_SEMI_END_BUF*/
+ "begin-position", /*OP_BEGIN_POSITION*/
+ "backref1", /*OP_BACKREF1*/
+ "backref2", /*OP_BACKREF2*/
+ "backrefn", /*OP_BACKREFN*/
+ "backrefn-ic", /*OP_BACKREFN_IC*/
+ "backref_multi", /*OP_BACKREF_MULTI*/
+ "backref_multi-ic", /*OP_BACKREF_MULTI_IC*/
+ "backref_at_level", /*OP_BACKREF_AT_LEVEL*/
+ "mem-start", /*OP_MEMORY_START*/
+ "mem-start-push", /*OP_MEMORY_START_PUSH*/
+ "mem-end-push", /*OP_MEMORY_END_PUSH*/
+ "mem-end-push-rec", /*OP_MEMORY_END_PUSH_REC*/
+ "mem-end", /*OP_MEMORY_END*/
+ "mem-end-rec", /*OP_MEMORY_END_REC*/
+ "fail", /*OP_FAIL*/
+ "jump", /*OP_JUMP*/
+ "push", /*OP_PUSH*/
+ "pop", /*OP_POP*/
+ "push-or-jump-e1", /*OP_PUSH_OR_JUMP_EXACT1*/
+ "push-if-peek-next", /*OP_PUSH_IF_PEEK_NEXT*/
+ "repeat", /*OP_REPEAT*/
+ "repeat-ng", /*OP_REPEAT_NG*/
+ "repeat-inc", /*OP_REPEAT_INC*/
+ "repeat-inc-ng", /*OP_REPEAT_INC_NG*/
+ "repeat-inc-sg", /*OP_REPEAT_INC_SG*/
+ "repeat-inc-ng-sg", /*OP_REPEAT_INC_NG_SG*/
+ "null-check-start", /*OP_NULL_CHECK_START*/
+ "null-check-end", /*OP_NULL_CHECK_END*/
+ "null-check-end-memst", /*OP_NULL_CHECK_END_MEMST*/
+ "null-check-end-memst-push", /*OP_NULL_CHECK_END_MEMST_PUSH*/
+ "push-pos", /*OP_PUSH_POS*/
+ "pop-pos", /*OP_POP_POS*/
+ "push-pos-not", /*OP_PUSH_POS_NOT*/
+ "fail-pos", /*OP_FAIL_POS*/
+ "push-stop-bt", /*OP_PUSH_STOP_BT*/
+ "pop-stop-bt", /*OP_POP_STOP_BT*/
+ "look-behind", /*OP_LOOK_BEHIND*/
+ "push-look-behind-not", /*OP_PUSH_LOOK_BEHIND_NOT*/
+ "fail-look-behind-not", /*OP_FAIL_LOOK_BEHIND_NOT*/
+ "call", /*OP_CALL*/
+ "return", /*OP_RETURN*/
+ "state-check-push", /*OP_STATE_CHECK_PUSH*/
+ "state-check-push-or-jump", /*OP_STATE_CHECK_PUSH_OR_JUMP*/
+ "state-check", /*OP_STATE_CHECK*/
+ "state-check-anychar*", /*OP_STATE_CHECK_ANYCHAR_STAR*/
+ "state-check-anychar-ml*", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+ "set-option-push", /*OP_SET_OPTION_PUSH*/
+ "set-option", /*OP_SET_OPTION*/
+
+ // single byte versions
+ "anychar-sb", /*OP_ANYCHAR*/
+ "anychar-ml-sb", /*OP_ANYCHAR_ML*/
+ "anychar*-sb", /*OP_ANYCHAR_STAR*/
+ "anychar-ml*-sb", /*OP_ANYCHAR_ML_STAR*/
+ "anychar*-peek-next-sb", /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+ "anychar-ml*-peek-next-sb", /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+ "state-check-anychar*-sb", /*OP_STATE_CHECK_ANYCHAR_STAR*/
+ "state-check-anychar-ml*-sb", /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+
+ "cclass-sb", /*OP_CCLASS*/
+ "cclass-not-sb", /*OP_CCLASS_NOT*/
+
+ "word-sb", /*OP_WORD*/
+ "not-word-sb", /*OP_NOT_WORD*/
+ "word-bound-sb", /*OP_WORD_BOUND*/
+ "not-word-bound-sb", /*OP_NOT_WORD_BOUND*/
+ "word-begin-sb", /*OP_WORD_BEGIN*/
+ "word-end-sb", /*OP_WORD_END*/
+
+ "look-behind-sb", /*OP_LOOK_BEHIND*/
+
+ "exact1-ic-sb", /*OP_EXACT1_IC*/
+ "exactn-ic-sb", /*OP_EXACTN_IC*/
+
+ };
+
+ private final static int OpCodeArgTypes[] = new int[] {
+ Arguments.NON, /*OP_FINISH*/
+ Arguments.NON, /*OP_END*/
+ Arguments.SPECIAL, /*OP_EXACT1*/
+ Arguments.SPECIAL, /*OP_EXACT2*/
+ Arguments.SPECIAL, /*OP_EXACT3*/
+ Arguments.SPECIAL, /*OP_EXACT4*/
+ Arguments.SPECIAL, /*OP_EXACT5*/
+ Arguments.SPECIAL, /*OP_EXACTN*/
+ Arguments.SPECIAL, /*OP_EXACTMB2N1*/
+ Arguments.SPECIAL, /*OP_EXACTMB2N2*/
+ Arguments.SPECIAL, /*OP_EXACTMB2N3*/
+ Arguments.SPECIAL, /*OP_EXACTMB2N*/
+ Arguments.SPECIAL, /*OP_EXACTMB3N*/
+ Arguments.SPECIAL, /*OP_EXACTMBN*/
+ Arguments.SPECIAL, /*OP_EXACT1_IC*/
+ Arguments.SPECIAL, /*OP_EXACTN_IC*/
+ Arguments.SPECIAL, /*OP_CCLASS*/
+ Arguments.SPECIAL, /*OP_CCLASS_MB*/
+ Arguments.SPECIAL, /*OP_CCLASS_MIX*/
+ Arguments.SPECIAL, /*OP_CCLASS_NOT*/
+ Arguments.SPECIAL, /*OP_CCLASS_MB_NOT*/
+ Arguments.SPECIAL, /*OP_CCLASS_MIX_NOT*/
+ Arguments.SPECIAL, /*OP_CCLASS_NODE*/
+ Arguments.NON, /*OP_ANYCHAR*/
+ Arguments.NON, /*OP_ANYCHAR_ML*/
+ Arguments.NON, /*OP_ANYCHAR_STAR*/
+ Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
+ Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+ Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+ Arguments.NON, /*OP_WORD*/
+ Arguments.NON, /*OP_NOT_WORD*/
+ Arguments.NON, /*OP_WORD_BOUND*/
+ Arguments.NON, /*OP_NOT_WORD_BOUND*/
+ Arguments.NON, /*OP_WORD_BEGIN*/
+ Arguments.NON, /*OP_WORD_END*/
+ Arguments.NON, /*OP_BEGIN_BUF*/
+ Arguments.NON, /*OP_END_BUF*/
+ Arguments.NON, /*OP_BEGIN_LINE*/
+ Arguments.NON, /*OP_END_LINE*/
+ Arguments.NON, /*OP_SEMI_END_BUF*/
+ Arguments.NON, /*OP_BEGIN_POSITION*/
+ Arguments.NON, /*OP_BACKREF1*/
+ Arguments.NON, /*OP_BACKREF2*/
+ Arguments.MEMNUM, /*OP_BACKREFN*/
+ Arguments.SPECIAL, /*OP_BACKREFN_IC*/
+ Arguments.SPECIAL, /*OP_BACKREF_MULTI*/
+ Arguments.SPECIAL, /*OP_BACKREF_MULTI_IC*/
+ Arguments.SPECIAL, /*OP_BACKREF_AT_LEVEL*/
+ Arguments.MEMNUM, /*OP_MEMORY_START*/
+ Arguments.MEMNUM, /*OP_MEMORY_START_PUSH*/
+ Arguments.MEMNUM, /*OP_MEMORY_END_PUSH*/
+ Arguments.MEMNUM, /*OP_MEMORY_END_PUSH_REC*/
+ Arguments.MEMNUM, /*OP_MEMORY_END*/
+ Arguments.MEMNUM, /*OP_MEMORY_END_REC*/
+ Arguments.NON, /*OP_FAIL*/
+ Arguments.RELADDR, /*OP_JUMP*/
+ Arguments.RELADDR, /*OP_PUSH*/
+ Arguments.NON, /*OP_POP*/
+ Arguments.SPECIAL, /*OP_PUSH_OR_JUMP_EXACT1*/
+ Arguments.SPECIAL, /*OP_PUSH_IF_PEEK_NEXT*/
+ Arguments.SPECIAL, /*OP_REPEAT*/
+ Arguments.SPECIAL, /*OP_REPEAT_NG*/
+ Arguments.MEMNUM, /*OP_REPEAT_INC*/
+ Arguments.MEMNUM, /*OP_REPEAT_INC_NG*/
+ Arguments.MEMNUM, /*OP_REPEAT_INC_SG*/
+ Arguments.MEMNUM, /*OP_REPEAT_INC_NG_SG*/
+ Arguments.MEMNUM, /*OP_NULL_CHECK_START*/
+ Arguments.MEMNUM, /*OP_NULL_CHECK_END*/
+ Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST*/
+ Arguments.MEMNUM, /*OP_NULL_CHECK_END_MEMST_PUSH*/
+ Arguments.NON, /*OP_PUSH_POS*/
+ Arguments.NON, /*OP_POP_POS*/
+ Arguments.RELADDR, /*OP_PUSH_POS_NOT*/
+ Arguments.NON, /*OP_FAIL_POS*/
+ Arguments.NON, /*OP_PUSH_STOP_BT*/
+ Arguments.NON, /*OP_POP_STOP_BT*/
+ Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
+ Arguments.SPECIAL, /*OP_PUSH_LOOK_BEHIND_NOT*/
+ Arguments.NON, /*OP_FAIL_LOOK_BEHIND_NOT*/
+ Arguments.ABSADDR, /*OP_CALL*/
+ Arguments.NON, /*OP_RETURN*/
+ Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH*/
+ Arguments.SPECIAL, /*OP_STATE_CHECK_PUSH_OR_JUMP*/
+ Arguments.STATE_CHECK, /*OP_STATE_CHECK*/
+ Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
+ Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+ Arguments.OPTION, /*OP_SET_OPTION_PUSH*/
+ Arguments.OPTION, /*OP_SET_OPTION*/
+
+ // single byte versions
+ Arguments.NON, /*OP_ANYCHAR*/
+ Arguments.NON, /*OP_ANYCHAR_ML*/
+ Arguments.NON, /*OP_ANYCHAR_STAR*/
+ Arguments.NON, /*OP_ANYCHAR_ML_STAR*/
+ Arguments.SPECIAL, /*OP_ANYCHAR_STAR_PEEK_NEXT*/
+ Arguments.SPECIAL, /*OP_ANYCHAR_ML_STAR_PEEK_NEXT*/
+ Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_STAR*/
+ Arguments.STATE_CHECK, /*OP_STATE_CHECK_ANYCHAR_ML_STAR*/
+
+ Arguments.SPECIAL, /*OP_CCLASS*/
+ Arguments.SPECIAL, /*OP_CCLASS_NOT*/
+
+ Arguments.NON, /*OP_WORD*/
+ Arguments.NON, /*OP_NOT_WORD*/
+ Arguments.NON, /*OP_WORD_BOUND*/
+ Arguments.NON, /*OP_NOT_WORD_BOUND*/
+ Arguments.NON, /*OP_WORD_BEGIN*/
+ Arguments.NON, /*OP_WORD_END*/
+
+ Arguments.SPECIAL, /*OP_LOOK_BEHIND*/
+
+ Arguments.SPECIAL, /*OP_EXACT1_IC*/
+ Arguments.SPECIAL, /*OP_EXACTN_IC*/
+ };
+
public ByteCodePrinter(Regex regex) {
code = regex.code;
codeLength = regex.codeLength;
@@ -76,8 +309,8 @@ class ByteCodePrinter {
CClassNode cc;
int tm, idx;
- sb.append("[" + OPCode.OpCodeNames[code[bp]]);
- int argType = OPCode.OpCodeArgTypes[code[bp]];
+ sb.append("[" + OpCodeNames[code[bp]]);
+ int argType = OpCodeArgTypes[code[bp]];
int ip = bp;
if (argType != Arguments.SPECIAL) {
bp++;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java
deleted file mode 100644
index 268f682c92e..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/CaptureTreeNode.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni;
-
-public class CaptureTreeNode {
-
-
- int group;
- int beg;
- int end;
- // int allocated;
- int numChildren;
- CaptureTreeNode[]children;
-
- CaptureTreeNode() {
- beg = Region.REGION_NOTPOS;
- end = Region.REGION_NOTPOS;
- group = -1;
- }
-
- static final int HISTORY_TREE_INIT_ALLOC_SIZE = 8;
- void addChild(CaptureTreeNode child) {
- if (children == null) {
- children = new CaptureTreeNode[HISTORY_TREE_INIT_ALLOC_SIZE];
- } else if (numChildren >= children.length) {
- CaptureTreeNode[]tmp = new CaptureTreeNode[children.length << 1];
- System.arraycopy(children, 0, tmp, 0, children.length);
- children = tmp;
- }
-
- children[numChildren] = child;
- numChildren++;
- }
-
- void clear() {
- for (int i=0; i, \k */
-
final boolean USE_MONOMANIAC_CHECK_CAPTURES_IN_ENDLESS_REPEAT = true; /* /(?:()|())*\2/ */
final boolean USE_NEWLINE_AT_END_OF_STRING_HAS_EMPTY_LINE = true; /* /\n$/ =~ "\n" */
final boolean USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR = false;
@@ -42,12 +38,10 @@ public interface Config {
final boolean CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS = true;
final boolean USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE = false;
- final boolean USE_CAPTURE_HISTORY = false;
final boolean USE_VARIABLE_META_CHARS = true;
final boolean USE_WORD_BEGIN_END = true; /* "\<": word-begin, "\>": word-end */
- final boolean USE_POSIX_API_REGION_OPTION = true; /* needed for POSIX API support */
+ final boolean USE_POSIX_API_REGION_OPTION = false; /* needed for POSIX API support */
final boolean USE_FIND_LONGEST_SEARCH_ALL_OF_RANGE = true;
- final boolean USE_COMBINATION_EXPLOSION_CHECK = false;
final int NREGION = 10;
final int MAX_BACKREF_NUM = 1000;
@@ -73,13 +67,6 @@ public interface Config {
final boolean USE_STRING_TEMPLATES = true; // use embeded string templates in Regex object as byte arrays instead of compiling them into int bytecode array
-
- final int MAX_CAPTURE_HISTORY_GROUP = 31;
-
-
- final int CHECK_STRING_THRESHOLD_LEN = 7;
- final int CHECK_BUFF_MAX_SIZE = 0x4000;
-
final boolean NON_UNICODE_SDW = true;
@@ -95,6 +82,4 @@ public interface Config {
final boolean DEBUG_COMPILE_BYTE_CODE_INFO = DEBUG_ALL;
final boolean DEBUG_SEARCH = DEBUG_ALL;
final boolean DEBUG_MATCH = DEBUG_ALL;
- final boolean DEBUG_ASM = true;
- final boolean DEBUG_ASM_EXEC = true;
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
index d3e54947aea..8c274fe0365 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java
@@ -95,20 +95,6 @@ public class EncodingHelper {
return s;
}
- /* onigenc_with_ascii_strncmp */
- public static int strNCmp(char[] chars1, int p1, int end, char[] chars2, int p2, int n) {
- while (n-- > 0) {
- if (p1 >= end) return chars2[p2];
- int c = chars1[p1];
- int x = chars2[p2] - c;
- if (x != 0) return x;
-
- p2++;
- p1++;
- }
- return 0;
- }
-
public static int mbcToCode(byte[] bytes, int p, int end) {
int code = 0;
for (int i = p; i < end; i++) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java
index c289f33d34d..53ab3ec066b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Lexer.java
@@ -27,10 +27,7 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.MetaChar;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TokenType;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
class Lexer extends ScannerSupport {
protected final ScanEnvironment env;
@@ -215,198 +212,6 @@ class Lexer extends ScannerSupport {
\k<-num+n>, \k<-num-n>
*/
- // value implicit (rnameEnd)
- private boolean fetchNameWithLevel(int startCode, Ptr rbackNum, Ptr rlevel) {
- int src = p;
- boolean existLevel = false;
- int isNum = 0;
- int sign = 1;
-
- int endCode = nameEndCodePoint(startCode);
- int pnumHead = p;
- int nameEnd = stop;
-
- String err = null;
- if (!left()) {
- newValueException(ERR_EMPTY_GROUP_NAME);
- } else {
- fetch();
- if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
- if (Character.isDigit(c)) {
- isNum = 1;
- } else if (c == '-') {
- isNum = 2;
- sign = -1;
- pnumHead = p;
- } else if (!EncodingHelper.isWord(c)) {
- err = ERR_INVALID_GROUP_NAME;
- }
- }
-
- while (left()) {
- nameEnd = p;
- fetch();
- if (c == endCode || c == ')' || c == '+' || c == '-') {
- if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
- break;
- }
-
- if (isNum != 0) {
- if (EncodingHelper.isDigit(c)) {
- isNum = 1;
- } else {
- err = ERR_INVALID_GROUP_NAME;
- // isNum = 0;
- }
- } else if (!EncodingHelper.isWord(c)) {
- err = ERR_INVALID_CHAR_IN_GROUP_NAME;
- }
- }
-
- boolean isEndCode = false;
- if (err == null && c != endCode) {
- if (c == '+' || c == '-') {
- int flag = c == '-' ? -1 : 1;
-
- fetch();
- if (!EncodingHelper.isDigit(c)) newValueException(ERR_INVALID_GROUP_NAME, src, stop);
- unfetch();
- int level = scanUnsignedNumber();
- if (level < 0) newValueException(ERR_TOO_BIG_NUMBER);
- rlevel.p = level * flag;
- existLevel = true;
-
- fetch();
- isEndCode = c == endCode;
- }
-
- if (!isEndCode) {
- err = ERR_INVALID_GROUP_NAME;
- nameEnd = stop;
- }
- }
-
- if (err == null) {
- if (isNum != 0) {
- mark();
- p = pnumHead;
- int backNum = scanUnsignedNumber();
- restore();
- if (backNum < 0) {
- newValueException(ERR_TOO_BIG_NUMBER);
- } else if (backNum == 0) {
- newValueException(ERR_INVALID_GROUP_NAME, src, stop);
- }
- rbackNum.p = backNum * sign;
- }
- value = nameEnd;
- return existLevel;
- } else {
- newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
- return false; // not reached
- }
- }
-
- // USE_NAMED_GROUP
- // ref: 0 -> define name (don't allow number name)
- // 1 -> reference name (allow number name)
- private int fetchNameForNamedGroup(int startCode, boolean ref) {
- int src = p;
- value = 0;
-
- int isNum = 0;
- int sign = 1;
-
- int endCode = nameEndCodePoint(startCode);
- int pnumHead = p;
- int nameEnd = stop;
-
- String err = null;
- if (!left()) {
- newValueException(ERR_EMPTY_GROUP_NAME);
- } else {
- fetch();
- if (c == endCode) newValueException(ERR_EMPTY_GROUP_NAME);
- if (EncodingHelper.isDigit(c)) {
- if (ref) {
- isNum = 1;
- } else {
- err = ERR_INVALID_GROUP_NAME;
- // isNum = 0;
- }
- } else if (c == '-') {
- if (ref) {
- isNum = 2;
- sign = -1;
- pnumHead = p;
- } else {
- err = ERR_INVALID_GROUP_NAME;
- // isNum = 0;
- }
- } else if (!EncodingHelper.isWord(c)) {
- err = ERR_INVALID_CHAR_IN_GROUP_NAME;
- }
- }
-
- if (err == null) {
- while (left()) {
- nameEnd = p;
- fetch();
- if (c == endCode || c == ')') {
- if (isNum == 2) err = ERR_INVALID_GROUP_NAME;
- break;
- }
-
- if (isNum != 0) {
- if (EncodingHelper.isDigit(c)) {
- isNum = 1;
- } else {
- if (!EncodingHelper.isWord(c)) {
- err = ERR_INVALID_CHAR_IN_GROUP_NAME;
- } else {
- err = ERR_INVALID_GROUP_NAME;
- }
- // isNum = 0;
- }
- } else {
- if (!EncodingHelper.isWord(c)) {
- err = ERR_INVALID_CHAR_IN_GROUP_NAME;
- }
- }
- }
-
- if (c != endCode) {
- err = ERR_INVALID_GROUP_NAME;
- nameEnd = stop;
- }
-
- int backNum = 0;
- if (isNum != 0) {
- mark();
- p = pnumHead;
- backNum = scanUnsignedNumber();
- restore();
- if (backNum < 0) {
- newValueException(ERR_TOO_BIG_NUMBER);
- } else if (backNum == 0) {
- newValueException(ERR_INVALID_GROUP_NAME, src, nameEnd);
- }
- backNum *= sign;
- }
- value = nameEnd;
- return backNum;
- } else {
- while (left()) {
- nameEnd = p;
- fetch();
- if (c == endCode || c == ')') break;
- }
- if (!left()) nameEnd = stop;
- newValueException(err, src, nameEnd);
- return 0; // not reached
- }
- }
-
// #else USE_NAMED_GROUP
// make it return nameEnd!
private final int fetchNameForNoNamedGroup(int startCode, boolean ref) {
@@ -472,11 +277,7 @@ class Lexer extends ScannerSupport {
}
protected final int fetchName(int startCode, boolean ref) {
- if (Config.USE_NAMED_GROUP) {
- return fetchNameForNamedGroup(startCode, ref);
- } else {
- return fetchNameForNoNamedGroup(startCode, ref);
- }
+ return fetchNameForNoNamedGroup(startCode, ref);
}
private boolean strExistCheckWithEsc(int[]s, int n, int bad) {
@@ -519,26 +320,6 @@ class Lexer extends ScannerSupport {
token.setPropNot(flag);
}
- private void fetchTokenInCCFor_p() {
- int c2 = peek(); // !!! migrate to peekIs
- if (c2 == '{' && syntax.op2EscPBraceCharProperty()) {
- inc();
- token.type = TokenType.CHAR_PROPERTY;
- token.setPropNot(c == 'P');
-
- if (syntax.op2EscPBraceCircumflexNot()) {
- c2 = fetchTo();
- if (c2 == '^') {
- token.setPropNot(!token.getPropNot());
- } else {
- unfetch();
- }
- }
- } else {
- syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
- }
- }
-
private void fetchTokenInCCFor_x() {
if (!left()) return;
int last = p;
@@ -604,30 +385,6 @@ class Lexer extends ScannerSupport {
}
}
- private void fetchTokenInCCFor_posixBracket() {
- if (syntax.opPosixBracket() && peekIs(':')) {
- token.backP = p; /* point at '[' is readed */
- inc();
- if (strExistCheckWithEsc(send, send.length, ']')) {
- token.type = TokenType.POSIX_BRACKET_OPEN;
- } else {
- unfetch();
- // remove duplication, goto cc_in_cc;
- if (syntax.op2CClassSetOp()) {
- token.type = TokenType.CC_CC_OPEN;
- } else {
- env.ccEscWarn("[");
- }
- }
- } else { // cc_in_cc:
- if (syntax.op2CClassSetOp()) {
- token.type = TokenType.CC_CC_OPEN;
- } else {
- env.ccEscWarn("[");
- }
- }
- }
-
private void fetchTokenInCCFor_and() {
if (syntax.op2CClassSetOp() && left() && peekIs('&')) {
inc();
@@ -683,10 +440,6 @@ class Lexer extends ScannerSupport {
case 'H':
if (syntax.op2EscHXDigit()) fetchTokenInCCFor_charType(true, CharacterType.XDIGIT);
break;
- case 'p':
- case 'P':
- fetchTokenInCCFor_p();
- break;
case 'x':
fetchTokenInCCFor_x();
break;
@@ -714,18 +467,12 @@ class Lexer extends ScannerSupport {
break;
} // switch
- } else if (c == '[') {
- fetchTokenInCCFor_posixBracket();
} else if (c == '&') {
fetchTokenInCCFor_and();
}
return token.type;
}
- protected final int backrefRelToAbs(int relNo) {
- return env.numMem + 1 + relNo;
- }
-
private void fetchTokenFor_repeat(int lower, int upper) {
token.type = TokenType.OP_REPEAT;
token.setRepeatLower(lower);
@@ -815,7 +562,6 @@ class Lexer extends ScannerSupport {
token.setBackrefNum(1);
token.setBackrefRef1(num);
token.setBackrefByName(false);
- if (Config.USE_BACKREF_WITH_LEVEL) token.setBackrefExistLevel(false);
return;
}
@@ -845,76 +591,6 @@ class Lexer extends ScannerSupport {
}
}
- private void fetchTokenFor_namedBackref() {
- if (syntax.op2EscKNamedBackref()) {
- if (left()) {
- fetch();
- if (c =='<' || c == '\'') {
- int last = p;
- int backNum;
- if (Config.USE_BACKREF_WITH_LEVEL) {
- Ptr rbackNum = new Ptr();
- Ptr rlevel = new Ptr();
- token.setBackrefExistLevel(fetchNameWithLevel(c, rbackNum, rlevel));
- token.setBackrefLevel(rlevel.p);
- backNum = rbackNum.p;
- } else {
- backNum = fetchName(c, true);
- } // USE_BACKREF_AT_LEVEL
- int nameEnd = value; // set by fetchNameWithLevel/fetchName
-
- if (backNum != 0) {
- if (backNum < 0) {
- backNum = backrefRelToAbs(backNum);
- if (backNum <= 0) newValueException(ERR_INVALID_BACKREF);
- }
-
- if (syntax.strictCheckBackref() && (backNum > env.numMem || env.memNodes == null)) {
- newValueException(ERR_INVALID_BACKREF);
- }
- token.type = TokenType.BACKREF;
- token.setBackrefByName(false);
- token.setBackrefNum(1);
- token.setBackrefRef1(backNum);
- } else {
- NameEntry e = env.reg.nameToGroupNumbers(chars, last, nameEnd);
- if (e == null) newValueException(ERR_UNDEFINED_NAME_REFERENCE, last, nameEnd);
-
- if (syntax.strictCheckBackref()) {
- if (e.backNum == 1) {
- if (e.backRef1 > env.numMem ||
- env.memNodes == null ||
- env.memNodes[e.backRef1] == null) newValueException(ERR_INVALID_BACKREF);
- } else {
- for (int i=0; i env.numMem ||
- env.memNodes == null ||
- env.memNodes[e.backRefs[i]] == null) newValueException(ERR_INVALID_BACKREF);
- }
- }
- }
-
- token.type = TokenType.BACKREF;
- token.setBackrefByName(true);
-
- if (e.backNum == 1) {
- token.setBackrefNum(1);
- token.setBackrefRef1(e.backRef1);
- } else {
- token.setBackrefNum(e.backNum);
- token.setBackrefRefs(e.backRefs);
- }
- }
- } else {
- unfetch();
- syntaxWarn(Warnings.INVALID_BACKREFERENCE);
- }
- } else {
- syntaxWarn(Warnings.INVALID_BACKREFERENCE);
- }
- }
- }
-
private void fetchTokenFor_subexpCall() {
if (syntax.op2EscGSubexpCall()) {
if (left()) {
@@ -937,25 +613,6 @@ class Lexer extends ScannerSupport {
}
}
- private void fetchTokenFor_charProperty() {
- if (peekIs('{') && syntax.op2EscPBraceCharProperty()) {
- inc();
- token.type = TokenType.CHAR_PROPERTY;
- token.setPropNot(c == 'P');
-
- if (syntax.op2EscPBraceCircumflexNot()) {
- fetch();
- if (c == '^') {
- token.setPropNot(!token.getPropNot());
- } else {
- unfetch();
- }
- }
- } else {
- syntaxWarn(Warnings.INVALID_UNICODE_PROPERTY, (char)c);
- }
- }
-
private void fetchTokenFor_metaChars() {
if (c == syntax.metaCharTable.anyChar) {
token.type = TokenType.ANYCHAR;
@@ -1091,19 +748,6 @@ class Lexer extends ScannerSupport {
case '0':
fetchTokenFor_zero();
break;
- case 'k':
- if (Config.USE_NAMED_GROUP) fetchTokenFor_namedBackref();
- break;
- case 'g':
- if (Config.USE_SUBEXP_CALL) fetchTokenFor_subexpCall();
- break;
- case 'Q':
- if (syntax.op2EscCapitalQQuote()) token.type = TokenType.QUOTE_OPEN;
- break;
- case 'p':
- case 'P':
- fetchTokenFor_charProperty();
- break;
default:
unfetch();
@@ -1244,24 +888,6 @@ class Lexer extends ScannerSupport {
}
}
- protected final int fetchCharPropertyToCType() {
- mark();
-
- while (left()) {
- int last = p;
- fetch();
- if (c == '}') {
- String name = new String(chars, _p, last - _p);
- return PosixBracket.propertyNameToCType(name);
- } else if (c == '(' || c == ')' || c == '{' || c == '|') {
- String name = new String(chars, _p, last - _p);
- throw new JOniException(ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
- }
- }
- newInternalException(ERR_PARSER_BUG);
- return 0; // not reached
- }
-
protected final void syntaxWarn(String message, char c) {
syntaxWarn(message.replace("<%n>", Character.toString(c)));
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java
index 4aea4acb787..911b23b391e 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Matcher.java
@@ -58,17 +58,10 @@ public abstract class Matcher extends IntHolder {
// main matching method
protected abstract int matchAt(int range, int sstart, int sprev);
- protected abstract void stateCheckBuffInit(int strLength, int offset, int stateNum);
- protected abstract void stateCheckBuffClear();
-
public final Region getRegion() {
return msaRegion;
}
- public final Region getEagerRegion() {
- return msaRegion != null ? msaRegion : new Region(msaBegin, msaEnd);
- }
-
public final int getBegin() {
return msaBegin;
}
@@ -86,11 +79,6 @@ public abstract class Matcher extends IntHolder {
public final int match(int at, int range, int option) {
msaInit(option, at);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- int offset = at = str;
- stateCheckBuffInit(end - str, offset, regex.numCombExpCheck); // move it to construction?
- } // USE_COMBINATION_EXPLOSION_CHECK
-
int prev = EncodingHelper.prevCharHead(str, at);
if (Config.USE_MATCH_RANGE_MUST_BE_INSIDE_OF_SPECIFIED_RANGE) {
@@ -377,8 +365,6 @@ public abstract class Matcher extends IntHolder {
prev = -1;
msaInit(option, start);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) stateCheckBuffClear();
-
if (matchCheck(end, s, prev)) return match(s);
return mismatch();
}
@@ -393,10 +379,6 @@ public abstract class Matcher extends IntHolder {
}
msaInit(option, origStart);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- int offset = Math.min(start, range) - str;
- stateCheckBuffInit(end - str, offset, regex.numCombExpCheck);
- }
s = start;
if (range > start) { /* forward search */
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java
deleted file mode 100644
index d35f725155e..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NameEntry.java
+++ /dev/null
@@ -1,97 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni;
-
-public final class NameEntry {
- static final int INIT_NAME_BACKREFS_ALLOC_NUM = 8;
-
- public final char[] name;
- public final int nameP;
- public final int nameEnd;
-
- int backNum;
- int backRef1;
- int backRefs[];
-
- public NameEntry(char[] chars, int p, int end) {
- name = chars;
- nameP = p;
- nameEnd = end;
- }
-
- public int[] getBackRefs() {
- switch (backNum) {
- case 0:
- return new int[]{};
- case 1:
- return new int[]{backRef1};
- default:
- int[]result = new int[backNum];
- System.arraycopy(backRefs, 0, result, 0, backNum);
- return result;
- }
- }
-
- private void alloc() {
- backRefs = new int[INIT_NAME_BACKREFS_ALLOC_NUM];
- }
-
- private void ensureSize() {
- if (backNum > backRefs.length) {
- int[]tmp = new int[backRefs.length << 1];
- System.arraycopy(backRefs, 0, tmp, 0, backRefs.length);
- backRefs = tmp;
- }
- }
-
- public void addBackref(int backRef) {
- backNum++;
-
- switch (backNum) {
- case 1:
- backRef1 = backRef;
- break;
- case 2:
- alloc();
- backRefs[0] = backRef1;
- backRefs[1] = backRef;
- break;
- default:
- ensureSize();
- backRefs[backNum - 1] = backRef;
- }
- }
-
- public String toString() {
- StringBuilder buff = new StringBuilder(new String(name, nameP, nameEnd - nameP) + " ");
- if (backNum == 0) {
- buff.append("-");
- } else if (backNum == 1){
- buff.append(backRef1);
- } else {
- for (int i=0; i 0) buff.append(", ");
- buff.append(backRefs[i]);
- }
- }
- return buff.toString();
- }
-
-}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java
deleted file mode 100644
index 2a3f2a13144..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/NativeMachine.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni;
-
-public abstract class NativeMachine extends Matcher {
-
- protected NativeMachine(Regex regex, char[] chars, int p, int end) {
- super(regex, chars, p, end);
- }
-}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java
index 13d569b7b08..749b1d4196d 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Parser.java
@@ -19,20 +19,15 @@
*/
package jdk.nashorn.internal.runtime.regexp.joni;
-import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnAtSimple;
import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsOnOff;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isIgnoreCase;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.PosixBracket;
-import jdk.nashorn.internal.runtime.regexp.joni.encoding.Ptr;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnchorNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.AnyCharNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.BackRefNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CTypeNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.CallNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
@@ -66,65 +61,6 @@ class Parser extends Lexer {
return root;
}
- private static final int POSIX_BRACKET_NAME_MIN_LEN = 4;
- private static final int POSIX_BRACKET_CHECK_LIMIT_LENGTH = 20;
- private static final char BRACKET_END[] = ":]".toCharArray();
- private boolean parsePosixBracket(CClassNode cc) {
- mark();
-
- boolean not;
- if (peekIs('^')) {
- inc();
- not = true;
- } else {
- not = false;
- }
- if (stop - p >= POSIX_BRACKET_NAME_MIN_LEN + 3) { // else goto not_posix_bracket
- char[][] pbs = PosixBracket.PBSNamesLower;
- for (int i=0; i POSIX_BRACKET_CHECK_LIMIT_LENGTH) break;
- }
-
- if (c == ':' && left()) {
- inc();
- if (left()) {
- fetch();
- if (c == ']') newSyntaxException(ERR_INVALID_POSIX_BRACKET_TYPE);
- }
- }
- restore();
- return true; /* 1: is not POSIX bracket, but no error. */
- }
-
- private CClassNode parseCharProperty() {
- int ctype = fetchCharPropertyToCType();
- CClassNode n = new CClassNode();
- n.addCType(ctype, false, env, this);
- if (token.getPropNot()) n.setNot();
- return n;
- }
-
private boolean codeExistCheck(int code, boolean ignoreEscaped) {
mark();
@@ -225,29 +161,11 @@ class Parser extends Lexer {
parseCharClassValEntry(cc, arg); // val_entry:, val_entry2
break;
- case POSIX_BRACKET_OPEN:
- if (parsePosixBracket(cc)) { /* true: is not POSIX bracket */
- env.ccEscWarn("[");
- p = token.backP;
- arg.v = token.getC();
- arg.vIsRaw = false;
- parseCharClassValEntry(cc, arg); // goto val_entry
- break;
- }
- cc.nextStateClass(arg, env); // goto next_class
- break;
-
case CHAR_TYPE:
cc.addCType(token.getPropCType(), token.getPropNot(), env, this);
cc.nextStateClass(arg, env); // next_class:
break;
- case CHAR_PROPERTY:
- int ctype = fetchCharPropertyToCType();
- cc.addCType(ctype, token.getPropNot(), env, this);
- cc.nextStateClass(arg, env); // goto next_class
- break;
-
case CC_RANGE:
if (arg.state == CCSTATE.VALUE) {
fetchTokenInCC();
@@ -413,15 +331,6 @@ class Parser extends Lexer {
node = new EncloseNode(EncloseType.STOP_BACKTRACK); // node_new_enclose
break;
case '\'':
- if (Config.USE_NAMED_GROUP) {
- if (syntax.op2QMarkLtNamedGroup()) {
- listCapture = false; // goto named_group1
- node = parseEncloseNamedGroup2(listCapture);
- break;
- } else {
- newSyntaxException(ERR_UNDEFINED_GROUP_OPTION);
- }
- } // USE_NAMED_GROUP
break;
case '<': /* look behind (?<=...), (?...) */
- }
- unfetch();
- }
- } // USE_NAMED_GROUP
- EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
+ EncloseNode en = new EncloseNode(); // node_new_enclose_memory
int num = env.addMemEntry();
if (num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
en.regNum = num;
@@ -546,7 +431,7 @@ class Parser extends Lexer {
returnCode = 1; /* group */
return node;
}
- EncloseNode en = new EncloseNode(env.option, false); // node_new_enclose_memory
+ EncloseNode en = new EncloseNode(); // node_new_enclose_memory
int num = env.addMemEntry();
en.regNum = num;
node = en;
@@ -570,48 +455,6 @@ class Parser extends Lexer {
return node; // ??
}
- private Node parseEncloseNamedGroup2(boolean listCapture) {
- int nm = p;
- int num = fetchName(c, false);
- int nameEnd = value;
- num = env.addMemEntry();
- if (listCapture && num >= BitStatus.BIT_STATUS_BITS_NUM) newValueException(ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY);
-
- regex.nameAdd(chars, nm, nameEnd, num, syntax);
- EncloseNode en = new EncloseNode(env.option, true); // node_new_enclose_memory
- en.regNum = num;
-
- Node node = en;
-
- if (listCapture) env.captureHistory = bsOnAtSimple(env.captureHistory, num);
- env.numNamed++;
- return node;
- }
-
- private int findStrPosition(int[]s, int n, int from, int to, Ptr nextChar) {
- int x;
- int q;
- int p = from;
- int i = 0;
- while (p < to) {
- x = chars[p];
- q = p + 1;
- if (x == s[0]) {
- for (i=1; i= n) {
- if (chars[nextChar.p] != 0) nextChar.p = q; // we may need zero term semantics...
- return p;
- }
- }
- p = q;
- }
- return -1;
- }
-
private Node parseExp(TokenType term) {
if (token.type == term) return StringNode.EMPTY; // goto end_of_token
@@ -656,16 +499,6 @@ class Parser extends Lexer {
node = new StringNode(buf, 0, 1);
break;
- case QUOTE_OPEN:
- int[] endOp = new int[] {syntax.metaCharTable.esc, 'E'};
- int qstart = p;
- Ptr nextChar = new Ptr();
- int qend = findStrPosition(endOp, endOp.length, qstart, stop, nextChar);
- if (qend == -1) nextChar.p = qend = stop;
- node = new StringNode(chars, qstart, qend);
- p = nextChar.p;
- break;
-
case CHAR_TYPE:
switch(token.getPropCType()) {
case CharacterType.D:
@@ -679,10 +512,6 @@ class Parser extends Lexer {
}
break;
- case CharacterType.WORD:
- node = new CTypeNode(token.getPropCType(), token.getPropNot());
- break;
-
case CharacterType.SPACE:
case CharacterType.DIGIT:
case CharacterType.XDIGIT:
@@ -699,10 +528,6 @@ class Parser extends Lexer {
} // inner switch
break;
- case CHAR_PROPERTY:
- node = parseCharProperty();
- break;
-
case CC_CC_OPEN:
CClassNode cc = parseCharClass();
node = cc;
@@ -735,20 +560,6 @@ class Parser extends Lexer {
token.getBackrefExistLevel(), // #ifdef USE_BACKREF_AT_LEVEL
token.getBackrefLevel(), // ...
env);
-
- break;
-
- case CALL:
- if (Config.USE_SUBEXP_CALL) {
- int gNum = token.getCallGNum();
-
- if (gNum < 0) {
- gNum = backrefRelToAbs(gNum);
- if (gNum <= 0) newValueException(ERR_INVALID_BACKREF);
- }
- node = new CallNode(chars, token.getCallNameP(), token.getCallNameEnd(), gNum);
- env.numCall++;
- } // USE_SUBEXP_CALL
break;
case ANCHOR:
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java
index da5b98271b7..b27814a71ce 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Regex.java
@@ -23,9 +23,11 @@ import static jdk.nashorn.internal.runtime.regexp.joni.BitStatus.bsAt;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isCaptureGroup;
import static jdk.nashorn.internal.runtime.regexp.joni.Option.isDontCaptureGroup;
+import java.nio.file.Files;
import java.util.HashMap;
import java.util.Iterator;
+import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
import jdk.nashorn.internal.runtime.regexp.joni.constants.AnchorType;
import jdk.nashorn.internal.runtime.regexp.joni.constants.RegexState;
import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
@@ -44,7 +46,6 @@ public final class Regex implements RegexState {
int numMem; /* used memory(...) num counted from 1 */
int numRepeat; /* OP_REPEAT/OP_REPEAT_NG id-counter */
int numNullCheck; /* OP_NULL_CHECK_START/END id counter */
- int numCombExpCheck; /* combination explosion check */
int numCall; /* number of subexp call */
int captureHistory; /* (?@...) flag (1-31) */
int btMemStart; /* need backtrack flag */
@@ -57,7 +58,7 @@ public final class Regex implements RegexState {
WarnCallback warnings;
MatcherFactory factory;
- private Analyser analyser;
+ protected Analyser analyser;
int options;
int userOptions;
@@ -65,8 +66,6 @@ public final class Regex implements RegexState {
//final Syntax syntax;
final int caseFoldFlag;
- HashMap nameTable; // named entries
-
/* optimization info (string search, char-map and anchors) */
SearchAlgorithm searchAlgorithm; /* optimize flag */
int thresholdLength; /* search str-length for apply optimize */
@@ -172,112 +171,6 @@ public final class Regex implements RegexState {
return numMem;
}
- public int numberOfCaptureHistories() {
- if (Config.USE_CAPTURE_HISTORY) {
- int n = 0;
- for (int i=0; i<=Config.MAX_CAPTURE_HISTORY_GROUP; i++) {
- if (bsAt(captureHistory, i)) n++;
- }
- return n;
- } else {
- return 0;
- }
- }
-
- String nameTableToString() {
- StringBuilder sb = new StringBuilder();
-
- if (nameTable != null) {
- sb.append("name table\n");
- for (NameEntry ne : nameTable.values()) {
- sb.append(" " + ne + "\n");
- }
- sb.append("\n");
- }
- return sb.toString();
- }
-
- NameEntry nameFind(char[] name, int nameP, int nameEnd) {
- if (nameTable != null) return nameTable.get(new String(name, nameP, nameEnd - nameP));
- return null;
- }
-
- void renumberNameTable(int[]map) {
- if (nameTable != null) {
- for (NameEntry e : nameTable.values()) {
- if (e.backNum > 1) {
- for (int i=0; i(); // 13, oni defaults to 5
- } else {
- e = nameFind(name, nameP, nameEnd);
- }
-
- if (e == null) {
- // dup the name here as oni does ?, what for ? (it has to manage it, we don't)
- e = new NameEntry(name, nameP, nameEnd);
- nameTable.put(new String(name, nameP, nameEnd - nameP), e);
- } else if (e.backNum >= 1 && !syntax.allowMultiplexDefinitionName()) {
- throw new ValueException(ErrorMessages.ERR_MULTIPLEX_DEFINED_NAME, new String(name, nameP, nameEnd - nameP));
- }
-
- e.addBackref(backRef);
- }
-
- NameEntry nameToGroupNumbers(char[] name, int nameP, int nameEnd) {
- return nameFind(name, nameP, nameEnd);
- }
-
- public int nameToBackrefNumber(char[] name, int nameP, int nameEnd, Region region) {
- NameEntry e = nameToGroupNumbers(name, nameP, nameEnd);
- if (e == null) throw new ValueException(ErrorMessages.ERR_UNDEFINED_NAME_REFERENCE,
- new String(name, nameP, nameEnd - nameP));
-
- switch(e.backNum) {
- case 0:
- throw new InternalException(ErrorMessages.ERR_PARSER_BUG);
- case 1:
- return e.backRef1;
- default:
- if (region != null) {
- for (int i = e.backNum - 1; i >= 0; i--) {
- if (region.beg[e.backRefs[i]] != Region.REGION_NOTPOS) return e.backRefs[i];
- }
- }
- return e.backRefs[e.backNum - 1];
- }
- }
-
- public Iterator namedBackrefIterator() {
- return nameTable.values().iterator();
- }
-
- public boolean noNameGroupIsActive(Syntax syntax) {
- if (isDontCaptureGroup(options)) return false;
-
- if (Config.USE_NAMED_GROUP) {
- if (numberOfNames() > 0 && syntax.captureOnlyNamedGroup() && !isCaptureGroup(options)) return false;
- }
- return true;
- }
-
/* set skip map for Boyer-Moor search */
void setupBMSkipMap() {
char[] chars = exact;
@@ -353,16 +246,6 @@ public final class Regex implements RegexState {
exactP = exactEnd = 0;
}
- public String encStringToString(byte[]bytes, int p, int end) {
- StringBuilder sb = new StringBuilder("\nPATTERN: /");
-
- while (p < end) {
- sb.append(new String(new byte[]{bytes[p]}));
- p++;
- }
- return sb.append("/").toString();
- }
-
public String optimizeInfoToString() {
String s = "";
s += "optimize: " + searchAlgorithm.getName() + "\n";
@@ -410,19 +293,13 @@ public final class Regex implements RegexState {
return options;
}
- public void setUserOptions(int options) {
- this.userOptions = options;
+ public String dumpTree() {
+ return analyser == null ? null : analyser.root.toString();
}
- public int getUserOptions() {
- return userOptions;
+ public String dumpByteCode() {
+ compile();
+ return new ByteCodePrinter(this).byteCodeListToString();
}
- public void setUserObject(Object object) {
- this.userObject = object;
- }
-
- public Object getUserObject() {
- return userObject;
- }
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java
index d685a249593..ee9eb16810b 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Region.java
@@ -25,7 +25,6 @@ public final class Region {
public final int numRegs;
public final int[]beg;
public final int[]end;
- public CaptureTreeNode historyRoot;
public Region(int num) {
this.numRegs = num;
@@ -33,20 +32,6 @@ public final class Region {
this.end = new int[num];
}
- public Region(int begin, int end) {
- this.numRegs = 1;
- this.beg = new int[]{begin};
- this.end = new int[]{end};
- }
-
- public Region clone() {
- Region region = new Region(numRegs);
- System.arraycopy(beg, 0, region.beg, 0, beg.length);
- System.arraycopy(end, 0, region.end, 0, end.length);
- if (historyRoot != null) region.historyRoot = historyRoot.cloneTree();
- return region;
- }
-
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Region: \n");
@@ -54,10 +39,6 @@ public final class Region {
return sb.toString();
}
- CaptureTreeNode getCaptureTree() {
- return historyRoot;
- }
-
void clear() {
for (int i=0; i 0 && strLength >= Config.CHECK_STRING_THRESHOLD_LEN) {
- int size = ((strLength + 1) * stateNum + 7) >>> 3;
- offset = (offset * stateNum) >>> 3;
-
- if (size > 0 && offset < size && size < Config.CHECK_BUFF_MAX_SIZE) {
- if (size >= STATE_CHECK_BUFF_MALLOC_THRESHOLD_SIZE) {
- stateCheckBuff = new byte[size];
- } else {
- // same impl, reduce...
- stateCheckBuff = new byte[size];
- }
- Arrays.fill(stateCheckBuff, offset, (size - offset), (byte)0);
- stateCheckBuffSize = size;
- } else {
- stateCheckBuff = null; // reduce
- stateCheckBuffSize = 0;
- }
- } else {
- stateCheckBuff = null; // reduce
- stateCheckBuffSize = 0;
- }
- }
-
- protected final void stateCheckBuffClear() {
- stateCheckBuff = null;
- stateCheckBuffSize = 0;
- }
-
private void push(int type, int pat, int s, int prev) {
StackEntry e = ensure1();
e.type = type;
e.setStatePCode(pat);
e.setStatePStr(s);
e.setStatePStrPrev(prev);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
@@ -172,30 +112,9 @@ abstract class StackMachine extends Matcher implements StackType {
StackEntry e = stack[stk];
e.type = type;
e.setStatePCode(pat);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(0);
stk++;
}
- protected final void pushAltWithStateCheck(int pat, int s, int sprev, int snum) {
- StackEntry e = ensure1();
- e.type = ALT;
- e.setStatePCode(pat);
- e.setStatePStr(s);
- e.setStatePStrPrev(sprev);
- if (Config.USE_COMBINATION_EXPLOSION_CHECK) e.setStateCheck(stateCheckBuff != null ? snum : 0);
- stk++;
- }
-
- protected final void pushStateCheck(int s, int snum) {
- if (stateCheckBuff != null) {
- StackEntry e = ensure1();
- e.type = STATE_CHECK_MARK;
- e.setStatePStr(s);
- e.setStateCheck(snum);
- stk++;
- }
- }
-
protected final void pushAlt(int pat, int s, int prev) {
push(ALT, pat, s, prev);
}
@@ -294,19 +213,6 @@ abstract class StackMachine extends Matcher implements StackType {
stk++;
}
- protected final void pushCallFrame(int pat) {
- StackEntry e = ensure1();
- e.type = CALL_FRAME;
- e.setCallFrameRetAddr(pat);
- stk++;
- }
-
- protected final void pushReturn() {
- StackEntry e = ensure1();
- e.type = RETURN;
- stk++;
- }
-
// stack debug routines here
// ...
@@ -331,8 +237,6 @@ abstract class StackMachine extends Matcher implements StackType {
if ((e.type & MASK_POP_USED) != 0) {
return e;
- } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@@ -346,8 +250,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_START) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
- } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@@ -368,8 +270,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
- } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@@ -391,8 +291,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_END){
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemStart();
- } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
@@ -414,8 +312,6 @@ abstract class StackMachine extends Matcher implements StackType {
} else if (e.type == MEM_END) {
repeatStk[memStartStk + e.getMemNum()] = e.getMemStart();
repeatStk[memEndStk + e.getMemNum()] = e.getMemEnd();
- } else if (Config.USE_COMBINATION_EXPLOSION_CHECK) {
- if (e.type == STATE_CHECK_MARK) stateCheckMark();
}
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java
index 07b52626eda..518a416e7fb 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Syntax.java
@@ -609,7 +609,7 @@ public final class Syntax implements SyntaxProperties{
OP_ESC_CONTROL_CHARS | OP_ESC_C_CONTROL | OP_ESC_X_HEX2)
& ~OP_ESC_LTGT_WORD_BEGIN_END ),
- ( OP2_QMARK_GROUP_EFFECT | OP2_CCLASS_SET_OP |
+ ( OP2_QMARK_GROUP_EFFECT |
OP2_ESC_V_VTAB | OP2_ESC_U_HEX4 ),
( GNU_REGEX_BV | DIFFERENT_LEN_ALT_LOOK_BEHIND ),
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java
deleted file mode 100644
index ca72e16742f..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/UnsetAddrList.java
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni;
-
-import jdk.nashorn.internal.runtime.regexp.joni.ast.EncloseNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.Node;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.InternalException;
-
-public final class UnsetAddrList {
- int num;
- Node[]targets;
- int[]offsets;
-
- public UnsetAddrList(int size) {
- targets = new Node[size];
- offsets = new int[size];
- }
-
- public void add(int offset, Node node) {
- if (num >= offsets.length) {
- Node []ttmp = new Node[targets.length << 1];
- System.arraycopy(targets, 0, ttmp, 0, num);
- targets = ttmp;
- int[]otmp = new int[offsets.length << 1];
- System.arraycopy(offsets, 0, otmp, 0, num);
- offsets = otmp;
- }
- targets[num] = node;
- offsets[num] = offset;
-
- num++;
- }
-
- public void fix(Regex regex) {
- for (int i=0; i 0) {
- for (int i=0; i set, WarnCallback warnings) {
- if (target == null || target.parent == this)
- warnings.warn(this.getAddressName() + " doesn't point to a target or the target has been stolen");
- // do not recurse here
- }
-
- @Override
- public String toString(int level) {
- StringBuilder value = new StringBuilder(super.toString(level));
- value.append("\n name: " + new String(name, nameP, nameEnd - nameP));
- value.append("\n groupNum: " + groupNum);
- value.append("\n target: " + pad(target.getAddressName(), level + 1));
- value.append("\n unsetAddrList: " + pad(unsetAddrList, level + 1));
-
- return value.toString();
- }
-
-}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java
index a60afb1d1d6..1c5bfe7d89d 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/EncloseNode.java
@@ -25,7 +25,7 @@ import jdk.nashorn.internal.runtime.regexp.joni.constants.EncloseType;
public final class EncloseNode extends StateNode implements EncloseType {
- public int type; // enclose type
+ public final int type; // enclose type
public int regNum;
public int option;
public Node target; /* EncloseNode : ENCLOSE_MEMORY */
@@ -42,10 +42,8 @@ public final class EncloseNode extends StateNode implements EncloseType {
}
// node_new_enclose_memory
- public EncloseNode(int option, boolean isNamed) {
+ public EncloseNode() {
this(MEMORY);
- if (isNamed) setNamedGroup();
- if (Config.USE_SUBEXP_CALL) this.option = option;
}
// node_new_option
@@ -104,46 +102,14 @@ public final class EncloseNode extends StateNode implements EncloseType {
return types.toString();
}
- public void setEncloseStatus(int flag) {
- state |= flag;
- }
-
- public void clearEncloseStatus(int flag) {
- state &= ~flag;
- }
-
- public void clearMemory() {
- type &= ~MEMORY;
- }
-
- public void setMemory() {
- type |= MEMORY;
- }
-
public boolean isMemory() {
return (type & MEMORY) != 0;
}
- public void clearOption() {
- type &= ~OPTION;
- }
-
- public void setOption() {
- type |= OPTION;
- }
-
public boolean isOption() {
return (type & OPTION) != 0;
}
- public void clearStopBacktrack() {
- type &= ~STOP_BACKTRACK;
- }
-
- public void setStopBacktrack() {
- type |= STOP_BACKTRACK;
- }
-
public boolean isStopBacktrack() {
return (type & STOP_BACKTRACK) != 0;
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java
index 26cde98506f..c87de29d74a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/QuantifierNode.java
@@ -21,9 +21,10 @@ package jdk.nashorn.internal.runtime.regexp.joni.ast;
import jdk.nashorn.internal.runtime.regexp.joni.Config;
import jdk.nashorn.internal.runtime.regexp.joni.ScanEnvironment;
-import jdk.nashorn.internal.runtime.regexp.joni.constants.Reduce;
import jdk.nashorn.internal.runtime.regexp.joni.constants.TargetInfo;
+import static jdk.nashorn.internal.runtime.regexp.joni.ast.QuantifierNode.ReduceType.*;
+
public final class QuantifierNode extends StateNode {
public Node target;
@@ -37,8 +38,33 @@ public final class QuantifierNode extends StateNode {
public Node nextHeadExact;
public boolean isRefered; /* include called node. don't eliminate even if {0} */
- // USE_COMBINATION_EXPLOSION_CHECK
- public int combExpCheckNum; /* 1,2,3...: check, 0: no check */
+ enum ReduceType {
+ ASIS, /* as is */
+ DEL, /* delete parent */
+ A, /* to '*' */
+ AQ, /* to '*?' */
+ QQ, /* to '??' */
+ P_QQ, /* to '+)??' */
+ PQ_Q, /* to '+?)?' */
+ }
+
+ private final static ReduceType[][] REDUCE_TABLE = {
+ {DEL, A, A, QQ, AQ, ASIS}, /* '?' */
+ {DEL, DEL, DEL, P_QQ, P_QQ, DEL}, /* '*' */
+ {A, A, DEL, ASIS, P_QQ, DEL}, /* '+' */
+ {DEL, AQ, AQ, DEL, AQ, AQ}, /* '??' */
+ {DEL, DEL, DEL, DEL, DEL, DEL}, /* '*?' */
+ {ASIS, PQ_Q, DEL, AQ, AQ, DEL} /* '+?' */
+ };
+
+ private final static String PopularQStr[] = new String[] {
+ "?", "*", "+", "??", "*?", "+?"
+ };
+
+ private final static String ReduceQStr[]= new String[] {
+ "", "", "*", "*?", "??", "+ and ??", "+? and ?"
+ };
+
public QuantifierNode(int lower, int upper, boolean byNumber) {
this.lower = lower;
@@ -92,7 +118,6 @@ public final class QuantifierNode extends StateNode {
value.append("\n headExact: " + pad(headExact, level + 1));
value.append("\n nextHeadExact: " + pad(nextHeadExact, level + 1));
value.append("\n isRefered: " + isRefered);
- value.append("\n combExpCheckNum: " + combExpCheckNum);
return value.toString();
}
@@ -134,7 +159,6 @@ public final class QuantifierNode extends StateNode {
headExact = other.headExact;
nextHeadExact = other.nextHeadExact;
isRefered = other.isRefered;
- combExpCheckNum = other.combExpCheckNum;
}
public void reduceNestedQuantifier(QuantifierNode other) {
@@ -143,7 +167,7 @@ public final class QuantifierNode extends StateNode {
if (pnum < 0 || cnum < 0) return;
- switch(Reduce.REDUCE_TABLE[cnum][pnum]) {
+ switch(REDUCE_TABLE[cnum][pnum]) {
case DEL:
// no need to set the parent here...
// swap ?
@@ -226,7 +250,7 @@ public final class QuantifierNode extends StateNode {
if (Config.USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR) {
if (!isByNumber() && !qnt.isByNumber() && env.syntax.warnReduntantNestedRepeat()) {
- switch(Reduce.REDUCE_TABLE[targetQNum][nestQNum]) {
+ switch(REDUCE_TABLE[targetQNum][nestQNum]) {
case ASIS:
break;
@@ -237,9 +261,9 @@ public final class QuantifierNode extends StateNode {
default:
env.reg.getWarnings().warn(new String(chars, p, end) +
- " nested repeat operator " + Reduce.PopularQStr[targetQNum] +
- " and " + Reduce.PopularQStr[nestQNum] + " was replaced with '" +
- Reduce.ReduceQStr[Reduce.REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
+ " nested repeat operator " + PopularQStr[targetQNum] +
+ " and " + PopularQStr[nestQNum] + " was replaced with '" +
+ ReduceQStr[REDUCE_TABLE[targetQNum][nestQNum].ordinal()] + "'");
}
}
} // USE_WARNING_REDUNDANT_NESTED_REPEAT_OPERATOR
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java
index 18101a4aed4..3f75f8630a8 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ast/StateNode.java
@@ -40,7 +40,6 @@ public abstract class StateNode extends Node implements NodeStatus {
if (isRecursion()) states.append("RECURSION ");
if (isCalled()) states.append("CALLED ");
if (isAddrFixed()) states.append("ADDR_FIXED ");
- if (isNamedGroup()) states.append("NAMED_GROUP ");
if (isNameRef()) states.append("NAME_REF ");
if (isInRepeat()) states.append("IN_REPEAT ");
if (isNestLevel()) states.append("NEST_LEVEL ");
@@ -57,10 +56,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MIN_FIXED;
}
- public void clearMinFixed() {
- state &= ~NST_MIN_FIXED;
- }
-
public boolean isMaxFixed() {
return (state & NST_MAX_FIXED) != 0;
}
@@ -69,10 +64,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MAX_FIXED;
}
- public void clearMaxFixed() {
- state &= ~NST_MAX_FIXED;
- }
-
public boolean isCLenFixed() {
return (state & NST_CLEN_FIXED) != 0;
}
@@ -81,10 +72,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_CLEN_FIXED;
}
- public void clearCLenFixed() {
- state &= ~NST_CLEN_FIXED;
- }
-
public boolean isMark1() {
return (state & NST_MARK1) != 0;
}
@@ -93,10 +80,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MARK1;
}
- public void clearMark1() {
- state &= ~NST_MARK1;
- }
-
public boolean isMark2() {
return (state & NST_MARK2) != 0;
}
@@ -117,10 +100,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_MEM_BACKREFED;
}
- public void clearMemBackrefed() {
- state &= ~NST_MEM_BACKREFED;
- }
-
public boolean isStopBtSimpleRepeat() {
return (state & NST_STOP_BT_SIMPLE_REPEAT) != 0;
}
@@ -129,10 +108,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_STOP_BT_SIMPLE_REPEAT;
}
- public void clearStopBtSimpleRepeat() {
- state &= ~NST_STOP_BT_SIMPLE_REPEAT;
- }
-
public boolean isRecursion() {
return (state & NST_RECURSION) != 0;
}
@@ -141,10 +116,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_RECURSION;
}
- public void clearRecursion() {
- state &= ~NST_RECURSION;
- }
-
public boolean isCalled() {
return (state & NST_CALLED) != 0;
}
@@ -153,10 +124,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_CALLED;
}
- public void clearCAlled() {
- state &= ~NST_CALLED;
- }
-
public boolean isAddrFixed() {
return (state & NST_ADDR_FIXED) != 0;
}
@@ -165,22 +132,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_ADDR_FIXED;
}
- public void clearAddrFixed() {
- state &= ~NST_ADDR_FIXED;
- }
-
- public boolean isNamedGroup() {
- return (state & NST_NAMED_GROUP) != 0;
- }
-
- public void setNamedGroup() {
- state |= NST_NAMED_GROUP;
- }
-
- public void clearNamedGroup() {
- state &= ~NST_NAMED_GROUP;
- }
-
public boolean isNameRef() {
return (state & NST_NAME_REF) != 0;
}
@@ -189,10 +140,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_NAME_REF;
}
- public void clearNameRef() {
- state &= ~NST_NAME_REF;
- }
-
public boolean isInRepeat() {
return (state & NST_IN_REPEAT) != 0;
}
@@ -201,10 +148,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_IN_REPEAT;
}
- public void clearInRepeat() {
- state &= ~NST_IN_REPEAT;
- }
-
public boolean isNestLevel() {
return (state & NST_NEST_LEVEL) != 0;
}
@@ -213,10 +156,6 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_NEST_LEVEL;
}
- public void clearNestLevel() {
- state &= ~NST_NEST_LEVEL;
- }
-
public boolean isByNumber() {
return (state & NST_BY_NUMBER) != 0;
}
@@ -225,8 +164,4 @@ public abstract class StateNode extends Node implements NodeStatus {
state |= NST_BY_NUMBER;
}
- public void clearByNumber() {
- state &= ~NST_BY_NUMBER;
- }
-
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java
deleted file mode 100644
index 9751b51d5c0..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/bench/AbstractBench.java
+++ /dev/null
@@ -1,49 +0,0 @@
-package jdk.nashorn.internal.runtime.regexp.joni.bench;
-
-import jdk.nashorn.internal.runtime.regexp.joni.Option;
-import jdk.nashorn.internal.runtime.regexp.joni.Regex;
-import jdk.nashorn.internal.runtime.regexp.joni.Syntax;
-
-public abstract class AbstractBench {
- protected void bench(String _reg, String _str, int warmup, int times) throws Exception {
- char[] reg = _reg.toCharArray();
- char[] str = _str.toCharArray();
-
- Regex p = new Regex(reg,0,reg.length,Option.DEFAULT,Syntax.DEFAULT);
-
- System.err.println("::: /" + _reg + "/ =~ \"" + _str + "\", " + warmup + " * " + times + " times");
-
- for(int j=0;j {
public T p;
- static final ObjPtr NULL = new ObjPtr();
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java
deleted file mode 100644
index 48978bf48ee..00000000000
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/encoding/PosixBracket.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS".toCharArray(), WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-package jdk.nashorn.internal.runtime.regexp.joni.encoding;
-
-import jdk.nashorn.internal.runtime.regexp.joni.exception.ErrorMessages;
-import jdk.nashorn.internal.runtime.regexp.joni.exception.JOniException;
-
-import java.util.HashMap;
-
-public class PosixBracket {
-
- public static final char[][] PBSNamesLower = {
- "alnum".toCharArray(),
- "alpha".toCharArray(),
- "blank".toCharArray(),
- "cntrl".toCharArray(),
- "digit".toCharArray(),
- "graph".toCharArray(),
- "lower".toCharArray(),
- "print".toCharArray(),
- "punct".toCharArray(),
- "space".toCharArray(),
- "upper".toCharArray(),
- "xdigit".toCharArray(),
- "ascii".toCharArray(),
- "word".toCharArray()
- };
-
- public static final int PBSValues[] = {
- CharacterType.ALNUM,
- CharacterType.ALPHA,
- CharacterType.BLANK,
- CharacterType.CNTRL,
- CharacterType.DIGIT,
- CharacterType.GRAPH,
- CharacterType.LOWER,
- CharacterType.PRINT,
- CharacterType.PUNCT,
- CharacterType.SPACE,
- CharacterType.UPPER,
- CharacterType.XDIGIT,
- CharacterType.ASCII,
- CharacterType.WORD,
- };
-
- public static int propertyNameToCType(String name) {
- name = name.toLowerCase();
- if (!PBSTableUpper.containsKey(name)) {
- throw new JOniException(ErrorMessages.ERR_INVALID_CHAR_PROPERTY_NAME.replaceAll("%n", name));
- }
- return PBSTableUpper.get(name);
- }
-
- private static final HashMap PBSTableUpper = new HashMap();
-
- static {
- for (int i=0; i" : "invalid char in group number <%n>";
- final String ERR_UNDEFINED_NAME_REFERENCE = "undefined name <%n> reference";
- final String ERR_UNDEFINED_GROUP_REFERENCE = "undefined group <%n> reference";
- final String ERR_MULTIPLEX_DEFINED_NAME = "multiplex defined name <%n>";
- final String ERR_MULTIPLEX_DEFINITION_NAME_CALL = "multiplex definition name <%n> call";
- final String ERR_NEVER_ENDING_RECURSION = "never ending recursion";
+ final String ERR_INVALID_CHAR_IN_GROUP_NAME = "invalid char in group number <%n>";
final String ERR_GROUP_NUMBER_OVER_FOR_CAPTURE_HISTORY = "group number is too big for capture history";
- final String ERR_NOT_SUPPORTED_ENCODING_COMBINATION = "not supported encoding combination";
final String ERR_INVALID_COMBINATION_OF_OPTIONS = "invalid combination of options";
- final String ERR_OVER_THREAD_PASS_LIMIT_COUNT = "over thread pass limit count";
- final String ERR_TOO_BIG_SB_CHAR_VALUE = "too big singlebyte char value";
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java
index d56a35a4190..597fe221572 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/exception/ValueException.java
@@ -30,8 +30,4 @@ public class ValueException extends SyntaxException{
super(message.replaceAll("%n", str));
}
- public ValueException(String message, byte[]bytes, int p, int end) {
- this(message, new String(bytes, p, end - p));
- }
-
}
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java
new file mode 100644
index 00000000000..c22838fb277
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/regexp/JdkRegExpTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.regexp;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import jdk.nashorn.internal.runtime.ParserException;
+import org.testng.annotations.Test;
+
+/**
+ * Basic tests for the JDK based RegExp implementation.
+ *
+ * @test
+ * @run testng jdk.nashorn.internal.runtime.regexp.JdkRegExpTest
+ */
+public class JdkRegExpTest {
+
+ /**
+ * Compile a regular expression using the JDK implementation
+ */
+ @Test
+ public void testMatcher() {
+ RegExp regexp = new RegExpFactory().compile("f(o)o", "");
+ RegExpMatcher matcher = regexp.match("foo");
+ assertNotNull(matcher);
+ assertTrue(matcher.search(0));
+ assertEquals(matcher.getInput(), "foo");
+ assertEquals(matcher.groupCount(), 1);
+ assertEquals(matcher.group(), "foo");
+ assertEquals(matcher.start(), 0);
+ assertEquals(matcher.end(), 3);
+ assertEquals(matcher.group(1), "o");
+ assertEquals(matcher.start(1), 1);
+ assertEquals(matcher.end(1), 2);
+ }
+}
diff --git a/nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java b/nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java
new file mode 100644
index 00000000000..a6981c8dc8c
--- /dev/null
+++ b/nashorn/test/src/jdk/nashorn/internal/runtime/regexp/joni/JoniTest.java
@@ -0,0 +1,52 @@
+/*
+ * 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.regexp.joni;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+/**
+ * Joni coverage tests
+ *
+ * @test
+ * @run testng jdk.nashorn.internal.runtime.regexp.joni.JoniTest
+ */
+public class JoniTest {
+
+ @Test
+ public void testDump() {
+ new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpTree();
+ new Regex("^a{3,}(.*)[z]++\\s\\1x$").dumpByteCode();
+ new Regex("(abc){4,}{2,5}").dumpTree();
+ new Regex("(abc){4,}{2,5}").dumpByteCode();
+ new Regex("aaa|aa|bbbb|ccc").dumpTree();
+ new Regex("aaa|aa|bbbb|ccc").dumpByteCode();
+ new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpTree();
+ new Regex("(?:ZFVR.(\\d+\\.\\d+))|(?:(?:Sversbk|TenaCnenqvfb|Vprjrnfry).(\\d+\\.\\d+))|(?:Bcren.(\\d+\\.\\d+))|(?:NccyrJroXvg.(\\d+(?:\\.\\d+)?))").dumpByteCode();
+ }
+}
From e0fcb74c7e43171e3425503ba4e250b2884d6b26 Mon Sep 17 00:00:00 2001
From: Konstantin Shefov
Date: Fri, 17 May 2013 16:44:22 -0300
Subject: [PATCH 018/206] 8014823: Reprise - Smoke test fail: Windows
JDK-8008554.js - access denied ("java.io.FilePermission"
"//C/aurora/sandbox/nashorn~source/test/script/basic/NASHORN-99.js" "read")
Reviewed-by: jlaskey
---
nashorn/test/script/basic/JDK-8008554.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nashorn/test/script/basic/JDK-8008554.js b/nashorn/test/script/basic/JDK-8008554.js
index 0cbe8b8e699..f8ec9587c34 100644
--- a/nashorn/test/script/basic/JDK-8008554.js
+++ b/nashorn/test/script/basic/JDK-8008554.js
@@ -32,5 +32,5 @@
var dir = __DIR__;
var file = __FILE__.replace("JDK-8008554", "NASHORN-99");
load(file);
-file = "file://" + __DIR__ + "NASHORN-99.js";
+file = "file:///" + __DIR__ + "NASHORN-99.js";
load(file);
From f5bda14b93b9d4161af60d065f8d5a9295d05023 Mon Sep 17 00:00:00 2001
From: Jonathan Gibbons
Date: Fri, 17 May 2013 13:48:41 -0700
Subject: [PATCH 019/206] 6885876: add comments to javac/util/Convert.java
Reviewed-by: mduigou
---
.../com/sun/tools/javac/util/Convert.java | 20 ++++++++++++++++++-
1 file changed, 19 insertions(+), 1 deletion(-)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/Convert.java b/langtools/src/share/classes/com/sun/tools/javac/util/Convert.java
index b2253aab2e7..c4725f3570a 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/Convert.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/Convert.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,24 @@ package com.sun.tools.javac.util;
/** Utility class for static conversion methods between numbers
* and strings in various formats.
*
+ *
Note regarding UTF-8.
+ * The JVMS defines its own version of the UTF-8 format so that it
+ * contains no zero bytes (modified UTF-8). This is not actually the same
+ * as Charset.forName("UTF-8").
+ *
+ *
+ *
+ * The methods here support modified UTF-8.
+ *
*
This is NOT part of any supported API.
* If you write code that depends on this, you do so at your own risk.
* This code and its internal interfaces are subject to change or
From cc79bd12371e6df1dc416992e9ca01a5f989ae2d Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Mon, 20 May 2013 16:38:38 +0200
Subject: [PATCH 020/206] 8006069: Range analysis first iteration, runtime
specializations
Reviewed-by: jlaskey, sundar
---
.../internal/codegen/CompilationPhase.java | 94 ++-
.../nashorn/internal/codegen/Compiler.java | 7 +-
.../internal/codegen/CompilerConstants.java | 2 +-
.../internal/codegen/MethodEmitter.java | 9 +-
.../internal/codegen/RangeAnalyzer.java | 474 ++++++++++++
.../nashorn/internal/codegen/types/Range.java | 705 ++++++++++++++++++
.../nashorn/internal/codegen/types/Type.java | 12 +-
.../jdk/nashorn/internal/ir/BinaryNode.java | 17 +
.../jdk/nashorn/internal/ir/FunctionNode.java | 2 +-
.../nashorn/internal/ir/LexicalContext.java | 20 +-
nashorn/src/jdk/nashorn/internal/ir/Node.java | 8 +
.../src/jdk/nashorn/internal/ir/Symbol.java | 33 +-
.../internal/runtime/CompiledFunction.java | 32 +-
.../runtime/FinalScriptFunctionData.java | 4 +-
.../RecompilableScriptFunctionData.java | 236 ++++--
.../internal/runtime/ScriptEnvironment.java | 6 +-
.../internal/runtime/ScriptFunctionData.java | 5 +-
.../runtime/resources/Options.properties | 6 +
nashorn/test/script/basic/ranges_disabled.js | 32 +
.../script/basic/ranges_disabled.js.EXPECTED | 4 +
nashorn/test/script/basic/ranges_enabled.js | 33 +
.../script/basic/ranges_enabled.js.EXPECTED | 4 +
nashorn/test/script/basic/ranges_payload.js | 74 ++
23 files changed, 1720 insertions(+), 99 deletions(-)
create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java
create mode 100644 nashorn/src/jdk/nashorn/internal/codegen/types/Range.java
create mode 100644 nashorn/test/script/basic/ranges_disabled.js
create mode 100644 nashorn/test/script/basic/ranges_disabled.js.EXPECTED
create mode 100644 nashorn/test/script/basic/ranges_enabled.js
create mode 100644 nashorn/test/script/basic/ranges_enabled.js.EXPECTED
create mode 100644 nashorn/test/script/basic/ranges_payload.js
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
index bfc71cc2198..f2603393612 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilationPhase.java
@@ -11,13 +11,21 @@ import static jdk.nashorn.internal.ir.FunctionNode.CompilationState.SPLIT;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Deque;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
+
+import jdk.nashorn.internal.codegen.types.Range;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.Block;
import jdk.nashorn.internal.ir.CallNode;
import jdk.nashorn.internal.ir.FunctionNode;
+import jdk.nashorn.internal.ir.ReturnNode;
+import jdk.nashorn.internal.ir.Symbol;
import jdk.nashorn.internal.ir.FunctionNode.CompilationState;
import jdk.nashorn.internal.ir.LexicalContext;
import jdk.nashorn.internal.ir.Node;
@@ -174,7 +182,7 @@ enum CompilationPhase {
FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
final TemporarySymbols ts = compiler.getTemporarySymbols();
final FunctionNode newFunctionNode = (FunctionNode)enterAttr(fn, ts).accept(new Attr(ts));
- if(compiler.getEnv()._print_mem_usage) {
+ if (compiler.getEnv()._print_mem_usage) {
Compiler.LOG.info("Attr temporary symbol count: " + ts.getTotalSymbolCount());
}
return newFunctionNode;
@@ -207,6 +215,89 @@ enum CompilationPhase {
}
},
+ /*
+ * Range analysis
+ * Conservatively prove that certain variables can be narrower than
+ * the most generic number type
+ */
+ RANGE_ANALYSIS_PHASE(EnumSet.of(INITIALIZED, PARSED, CONSTANT_FOLDED, LOWERED, ATTR)) {
+ @Override
+ FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
+ if (!compiler.getEnv()._range_analysis) {
+ return fn;
+ }
+
+ FunctionNode newFunctionNode = (FunctionNode)fn.accept(new RangeAnalyzer());
+ final List returns = new ArrayList<>();
+
+ newFunctionNode = (FunctionNode)newFunctionNode.accept(new NodeVisitor() {
+ private final Deque> returnStack = new ArrayDeque<>();
+
+ @Override
+ public boolean enterFunctionNode(final FunctionNode functionNode) {
+ returnStack.push(new ArrayList());
+ return true;
+ }
+
+ @Override
+ public Node leaveFunctionNode(final FunctionNode functionNode) {
+ Type returnType = Type.UNKNOWN;
+ for (final ReturnNode ret : returnStack.pop()) {
+ if (ret.getExpression() == null) {
+ returnType = Type.OBJECT;
+ break;
+ }
+ returnType = Type.widest(returnType, ret.getExpression().getType());
+ }
+ return functionNode.setReturnType(getLexicalContext(), returnType);
+ }
+
+ @Override
+ public Node leaveReturnNode(final ReturnNode returnNode) {
+ final ReturnNode result = (ReturnNode)leaveDefault(returnNode);
+ returns.add(result);
+ return result;
+ }
+
+ @Override
+ public Node leaveDefault(final Node node) {
+ final Symbol symbol = node.getSymbol();
+ if (symbol != null) {
+ final Range range = symbol.getRange();
+ final Type symbolType = symbol.getSymbolType();
+ if (!symbolType.isNumeric()) {
+ return node;
+ }
+ final Type rangeType = range.getType();
+ if (!Type.areEquivalent(symbolType, rangeType) && Type.widest(symbolType, rangeType) == symbolType) { //we can narrow range
+ RangeAnalyzer.LOG.info("[", getLexicalContext().getCurrentFunction().getName(), "] ", symbol, " can be ", range.getType(), " ", symbol.getRange());
+ return node.setSymbol(getLexicalContext(), symbol.setTypeOverrideShared(range.getType(), compiler.getTemporarySymbols()));
+ }
+ }
+ return node;
+ }
+ });
+
+ Type returnType = Type.UNKNOWN;
+ for (final ReturnNode node : returns) {
+ if (node.getExpression() != null) {
+ returnType = Type.widest(returnType, node.getExpression().getType());
+ } else {
+ returnType = Type.OBJECT;
+ break;
+ }
+ }
+
+ return newFunctionNode.setReturnType(null, returnType);
+ }
+
+ @Override
+ public String toString() {
+ return "[Range Analysis]";
+ }
+ },
+
+
/*
* Splitter Split the AST into several compile units based on a size
* heuristic Splitter needs attributed AST for weight calculations (e.g. is
@@ -218,7 +309,6 @@ enum CompilationPhase {
FunctionNode transform(final Compiler compiler, final FunctionNode fn) {
final CompileUnit outermostCompileUnit = compiler.addCompileUnit(compiler.firstCompileUnitName());
-// assert fn.isProgram() ;
final FunctionNode newFunctionNode = new Splitter(compiler, fn, outermostCompileUnit).split(fn);
assert newFunctionNode.getCompileUnit() == outermostCompileUnit : "fn.compileUnit (" + newFunctionNode.getCompileUnit() + ") != " + outermostCompileUnit;
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
index 81a76186ce8..faf7a3c5a09 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/Compiler.java
@@ -99,7 +99,7 @@ public final class Compiler {
private boolean strict;
- private CodeInstaller installer;
+ private final CodeInstaller installer;
private final TemporarySymbols temporarySymbols = new TemporarySymbols();
@@ -219,6 +219,7 @@ public final class Compiler {
CompilationPhase.CONSTANT_FOLDING_PHASE,
CompilationPhase.LOWERING_PHASE,
CompilationPhase.ATTRIBUTION_PHASE,
+ CompilationPhase.RANGE_ANALYSIS_PHASE,
CompilationPhase.SPLITTING_PHASE,
CompilationPhase.TYPE_FINALIZATION_PHASE,
CompilationPhase.BYTECODE_GENERATION_PHASE);
@@ -384,6 +385,8 @@ public final class Compiler {
if (info) {
final StringBuilder sb = new StringBuilder();
sb.append("Compile job for '").
+ append(newFunctionNode.getSource()).
+ append(':').
append(newFunctionNode.getName()).
append("' finished");
@@ -487,7 +490,7 @@ public final class Compiler {
}
if (sb != null) {
- LOG.info(sb);
+ LOG.fine(sb);
}
return rootClass;
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
index 6912534dee6..d9c68ad8288 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java
@@ -262,7 +262,7 @@ public enum CompilerConstants {
* @return the internal descriptor for this type
*/
public static String typeDescriptor(final Class> clazz) {
- return Type.getDescriptor(clazz);
+ return Type.typeFor(clazz).getDescriptor();
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
index c156c865f69..4e07c4777dc 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/MethodEmitter.java
@@ -2081,7 +2081,9 @@ public class MethodEmitter implements Emitter {
* @param args debug information to print
*/
private void debug(final Object... args) {
- debug(30, args);
+ if (DEBUG) {
+ debug(30, args);
+ }
}
/**
@@ -2091,7 +2093,9 @@ public class MethodEmitter implements Emitter {
* @param args debug information to print
*/
private void debug_label(final Object... args) {
- debug(26, args);
+ if (DEBUG) {
+ debug(22, args);
+ }
}
private void debug(final int padConstant, final Object... args) {
@@ -2164,7 +2168,6 @@ public class MethodEmitter implements Emitter {
new Throwable().printStackTrace(LOG.getOutputStream());
}
}
-
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java b/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java
new file mode 100644
index 00000000000..1229caa1fea
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/RangeAnalyzer.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.codegen;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+
+import jdk.nashorn.internal.codegen.types.Range;
+import jdk.nashorn.internal.codegen.types.Type;
+import jdk.nashorn.internal.ir.Assignment;
+import jdk.nashorn.internal.ir.BinaryNode;
+import jdk.nashorn.internal.ir.ForNode;
+import jdk.nashorn.internal.ir.IdentNode;
+import jdk.nashorn.internal.ir.LiteralNode;
+import jdk.nashorn.internal.ir.LiteralNode.ArrayLiteralNode;
+import jdk.nashorn.internal.ir.LoopNode;
+import jdk.nashorn.internal.ir.Node;
+import jdk.nashorn.internal.ir.RuntimeNode;
+import jdk.nashorn.internal.ir.Symbol;
+import jdk.nashorn.internal.ir.UnaryNode;
+import jdk.nashorn.internal.ir.VarNode;
+import jdk.nashorn.internal.ir.visitor.NodeOperatorVisitor;
+import jdk.nashorn.internal.ir.visitor.NodeVisitor;
+import jdk.nashorn.internal.parser.TokenType;
+import jdk.nashorn.internal.runtime.DebugLogger;
+
+/**
+ * Range analysis and narrowing of type where it can be proven
+ * that there is no spillover, e.g.
+ *
+ * function func(c) {
+ * var v = c & 0xfff;
+ * var w = c & 0xeee;
+ * var x = v * w;
+ * return x;
+ * }
+ *
+ * Proves that the multiplication never exceeds 24 bits and can thus be an int
+ */
+final class RangeAnalyzer extends NodeOperatorVisitor {
+ static final DebugLogger LOG = new DebugLogger("ranges");
+
+ private static final Range.Functionality RANGE = new Range.Functionality(LOG);
+
+ private final Map loopCounters = new HashMap<>();
+
+ RangeAnalyzer() {
+ }
+
+ @Override
+ public boolean enterForNode(final ForNode forNode) {
+ //conservatively attempt to identify the loop counter. Null means that it wasn't
+ //properly identified and that no optimizations can be made with it - its range is
+ //simply unknown in that case, if it is assigned in the loop
+ final Symbol counter = findLoopCounter(forNode);
+ LOG.fine("Entering forNode " + forNode + " counter = " + counter);
+ if (counter != null && !assignedInLoop(forNode, counter)) {
+ loopCounters.put(forNode, counter);
+ }
+ return true;
+ }
+
+ //destination visited
+ private Symbol setRange(final Node dest, final Range range) {
+ if (range.isUnknown()) {
+ return null;
+ }
+
+ final Symbol symbol = dest.getSymbol();
+ assert symbol != null : dest + " " + dest.getClass() + " has no symbol";
+ assert symbol.getRange() != null : symbol + " has no range";
+ final Range symRange = RANGE.join(symbol.getRange(), range);
+
+ //anything assigned in the loop, not being the safe loop counter(s) invalidates its entire range
+ if (getLexicalContext().inLoop() && !isLoopCounter(getLexicalContext().getCurrentLoop(), symbol)) {
+ symbol.setRange(Range.createGenericRange());
+ return symbol;
+ }
+
+ if (!symRange.equals(symbol.getRange())) {
+ LOG.fine("Modify range for " + dest + " " + symbol + " from " + symbol.getRange() + " to " + symRange + " (in node = " + dest + ")" );
+ symbol.setRange(symRange);
+ }
+
+ return null;
+ }
+
+ @Override
+ public Node leaveADD(final BinaryNode node) {
+ setRange(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveSUB(final BinaryNode node) {
+ setRange(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveMUL(final BinaryNode node) {
+ setRange(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveDIV(final BinaryNode node) {
+ setRange(node, RANGE.div(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveMOD(final BinaryNode node) {
+ setRange(node, RANGE.mod(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveBIT_AND(final BinaryNode node) {
+ setRange(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveBIT_OR(final BinaryNode node) {
+ setRange(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveBIT_XOR(final BinaryNode node) {
+ setRange(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveSAR(final BinaryNode node) {
+ setRange(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveSHL(final BinaryNode node) {
+ setRange(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveSHR(final BinaryNode node) {
+ setRange(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ private Node leaveCmp(final BinaryNode node) {
+ setRange(node, Range.createTypeRange(Type.BOOLEAN));
+ return node;
+ }
+
+ @Override
+ public Node leaveEQ(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveEQ_STRICT(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveNE(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveNE_STRICT(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveLT(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveLE(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveGT(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveGE(final BinaryNode node) {
+ return leaveCmp(node);
+ }
+
+ @Override
+ public Node leaveASSIGN(final BinaryNode node) {
+ Range range = node.rhs().getSymbol().getRange();
+ if (range.isUnknown()) {
+ range = Range.createGenericRange();
+ }
+
+ setRange(node.lhs(), range);
+ setRange(node, range);
+
+ return node;
+ }
+
+ private Node leaveSelfModifyingAssign(final BinaryNode node, final Range range) {
+ setRange(node.lhs(), range);
+ setRange(node, range);
+ return node;
+ }
+
+ private Node leaveSelfModifyingAssign(final UnaryNode node, final Range range) {
+ setRange(node.rhs(), range);
+ setRange(node, range);
+ return node;
+ }
+
+ @Override
+ public Node leaveASSIGN_ADD(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.add(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_SUB(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.sub(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_MUL(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.mul(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_DIV(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, Range.createTypeRange(Type.NUMBER));
+ }
+
+ @Override
+ public Node leaveASSIGN_MOD(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, Range.createTypeRange(Type.NUMBER));
+ }
+
+ @Override
+ public Node leaveASSIGN_BIT_AND(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.and(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_BIT_OR(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.or(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_BIT_XOR(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.xor(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_SAR(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.sar(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_SHR(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.shr(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveASSIGN_SHL(final BinaryNode node) {
+ return leaveSelfModifyingAssign(node, RANGE.shl(node.lhs().getSymbol().getRange(), node.rhs().getSymbol().getRange()));
+ }
+
+ @Override
+ public Node leaveDECINC(final UnaryNode node) {
+ switch (node.tokenType()) {
+ case DECPREFIX:
+ case DECPOSTFIX:
+ return leaveSelfModifyingAssign(node, RANGE.sub(node.rhs().getSymbol().getRange(), Range.createRange(1)));
+ case INCPREFIX:
+ case INCPOSTFIX:
+ return leaveSelfModifyingAssign(node, RANGE.add(node.rhs().getSymbol().getRange(), Range.createRange(1)));
+ default:
+ assert false;
+ return node;
+ }
+ }
+
+ @Override
+ public Node leaveADD(final UnaryNode node) {
+ Range range = node.rhs().getSymbol().getRange();
+ if (!range.getType().isNumeric()) {
+ range = Range.createTypeRange(Type.NUMBER);
+ }
+ setRange(node, range);
+ return node;
+ }
+
+ @Override
+ public Node leaveBIT_NOT(final UnaryNode node) {
+ setRange(node, Range.createTypeRange(Type.INT));
+ return node;
+ }
+
+ @Override
+ public Node leaveNOT(final UnaryNode node) {
+ setRange(node, Range.createTypeRange(Type.BOOLEAN));
+ return node;
+ }
+
+ @Override
+ public Node leaveSUB(final UnaryNode node) {
+ setRange(node, RANGE.neg(node.rhs().getSymbol().getRange()));
+ return node;
+ }
+
+ @Override
+ public Node leaveVarNode(final VarNode node) {
+ if (node.isAssignment()) {
+ Range range = node.getInit().getSymbol().getRange();
+ range = range.isUnknown() ? Range.createGenericRange() : range;
+
+ setRange(node.getName(), range);
+ setRange(node, range);
+ }
+
+ return node;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public boolean enterLiteralNode(final LiteralNode node) {
+ // ignore array literals
+ return !(node instanceof ArrayLiteralNode);
+ }
+
+ @Override
+ public Node leaveLiteralNode(@SuppressWarnings("rawtypes") final LiteralNode node) {
+ if (node.getType().isInteger()) {
+ setRange(node, Range.createRange(node.getInt32()));
+ } else if (node.getType().isNumber()) {
+ setRange(node, Range.createRange(node.getNumber()));
+ } else if (node.getType().isLong()) {
+ setRange(node, Range.createRange(node.getLong()));
+ } else if (node.getType().isBoolean()) {
+ setRange(node, Range.createTypeRange(Type.BOOLEAN));
+ } else {
+ setRange(node, Range.createGenericRange());
+ }
+ return node;
+ }
+
+ @Override
+ public boolean enterRuntimeNode(final RuntimeNode node) {
+ // a runtime node that cannot be specialized is no point entering
+ return node.getRequest().canSpecialize();
+ }
+
+ /**
+ * Check whether a symbol is unsafely assigned in a loop - i.e. repeteadly assigned and
+ * not being identified as the loop counter. That means we don't really know anything
+ * about its range.
+ * @param loopNode loop node
+ * @param symbol symbol
+ * @return true if assigned in loop
+ */
+ // TODO - this currently checks for nodes only - needs to be augmented for while nodes
+ // assignment analysis is also very conservative
+ private static boolean assignedInLoop(final LoopNode loopNode, final Symbol symbol) {
+ final HashSet skip = new HashSet<>();
+ final HashSet assignmentsInLoop = new HashSet<>();
+
+ loopNode.accept(new NodeVisitor() {
+ private boolean assigns(final Node node, final Symbol s) {
+ return node.isAssignment() && ((Assignment>)node).getAssignmentDest().getSymbol() == s;
+ }
+
+ @Override
+ public boolean enterForNode(final ForNode forNode) {
+ if (forNode.getInit() != null) {
+ skip.add(forNode.getInit());
+ }
+ if (forNode.getModify() != null) {
+ skip.add(forNode.getModify());
+ }
+ return true;
+ }
+
+ @Override
+ public Node leaveDefault(final Node node) {
+ //if this is an assignment to symbol
+ if (!skip.contains(node) && assigns(node, symbol)) {
+ assignmentsInLoop.add(node);
+ }
+ return node;
+ }
+ });
+
+ return !assignmentsInLoop.isEmpty();
+ }
+
+ /**
+ * Check for a loop counter. This is currently quite conservative, in that it only handles
+ * x <= counter and x < counter.
+ *
+ * @param node loop node to check
+ * @return
+ */
+ private static Symbol findLoopCounter(final LoopNode node) {
+ final Node test = node.getTest();
+
+ if (test != null && test.isComparison()) {
+ final BinaryNode binaryNode = (BinaryNode)test;
+ final Node lhs = binaryNode.lhs();
+ final Node rhs = binaryNode.rhs();
+
+ //detect ident cmp int_literal
+ if (lhs instanceof IdentNode && rhs instanceof LiteralNode && ((LiteralNode>)rhs).getType().isInteger()) {
+ final Symbol symbol = lhs.getSymbol();
+ final int margin = ((LiteralNode>)rhs).getInt32();
+ final TokenType op = test.tokenType();
+
+ switch (op) {
+ case LT:
+ case LE:
+ symbol.setRange(RANGE.join(symbol.getRange(), Range.createRange(op == TokenType.LT ? margin - 1 : margin)));
+ return symbol;
+ case GT:
+ case GE:
+ //setRange(lhs, Range.createRange(op == TokenType.GT ? margin + 1 : margin));
+ //return symbol;
+ default:
+ break;
+ }
+ }
+ }
+
+ return null;
+ }
+
+ private boolean isLoopCounter(final LoopNode loopNode, final Symbol symbol) {
+ //this only works if loop nodes aren't replaced by other ones during this transform, but they are not
+ return loopCounters.get(loopNode) == symbol;
+ }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Range.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Range.java
new file mode 100644
index 00000000000..2845d90240e
--- /dev/null
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Range.java
@@ -0,0 +1,705 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package jdk.nashorn.internal.codegen.types;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import jdk.nashorn.internal.runtime.DebugLogger;
+import jdk.nashorn.internal.runtime.JSType;
+
+/**
+ * Represents the value range of a symbol.
+ */
+public abstract class Range {
+
+ private static final Range GENERIC_RANGE = new Range() {
+ @Override
+ public Type getType() {
+ return Type.OBJECT;
+ }
+ };
+
+ private static final Range NUMBER_RANGE = new Range() {
+ @Override
+ public Type getType() {
+ return Type.NUMBER;
+ }
+ };
+
+ private static final Range UNKNOWN_RANGE = new Range() {
+ @Override
+ public Type getType() {
+ return Type.UNKNOWN;
+ }
+
+ @Override
+ public boolean isUnknown() {
+ return true;
+ }
+ };
+
+ private static class IntegerRange extends Range {
+ private final long min;
+ private final long max;
+ private final Type type;
+
+ private IntegerRange(final long min, final long max) {
+ assert min <= max;
+ this.min = min;
+ this.max = max;
+ this.type = typeFromRange(min, max);
+ }
+
+ private static Type typeFromRange(final long from, final long to) {
+ if (from >= Integer.MIN_VALUE && to <= Integer.MAX_VALUE) {
+ return Type.INT;
+ }
+ return Type.LONG;
+ }
+
+ @Override
+ public Type getType() {
+ return type;
+ }
+
+ public long getMin() {
+ return min;
+ }
+
+ public long getMax() {
+ return max;
+ }
+
+ @Override
+ public boolean isIntegerConst() {
+ return getMin() == getMax();
+ }
+
+ private long getBitMask() {
+ if (min == max) {
+ return min;
+ }
+
+ if (min < 0) {
+ return ~0L;
+ }
+
+ long mask = 1;
+ while (mask < max) {
+ mask = (mask << 1) | 1;
+ }
+ return mask;
+ }
+
+ @Override
+ public boolean equals(final Object obj) {
+ if (obj instanceof IntegerRange) {
+ final IntegerRange other = (IntegerRange)obj;
+ return this.type == other.type && this.min == other.min && this.max == other.max;
+ }
+ return false;
+ }
+
+ @Override
+ public int hashCode() {
+ return Long.hashCode(min) ^ Long.hashCode(max);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "[" + min +", " + max + "]";
+ }
+ }
+
+ /**
+ * Get narrowest type for this range
+ * @return type
+ */
+ public abstract Type getType();
+
+ /**
+ * Is this range unknown
+ * @return true if unknown
+ */
+ public boolean isUnknown() {
+ return false;
+ }
+
+ /**
+ * Check if an integer is enough to span this range
+ * @return true if integer is enough
+ */
+ public boolean isIntegerType() {
+ return this instanceof IntegerRange;
+ }
+
+ /**
+ * Check if an integer is enough to span this range
+ * @return true if integer is enough
+ */
+ public boolean isIntegerConst() {
+ return false;
+ }
+
+ /**
+ * Create an unknown range - this is most likely a singleton object
+ * and it represents "we have no known range information"
+ * @return the range
+ */
+ public static Range createUnknownRange() {
+ return UNKNOWN_RANGE;
+ }
+
+ /**
+ * Create a constant range: [value, value]
+ * @param value value
+ * @return the range
+ */
+ public static Range createRange(final int value) {
+ return createIntegerRange(value, value);
+ }
+
+ /**
+ * Create a constant range: [value, value]
+ * @param value value
+ * @return the range
+ */
+ public static Range createRange(final long value) {
+ return createIntegerRange(value, value);
+ }
+
+ /**
+ * Create a constant range: [value, value]
+ * @param value value
+ * @return the range
+ */
+ public static Range createRange(final double value) {
+ if (isRepresentableAsLong(value)) {
+ return createIntegerRange((long) value, (long) value);
+ }
+ return createNumberRange();
+ }
+
+ /**
+ * Create a constant range: [value, value]
+ * @param value value
+ * @return the range
+ */
+ public static Range createRange(final Object value) {
+ if (value instanceof Integer) {
+ return createRange((int)value);
+ } else if (value instanceof Long) {
+ return createRange((long)value);
+ } else if (value instanceof Double) {
+ return createRange((double)value);
+ }
+
+ return createGenericRange();
+ }
+
+ /**
+ * Create a generic range - object symbol that carries no range
+ * information
+ * @return the range
+ */
+ public static Range createGenericRange() {
+ return GENERIC_RANGE;
+ }
+
+ /**
+ * Create a number range - number symbol that carries no range
+ * information
+ * @return the range
+ */
+ public static Range createNumberRange() {
+ return NUMBER_RANGE;
+ }
+
+ /**
+ * Create an integer range [min, max]
+ * @param min minimum value, inclusive
+ * @param max maximum value, inclusive
+ * @return the range
+ */
+ public static IntegerRange createIntegerRange(final long min, final long max) {
+ return new IntegerRange(min, max);
+ }
+
+ /**
+ * Create an integer range of maximum type width for the given type
+ * @param type the type
+ * @return the range
+ */
+ public static IntegerRange createIntegerRange(final Type type) {
+ assert type.isNumeric() && !type.isNumber();
+ final long min;
+ final long max;
+ if (type.isInteger()) {
+ min = Integer.MIN_VALUE;
+ max = Integer.MAX_VALUE;
+ } else if (type.isLong()) {
+ min = Long.MIN_VALUE;
+ max = Long.MAX_VALUE;
+ } else {
+ throw new AssertionError(); //type incompatible with integer range
+ }
+ return new IntegerRange(min, max);
+ }
+
+ /**
+ * Create an range of maximum type width for the given type
+ * @param type the type
+ * @return the range
+ */
+ public static Range createTypeRange(final Type type) {
+ if (type.isNumber()) {
+ return createNumberRange();
+ } else if (type.isNumeric()) {
+ return createIntegerRange(type);
+ } else {
+ return createGenericRange();
+ }
+ }
+
+ // check that add doesn't overflow
+ private static boolean checkAdd(final long a, final long b) {
+ final long result = a + b;
+ return ((a ^ result) & (b ^ result)) >= 0;
+ }
+
+ // check that sub doesn't overflow
+ private static boolean checkSub(final long a, final long b) {
+ final long result = a - b;
+ return ((a ^ result) & (b ^ result)) >= 0;
+ }
+
+ private static boolean checkMul(final long a, final long b) {
+ // TODO correct overflow check
+ return a >= Integer.MIN_VALUE && a <= Integer.MAX_VALUE && b >= Integer.MIN_VALUE && b <= Integer.MAX_VALUE;
+ }
+
+ /**
+ * The range functionality class responsible for merging ranges and drawing
+ * range conclusions from operations executed
+ */
+ public static class Functionality {
+ /** logger */
+ protected final DebugLogger log;
+
+ /**
+ * Constructor
+ * @param log logger
+ */
+ public Functionality(final DebugLogger log) {
+ this.log = log;
+ }
+
+ /**
+ * Join two ranges
+ * @param a first range
+ * @param b second range
+ * @return the joined range
+ */
+ public Range join(final Range a, final Range b) {
+ if (a.equals(b)) {
+ return a;
+ }
+
+ Type joinedType = a.getType();
+ if (a.getType() != b.getType()) {
+ if (a.isUnknown()) {
+ return b;
+ }
+ if (b.isUnknown()) {
+ return a;
+ }
+
+ joinedType = Type.widest(a.getType(), b.getType());
+ }
+
+ if (joinedType.isInteger() || joinedType.isLong()) {
+ return createIntegerRange(
+ Math.min(((IntegerRange) a).getMin(), ((IntegerRange) b).getMin()),
+ Math.max(((IntegerRange) a).getMax(), ((IntegerRange) b).getMax()));
+ }
+
+ return createTypeRange(joinedType);
+ }
+
+ /**
+ * Add operation
+ * @param a range of first symbol to be added
+ * @param b range of second symbol to be added
+ * @return resulting range representing the value range after add
+ */
+ public Range add(final Range a, final Range b) {
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final IntegerRange lhs = (IntegerRange)a;
+ final IntegerRange rhs = (IntegerRange)b;
+ if (checkAdd(lhs.getMin(), rhs.getMin()) && checkAdd(lhs.getMax(), rhs.getMax())) {
+ return createIntegerRange(lhs.getMin() + rhs.getMin(), lhs.getMax() + rhs.getMax());
+ }
+ }
+
+ if (a.getType().isNumeric() && b.getType().isNumeric()) {
+ return createNumberRange();
+ }
+
+ return createGenericRange();
+ }
+
+ /**
+ * Sub operation
+ * @param a range of first symbol to be subtracted
+ * @param b range of second symbol to be subtracted
+ * @return resulting range representing the value range after subtraction
+ */
+ public Range sub(final Range a, final Range b) {
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final IntegerRange lhs = (IntegerRange)a;
+ final IntegerRange rhs = (IntegerRange)b;
+ if (checkSub(lhs.getMin(), rhs.getMax()) && checkSub(lhs.getMax(), rhs.getMin())) {
+ return createIntegerRange(lhs.getMin() - rhs.getMax(), lhs.getMax() - rhs.getMin());
+ }
+ }
+
+ if (a.getType().isNumeric() && b.getType().isNumeric()) {
+ return createNumberRange();
+ }
+
+ return createGenericRange();
+ }
+
+ /**
+ * Mul operation
+ * @param a range of first symbol to be multiplied
+ * @param b range of second symbol to be multiplied
+ * @return resulting range representing the value range after multiplication
+ */
+ public Range mul(final Range a, final Range b) {
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final IntegerRange lhs = (IntegerRange)a;
+ final IntegerRange rhs = (IntegerRange)b;
+
+ //ensure that nothing ever overflows or underflows
+ if (checkMul(lhs.getMin(), rhs.getMin()) &&
+ checkMul(lhs.getMax(), rhs.getMax()) &&
+ checkMul(lhs.getMin(), rhs.getMax()) &&
+ checkMul(lhs.getMax(), rhs.getMin())) {
+
+ final List results =
+ Arrays.asList(
+ lhs.getMin() * rhs.getMin(),
+ lhs.getMin() * rhs.getMax(),
+ lhs.getMax() * rhs.getMin(),
+ lhs.getMax() * rhs.getMax());
+ return createIntegerRange(Collections.min(results), Collections.max(results));
+ }
+ }
+
+ if (a.getType().isNumeric() && b.getType().isNumeric()) {
+ return createNumberRange();
+ }
+
+ return createGenericRange();
+ }
+
+ /**
+ * Neg operation
+ * @param a range of value symbol to be negated
+ * @return resulting range representing the value range after neg
+ */
+ public Range neg(final Range a) {
+ if (a.isIntegerType()) {
+ final IntegerRange rhs = (IntegerRange)a;
+ if (rhs.getMin() != Long.MIN_VALUE && rhs.getMax() != Long.MIN_VALUE) {
+ return createIntegerRange(-rhs.getMax(), -rhs.getMin());
+ }
+ }
+
+ if (a.getType().isNumeric()) {
+ return createNumberRange();
+ }
+
+ return createGenericRange();
+ }
+
+ /**
+ * Bitwise and operation
+ * @param a range of first symbol to be and:ed
+ * @param b range of second symbol to be and:ed
+ * @return resulting range representing the value range after and
+ */
+ public Range and(final Range a, final Range b) {
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final int resultMask = (int) (((IntegerRange)a).getBitMask() & ((IntegerRange)b).getBitMask());
+ if (resultMask >= 0) {
+ return createIntegerRange(0, resultMask);
+ }
+ } else if (a.isUnknown() && b.isIntegerType()) {
+ final long operandMask = ((IntegerRange)b).getBitMask();
+ if (operandMask >= 0) {
+ return createIntegerRange(0, operandMask);
+ }
+ } else if (a.isIntegerType() && b.isUnknown()) {
+ final long operandMask = ((IntegerRange)a).getBitMask();
+ if (operandMask >= 0) {
+ return createIntegerRange(0, operandMask);
+ }
+ }
+
+ return createTypeRange(Type.INT);
+ }
+
+ /**
+ * Bitwise or operation
+ * @param a range of first symbol to be or:ed
+ * @param b range of second symbol to be or:ed
+ * @return resulting range representing the value range after or
+ */
+ public Range or(final Range a, final Range b) {
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final int resultMask = (int)(((IntegerRange)a).getBitMask() | ((IntegerRange)b).getBitMask());
+ if (resultMask >= 0) {
+ return createIntegerRange(0, resultMask);
+ }
+ }
+
+ return createTypeRange(Type.INT);
+ }
+
+ /**
+ * Bitwise xor operation
+ * @param a range of first symbol to be xor:ed
+ * @param b range of second symbol to be xor:ed
+ * @return resulting range representing the value range after and
+ */
+ public Range xor(final Range a, final Range b) {
+ if (a.isIntegerConst() && b.isIntegerConst()) {
+ return createRange(((IntegerRange)a).getMin() ^ ((IntegerRange)b).getMin());
+ }
+
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final int resultMask = (int)(((IntegerRange)a).getBitMask() | ((IntegerRange)b).getBitMask());
+ if (resultMask >= 0) {
+ return createIntegerRange(0, createIntegerRange(0, resultMask).getBitMask());
+ }
+ }
+ return createTypeRange(Type.INT);
+ }
+
+ /**
+ * Bitwise shl operation
+ * @param a range of first symbol to be shl:ed
+ * @param b range of second symbol to be shl:ed
+ * @return resulting range representing the value range after shl
+ */
+ public Range shl(final Range a, final Range b) {
+ if (b.isIntegerType() && b.isIntegerConst()) {
+ final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
+ final int shift = (int)((IntegerRange) b).getMin() & 0x1f;
+ final int min = (int)left.getMin() << shift;
+ final int max = (int)left.getMax() << shift;
+ if (min >> shift == left.getMin() && max >> shift == left.getMax()) {
+ return createIntegerRange(min, max);
+ }
+ }
+
+ return createTypeRange(Type.INT);
+ }
+
+ /**
+ * Bitwise shr operation
+ * @param a range of first symbol to be shr:ed
+ * @param b range of second symbol to be shr:ed
+ * @return resulting range representing the value range after shr
+ */
+ public Range shr(final Range a, final Range b) {
+ if (b.isIntegerType() && b.isIntegerConst()) {
+ final long shift = ((IntegerRange) b).getMin() & 0x1f;
+ final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
+ if (left.getMin() >= 0) {
+ long min = left.getMin() >>> shift;
+ long max = left.getMax() >>> shift;
+ return createIntegerRange(min, max);
+ } else if (shift >= 1) {
+ return createIntegerRange(0, JSType.MAX_UINT >>> shift);
+ }
+ }
+
+ return createTypeRange(Type.INT);
+ }
+
+ /**
+ * Bitwise sar operation
+ * @param a range of first symbol to be sar:ed
+ * @param b range of second symbol to be sar:ed
+ * @return resulting range representing the value range after sar
+ */
+ public Range sar(final Range a, final Range b) {
+ if (b.isIntegerType() && b.isIntegerConst()) {
+ final IntegerRange left = (IntegerRange)(a.isIntegerType() ? a : createTypeRange(Type.INT));
+ final long shift = ((IntegerRange) b).getMin() & 0x1f;
+ final long min = left.getMin() >> shift;
+ final long max = left.getMax() >> shift;
+ return createIntegerRange(min, max);
+ }
+
+ return createTypeRange(Type.INT);
+ }
+
+ /**
+ * Modulo operation
+ * @param a range of first symbol to the mod operation
+ * @param b range of second symbol to be mod operation
+ * @return resulting range representing the value range after mod
+ */
+ public Range mod(final Range a, final Range b) {
+ if (a.isIntegerType() && b.isIntegerType()) {
+ final IntegerRange rhs = (IntegerRange) b;
+ if (rhs.getMin() > 0 || rhs.getMax() < 0) { // divisor range must not include 0
+ final long absmax = Math.max(Math.abs(rhs.getMin()), Math.abs(rhs.getMax())) - 1;
+ return createIntegerRange(rhs.getMin() > 0 ? 0 : -absmax, rhs.getMax() < 0 ? 0 : +absmax);
+ }
+ }
+ return createTypeRange(Type.NUMBER);
+ }
+
+ /**
+ * Division operation
+ * @param a range of first symbol to the division
+ * @param b range of second symbol to be division
+ * @return resulting range representing the value range after division
+ */
+ public Range div(final Range a, final Range b) {
+ // TODO
+ return createTypeRange(Type.NUMBER);
+ }
+ }
+
+ /**
+ * Simple trace functionality that will log range creation
+ */
+ public static class TraceFunctionality extends Functionality {
+ TraceFunctionality(final DebugLogger log) {
+ super(log);
+ }
+
+ private Range trace(final Range result, final String operation, final Range... operands) {
+ log.fine("range::" + operation + Arrays.toString(operands) + " => " + result);
+ return result;
+ }
+
+ @Override
+ public Range join(final Range a, final Range b) {
+ final Range result = super.join(a, b);
+ if (!a.equals(b)) {
+ trace(result, "join", a, b);
+ }
+ return result;
+ }
+
+ @Override
+ public Range add(final Range a, final Range b) {
+ return trace(super.add(a, b), "add", a, b);
+ }
+
+ @Override
+ public Range sub(final Range a, final Range b) {
+ return trace(super.sub(a, b), "sub", a, b);
+ }
+
+ @Override
+ public Range mul(final Range a, final Range b) {
+ return trace(super.mul(a, b), "mul", a, b);
+ }
+
+ @Override
+ public Range neg(final Range a) {
+ return trace(super.neg(a), "neg", a);
+ }
+
+ @Override
+ public Range and(final Range a, final Range b) {
+ return trace(super.and(a, b), "and", a, b);
+ }
+
+ @Override
+ public Range or(final Range a, final Range b) {
+ return trace(super.or(a, b), "or", a, b);
+ }
+
+ @Override
+ public Range xor(final Range a, final Range b) {
+ return trace(super.xor(a, b), "xor", a, b);
+ }
+
+ @Override
+ public Range shl(final Range a, final Range b) {
+ return trace(super.shl(a, b), "shl", a, b);
+ }
+
+ @Override
+ public Range shr(final Range a, final Range b) {
+ return trace(super.shr(a, b), "shr", a, b);
+ }
+
+ @Override
+ public Range sar(final Range a, final Range b) {
+ return trace(super.sar(a, b), "sar", a, b);
+ }
+
+ @Override
+ public Range mod(final Range a, final Range b) {
+ return trace(super.mod(a, b), "mod", a, b);
+ }
+
+ @Override
+ public Range div(final Range a, final Range b) {
+ return trace(super.div(a, b), "div", a, b);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(getType());
+ }
+
+ @SuppressWarnings("unused")
+ private static boolean isRepresentableAsInt(final double number) {
+ return (int)number == number && !isNegativeZero(number);
+ }
+
+ private static boolean isRepresentableAsLong(final double number) {
+ return (long)number == number && !isNegativeZero(number);
+ }
+
+ private static boolean isNegativeZero(final double number) {
+ return Double.doubleToLongBits(number) == Double.doubleToLongBits(-0.0);
+ }
+}
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
index 747793e8d5c..57b0212a59b 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/types/Type.java
@@ -106,22 +106,12 @@ public abstract class Type implements Comparable, BytecodeOps {
Type(final String name, final Class> clazz, final int weight, final int slots) {
this.name = name;
this.clazz = clazz;
- this.descriptor = Type.getDescriptor(clazz);
+ this.descriptor = jdk.internal.org.objectweb.asm.Type.getDescriptor(clazz);
this.weight = weight;
assert weight >= MIN_WEIGHT && weight <= MAX_WEIGHT : "illegal type weight: " + weight;
this.slots = slots;
}
- /**
- * Return an internal descriptor for a type
- *
- * @param type the type
- * @return descriptor string
- */
- public static String getDescriptor(final Class> type) {
- return jdk.internal.org.objectweb.asm.Type.getDescriptor(type);
- }
-
/**
* Get the weight of this type - use this e.g. for sorting method descriptors
* @return the weight
diff --git a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
index 61454fef0a1..51a0664688d 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/BinaryNode.java
@@ -59,6 +59,23 @@ public final class BinaryNode extends Node implements Assignment {
this.rhs = rhs;
}
+ @Override
+ public boolean isComparison() {
+ switch (tokenType()) {
+ case EQ:
+ case EQ_STRICT:
+ case NE:
+ case NE_STRICT:
+ case LE:
+ case LT:
+ case GE:
+ case GT:
+ return true;
+ default:
+ return false;
+ }
+ }
+
/**
* Return the widest possible type for this operation. This is used for compile time
* static type inference
diff --git a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
index 715d4507ac3..d271985cc8b 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/FunctionNode.java
@@ -340,7 +340,7 @@ public final class FunctionNode extends LexicalContextNode implements Flags iter = new NodeIterator<>(LoopNode.class, getCurrentFunction());
+ return iter.hasNext() ? iter.next() : null;
+ }
+
/**
* Find the breakable node corresponding to this label.
* @param label label to search for, if null the closest breakable node will be returned unconditionally, e.g. a while loop with no label
@@ -461,8 +478,7 @@ public class LexicalContext {
}
private LoopNode getContinueTo() {
- final Iterator iter = new NodeIterator<>(LoopNode.class, getCurrentFunction());
- return iter.hasNext() ? iter.next() : null;
+ return getCurrentLoop();
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Node.java b/nashorn/src/jdk/nashorn/internal/ir/Node.java
index 0fb95cc3852..99e543e6110 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Node.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Node.java
@@ -152,6 +152,14 @@ public abstract class Node implements Cloneable {
return Type.OBJECT;
}
+ /**
+ * Returns true if this node represents a comparison operator
+ * @return true if comparison
+ */
+ public boolean isComparison() {
+ return false;
+ }
+
/**
* For reference copies - ensure that labels in the copy node are unique
* using an appropriate copy constructor
diff --git a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
index 05495152709..d26fe561627 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/Symbol.java
@@ -29,6 +29,8 @@ import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
import java.util.StringTokenizer;
+
+import jdk.nashorn.internal.codegen.types.Range;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Debug;
@@ -89,6 +91,9 @@ public final class Symbol implements Comparable {
/** Number of times this symbol is used in code */
private int useCount;
+ /** Range for symbol */
+ private Range range;
+
/** Debugging option - dump info and stack trace when symbols with given names are manipulated */
private static final Set TRACE_SYMBOLS;
private static final Set TRACE_SYMBOLS_STACKTRACE;
@@ -131,6 +136,7 @@ public final class Symbol implements Comparable {
this.type = type;
this.slot = slot;
this.fieldIndex = -1;
+ this.range = Range.createUnknownRange();
trace("CREATE SYMBOL");
}
@@ -157,12 +163,13 @@ public final class Symbol implements Comparable {
private Symbol(final Symbol base, final String name, final int flags) {
this.flags = flags;
- this.name = name;
+ this.name = name;
this.fieldIndex = base.fieldIndex;
- this.slot = base.slot;
- this.type = base.type;
- this.useCount = base.useCount;
+ this.slot = base.slot;
+ this.type = base.type;
+ this.useCount = base.useCount;
+ this.range = base.range;
}
private static String align(final String string, final int max) {
@@ -276,7 +283,7 @@ public final class Symbol implements Comparable {
@Override
public String toString() {
- final StringBuilder sb = new StringBuilder();
+ final StringBuilder sb = new StringBuilder();
sb.append(name).
append(' ').
@@ -409,6 +416,22 @@ public final class Symbol implements Comparable {
return (flags & KINDMASK) == IS_PARAM;
}
+ /**
+ * Get the range for this symbol
+ * @return range for symbol
+ */
+ public Range getRange() {
+ return range;
+ }
+
+ /**
+ * Set the range for this symbol
+ * @param range range
+ */
+ public void setRange(final Range range) {
+ this.range = range;
+ }
+
/**
* Check if this symbol is a function parameter of known
* narrowest type
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
index d36f216c2b0..afa3657c1b5 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/CompiledFunction.java
@@ -35,21 +35,27 @@ import jdk.nashorn.internal.codegen.types.Type;
*/
final class CompiledFunction implements Comparable {
+ /** The method type may be more specific than the invoker, if. e.g.
+ * the invoker is guarded, and a guard with a generic object only
+ * fallback, while the target is more specific, we still need the
+ * more specific type for sorting */
+ private final MethodType type;
private final MethodHandle invoker;
private MethodHandle constructor;
- CompiledFunction(final MethodHandle invoker) {
- this(invoker, null);
+ CompiledFunction(final MethodType type, final MethodHandle invoker) {
+ this(type, invoker, null);
}
- CompiledFunction(final MethodHandle invoker, final MethodHandle constructor) {
- this.invoker = invoker;
- this.constructor = constructor; //isConstructor
+ CompiledFunction(final MethodType type, final MethodHandle invoker, final MethodHandle constructor) {
+ this.type = type;
+ this.invoker = invoker;
+ this.constructor = constructor;
}
@Override
public String toString() {
- return "";
+ return "";
}
MethodHandle getInvoker() {
@@ -69,7 +75,7 @@ final class CompiledFunction implements Comparable {
}
MethodType type() {
- return invoker.type();
+ return type;
}
@Override
@@ -103,8 +109,8 @@ final class CompiledFunction implements Comparable {
return weight() > o.weight();
}
- boolean moreGenericThan(final MethodType type) {
- return weight() > weight(type);
+ boolean moreGenericThan(final MethodType mt) {
+ return weight() > weight(mt);
}
/**
@@ -112,15 +118,15 @@ final class CompiledFunction implements Comparable {
* It is compatible if the types are narrower than the invocation type so that
* a semantically equivalent linkage can be performed.
*
- * @param typesc
+ * @param mt type to check against
* @return
*/
- boolean typeCompatible(final MethodType type) {
- final Class>[] wantedParams = type.parameterArray();
+ boolean typeCompatible(final MethodType mt) {
+ final Class>[] wantedParams = mt.parameterArray();
final Class>[] existingParams = type().parameterArray();
//if we are not examining a varargs type, the number of parameters must be the same
- if (wantedParams.length != existingParams.length && !isVarArgsType(type)) {
+ if (wantedParams.length != existingParams.length && !isVarArgsType(mt)) {
return false;
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
index ed54b2e92a3..469245f113a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FinalScriptFunctionData.java
@@ -78,9 +78,9 @@ public final class FinalScriptFunctionData extends ScriptFunctionData {
//only nasgen constructors: (boolean, self, args) are subject to binding a boolean newObj. isConstructor
//is too conservative a check. However, isConstructor(mh) always implies isConstructor param
assert isConstructor();
- code.add(new CompiledFunction(MH.insertArguments(mh, 0, false), composeConstructor(MH.insertArguments(mh, 0, true), needsCallee))); //make sure callee state can be determined when we reach constructor
+ code.add(new CompiledFunction(mh.type(), MH.insertArguments(mh, 0, false), composeConstructor(MH.insertArguments(mh, 0, true), needsCallee))); //make sure callee state can be determined when we reach constructor
} else {
- code.add(new CompiledFunction(mh));
+ code.add(new CompiledFunction(mh.type(), mh));
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
index 03a25dab1b7..226d83d1b76 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/RecompilableScriptFunctionData.java
@@ -30,6 +30,8 @@ import static jdk.nashorn.internal.lookup.Lookup.MH;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedList;
import jdk.nashorn.internal.codegen.Compiler;
@@ -49,9 +51,16 @@ import jdk.nashorn.internal.parser.TokenType;
*/
public final class RecompilableScriptFunctionData extends ScriptFunctionData {
+ /** FunctionNode with the code for this ScriptFunction */
private FunctionNode functionNode;
- private final PropertyMap allocatorMap;
+
+ /** Allocator map from makeMap() */
+ private final PropertyMap allocatorMap;
+
+ /** Code installer used for all further recompilation/specialization of this ScriptFunction */
private final CodeInstaller installer;
+
+ /** Name of class where allocator function resides */
private final String allocatorClassName;
/** lazily generated allocator */
@@ -59,6 +68,23 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+ /**
+ * Used for specialization based on runtime arguments. Whenever we specialize on
+ * callsite parameter types at runtime, we need to use a parameter type guard to
+ * ensure that the specialized version of the script function continues to be
+ * applicable for a particular callsite *
+ */
+ private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class, Object[].class);
+
+ /**
+ * It is usually a good gamble whever we detect a runtime callsite with a double
+ * (or java.lang.Number instance) to specialize the parameter to an integer, if the
+ * parameter in question can be represented as one. The double typically only exists
+ * because the compiler doesn't know any better than "a number type" and conservatively
+ * picks doubles when it can't prove that an integer addition wouldn't overflow
+ */
+ private static final MethodHandle ENSURE_INT = findOwnMH("ensureInt", int.class, Object.class);
+
/**
* Constructor - public as scripts use it
*
@@ -141,14 +167,6 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
return; // nothing to do, we have code, at least some.
}
- // check if function node is lazy, need to compile it.
- // note that currently function cloning is not working completely, which
- // means that the compiler will mutate the function node it has been given
- // once it has been compiled, it cannot be recompiled. This means that
- // lazy compilation works (not compiled yet) but e.g. specializations won't
- // until the copy-on-write changes for IR are in, making cloning meaningless.
- // therefore, currently method specialization is disabled. TODO
-
if (functionNode.isLazy()) {
Compiler.LOG.info("Trampoline hit: need to do lazy compilation of '", functionNode.getName(), "'");
final Compiler compiler = new Compiler(installer);
@@ -156,38 +174,55 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
assert !functionNode.isLazy();
compiler.install(functionNode);
- // we don't need to update any flags - varArgs and needsCallee are instrincic
- // in the function world we need to get a destination node from the compile instead
- // and replace it with our function node. TODO
+ /*
+ * We don't need to update any flags - varArgs and needsCallee are instrincic
+ * in the function world we need to get a destination node from the compile instead
+ * and replace it with our function node. TODO
+ */
}
- // we can't get here unless we have bytecode, either from eager compilation or from
- // running a lazy compile on the lines above
+ /*
+ * We can't get to this program point unless we have bytecode, either from
+ * eager compilation or from running a lazy compile on the lines above
+ */
assert functionNode.hasState(CompilationState.EMITTED) : functionNode.getName() + " " + functionNode.getState() + " " + Debug.id(functionNode);
// code exists - look it up and add it into the automatically sorted invoker list
- addCode(functionNode, null, null);
+ addCode(functionNode);
}
- private MethodHandle addCode(final FunctionNode fn, final MethodHandle guard, final MethodHandle fallback) {
- final MethodHandle target =
+ private MethodHandle addCode(final FunctionNode fn) {
+ return addCode(fn, null, null, null);
+ }
+
+ private MethodHandle addCode(final FunctionNode fn, final MethodType runtimeType, final MethodHandle guard, final MethodHandle fallback) {
+ final MethodType targetType = new FunctionSignature(fn).getMethodType();
+ MethodHandle target =
MH.findStatic(
LOOKUP,
fn.getCompileUnit().getCode(),
fn.getName(),
- new FunctionSignature(fn).
- getMethodType());
- MethodHandle mh = target;
- if (guard != null) {
- try {
- mh = MH.guardWithTest(MH.asCollector(guard, Object[].class, target.type().parameterCount()), MH.asType(target, fallback.type()), fallback);
- } catch (Throwable e) {
- e.printStackTrace();
+ targetType);
+
+ /*
+ * For any integer argument. a double that is representable as an integer is OK.
+ * otherwise the guard would have failed. in that case introduce a filter that
+ * casts the double to an integer, which we know will preserve all precision.
+ */
+ for (int i = 0; i < targetType.parameterCount(); i++) {
+ if (targetType.parameterType(i) == int.class) {
+ //representable as int
+ target = MH.filterArguments(target, i, ENSURE_INT);
}
}
- final CompiledFunction cf = new CompiledFunction(mh);
+ MethodHandle mh = target;
+ if (guard != null) {
+ mh = MH.guardWithTest(MH.asCollector(guard, Object[].class, target.type().parameterCount()), MH.asType(target, fallback.type()), fallback);
+ }
+
+ final CompiledFunction cf = new CompiledFunction(runtimeType == null ? targetType : runtimeType, mh);
code.add(cf);
return cf.getInvoker();
@@ -212,69 +247,162 @@ public final class RecompilableScriptFunctionData extends ScriptFunctionData {
return Type.OBJECT;
}
- @SuppressWarnings("unused")
- private static boolean paramTypeGuard(final Type[] compileTimeTypes, final Type[] runtimeTypes, Object... args) {
- //System.err.println("Param type guard " + Arrays.asList(args));
+ private static boolean canCoerce(final Object arg, final Type type) {
+ Type argType = runtimeType(arg);
+ if (Type.widest(argType, type) == type || arg == ScriptRuntime.UNDEFINED) {
+ return true;
+ }
+ System.err.println(arg + " does not fit in "+ argType + " " + type + " " + arg.getClass());
+ new Throwable().printStackTrace();
return false;
}
- private static final MethodHandle PARAM_TYPE_GUARD = findOwnMH("paramTypeGuard", boolean.class, Type[].class, Type[].class, Object[].class);
+ @SuppressWarnings("unused")
+ private static boolean paramTypeGuard(final Type[] paramTypes, final Object... args) {
+ final int length = args.length;
+ assert args.length >= paramTypes.length;
+
+ //i==start, skip the this, callee params etc
+ int start = args.length - paramTypes.length;
+ for (int i = start; i < args.length; i++) {
+ final Object arg = args[i];
+ if (!canCoerce(arg, paramTypes[i - start])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @SuppressWarnings("unused")
+ private static int ensureInt(final Object arg) {
+ if (arg instanceof Number) {
+ return ((Number)arg).intValue();
+ } else if (arg instanceof Undefined) {
+ return 0;
+ }
+ throw new AssertionError(arg);
+ }
+
+ /**
+ * Given the runtime callsite args, compute a method type that is equivalent to what
+ * was passed - this is typically a lot more specific that what the compiler has been
+ * able to deduce
+ * @param callSiteType callsite type for the compiled callsite target
+ * @param args runtime arguments to the compiled callsite target
+ * @return adjusted method type, narrowed as to conform to runtime callsite type instead
+ */
+ private static MethodType runtimeType(final MethodType callSiteType, final Object[] args) {
+ if (args == null) {
+ //for example bound, or otherwise runtime arguments to callsite unavailable, then
+ //do not change the type
+ return callSiteType;
+ }
+ final Class>[] paramTypes = new Class>[callSiteType.parameterCount()];
+ final int start = args.length - callSiteType.parameterCount();
+ for (int i = start; i < args.length; i++) {
+ paramTypes[i - start] = runtimeType(args[i]).getTypeClass();
+ }
+ return MH.type(callSiteType.returnType(), paramTypes);
+ }
+
+ private static ArrayList runtimeType(final MethodType mt) {
+ final ArrayList type = new ArrayList<>();
+ for (int i = 0; i < mt.parameterCount(); i++) {
+ type.add(Type.typeFor(mt.parameterType(i)));
+ }
+ return type;
+ }
@Override
MethodHandle getBestInvoker(final MethodType callSiteType, final Object[] args) {
- final MethodHandle mh = super.getBestInvoker(callSiteType, args);
+ final MethodType runtimeType = runtimeType(callSiteType, args);
+ assert runtimeType.parameterCount() == callSiteType.parameterCount();
- if (!functionNode.canSpecialize() || !code.isLessSpecificThan(callSiteType)) {
+ final MethodHandle mh = super.getBestInvoker(runtimeType, args);
+
+ /*
+ * Not all functions can be specialized, for example, if we deemed memory
+ * footprint too large to store a parse snapshot, or if it is meaningless
+ * to do so, such as e.g. for runScript
+ */
+ if (!functionNode.canSpecialize()) {
return mh;
}
- final FunctionNode snapshot = functionNode.getSnapshot();
- if (snapshot == null) {
+ /*
+ * Check if best invoker is equally specific or more specific than runtime
+ * type. In that case, we don't need further specialization, but can use
+ * whatever we have already. We know that it will match callSiteType, or it
+ * would not have been returned from getBestInvoker
+ */
+ if (!code.isLessSpecificThan(runtimeType)) {
return mh;
}
int i;
+ final FunctionNode snapshot = functionNode.getSnapshot();
+ assert snapshot != null;
- //classes known at runtime
- final LinkedList runtimeArgs = new LinkedList<>();
- for (i = args.length - 1; i >= args.length - snapshot.getParameters().size(); i--) {
- runtimeArgs.addLast(runtimeType(args[i]));
- }
-
- //classes known at compile time
+ /*
+ * Create a list of the arg types that the compiler knows about
+ * typically, the runtime args are a lot more specific, and we should aggressively
+ * try to use those whenever possible
+ * We WILL try to make an aggressive guess as possible, and add guards if needed.
+ * For example, if the compiler can deduce that we have a number type, but the runtime
+ * passes and int, we might still want to keep it an int, and the gamble to
+ * check that whatever is passed is int representable usually pays off
+ * If the compiler only knows that a parameter is an "Object", it is still worth
+ * it to try to specialize it by looking at the runtime arg.
+ */
final LinkedList compileTimeArgs = new LinkedList<>();
for (i = callSiteType.parameterCount() - 1; i >= 0 && compileTimeArgs.size() < snapshot.getParameters().size(); i--) {
- compileTimeArgs.addLast(Type.typeFor(callSiteType.parameterType(i)));
+ compileTimeArgs.addFirst(Type.typeFor(callSiteType.parameterType(i)));
}
- //the classes known at compile time are a safe to generate as primitives without parameter guards
- //the classes known at runtime are safe to generate as primitives IFF there are parameter guards
+ /*
+ * The classes known at compile time are a safe to generate as primitives without parameter guards
+ * But the classes known at runtime (if more specific than compile time types) are safe to generate as primitives
+ * IFF there are parameter guards
+ */
MethodHandle guard = null;
+ final ArrayList runtimeParamTypes = runtimeType(runtimeType);
+ while (runtimeParamTypes.size() > functionNode.getParameters().size()) {
+ runtimeParamTypes.remove(0);
+ }
for (i = 0; i < compileTimeArgs.size(); i++) {
- final Type runtimeType = runtimeArgs.get(i);
- final Type compileType = compileTimeArgs.get(i);
+ final Type rparam = Type.typeFor(runtimeType.parameterType(i));
+ final Type cparam = compileTimeArgs.get(i);
- if (compileType.isObject() && !runtimeType.isObject()) {
+ if (cparam.isObject() && !rparam.isObject()) {
+ //check that the runtime object is still coercible to the runtime type, because compiler can't prove it's always primitive
if (guard == null) {
- guard = PARAM_TYPE_GUARD;
- guard = MH.insertArguments(guard, 0, compileTimeArgs.toArray(new Type[compileTimeArgs.size()]), runtimeArgs.toArray(new Type[runtimeArgs.size()]));
+ guard = MH.insertArguments(PARAM_TYPE_GUARD, 0, (Object)runtimeParamTypes.toArray(new Type[runtimeParamTypes.size()]));
}
}
}
- //System.err.println("Specialized " + name + " " + runtimeArgs + " known=" + compileTimeArgs);
+ Compiler.LOG.info("Callsite specialized ", name, " runtimeType=", runtimeType, " parameters=", snapshot.getParameters(), " args=", Arrays.asList(args));
assert snapshot != null;
assert snapshot != functionNode;
final Compiler compiler = new Compiler(installer);
- final FunctionNode compiledSnapshot = compiler.compile(snapshot.setHints(null, new Compiler.Hints(compileTimeArgs.toArray(new Type[compileTimeArgs.size()]))));
+ final FunctionNode compiledSnapshot = compiler.compile(
+ snapshot.setHints(
+ null,
+ new Compiler.Hints(runtimeParamTypes.toArray(new Type[runtimeParamTypes.size()]))));
+
+ /*
+ * No matter how narrow your types were, they can never be narrower than Attr during recompile made them. I.e. you
+ * can put an int into the function here, if you see it as a runtime type, but if the function uses a multiplication
+ * on it, it will still need to be a double. At least until we have overflow checks. Similarly, if an int is
+ * passed but it is used as a string, it makes no sense to make the parameter narrower than Object. At least until
+ * the "different types for one symbol in difference places" work is done
+ */
compiler.install(compiledSnapshot);
- final MethodHandle nmh = addCode(compiledSnapshot, guard, mh);
-
- return nmh;
+ return addCode(compiledSnapshot, runtimeType, guard, mh);
}
private static MethodHandle findOwnMH(final String name, final Class> rtype, final Class>... types) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
index 0a556f9d51c..3bcf9d4f5a3 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
@@ -54,7 +54,7 @@ public final class ScriptEnvironment {
private final Namespace namespace;
/** Current Options object. */
- private Options options;
+ private final Options options;
/** Always allow functions as statements */
public final boolean _anon_functions;
@@ -155,6 +155,9 @@ public final class ScriptEnvironment {
/** print symbols and their contents for the script */
public final boolean _print_symbols;
+ /** range analysis for known types */
+ public final boolean _range_analysis;
+
/** is this environment in scripting mode? */
public final boolean _scripting;
@@ -219,6 +222,7 @@ public final class ScriptEnvironment {
_print_parse = options.getBoolean("print.parse");
_print_lower_parse = options.getBoolean("print.lower.parse");
_print_symbols = options.getBoolean("print.symbols");
+ _range_analysis = options.getBoolean("range.analysis");
_scripting = options.getBoolean("scripting");
_strict = options.getBoolean("strict");
_version = options.getBoolean("version");
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
index 1e899be5805..f98817c8ee6 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptFunctionData.java
@@ -91,12 +91,13 @@ public abstract class ScriptFunctionData {
CompiledFunction bind(final CompiledFunction originalInv, final ScriptFunction fn, final Object self, final Object[] args) {
final MethodHandle boundInvoker = bindInvokeHandle(originalInv.getInvoker(), fn, self, args);
+ //TODO the boundinvoker.type() could actually be more specific here
if (isConstructor()) {
ensureConstructor(originalInv);
- return new CompiledFunction(boundInvoker, bindConstructHandle(originalInv.getConstructor(), fn, args));
+ return new CompiledFunction(boundInvoker.type(), boundInvoker, bindConstructHandle(originalInv.getConstructor(), fn, args));
}
- return new CompiledFunction(boundInvoker);
+ return new CompiledFunction(boundInvoker.type(), boundInvoker);
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
index 4717319710f..59e971917eb 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
@@ -277,6 +277,12 @@ nashorn.option.print.symbols = { \
desc="Print the symbol table." \
}
+nashorn.option.range.analysis = { \
+ name="--range-analysis", \
+ is_undocumented=true, \
+ desc="Do range analysis using known compile time types, and try to narrow number types" \
+}
+
nashorn.option.D = { \
name="-D", \
desc="-Dname=value. Set a system property. This option can be repeated.", \
diff --git a/nashorn/test/script/basic/ranges_disabled.js b/nashorn/test/script/basic/ranges_disabled.js
new file mode 100644
index 00000000000..5bc8846ee54
--- /dev/null
+++ b/nashorn/test/script/basic/ranges_disabled.js
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/**
+ * range analysis test. check that computation return values are correct
+ * both with and without range analysis
+ *
+ * @test
+ * @run
+ */
+
+load(__DIR__ + "ranges_payload.js");
diff --git a/nashorn/test/script/basic/ranges_disabled.js.EXPECTED b/nashorn/test/script/basic/ranges_disabled.js.EXPECTED
new file mode 100644
index 00000000000..1a99c91b7e6
--- /dev/null
+++ b/nashorn/test/script/basic/ranges_disabled.js.EXPECTED
@@ -0,0 +1,4 @@
+289
+11094405
+4294967293
+-4722
diff --git a/nashorn/test/script/basic/ranges_enabled.js b/nashorn/test/script/basic/ranges_enabled.js
new file mode 100644
index 00000000000..45d9efb08d9
--- /dev/null
+++ b/nashorn/test/script/basic/ranges_enabled.js
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+
+/**
+ * range analysis test. check that computation return values are correct
+ * both with and without range analysis
+ *
+ * @test
+ * @option --range-analysis
+ * @run
+ */
+
+load(__DIR__ + "ranges_payload.js");
diff --git a/nashorn/test/script/basic/ranges_enabled.js.EXPECTED b/nashorn/test/script/basic/ranges_enabled.js.EXPECTED
new file mode 100644
index 00000000000..1a99c91b7e6
--- /dev/null
+++ b/nashorn/test/script/basic/ranges_enabled.js.EXPECTED
@@ -0,0 +1,4 @@
+289
+11094405
+4294967293
+-4722
diff --git a/nashorn/test/script/basic/ranges_payload.js b/nashorn/test/script/basic/ranges_payload.js
new file mode 100644
index 00000000000..f10a4a28b1f
--- /dev/null
+++ b/nashorn/test/script/basic/ranges_payload.js
@@ -0,0 +1,74 @@
+/*
+ * 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.
+ */
+
+/**
+ * range analysis test. check that computation return values are correct
+ * both with and without range analysis
+ *
+ * @subtest
+ */
+
+function f(c) {
+ var v = c & 0xffff;
+ var w = v & 0xfff;
+ var x = v * w;
+ return x;
+}
+
+function g() {
+ var sum = 0;
+ for (var x = 0; x < 4711; x++) {
+ sum += x;
+ }
+ return sum;
+}
+
+function g2() {
+ var sum = 0;
+ //make sure we overflow
+ var displacement = 0x7ffffffe;
+ for (var x = displacement; x < (displacement + 2); x++) {
+ sum += x;
+ }
+ return sum;
+}
+
+//mostly provide code coverage for all the range operations
+function h() {
+ var sum = 0;
+ sum += 4711;
+ sum &= 0xffff;
+ sum /= 2;
+ sum *= 2;
+ sum -= 4;
+ sum |= 2;
+ sum ^= 17;
+ sum = sum % 10000;
+ sum = -sum;
+ return sum
+}
+
+print(f(17));
+print(g());
+print(g2());
+print(h());
From 32261c12b2f6a3983665dafa276f6d6c17601a50 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Mon, 20 May 2013 23:04:01 +0530
Subject: [PATCH 021/206] 8014909: ant test compilation error with
JoniTest.java
Reviewed-by: jlaskey
---
nashorn/make/build.xml | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/nashorn/make/build.xml b/nashorn/make/build.xml
index c647ba4b922..7c05e789fe9 100644
--- a/nashorn/make/build.xml
+++ b/nashorn/make/build.xml
@@ -212,7 +212,9 @@
target="${javac.target}"
debug="${javac.debug}"
encoding="${javac.encoding}"
- includeantruntime="false"/>
+ includeantruntime="false">
+
+
From 34bc5ff07fc75ef6adc513fe8b2818ebf1c93a0b Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Mon, 20 May 2013 21:25:14 +0200
Subject: [PATCH 022/206] 8014797: rename Java.toJavaArray/toJavaScriptArray to
Java.to/from, respectively
Reviewed-by: jlaskey, sundar
---
.../docs/JavaScriptingProgrammersGuide.html | 10 ++--
nashorn/docs/source/javaarray.js | 4 +-
.../nashorn/api/scripting/resources/engine.js | 2 +-
.../nashorn/internal/objects/NativeJava.java | 51 ++++++++++++-------
.../runtime/resources/Messages.properties | 1 +
nashorn/test/script/basic/NASHORN-556.js | 24 ++++-----
.../test/script/basic/javaarrayconversion.js | 16 +++---
.../script/currently-failing/logcoverage.js | 3 +-
nashorn/test/script/trusted/NASHORN-638.js | 3 +-
nashorn/test/script/trusted/NASHORN-653.js | 3 +-
10 files changed, 64 insertions(+), 53 deletions(-)
diff --git a/nashorn/docs/JavaScriptingProgrammersGuide.html b/nashorn/docs/JavaScriptingProgrammersGuide.html
index a9af9612271..a9803f7fd81 100644
--- a/nashorn/docs/JavaScriptingProgrammersGuide.html
+++ b/nashorn/docs/JavaScriptingProgrammersGuide.html
@@ -616,26 +616,26 @@ print(a[0]);
It is also possible to convert between JavaScript and Java arrays.
-Given a JavaScript array and a Java type, Java.toJavaArray returns a Java array with the same initial contents, and with the specified component type.
+Given a JavaScript array and a Java type, Java.to returns a Java array with the same initial contents, and with the specified array type.
var anArray = [1, "13", false]
- var javaIntArray = Java.toJavaArray(anArray, "int")
+ var javaIntArray = Java.to(anArray, "int[]")
print(javaIntArray[0]) // prints 1
print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
-You can use either a string or a type object returned from Java.type() to specify the component type of the array.
+You can use either a string or a type object returned from Java.type() to specify the type of the array.
You can also omit the array type, in which case a Object[] will be created.
-Given a Java array or Collection, Java.toJavaScriptArray returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
+Given a Java array or Collection, Java.from returns a JavaScript array with a shallow copy of its contents. Note that in most cases, you can use Java arrays and lists natively in Nashorn; in cases where for some reason you need to have an actual JavaScript native array (e.g. to work with the array comprehensions functions), you will want to use this method.
var File = Java.type("java.io.File");
var listCurDir = new File(".").listFiles();
-var jsList = Java.toJavaScriptArray(listCurDir);
+var jsList = Java.from(listCurDir);
print(jsList);
diff --git a/nashorn/docs/source/javaarray.js b/nashorn/docs/source/javaarray.js
index a02aa3ca9f6..d0de9124684 100644
--- a/nashorn/docs/source/javaarray.js
+++ b/nashorn/docs/source/javaarray.js
@@ -40,7 +40,7 @@ print(a[0]);
// convert a script array to Java array
var anArray = [1, "13", false];
-var javaIntArray = Java.toJavaArray(anArray, "int");
+var javaIntArray = Java.to(anArray, "int[]");
print(javaIntArray[0]);// prints 1
print(javaIntArray[1]); // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
@@ -48,5 +48,5 @@ print(javaIntArray[2]);// prints 0, as boolean false was converted to number 0 a
// convert a Java array to a JavaScript array
var File = Java.type("java.io.File");
var listCurDir = new File(".").listFiles();
-var jsList = Java.toJavaScriptArray(listCurDir);
+var jsList = Java.from(listCurDir);
print(jsList);
diff --git a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
index e95607287d4..62d6735ee3f 100644
--- a/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
+++ b/nashorn/src/jdk/nashorn/api/scripting/resources/engine.js
@@ -88,7 +88,7 @@ Object.defineProperty(this, "sprintf", {
}
}
- array = Java.toJavaArray(array);
+ array = Java.to(array);
return Packages.jdk.nashorn.api.scripting.ScriptUtils.format(format, array);
}
});
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
index 5faec5ea98b..800b224f10d 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeJava.java
@@ -240,39 +240,52 @@ public final class NativeJava {
}
/**
- * Given a JavaScript array and a Java type, returns a Java array with the same initial contents, and with the
- * specified component type. Example:
+ * Given a script object and a Java type, converts the script object into the desired Java type. Currently it only
+ * performs shallow creation of Java arrays, but might be extended for other types in the future. Example:
*
* var anArray = [1, "13", false]
- * var javaIntArray = Java.toJavaArray(anArray, "int")
+ * var javaIntArray = Java.to(anArray, "int[]")
* print(javaIntArray[0]) // prints 1
* print(javaIntArray[1]) // prints 13, as string "13" was converted to number 13 as per ECMAScript ToNumber conversion
* print(javaIntArray[2]) // prints 0, as boolean false was converted to number 0 as per ECMAScript ToNumber conversion
*
* @param self not used
- * @param objArray the JavaScript array. Can be null.
- * @param objType either a {@link #type(Object, Object) type object} or a String describing the component type of
- * the Java array to create. Can not be null. If undefined, Object is assumed (allowing the argument to be omitted).
- * @return a Java array with the copy of JavaScript array's contents, converted to the appropriate Java component
- * type. Returns null if objArray is null.
+ * @param objArray the script object. Can be null.
+ * @param objType either a {@link #type(Object, Object) type object} or a String describing the type of the Java
+ * object to create. Can not be null. If undefined, a "default" conversion is presumed (allowing the argument to be
+ * omitted).
+ * @return a Java object whose value corresponds to the original script object's value. Specifically, for array
+ * target types, returns a Java array of the same type with contents converted to the array's component type. Does
+ * not recursively convert for multidimensional arrays.
+ * type. Returns null if scriptObject is null.
* @throws ClassNotFoundException if the class described by objType is not found
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
- public static Object toJavaArray(final Object self, final Object objArray, final Object objType) throws ClassNotFoundException {
- final StaticClass componentType =
- objType instanceof StaticClass ?
- (StaticClass)objType :
- objType == UNDEFINED ?
- StaticClass.forClass(Object.class) :
- type(objType);
-
+ public static Object to(final Object self, final Object objArray, final Object objType) throws ClassNotFoundException {
if (objArray == null) {
return null;
}
+ final Class> componentType;
+ if(objType == UNDEFINED) {
+ componentType = Object.class;
+ } else {
+ final StaticClass arrayType;
+ if(objType instanceof StaticClass) {
+ arrayType = (StaticClass)objType;
+ } else {
+ arrayType = type(objType);
+ }
+ final Class> arrayClass = arrayType.getRepresentedClass();
+ if(!arrayClass.isArray()) {
+ throw typeError("to.expects.array.type", arrayClass.getName());
+ }
+ componentType = arrayClass.getComponentType();
+ }
+
Global.checkObject(objArray);
- return ((ScriptObject)objArray).getArray().asArrayOfType(componentType.getRepresentedClass());
+ return ((ScriptObject)objArray).getArray().asArrayOfType(componentType);
}
/**
@@ -283,7 +296,7 @@ public final class NativeJava {
*
* var File = Java.type("java.io.File")
* var listHomeDir = new File("~").listFiles()
- * var jsListHome = Java.toJavaScriptArray(listHomeDir)
+ * var jsListHome = Java.from(listHomeDir)
* var jpegModifiedDates = jsListHome
* .filter(function(val) { return val.getName().endsWith(".jpg") })
* .map(function(val) { return val.lastModified() })
@@ -294,7 +307,7 @@ public final class NativeJava {
* null.
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
- public static Object toJavaScriptArray(final Object self, final Object objArray) {
+ public static Object from(final Object self, final Object objArray) {
if (objArray == null) {
return null;
} else if (objArray instanceof Collection) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
index 9f327521bcc..4f435ea2e96 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Messages.properties
@@ -125,6 +125,7 @@ type.error.no.constructor.matches.args=Can not construct {0} with the passed arg
type.error.no.method.matches.args=Can not invoke method {0} with the passed arguments; they do not match any of its method signatures.
type.error.method.not.constructor=Java method {0} can't be used as a constructor.
type.error.env.not.object=$ENV must be an Object.
+type.error.to.expects.array.type=Java.to() expects an array target type. {0} is not an array type.
range.error.inappropriate.array.length=inappropriate array length: {0}
range.error.invalid.fraction.digits=fractionDigits argument to {0} must be in [0, 20]
range.error.invalid.precision=precision argument toPrecision() must be in [1, 21]
diff --git a/nashorn/test/script/basic/NASHORN-556.js b/nashorn/test/script/basic/NASHORN-556.js
index 5cb164a0cf3..1332d02bef8 100644
--- a/nashorn/test/script/basic/NASHORN-556.js
+++ b/nashorn/test/script/basic/NASHORN-556.js
@@ -47,7 +47,7 @@ function f1() {
// (NoTypeArrayData)
var empty = {};
empty.length = 10;
- Java.toJavaArray(empty);
+ Java.to(empty);
delete empty[0];
Array.prototype.slice.call(empty, 0, 1);
Array.prototype.pop.call(empty);
@@ -63,7 +63,7 @@ function f1() {
function f2() {
// DeletedArrayFilter
var deleted = [,1,,2,,3,,4,,];
- assertEq(2, Java.toJavaArray(deleted)[3]);
+ assertEq(2, Java.to(deleted)[3]);
assertEq(undefined, deleted.pop());
assertEq(4, deleted.pop());
deleted.unshift(5);
@@ -78,7 +78,7 @@ function f2() {
function f3() {
// DeletedRangeArrayFilter
var delrange = [1,2,3,,,,,,,,,,];
- Java.toJavaArray(delrange);
+ Java.to(delrange);
delrange.unshift(4);
p.apply(null, delrange);
print(delrange.slice(1,3), delrange.slice(2,6));
@@ -88,7 +88,7 @@ function f3() {
function f4() {
// NumberArrayData
var num = [1.1,2.2,3.3,4.4,5.5];
- Java.toJavaArray(num);
+ Java.to(num);
assertEq(2, num[3] >>> 1);
assertEq(5, num[4] | 0);
assertEq(5.5, num.pop());
@@ -104,7 +104,7 @@ function f4() {
function f5() {
// ObjectArrayData
var obj = [2,"two",3.14,"pi",14,"fourteen"];
- Java.toJavaArray(obj);
+ Java.to(obj);
assertEq(-12.86, obj[2] - 16);
assertEq(7, obj[4] >>> 1);
obj.unshift("one");
@@ -131,14 +131,14 @@ function f6() {
sparse.length = 1024*1024;
sparse.push(sparse.length);
delete sparse[sparse.length-1];
- //print(Java.toJavaArray(sparse).length);
+ //print(Java.to(sparse).length);
(function(){}).apply(null, sparse);
}
function f7() {
// UndefinedArrayFilter
var undef = [1,2,3,4,5,undefined,7,8,9,19];
- Java.toJavaArray(undef);
+ Java.to(undef);
assertEq(4, undef[8] >>> 1);
var tmp = undef[9] >>> 1;
undef[8] = tmp;
@@ -154,8 +154,8 @@ function f7() {
function f8() {
// LongArrayData
- var j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
- Java.toJavaArray(j);
+ var j = Java.from(Java.to([23,37,42,86,47], "long[]"));
+ Java.to(j);
p.apply(null, j);
assertEq(43, j[3] >>> 1);
assertEq(36, j[4] - 11);
@@ -164,12 +164,12 @@ function f8() {
assertEq(7, j.shift());
assertEq(47, j.pop());
j.push("asdf");
- j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+ j = Java.from(Java.to([23,37,42,86,47], "long[]"));
j.length = 3;
j[0] = 13;
- j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+ j = Java.from(Java.to([23,37,42,86,47], "long[]"));
delete j[0];
- j = Java.toJavaScriptArray(Java.toJavaArray([23,37,42,86,47], "long"));
+ j = Java.from(Java.to([23,37,42,86,47], "long[]"));
j.length = 20;
j[0] = 13.37;
}
diff --git a/nashorn/test/script/basic/javaarrayconversion.js b/nashorn/test/script/basic/javaarrayconversion.js
index 34e2f95fb12..96ebe904668 100644
--- a/nashorn/test/script/basic/javaarrayconversion.js
+++ b/nashorn/test/script/basic/javaarrayconversion.js
@@ -34,7 +34,7 @@ var x; // used for undefined
var testCount = 0;
function testF(inputValue, type, testFn) {
- var x = Java.toJavaArray([inputValue], type)[0];
+ var x = Java.to([inputValue], type + "[]")[0];
if(!testFn(x)) {
throw ("unexpected value: " + x)
}
@@ -130,7 +130,7 @@ test({ valueOf: function() { return "42"; }, toString: function() { return "43"
function assertCantConvert(sourceType, targetType) {
try {
- Java.toJavaArray([new Java.type(sourceType)()], targetType)
+ Java.to([new Java.type(sourceType)()], targetType + "[]")
throw "no TypeError encountered"
} catch(e) {
if(!(e instanceof TypeError)) {
@@ -164,7 +164,7 @@ var intArray = new (Java.type("int[]"))(3)
intArray[0] = 1234;
intArray[1] = 42;
intArray[2] = 5;
-var jsIntArray = Java.toJavaScriptArray(intArray)
+var jsIntArray = Java.from(intArray)
assert(jsIntArray instanceof Array);
assert(jsIntArray[0] === 1234);
assert(jsIntArray[1] === 42);
@@ -179,7 +179,7 @@ assert(intArray[2] === 6);
var byteArray = new (Java.type("byte[]"))(2)
byteArray[0] = -128;
byteArray[1] = 127;
-var jsByteArray = Java.toJavaScriptArray(byteArray)
+var jsByteArray = Java.from(byteArray)
assert(jsByteArray instanceof Array);
assert(jsByteArray[0] === -128);
assert(jsByteArray[1] === 127);
@@ -187,7 +187,7 @@ assert(jsByteArray[1] === 127);
var shortArray = new (Java.type("short[]"))(2)
shortArray[0] = -32768;
shortArray[1] = 32767;
-var jsShortArray = Java.toJavaScriptArray(shortArray)
+var jsShortArray = Java.from(shortArray)
assert(jsShortArray instanceof Array);
assert(jsShortArray[0] === -32768);
assert(jsShortArray[1] === 32767);
@@ -195,7 +195,7 @@ assert(jsShortArray[1] === 32767);
var floatArray = new (Java.type("float[]"))(2)
floatArray[0] = java.lang.Float.MIN_VALUE;
floatArray[1] = java.lang.Float.MAX_VALUE;
-var jsFloatArray = Java.toJavaScriptArray(floatArray)
+var jsFloatArray = Java.from(floatArray)
assert(jsFloatArray instanceof Array);
assert(jsFloatArray[0] == java.lang.Float.MIN_VALUE);
assert(jsFloatArray[1] == java.lang.Float.MAX_VALUE);
@@ -204,7 +204,7 @@ var charArray = new (Java.type("char[]"))(3)
charArray[0] = "a";
charArray[1] = "b";
charArray[2] = "1";
-var jsCharArray = Java.toJavaScriptArray(charArray)
+var jsCharArray = Java.from(charArray)
assert(jsCharArray instanceof Array);
assert(jsCharArray[0] === 97);
assert(jsCharArray[1] === 98);
@@ -213,7 +213,7 @@ assert(jsCharArray[2] === 49);
var booleanArray = new (Java.type("boolean[]"))(2)
booleanArray[0] = true;
booleanArray[1] = false;
-var jsBooleanArray = Java.toJavaScriptArray(booleanArray)
+var jsBooleanArray = Java.from(booleanArray)
assert(jsBooleanArray instanceof Array);
assert(jsBooleanArray[0] === true);
assert(jsBooleanArray[1] === false);
diff --git a/nashorn/test/script/currently-failing/logcoverage.js b/nashorn/test/script/currently-failing/logcoverage.js
index 18b16aa1e00..2d8d410a881 100644
--- a/nashorn/test/script/currently-failing/logcoverage.js
+++ b/nashorn/test/script/currently-failing/logcoverage.js
@@ -53,8 +53,7 @@ function runScriptEngine(opts, name) {
// set new standard err
System.setErr(newErr);
System.setOut(newOut);
- var strType = Java.type("java.lang.String");
- var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
var reader = new java.io.FileReader(name);
engine.eval(reader);
newErr.flush();
diff --git a/nashorn/test/script/trusted/NASHORN-638.js b/nashorn/test/script/trusted/NASHORN-638.js
index 9cb6d694c55..1ff789a919b 100644
--- a/nashorn/test/script/trusted/NASHORN-638.js
+++ b/nashorn/test/script/trusted/NASHORN-638.js
@@ -47,8 +47,7 @@ function runScriptEngine(opts, code) {
try {
// set new standard err
System.setErr(newErr);
- var strType = Java.type("java.lang.String");
- var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
engine.eval(code);
newErr.flush();
return new java.lang.String(baos.toByteArray());
diff --git a/nashorn/test/script/trusted/NASHORN-653.js b/nashorn/test/script/trusted/NASHORN-653.js
index 2084bf70aeb..14a2cbc4c1c 100644
--- a/nashorn/test/script/trusted/NASHORN-653.js
+++ b/nashorn/test/script/trusted/NASHORN-653.js
@@ -85,8 +85,7 @@ function runScriptEngine(opts, code) {
try {
// set new standard err
System.setErr(newErr);
- var strType = Java.type("java.lang.String");
- var engine = fac.getScriptEngine(Java.toJavaArray(opts, strType));
+ var engine = fac.getScriptEngine(Java.to(opts, "java.lang.String[]"));
engine.eval(code);
newErr.flush();
return new java.lang.String(baos.toByteArray());
From 80041e51d1d0dbd291ca55056f8ad1a40d67cc2b Mon Sep 17 00:00:00 2001
From: Joe Wang
Date: Mon, 20 May 2013 16:11:49 -0700
Subject: [PATCH 023/206] 8014891: Redundant setting of external access
properties in setFeatures
Reviewed-by: lancea
---
.../org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java | 4 ----
.../sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java | 4 ----
2 files changed, 8 deletions(-)
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
index 39112a61f64..520bc87ea6a 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderImpl.java
@@ -236,10 +236,6 @@ public class DocumentBuilderImpl extends DocumentBuilder
String feature = (String) entry.getKey();
boolean value = ((Boolean) entry.getValue()).booleanValue();
domParser.setFeature(feature, value);
- if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) {
- domParser.setProperty(ACCESS_EXTERNAL_DTD, "");
- domParser.setProperty(ACCESS_EXTERNAL_SCHEMA, "");
- }
}
}
}
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
index bbb609e9e28..a57c1543d84 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/jaxp/SAXParserImpl.java
@@ -242,10 +242,6 @@ public class SAXParserImpl extends javax.xml.parsers.SAXParser
String feature = (String) entry.getKey();
boolean value = ((Boolean) entry.getValue()).booleanValue();
xmlReader.setFeature0(feature, value);
- if (feature.equals(XMLConstants.FEATURE_SECURE_PROCESSING) && value) {
- xmlReader.setProperty0(ACCESS_EXTERNAL_DTD, "");
- xmlReader.setProperty0(ACCESS_EXTERNAL_SCHEMA, "");
- }
}
}
}
From ed440d1096ba1a1b1c6b49b3e5da2a43eee0992b Mon Sep 17 00:00:00 2001
From: Joe Wang
Date: Mon, 20 May 2013 23:46:51 -0700
Subject: [PATCH 024/206] 8012683: Remove unused, obsolete ObjectFactory
classes
Reviewed-by: lancea
---
.../internal/xinclude/ObjectFactory.java | 553 ------------------
.../xml/internal/serialize/ObjectFactory.java | 553 ------------------
2 files changed, 1106 deletions(-)
delete mode 100644 jaxp/src/com/sun/org/apache/xerces/internal/xinclude/ObjectFactory.java
delete mode 100644 jaxp/src/com/sun/org/apache/xml/internal/serialize/ObjectFactory.java
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/ObjectFactory.java b/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/ObjectFactory.java
deleted file mode 100644
index 9c6ad1300cd..00000000000
--- a/jaxp/src/com/sun/org/apache/xerces/internal/xinclude/ObjectFactory.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/*
- * Copyright 2001-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.sun.org.apache.xerces.internal.xinclude;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-
-import java.util.Properties;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-/**
- * This class is duplicated for each JAXP subpackage so keep it in sync.
- * It is package private and therefore is not exposed as part of the JAXP
- * API.
- *
- * This code is designed to implement the JAXP 1.1 spec pluggability
- * feature and is designed to run on JDK version 1.1 and
- * later, and to compile on JDK 1.2 and onward.
- * The code also runs both as part of an unbundled jar file and
- * when bundled as part of the JDK.
- *
- *
- */
-final class ObjectFactory {
-
- //
- // Constants
- //
-
- // name of default properties file to look for in JDK's jre/lib directory
- private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties";
-
- /** Set to true for debugging */
- private static final boolean DEBUG = false;
-
- /**
- * Default columns per line.
- */
- private static final int DEFAULT_LINE_LENGTH = 80;
-
- /** cache the contents of the xerces.properties file.
- * Until an attempt has been made to read this file, this will
- * be null; if the file does not exist or we encounter some other error
- * during the read, this will be empty.
- */
- private static Properties fXercesProperties = null;
-
- /***
- * Cache the time stamp of the xerces.properties file so
- * that we know if it's been modified and can invalidate
- * the cache when necessary.
- */
- private static long fLastModified = -1;
-
- //
- // static methods
- //
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- *
query the system property using System.getProperty
- *
read META-INF/services/factoryId file
- *
use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId, String fallbackClassName)
- throws ConfigurationError {
- return createObject(factoryId, null, fallbackClassName);
- } // createObject(String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- *
query the system property using System.getProperty
- *
read $java.home/lib/propertiesFilename file
- *
read META-INF/services/factoryId file
- *
use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xerces.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- if (DEBUG) debugPrintln("debug is on");
-
- SecuritySupport ss = SecuritySupport.getInstance();
- ClassLoader cl = findClassLoader();
-
- // Use the system property first
- try {
- String systemProp = ss.getSystemProperty(factoryId);
- if (systemProp != null) {
- if (DEBUG) debugPrintln("found system property, value=" + systemProp);
- return newInstance(systemProp, cl, true);
- }
- } catch (SecurityException se) {
- // Ignore and continue w/ next location
- }
-
- // JAXP specific change
- // always use fallback class to avoid the expense of constantly
- // "stat"ing a non-existent "xerces.properties" and jar SPI entry
- // see CR 6400863: Expensive creating of SAX parser in Mustang
- if (true) {
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- }
-
- // Try to read from propertiesFilename, or $java.home/lib/xerces.properties
- String factoryClassName = null;
- // no properties file name specified; use $JAVA_HOME/lib/xerces.properties:
- if (propertiesFilename == null) {
- File propertiesFile = null;
- boolean propertiesFileExists = false;
- try {
- String javah = ss.getSystemProperty("java.home");
- propertiesFilename = javah + File.separator +
- "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
- propertiesFile = new File(propertiesFilename);
- propertiesFileExists = ss.getFileExists(propertiesFile);
- } catch (SecurityException e) {
- // try again...
- fLastModified = -1;
- fXercesProperties = null;
- }
-
- synchronized (ObjectFactory.class) {
- boolean loadProperties = false;
- FileInputStream fis = null;
- try {
- // file existed last time
- if(fLastModified >= 0) {
- if(propertiesFileExists &&
- (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
- loadProperties = true;
- } else {
- // file has stopped existing...
- if(!propertiesFileExists) {
- fLastModified = -1;
- fXercesProperties = null;
- } // else, file wasn't modified!
- }
- } else {
- // file has started to exist:
- if(propertiesFileExists) {
- loadProperties = true;
- fLastModified = ss.getLastModified(propertiesFile);
- } // else, nothing's changed
- }
- if(loadProperties) {
- // must never have attempted to read xerces.properties before (or it's outdeated)
- fXercesProperties = new Properties();
- fis = ss.getFileInputStream(propertiesFile);
- fXercesProperties.load(fis);
- }
- } catch (Exception x) {
- fXercesProperties = null;
- fLastModified = -1;
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if(fXercesProperties != null) {
- factoryClassName = fXercesProperties.getProperty(factoryId);
- }
- } else {
- FileInputStream fis = null;
- try {
- fis = ss.getFileInputStream(new File(propertiesFilename));
- Properties props = new Properties();
- props.load(fis);
- factoryClassName = props.getProperty(factoryId);
- } catch (Exception x) {
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if (factoryClassName != null) {
- if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName);
- return newInstance(factoryClassName, cl, true);
- }
-
- // Try Jar Service Provider Mechanism
- Object provider = findJarServiceProvider(factoryId);
- if (provider != null) {
- return provider;
- }
-
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- } // createObject(String,String,String):Object
-
- //
- // Private static methods
- //
-
- /** Prints a message to standard error if debugging is enabled. */
- private static void debugPrintln(String msg) {
- if (DEBUG) {
- System.err.println("JAXP: " + msg);
- }
- } // debugPrintln(String)
-
- /**
- * Figure out which ClassLoader to use. For JDK 1.2 and later use
- * the context ClassLoader.
- */
- static ClassLoader findClassLoader()
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
-
- // Figure out which ClassLoader to use for loading the provider
- // class. If there is a Context ClassLoader then use it.
- ClassLoader context = ss.getContextClassLoader();
- ClassLoader system = ss.getSystemClassLoader();
-
- ClassLoader chain = system;
- while (true) {
- if (context == chain) {
- // Assert: we are on JDK 1.1 or we have no Context ClassLoader
- // or any Context ClassLoader in chain of system classloader
- // (including extension ClassLoader) so extend to widest
- // ClassLoader (always look in system ClassLoader if Xerces
- // is in boot/extension/system classpath and in current
- // ClassLoader otherwise); normal classloaders delegate
- // back to system ClassLoader first so this widening doesn't
- // change the fact that context ClassLoader will be consulted
- ClassLoader current = ObjectFactory.class.getClassLoader();
-
- chain = system;
- while (true) {
- if (current == chain) {
- // Assert: Current ClassLoader in chain of
- // boot/extension/system ClassLoaders
- return system;
- }
- if (chain == null) {
- break;
- }
- chain = ss.getParentClassLoader(chain);
- }
-
- // Assert: Current ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return current;
- }
-
- if (chain == null) {
- // boot ClassLoader reached
- break;
- }
-
- // Check for any extension ClassLoaders in chain up to
- // boot ClassLoader
- chain = ss.getParentClassLoader(chain);
- };
-
- // Assert: Context ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return context;
- } // findClassLoader():ClassLoader
-
- /**
- * Create an instance of a class using the specified ClassLoader
- */
- static Object newInstance(String className, ClassLoader cl,
- boolean doFallback)
- throws ConfigurationError
- {
- // assert(className != null);
- try{
- Class providerClass = findProviderClass(className, cl, doFallback);
- Object instance = providerClass.newInstance();
- if (DEBUG) debugPrintln("created new instance of " + providerClass +
- " using ClassLoader: " + cl);
- return instance;
- } catch (ClassNotFoundException x) {
- throw new ConfigurationError(
- "Provider " + className + " not found", x);
- } catch (Exception x) {
- throw new ConfigurationError(
- "Provider " + className + " could not be instantiated: " + x,
- x);
- }
- }
-
- /**
- * Find a Class using the specified ClassLoader
- */
- static Class findProviderClass(String className, ClassLoader cl,
- boolean doFallback)
- throws ClassNotFoundException, ConfigurationError
- {
- //throw security exception if the calling thread is not allowed to access the package
- //restrict the access to package as speicified in java.security policy
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- final int lastDot = className.lastIndexOf(".");
- String packageName = className;
- if (lastDot != -1) packageName = className.substring(0, lastDot);
- security.checkPackageAccess(packageName);
- }
- Class providerClass;
- if (cl == null) {
- // XXX Use the bootstrap ClassLoader. There is no way to
- // load a class using the bootstrap ClassLoader that works
- // in both JDK 1.1 and Java 2. However, this should still
- // work b/c the following should be true:
- //
- // (cl == null) iff current ClassLoader == null
- //
- // Thus Class.forName(String) will use the current
- // ClassLoader which will be the bootstrap ClassLoader.
- providerClass = Class.forName(className);
- } else {
- try {
- providerClass = cl.loadClass(className);
- } catch (ClassNotFoundException x) {
- if (doFallback) {
- // Fall back to current classloader
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (current == null) {
- providerClass = Class.forName(className);
- } else if (cl != current) {
- cl = current;
- providerClass = cl.loadClass(className);
- } else {
- throw x;
- }
- } else {
- throw x;
- }
- }
- }
-
- return providerClass;
- }
-
- /*
- * Try to find provider using Jar Service Provider Mechanism
- *
- * @return instance of provider class if found or null
- */
- private static Object findJarServiceProvider(String factoryId)
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
- String serviceId = "META-INF/services/" + factoryId;
- InputStream is = null;
-
- // First try the Context ClassLoader
- ClassLoader cl = findClassLoader();
-
- is = ss.getResourceAsStream(cl, serviceId);
-
- // If no provider found then try the current ClassLoader
- if (is == null) {
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (cl != current) {
- cl = current;
- is = ss.getResourceAsStream(cl, serviceId);
- }
- }
-
- if (is == null) {
- // No provider found
- return null;
- }
-
- if (DEBUG) debugPrintln("found jar resource=" + serviceId +
- " using ClassLoader: " + cl);
-
- // Read the service provider name in UTF-8 as specified in
- // the jar spec. Unfortunately this fails in Microsoft
- // VJ++, which does not implement the UTF-8
- // encoding. Theoretically, we should simply let it fail in
- // that case, since the JVM is obviously broken if it
- // doesn't support such a basic standard. But since there
- // are still some users attempting to use VJ++ for
- // development, we have dropped in a fallback which makes a
- // second attempt using the platform's default encoding. In
- // VJ++ this is apparently ASCII, which is a subset of
- // UTF-8... and since the strings we'll be reading here are
- // also primarily limited to the 7-bit ASCII range (at
- // least, in English versions), this should work well
- // enough to keep us on the air until we're ready to
- // officially decommit from VJ++. [Edited comment from
- // jkesselm]
- BufferedReader rd;
- try {
- rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
- } catch (java.io.UnsupportedEncodingException e) {
- rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
- }
-
- String factoryClassName = null;
- try {
- // XXX Does not handle all possible input as specified by the
- // Jar Service Provider specification
- factoryClassName = rd.readLine();
- } catch (IOException x) {
- // No provider found
- return null;
- }
- finally {
- try {
- // try to close the reader.
- rd.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
-
- if (factoryClassName != null &&
- ! "".equals(factoryClassName)) {
- if (DEBUG) debugPrintln("found in resource, value="
- + factoryClassName);
-
- // Note: here we do not want to fall back to the current
- // ClassLoader because we want to avoid the case where the
- // resource file was found using one ClassLoader and the
- // provider class was instantiated using a different one.
- return newInstance(factoryClassName, cl, false);
- }
-
- // No provider found
- return null;
- }
-
- //
- // Classes
- //
-
- /**
- * A configuration error.
- */
- static final class ConfigurationError
- extends Error {
-
- /** Serialization version. */
- static final long serialVersionUID = 5061904944269807898L;
-
- //
- // Data
- //
-
- /** Exception. */
- private Exception exception;
-
- //
- // Constructors
- //
-
- /**
- * Construct a new instance with the specified detail string and
- * exception.
- */
- ConfigurationError(String msg, Exception x) {
- super(msg);
- this.exception = x;
- } // (String,Exception)
-
- //
- // methods
- //
-
- /** Returns the exception associated to this error. */
- Exception getException() {
- return exception;
- } // getException():Exception
-
- } // class ConfigurationError
-
-} // class ObjectFactory
diff --git a/jaxp/src/com/sun/org/apache/xml/internal/serialize/ObjectFactory.java b/jaxp/src/com/sun/org/apache/xml/internal/serialize/ObjectFactory.java
deleted file mode 100644
index de2d7aaca25..00000000000
--- a/jaxp/src/com/sun/org/apache/xml/internal/serialize/ObjectFactory.java
+++ /dev/null
@@ -1,553 +0,0 @@
-/*
- * reserved comment block
- * DO NOT REMOVE OR ALTER!
- */
-/*
- * Copyright 2001-2005 The Apache Software Foundation.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.sun.org.apache.xml.internal.serialize;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.File;
-import java.io.FileInputStream;
-
-import java.util.Properties;
-import java.io.BufferedReader;
-import java.io.InputStreamReader;
-
-/**
- * This class is duplicated for each JAXP subpackage so keep it in sync.
- * It is package private and therefore is not exposed as part of the JAXP
- * API.
- *
- * This code is designed to implement the JAXP 1.1 spec pluggability
- * feature and is designed to run on JDK version 1.1 and
- * later, and to compile on JDK 1.2 and onward.
- * The code also runs both as part of an unbundled jar file and
- * when bundled as part of the JDK.
- *
- *
- */
-final class ObjectFactory {
-
- //
- // Constants
- //
-
- // name of default properties file to look for in JDK's jre/lib directory
- private static final String DEFAULT_PROPERTIES_FILENAME = "xerces.properties";
-
- /** Set to true for debugging */
- private static final boolean DEBUG = false;
-
- /**
- * Default columns per line.
- */
- private static final int DEFAULT_LINE_LENGTH = 80;
-
- /** cache the contents of the xerces.properties file.
- * Until an attempt has been made to read this file, this will
- * be null; if the file does not exist or we encounter some other error
- * during the read, this will be empty.
- */
- private static Properties fXercesProperties = null;
-
- /***
- * Cache the time stamp of the xerces.properties file so
- * that we know if it's been modified and can invalidate
- * the cache when necessary.
- */
- private static long fLastModified = -1;
-
- //
- // static methods
- //
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- *
query the system property using System.getProperty
- *
read META-INF/services/factoryId file
- *
use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId, String fallbackClassName)
- throws ConfigurationError {
- return createObject(factoryId, null, fallbackClassName);
- } // createObject(String,String):Object
-
- /**
- * Finds the implementation Class object in the specified order. The
- * specified order is the following:
- *
- *
query the system property using System.getProperty
- *
read $java.home/lib/propertiesFilename file
- *
read META-INF/services/factoryId file
- *
use fallback classname
- *
- *
- * @return Class object of factory, never null
- *
- * @param factoryId Name of the factory to find, same as
- * a property name
- * @param propertiesFilename The filename in the $java.home/lib directory
- * of the properties file. If none specified,
- * ${java.home}/lib/xerces.properties will be used.
- * @param fallbackClassName Implementation class name, if nothing else
- * is found. Use null to mean no fallback.
- *
- * @exception ObjectFactory.ConfigurationError
- */
- static Object createObject(String factoryId,
- String propertiesFilename,
- String fallbackClassName)
- throws ConfigurationError
- {
- if (DEBUG) debugPrintln("debug is on");
-
- SecuritySupport ss = SecuritySupport.getInstance();
- ClassLoader cl = findClassLoader();
-
- // Use the system property first
- try {
- String systemProp = ss.getSystemProperty(factoryId);
- if (systemProp != null) {
- if (DEBUG) debugPrintln("found system property, value=" + systemProp);
- return newInstance(systemProp, cl, true);
- }
- } catch (SecurityException se) {
- // Ignore and continue w/ next location
- }
-
- // JAXP specific change
- // always use fallback class to avoid the expense of constantly
- // "stat"ing a non-existent "xerces.properties" and jar SPI entry
- // see CR 6400863: Expensive creating of SAX parser in Mustang
- if (true) {
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- }
-
- // Try to read from propertiesFilename, or $java.home/lib/xerces.properties
- String factoryClassName = null;
- // no properties file name specified; use $JAVA_HOME/lib/xerces.properties:
- if (propertiesFilename == null) {
- File propertiesFile = null;
- boolean propertiesFileExists = false;
- try {
- String javah = ss.getSystemProperty("java.home");
- propertiesFilename = javah + File.separator +
- "lib" + File.separator + DEFAULT_PROPERTIES_FILENAME;
- propertiesFile = new File(propertiesFilename);
- propertiesFileExists = ss.getFileExists(propertiesFile);
- } catch (SecurityException e) {
- // try again...
- fLastModified = -1;
- fXercesProperties = null;
- }
-
- synchronized (ObjectFactory.class) {
- boolean loadProperties = false;
- FileInputStream fis = null;
- try {
- // file existed last time
- if(fLastModified >= 0) {
- if(propertiesFileExists &&
- (fLastModified < (fLastModified = ss.getLastModified(propertiesFile)))) {
- loadProperties = true;
- } else {
- // file has stopped existing...
- if(!propertiesFileExists) {
- fLastModified = -1;
- fXercesProperties = null;
- } // else, file wasn't modified!
- }
- } else {
- // file has started to exist:
- if(propertiesFileExists) {
- loadProperties = true;
- fLastModified = ss.getLastModified(propertiesFile);
- } // else, nothing's changed
- }
- if(loadProperties) {
- // must never have attempted to read xerces.properties before (or it's outdeated)
- fXercesProperties = new Properties();
- fis = ss.getFileInputStream(propertiesFile);
- fXercesProperties.load(fis);
- }
- } catch (Exception x) {
- fXercesProperties = null;
- fLastModified = -1;
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if(fXercesProperties != null) {
- factoryClassName = fXercesProperties.getProperty(factoryId);
- }
- } else {
- FileInputStream fis = null;
- try {
- fis = ss.getFileInputStream(new File(propertiesFilename));
- Properties props = new Properties();
- props.load(fis);
- factoryClassName = props.getProperty(factoryId);
- } catch (Exception x) {
- // assert(x instanceof FileNotFoundException
- // || x instanceof SecurityException)
- // In both cases, ignore and continue w/ next location
- }
- finally {
- // try to close the input stream if one was opened.
- if (fis != null) {
- try {
- fis.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
- }
- }
- if (factoryClassName != null) {
- if (DEBUG) debugPrintln("found in " + propertiesFilename + ", value=" + factoryClassName);
- return newInstance(factoryClassName, cl, true);
- }
-
- // Try Jar Service Provider Mechanism
- Object provider = findJarServiceProvider(factoryId);
- if (provider != null) {
- return provider;
- }
-
- if (fallbackClassName == null) {
- throw new ConfigurationError(
- "Provider for " + factoryId + " cannot be found", null);
- }
-
- if (DEBUG) debugPrintln("using fallback, value=" + fallbackClassName);
- return newInstance(fallbackClassName, cl, true);
- } // createObject(String,String,String):Object
-
- //
- // Private static methods
- //
-
- /** Prints a message to standard error if debugging is enabled. */
- private static void debugPrintln(String msg) {
- if (DEBUG) {
- System.err.println("JAXP: " + msg);
- }
- } // debugPrintln(String)
-
- /**
- * Figure out which ClassLoader to use. For JDK 1.2 and later use
- * the context ClassLoader.
- */
- static ClassLoader findClassLoader()
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
-
- // Figure out which ClassLoader to use for loading the provider
- // class. If there is a Context ClassLoader then use it.
- ClassLoader context = ss.getContextClassLoader();
- ClassLoader system = ss.getSystemClassLoader();
-
- ClassLoader chain = system;
- while (true) {
- if (context == chain) {
- // Assert: we are on JDK 1.1 or we have no Context ClassLoader
- // or any Context ClassLoader in chain of system classloader
- // (including extension ClassLoader) so extend to widest
- // ClassLoader (always look in system ClassLoader if Xerces
- // is in boot/extension/system classpath and in current
- // ClassLoader otherwise); normal classloaders delegate
- // back to system ClassLoader first so this widening doesn't
- // change the fact that context ClassLoader will be consulted
- ClassLoader current = ObjectFactory.class.getClassLoader();
-
- chain = system;
- while (true) {
- if (current == chain) {
- // Assert: Current ClassLoader in chain of
- // boot/extension/system ClassLoaders
- return system;
- }
- if (chain == null) {
- break;
- }
- chain = ss.getParentClassLoader(chain);
- }
-
- // Assert: Current ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return current;
- }
-
- if (chain == null) {
- // boot ClassLoader reached
- break;
- }
-
- // Check for any extension ClassLoaders in chain up to
- // boot ClassLoader
- chain = ss.getParentClassLoader(chain);
- };
-
- // Assert: Context ClassLoader not in chain of
- // boot/extension/system ClassLoaders
- return context;
- } // findClassLoader():ClassLoader
-
- /**
- * Create an instance of a class using the specified ClassLoader
- */
- static Object newInstance(String className, ClassLoader cl,
- boolean doFallback)
- throws ConfigurationError
- {
- // assert(className != null);
- try{
- Class providerClass = findProviderClass(className, cl, doFallback);
- Object instance = providerClass.newInstance();
- if (DEBUG) debugPrintln("created new instance of " + providerClass +
- " using ClassLoader: " + cl);
- return instance;
- } catch (ClassNotFoundException x) {
- throw new ConfigurationError(
- "Provider " + className + " not found", x);
- } catch (Exception x) {
- throw new ConfigurationError(
- "Provider " + className + " could not be instantiated: " + x,
- x);
- }
- }
-
- /**
- * Find a Class using the specified ClassLoader
- */
- static Class findProviderClass(String className, ClassLoader cl,
- boolean doFallback)
- throws ClassNotFoundException, ConfigurationError
- {
- //throw security exception if the calling thread is not allowed to access the package
- //restrict the access to package as speicified in java.security policy
- SecurityManager security = System.getSecurityManager();
- if (security != null) {
- final int lastDot = className.lastIndexOf(".");
- String packageName = className;
- if (lastDot != -1) packageName = className.substring(0, lastDot);
- security.checkPackageAccess(packageName);
- }
- Class providerClass;
- if (cl == null) {
- // XXX Use the bootstrap ClassLoader. There is no way to
- // load a class using the bootstrap ClassLoader that works
- // in both JDK 1.1 and Java 2. However, this should still
- // work b/c the following should be true:
- //
- // (cl == null) iff current ClassLoader == null
- //
- // Thus Class.forName(String) will use the current
- // ClassLoader which will be the bootstrap ClassLoader.
- providerClass = Class.forName(className);
- } else {
- try {
- providerClass = cl.loadClass(className);
- } catch (ClassNotFoundException x) {
- if (doFallback) {
- // Fall back to current classloader
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (current == null) {
- providerClass = Class.forName(className);
- } else if (cl != current) {
- cl = current;
- providerClass = cl.loadClass(className);
- } else {
- throw x;
- }
- } else {
- throw x;
- }
- }
- }
-
- return providerClass;
- }
-
- /*
- * Try to find provider using Jar Service Provider Mechanism
- *
- * @return instance of provider class if found or null
- */
- private static Object findJarServiceProvider(String factoryId)
- throws ConfigurationError
- {
- SecuritySupport ss = SecuritySupport.getInstance();
- String serviceId = "META-INF/services/" + factoryId;
- InputStream is = null;
-
- // First try the Context ClassLoader
- ClassLoader cl = findClassLoader();
-
- is = ss.getResourceAsStream(cl, serviceId);
-
- // If no provider found then try the current ClassLoader
- if (is == null) {
- ClassLoader current = ObjectFactory.class.getClassLoader();
- if (cl != current) {
- cl = current;
- is = ss.getResourceAsStream(cl, serviceId);
- }
- }
-
- if (is == null) {
- // No provider found
- return null;
- }
-
- if (DEBUG) debugPrintln("found jar resource=" + serviceId +
- " using ClassLoader: " + cl);
-
- // Read the service provider name in UTF-8 as specified in
- // the jar spec. Unfortunately this fails in Microsoft
- // VJ++, which does not implement the UTF-8
- // encoding. Theoretically, we should simply let it fail in
- // that case, since the JVM is obviously broken if it
- // doesn't support such a basic standard. But since there
- // are still some users attempting to use VJ++ for
- // development, we have dropped in a fallback which makes a
- // second attempt using the platform's default encoding. In
- // VJ++ this is apparently ASCII, which is a subset of
- // UTF-8... and since the strings we'll be reading here are
- // also primarily limited to the 7-bit ASCII range (at
- // least, in English versions), this should work well
- // enough to keep us on the air until we're ready to
- // officially decommit from VJ++. [Edited comment from
- // jkesselm]
- BufferedReader rd;
- try {
- rd = new BufferedReader(new InputStreamReader(is, "UTF-8"), DEFAULT_LINE_LENGTH);
- } catch (java.io.UnsupportedEncodingException e) {
- rd = new BufferedReader(new InputStreamReader(is), DEFAULT_LINE_LENGTH);
- }
-
- String factoryClassName = null;
- try {
- // XXX Does not handle all possible input as specified by the
- // Jar Service Provider specification
- factoryClassName = rd.readLine();
- } catch (IOException x) {
- // No provider found
- return null;
- }
- finally {
- try {
- // try to close the reader.
- rd.close();
- }
- // Ignore the exception.
- catch (IOException exc) {}
- }
-
- if (factoryClassName != null &&
- ! "".equals(factoryClassName)) {
- if (DEBUG) debugPrintln("found in resource, value="
- + factoryClassName);
-
- // Note: here we do not want to fall back to the current
- // ClassLoader because we want to avoid the case where the
- // resource file was found using one ClassLoader and the
- // provider class was instantiated using a different one.
- return newInstance(factoryClassName, cl, false);
- }
-
- // No provider found
- return null;
- }
-
- //
- // Classes
- //
-
- /**
- * A configuration error.
- */
- static final class ConfigurationError
- extends Error {
-
- /** Serialization version. */
- static final long serialVersionUID = 937647395548533254L;
-
- //
- // Data
- //
-
- /** Exception. */
- private Exception exception;
-
- //
- // Constructors
- //
-
- /**
- * Construct a new instance with the specified detail string and
- * exception.
- */
- ConfigurationError(String msg, Exception x) {
- super(msg);
- this.exception = x;
- } // (String,Exception)
-
- //
- // methods
- //
-
- /** Returns the exception associated to this error. */
- Exception getException() {
- return exception;
- } // getException():Exception
-
- } // class ConfigurationError
-
-} // class ObjectFactory
From 4a4457b2374081f3f29878512f5b64133971961e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Joel=20Borggr=C3=A9n-Franck?=
Date: Tue, 21 May 2013 12:00:29 +0200
Subject: [PATCH 025/206] 8013180: Qualified type reference with annotations in
throws list crashes compiler
Reviewed-by: jjg
---
.../8013180/QualifiedName.java | 39 +++++++++++++++++++
1 file changed, 39 insertions(+)
create mode 100644 langtools/test/tools/javac/annotations/typeAnnotations/8013180/QualifiedName.java
diff --git a/langtools/test/tools/javac/annotations/typeAnnotations/8013180/QualifiedName.java b/langtools/test/tools/javac/annotations/typeAnnotations/8013180/QualifiedName.java
new file mode 100644
index 00000000000..5661e837240
--- /dev/null
+++ b/langtools/test/tools/javac/annotations/typeAnnotations/8013180/QualifiedName.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Target;
+
+/*
+ * @test
+ * @bug 8013180
+ * @summary Qualified type annotation name used to crash javac
+ * @compile QualifiedName.java
+ */
+
+public class QualifiedName {
+ @Target(ElementType.TYPE_USE) @interface TA { }
+ class E extends Exception { }
+
+ void m() throws @TA QualifiedName.@TA E { }
+}
From a95cb95e1f436900cc3f3a5cdd2dc9e6e244d36d Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 21 May 2013 11:41:21 +0100
Subject: [PATCH 026/206] 7177168: Redundant array copy in UnsharedNameTable
Reviewed-by: mcimadamore
---
.../classes/com/sun/tools/javac/util/UnsharedNameTable.java | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java b/langtools/src/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java
index fe88c122805..ab4c0b881e6 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/util/UnsharedNameTable.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -125,8 +125,6 @@ public class UnsharedNameTable extends Name.Table {
System.arraycopy(cs, start, bytes, 0, len);
n = new NameImpl(this, bytes, index++);
- System.arraycopy(cs, start, n.bytes, 0, len);
-
HashEntry newEntry = new HashEntry(n);
if (previousNonNullTableEntry == null) { // We are not the first name with that hashCode.
From a24da777522a45f415856047e8a4bc6185b7a757 Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 21 May 2013 12:17:18 +0100
Subject: [PATCH 027/206] 7060779: test/tools/javac/diags/Example.java leaves
directories in tempdir
Reviewed-by: mcimadamore
---
langtools/test/tools/javac/diags/Example.java | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/langtools/test/tools/javac/diags/Example.java b/langtools/test/tools/javac/diags/Example.java
index 61007440203..b53b1aa2673 100644
--- a/langtools/test/tools/javac/diags/Example.java
+++ b/langtools/test/tools/javac/diags/Example.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+ * 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
@@ -296,7 +296,10 @@ class Example implements Comparable {
private Set actualKeys;
private Set declaredKeys;
- static File tempDir = new File(System.getProperty("java.io.tmpdir"));
+ static File tempDir = (System.getProperty("test.src") != null) ?
+ new File(System.getProperty("user.dir")):
+ new File(System.getProperty("java.io.tmpdir"));
+
static void setTempDir(File tempDir) {
Example.tempDir = tempDir;
}
From 1a3b9278eb287f71508fa1ac2ecf77b1266d283a Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Tue, 21 May 2013 13:40:12 +0200
Subject: [PATCH 028/206] 8014953: Have NativeJavaPackage throw a
ClassNotFoundException when invoked
Reviewed-by: jlaskey, sundar
---
.../internal/runtime/NativeJavaPackage.java | 37 +++++++++++++++
nashorn/test/script/basic/JDK-8014953.js | 45 +++++++++++++++++++
.../test/script/basic/JDK-8014953.js.EXPECTED | 6 +++
3 files changed, 88 insertions(+)
create mode 100644 nashorn/test/script/basic/JDK-8014953.js
create mode 100644 nashorn/test/script/basic/JDK-8014953.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
index b10b72df0ac..883ff85cf1f 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/NativeJavaPackage.java
@@ -25,10 +25,16 @@
package jdk.nashorn.internal.runtime;
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.beans.StaticClass;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
+import jdk.internal.dynalink.support.Guards;
+import jdk.nashorn.internal.lookup.MethodHandleFactory;
+import jdk.nashorn.internal.lookup.MethodHandleFunctionality;
import jdk.nashorn.internal.objects.NativeJava;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Function;
@@ -65,6 +71,10 @@ import jdk.nashorn.internal.objects.annotations.Function;
*
*/
public final class NativeJavaPackage extends ScriptObject {
+ private static final MethodHandleFunctionality MH = MethodHandleFactory.getFunctionality();
+ private static final MethodHandle CLASS_NOT_FOUND = findOwnMH("classNotFound", Void.TYPE, NativeJavaPackage.class);
+ private static final MethodHandle TYPE_GUARD = Guards.getClassGuard(NativeJavaPackage.class);
+
/** Full name of package (includes path.) */
private final String name;
@@ -123,6 +133,30 @@ public final class NativeJavaPackage extends ScriptObject {
return super.getDefaultValue(hint);
}
+ @Override
+ protected GuardedInvocation findNewMethod(CallSiteDescriptor desc) {
+ return createClassNotFoundInvocation(desc);
+ }
+
+ @Override
+ protected GuardedInvocation findCallMethod(CallSiteDescriptor desc, LinkRequest request) {
+ return createClassNotFoundInvocation(desc);
+ }
+
+ private static GuardedInvocation createClassNotFoundInvocation(final CallSiteDescriptor desc) {
+ // If NativeJavaPackage is invoked either as a constructor or as a function, throw a ClassNotFoundException as
+ // we can assume the user attempted to instantiate a non-existent class.
+ final MethodType type = desc.getMethodType();
+ return new GuardedInvocation(
+ MH.dropArguments(CLASS_NOT_FOUND, 1, type.parameterList().subList(1, type.parameterCount())),
+ type.parameterType(0) == NativeJavaPackage.class ? null : TYPE_GUARD);
+ }
+
+ @SuppressWarnings("unused")
+ private static void classNotFound(final NativeJavaPackage pkg) throws ClassNotFoundException {
+ throw new ClassNotFoundException(pkg.name);
+ }
+
/**
* "No such property" call placeholder.
*
@@ -188,4 +222,7 @@ public final class NativeJavaPackage extends ScriptObject {
return noSuchProperty(desc, request);
}
+ private static MethodHandle findOwnMH(final String name, final Class> rtype, final Class>... types) {
+ return MH.findStatic(MethodHandles.lookup(), NativeJavaPackage.class, name, MH.type(rtype, types));
+ }
}
diff --git a/nashorn/test/script/basic/JDK-8014953.js b/nashorn/test/script/basic/JDK-8014953.js
new file mode 100644
index 00000000000..ba7cef0f9ef
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014953.js
@@ -0,0 +1,45 @@
+/*
+ * 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-8014953: Have NativeJavaPackage throw a ClassNotFoundException when invoked with "new"
+ *
+ * @test
+ * @run
+ */
+
+try {
+ new java.util.ArrrayList(16)
+} catch(e) {
+ print("Invoked as constructor");
+ print("e.class=" + e.class)
+ print("e.message=" + e.message);
+}
+
+try {
+ java.util.ArrrayList(16)
+} catch(e) {
+ print("Invoked as method");
+ print("e.class=" + e.class)
+ print("e.message=" + e.message);
+}
diff --git a/nashorn/test/script/basic/JDK-8014953.js.EXPECTED b/nashorn/test/script/basic/JDK-8014953.js.EXPECTED
new file mode 100644
index 00000000000..d371112156b
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014953.js.EXPECTED
@@ -0,0 +1,6 @@
+Invoked as constructor
+e.class=class java.lang.ClassNotFoundException
+e.message=java.util.ArrrayList
+Invoked as method
+e.class=class java.lang.ClassNotFoundException
+e.message=java.util.ArrrayList
From 6a02cd46e05d40a54a0a23d6bdd4b6883b974003 Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 21 May 2013 13:50:56 +0100
Subject: [PATCH 029/206] 8005207: test has 2 @bug tags
Reviewed-by: mcimadamore
---
langtools/test/tools/doclint/RunTest.java | 14 +--
langtools/test/tools/javac/5045412/Bar.java | 8 +-
langtools/test/tools/javac/5045412/Foo.java | 7 +-
.../lambda/MethodReferenceParserTest.java | 3 +-
.../tools/javac/lambda/TestInvokeDynamic.java | 23 +++--
.../mandatoryWarnings/deprecated/Test.java | 92 +------------------
.../mandatoryWarnings/unchecked/Test.java | 80 +---------------
.../test/tools/javac/policy/test3/Test.java | 46 +---------
8 files changed, 22 insertions(+), 251 deletions(-)
diff --git a/langtools/test/tools/doclint/RunTest.java b/langtools/test/tools/doclint/RunTest.java
index d42b02364f1..99662e7bac7 100644
--- a/langtools/test/tools/doclint/RunTest.java
+++ b/langtools/test/tools/doclint/RunTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -22,20 +22,13 @@
*/
/* @test
- * @bug 8004832
+ * @bug 8004832 8000103
* @summary Add new doclint package
- * @bug 8000103
* @summary Create doclint utility
*/
-import com.sun.tools.doclint.DocLint;
-import com.sun.tools.doclint.DocLint.BadArgs;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FilterOutputStream;
import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.annotation.Annotation;
@@ -44,6 +37,9 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import com.sun.tools.doclint.DocLint;
+import com.sun.tools.doclint.DocLint.BadArgs;
+
/** javadoc error on toplevel: a & b. */
public class RunTest {
/** javadoc error on member: a < b */
diff --git a/langtools/test/tools/javac/5045412/Bar.java b/langtools/test/tools/javac/5045412/Bar.java
index 9225d54f1fb..867a313a538 100644
--- a/langtools/test/tools/javac/5045412/Bar.java
+++ b/langtools/test/tools/javac/5045412/Bar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -21,12 +21,6 @@
* questions.
*/
-/**
- * @test
- * @bug 5045412 6627366
- * @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Bar.java
- */
-
/**
* @test
* @bug 5045412 6627366
diff --git a/langtools/test/tools/javac/5045412/Foo.java b/langtools/test/tools/javac/5045412/Foo.java
index a797566e783..dbbc6184f3f 100644
--- a/langtools/test/tools/javac/5045412/Foo.java
+++ b/langtools/test/tools/javac/5045412/Foo.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -25,11 +25,6 @@
* @test
* @bug 5045412 6627366
* @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Foo.java
- */
-
-/**
- * @test
- * @bug 5045412 6627366
* @compile -Xlint:serial -XDfailcomplete=java.io.Serializable Foo.java Bar.java
*/
diff --git a/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java b/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java
index 3366f902644..513f1e37765 100644
--- a/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java
+++ b/langtools/test/tools/javac/lambda/MethodReferenceParserTest.java
@@ -23,8 +23,7 @@
/*
* @test
- * @bug 7115052
- * @bug 8003280 8006694
+ * @bug 7115052 8003280 8006694
* @summary Add lambda tests
* Add parser support for method references
* temporarily workaround combo tests are causing time out in several platforms
diff --git a/langtools/test/tools/javac/lambda/TestInvokeDynamic.java b/langtools/test/tools/javac/lambda/TestInvokeDynamic.java
index a804d04fb38..3a3a03f2816 100644
--- a/langtools/test/tools/javac/lambda/TestInvokeDynamic.java
+++ b/langtools/test/tools/javac/lambda/TestInvokeDynamic.java
@@ -23,8 +23,7 @@
/*
* @test
- * @bug 7194586
- * @bug 8003280 8006694 8010404
+ * @bug 7194586 8003280 8006694 8010404
* @summary Add lambda tests
* Add back-end support for invokedynamic
* temporarily workaround combo tests are causing time out in several platforms
@@ -36,6 +35,16 @@
// use /othervm to avoid jtreg timeout issues (CODETOOLS-7900047)
// see JDK-8006746
+import java.io.File;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Locale;
+
+import javax.tools.Diagnostic;
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+
import com.sun.source.tree.MethodInvocationTree;
import com.sun.source.tree.MethodTree;
import com.sun.source.util.TaskEvent;
@@ -63,16 +72,6 @@ import com.sun.tools.javac.tree.JCTree.JCIdent;
import com.sun.tools.javac.util.Context;
import com.sun.tools.javac.util.Names;
-import java.io.File;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Locale;
-
-import javax.tools.Diagnostic;
-import javax.tools.JavaFileObject;
-import javax.tools.SimpleJavaFileObject;
-
import static com.sun.tools.javac.jvm.ClassFile.*;
public class TestInvokeDynamic
diff --git a/langtools/test/tools/javac/mandatoryWarnings/deprecated/Test.java b/langtools/test/tools/javac/mandatoryWarnings/deprecated/Test.java
index 28e3e2f222b..edaae6e5f27 100644
--- a/langtools/test/tools/javac/mandatoryWarnings/deprecated/Test.java
+++ b/langtools/test/tools/javac/mandatoryWarnings/deprecated/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,109 +29,19 @@
* @bug 5047307
* @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test1.out -XDrawDiagnostics A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test1.out -XDrawDiagnostics -nowarn A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test1.out -XDrawDiagnostics -Xmaxwarns 1 A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test2.out -XDrawDiagnostics A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test2.out -XDrawDiagnostics -nowarn A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test2.out -XDrawDiagnostics -Xmaxwarns 1 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test3.out -XDrawDiagnostics -Xlint:deprecation A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test3.out -XDrawDiagnostics -nowarn -Xlint:deprecation A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test3b.out -XDrawDiagnostics -nowarn -Xlint:deprecation -Xmaxwarns 1 A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4.out -XDrawDiagnostics -Xlint:deprecation A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4.out -XDrawDiagnostics -nowarn -Xlint:deprecation A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4b.out -XDrawDiagnostics -nowarn -Xlint:deprecation -Xmaxwarns 1 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4c.out -XDrawDiagnostics -nowarn -Xlint:deprecation -Xmaxwarns 2 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4d.out -XDrawDiagnostics -nowarn -Xlint:deprecation -Xmaxwarns 3 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test5.out -XDrawDiagnostics -Xlint:deprecation P.java Q.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test5b.out -XDrawDiagnostics -Xlint:deprecation -Xmaxwarns 2 P.java Q.java
*/
diff --git a/langtools/test/tools/javac/mandatoryWarnings/unchecked/Test.java b/langtools/test/tools/javac/mandatoryWarnings/unchecked/Test.java
index 6bce09f55fd..434889cb8ec 100644
--- a/langtools/test/tools/javac/mandatoryWarnings/unchecked/Test.java
+++ b/langtools/test/tools/javac/mandatoryWarnings/unchecked/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,95 +29,17 @@
* @bug 5047307
* @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test1.out -XDrawDiagnostics A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test1.out -XDrawDiagnostics -nowarn A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test1.out -XDrawDiagnostics -Xmaxwarns 1 A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test2.out -XDrawDiagnostics A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test2.out -XDrawDiagnostics -nowarn A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test2.out -XDrawDiagnostics -Xmaxwarns 1 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test3.out -XDrawDiagnostics -Xlint:unchecked A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test3.out -XDrawDiagnostics -nowarn -Xlint:unchecked A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test3b.out -XDrawDiagnostics -nowarn -Xlint:unchecked -Xmaxwarns 1 A.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4.out -XDrawDiagnostics -Xlint:unchecked A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4.out -XDrawDiagnostics -nowarn -Xlint:unchecked A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4b.out -XDrawDiagnostics -nowarn -Xlint:unchecked -Xmaxwarns 1 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4c.out -XDrawDiagnostics -nowarn -Xlint:unchecked -Xmaxwarns 2 A.java B.java
- */
-
-/*
- * @test
- * @bug 5047307
- * @summary javac -nowarn improperly suppresses JLS-mandated warnings
* @compile/ref=Test4d.out -XDrawDiagnostics -nowarn -Xlint:unchecked -Xmaxwarns 3 A.java B.java
*/
diff --git a/langtools/test/tools/javac/policy/test3/Test.java b/langtools/test/tools/javac/policy/test3/Test.java
index d26ef8e22f6..fafc872c38a 100644
--- a/langtools/test/tools/javac/policy/test3/Test.java
+++ b/langtools/test/tools/javac/policy/test3/Test.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 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
@@ -123,47 +123,3 @@ public class Test {
int errors;
}
-
-
-
-
-
-
-
-
-
-
-
-
-// These tests test the ability of the compiler to continue in the face of
-// errors, accordining to the shouldStopPolicy
-
-/* @ test /nodynamiccopyright/
- * @bug 6813059
- * @summary
- * @compile/fail/ref=flow.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy -XDshouldStopPolicy=FLOW Test.java
-
- * @compile/fail/ref=default.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy Test.java
- * @compile/fail/ref=enter.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy -XDshouldStopPolicy=ENTER Test.java
- * @compile/fail/ref=attr.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy -XDshouldStopPolicy=ATTR Test.java
- * @compile/fail/ref=transtypes.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy -XDshouldStopPolicy=TRANSTYPES Test.java
- * @compile/fail/ref=lower.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy -XDshouldStopPolicy=LOWER Test.java
- * @compile/fail/ref=generate.out -XDrawDiagnostics -XDcompilePolicy=byfile -XDverboseCompilePolicy -XDshouldStopPolicy=GENERATE Test.java
- */
-
-/*
-class Test {
- void m1() {
- System.err.println("hello");
- 0 // syntax error
- System.err.println("world");
- }
-
- void m2() {
- }
-}
-
-class Test2 {
-}
-*/
-
From 9e9c04939b7e647a72b0f55ccfdb19f91317c328 Mon Sep 17 00:00:00 2001
From: James Laskey
Date: Tue, 21 May 2013 10:17:09 -0300
Subject: [PATCH 030/206] 8014827: readLine should accept a prompt as an
argument
Reviewed-by: sundar, hannesw
---
.../nashorn/internal/runtime/ScriptingFunctions.java | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
index 596ec1bf955..1d046ca96c8 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptingFunctions.java
@@ -46,7 +46,7 @@ import java.util.StringTokenizer;
public final class ScriptingFunctions {
/** Handle to implementation of {@link ScriptingFunctions#readLine} - Nashorn extension */
- public static final MethodHandle READLINE = findOwnMH("readLine", Object.class, Object.class);
+ public static final MethodHandle READLINE = findOwnMH("readLine", Object.class, Object.class, Object.class);
/** Handle to implementation of {@link ScriptingFunctions#readFully} - Nashorn extension */
public static final MethodHandle READFULLY = findOwnMH("readFully", Object.class, Object.class, Object.class);
@@ -78,13 +78,17 @@ public final class ScriptingFunctions {
* Nashorn extension: global.readLine (scripting-mode-only)
* Read one line of input from the standard input.
*
- * @param self self reference
+ * @param self self reference
+ * @param prompt String used as input prompt
*
* @return line that was read
*
* @throws IOException if an exception occurs
*/
- public static Object readLine(final Object self) throws IOException {
+ public static Object readLine(final Object self, final Object prompt) throws IOException {
+ if (prompt != UNDEFINED) {
+ System.out.print(JSType.toString(prompt));
+ }
final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
return reader.readLine();
}
From 5b545ba465d87772b9c3f1999d1ff24e479a7ffb Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 21 May 2013 14:33:09 +0100
Subject: [PATCH 031/206] 7164114: Two jtreg tests are not run due to no file
extension on the test files
Reviewed-by: mcimadamore
---
.../tools/javac/HiddenAbstractMethod/{Test => Test.java} | 2 +-
.../tools/javac/NonAmbiguousField/{Test => Test.java} | 4 ++--
.../test/tools/javac/NonAmbiguousField/two/Child2.java | 8 +++-----
3 files changed, 6 insertions(+), 8 deletions(-)
rename langtools/test/tools/javac/HiddenAbstractMethod/{Test => Test.java} (87%)
rename langtools/test/tools/javac/NonAmbiguousField/{Test => Test.java} (60%)
diff --git a/langtools/test/tools/javac/HiddenAbstractMethod/Test b/langtools/test/tools/javac/HiddenAbstractMethod/Test.java
similarity index 87%
rename from langtools/test/tools/javac/HiddenAbstractMethod/Test
rename to langtools/test/tools/javac/HiddenAbstractMethod/Test.java
index d511864c42e..775eb1b8509 100644
--- a/langtools/test/tools/javac/HiddenAbstractMethod/Test
+++ b/langtools/test/tools/javac/HiddenAbstractMethod/Test.java
@@ -8,5 +8,5 @@
* the method has the same name, it does not override.
* @author turnidge
*
- * @compile/fail -nowrite one/Parent.java two/Child.java
+ * @compile/fail one/Parent.java two/Child.java
*/
diff --git a/langtools/test/tools/javac/NonAmbiguousField/Test b/langtools/test/tools/javac/NonAmbiguousField/Test.java
similarity index 60%
rename from langtools/test/tools/javac/NonAmbiguousField/Test
rename to langtools/test/tools/javac/NonAmbiguousField/Test.java
index fb4cfd79a85..131bc8705c1 100644
--- a/langtools/test/tools/javac/NonAmbiguousField/Test
+++ b/langtools/test/tools/javac/NonAmbiguousField/Test.java
@@ -5,6 +5,6 @@
* compiler as ambigous.
* @author turnidge
*
- * @compile -nowrite one/Parent.java two/Child.java
- * @compile -nowrite one/Parent2.java two/Child2.java
+ * @compile one/Parent.java two/Child.java
+ * @compile/fail one/Parent2.java two/Child2.java
*/
diff --git a/langtools/test/tools/javac/NonAmbiguousField/two/Child2.java b/langtools/test/tools/javac/NonAmbiguousField/two/Child2.java
index 64fcc52dc4c..13ce68f937a 100644
--- a/langtools/test/tools/javac/NonAmbiguousField/two/Child2.java
+++ b/langtools/test/tools/javac/NonAmbiguousField/two/Child2.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,7 @@ interface I {
}
public class Child2 extends one.Parent2 implements I {
- class inner {
- void method() {
- System.out.println(i);
- }
+ void method() {
+ System.out.println(i);
}
}
From de93893f4e5583fbebf688351f7fc606d6e8eac1 Mon Sep 17 00:00:00 2001
From: Mikael Vidstedt
Date: Tue, 21 May 2013 09:43:23 -0700
Subject: [PATCH 032/206] 8013726: runtime/memory/ReserveMemory.java fails due
to 'assert(bytes % os::vm_allocation_granularity() == 0) failed: reserve
block size'
Fix regression test to work on all platforms
Reviewed-by: ctornqvi, dholmes
---
hotspot/src/share/vm/prims/whitebox.cpp | 17 ++++++++++++---
.../test/runtime/memory/ReserveMemory.java | 21 +++++++------------
.../whitebox/sun/hotspot/WhiteBox.java | 2 +-
3 files changed, 22 insertions(+), 18 deletions(-)
diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp
index 7742c036114..92f2349bb7c 100644
--- a/hotspot/src/share/vm/prims/whitebox.cpp
+++ b/hotspot/src/share/vm/prims/whitebox.cpp
@@ -37,6 +37,7 @@
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
#include "utilities/macros.hpp"
+#include "utilities/exceptions.hpp"
#if INCLUDE_ALL_GCS
#include "gc_implementation/g1/concurrentMark.hpp"
@@ -330,8 +331,18 @@ WB_ENTRY(void, WB_FullGC(JNIEnv* env, jobject o))
WB_END
-WB_ENTRY(jlong, WB_ReserveMemory(JNIEnv* env, jobject o, jlong size))
- return (jlong)os::reserve_memory(size, NULL, 0);
+WB_ENTRY(void, WB_ReadReservedMemory(JNIEnv* env, jobject o))
+ // static+volatile in order to force the read to happen
+ // (not be eliminated by the compiler)
+ static char c;
+ static volatile char* p;
+
+ p = os::reserve_memory(os::vm_allocation_granularity(), NULL, 0);
+ if (p == NULL) {
+ THROW_MSG(vmSymbols::java_lang_OutOfMemoryError(), "Failed to reserve memory");
+ }
+
+ c = *p;
WB_END
//Some convenience methods to deal with objects from java
@@ -437,7 +448,7 @@ static JNINativeMethod methods[] = {
{CC"isInStringTable", CC"(Ljava/lang/String;)Z", (void*)&WB_IsInStringTable },
{CC"fullGC", CC"()V", (void*)&WB_FullGC },
- {CC"reserveMemory", CC"(J)J", (void*)&WB_ReserveMemory },
+ {CC"readReservedMemory", CC"()V", (void*)&WB_ReadReservedMemory },
};
#undef CC
diff --git a/hotspot/test/runtime/memory/ReserveMemory.java b/hotspot/test/runtime/memory/ReserveMemory.java
index fbf1a413371..4d234d34d80 100644
--- a/hotspot/test/runtime/memory/ReserveMemory.java
+++ b/hotspot/test/runtime/memory/ReserveMemory.java
@@ -34,29 +34,20 @@
import com.oracle.java.testlibrary.*;
-import java.lang.reflect.Field;
import sun.hotspot.WhiteBox;
-import sun.misc.Unsafe;
public class ReserveMemory {
- private static Unsafe getUnsafe() throws Exception {
- Field f = Unsafe.class.getDeclaredField("theUnsafe");
- f.setAccessible(true);
- return (Unsafe)f.get(null);
- }
-
private static boolean isWindows() {
return System.getProperty("os.name").toLowerCase().startsWith("win");
}
+ private static boolean isOsx() {
+ return System.getProperty("os.name").toLowerCase().startsWith("mac");
+ }
+
public static void main(String args[]) throws Exception {
if (args.length > 0) {
- long address = WhiteBox.getWhiteBox().reserveMemory(4096);
-
- System.out.println("Reserved memory at address: 0x" + Long.toHexString(address));
- System.out.println("Will now read from the address, expecting a crash!");
-
- int x = getUnsafe().getInt(address);
+ WhiteBox.getWhiteBox().readReservedMemory();
throw new Exception("Read of reserved/uncommitted memory unexpectedly succeeded, expected crash!");
}
@@ -71,6 +62,8 @@ public class ReserveMemory {
OutputAnalyzer output = new OutputAnalyzer(pb.start());
if (isWindows()) {
output.shouldContain("EXCEPTION_ACCESS_VIOLATION");
+ } else if (isOsx()) {
+ output.shouldContain("SIGBUS");
} else {
output.shouldContain("SIGSEGV");
}
diff --git a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
index cd3f576d986..3e451213311 100644
--- a/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
+++ b/hotspot/test/testlibrary/whitebox/sun/hotspot/WhiteBox.java
@@ -115,7 +115,7 @@ public class WhiteBox {
public native boolean isInStringTable(String str);
// Memory
- public native long reserveMemory(long size);
+ public native void readReservedMemory();
// force Full GC
public native void fullGC();
From 19da55568fd2ac858fb02edf91f2589b173e4213 Mon Sep 17 00:00:00 2001
From: Bharadwaj Yadavalli
Date: Tue, 21 May 2013 16:17:51 -0700
Subject: [PATCH 033/206] 8014059: JSR292: Failed to reject invalid class
cplmhl00201m28n
Restrict reference of interface methods by invokestatic and invokespecial to classfile version 52 or later.
Reviewed-by: kvn, hseigel
---
hotspot/src/share/vm/classfile/classFileParser.cpp | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 6b2ddd140c6..f7676c0def4 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -444,8 +444,8 @@ constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
break;
case JVM_REF_invokeStatic:
case JVM_REF_invokeSpecial:
- check_property(
- tag.is_method() || tag.is_interface_method(),
+ check_property(tag.is_method() ||
+ ((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
"Invalid constant pool index %u in class file %s (not a method)",
ref_index, CHECK_(nullHandle));
break;
From a50a5688af6213dd9b171223d5c95ec3fbc0d1e7 Mon Sep 17 00:00:00 2001
From: Tao Mao
Date: Tue, 21 May 2013 16:43:41 -0700
Subject: [PATCH 034/206] 8015007: Incorrect print format in error message for
VM cannot allocate the requested heap
Correct the wrong print format in error message for VM cannot allocate the requested heap; and clean up the error message call in check_alignment()
Reviewed-by: brutisso, tschatzl
---
hotspot/src/share/vm/memory/universe.cpp | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 77fc4b846c8..22af6d6906c 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -228,11 +228,8 @@ void Universe::serialize(SerializeClosure* f, bool do_all) {
void Universe::check_alignment(uintx size, uintx alignment, const char* name) {
if (size < alignment || size % alignment != 0) {
- ResourceMark rm;
- stringStream st;
- st.print("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment);
- char* error = st.as_string();
- vm_exit_during_initialization(error);
+ vm_exit_during_initialization(
+ err_msg("Size of %s (" UINTX_FORMAT " bytes) must be aligned to " UINTX_FORMAT " bytes", name, size, alignment));
}
}
@@ -916,7 +913,7 @@ ReservedSpace Universe::reserve_heap(size_t heap_size, size_t alignment) {
}
if (!total_rs.is_reserved()) {
- vm_exit_during_initialization(err_msg("Could not reserve enough space for object heap %d bytes", total_reserved));
+ vm_exit_during_initialization(err_msg("Could not reserve enough space for " SIZE_FORMAT "KB object heap", total_reserved/K));
return total_rs;
}
From 41974c2e0729200c33cec32161143878662e7c46 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Wed, 22 May 2013 16:39:48 +0530
Subject: [PATCH 035/206] 8008947: ScriptEnvironment ctor should be public
Reviewed-by: lagergren, attila
---
nashorn/.hgignore | 1 +
nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java | 2 +-
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/nashorn/.hgignore b/nashorn/.hgignore
index 56e01bae4c0..6d68c1d476d 100644
--- a/nashorn/.hgignore
+++ b/nashorn/.hgignore
@@ -24,3 +24,4 @@ jcov2/*
.idea/*
test/lib/testng.jar
test/script/external/*
+.project
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
index 3bcf9d4f5a3..c1c25b3eecc 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
@@ -186,7 +186,7 @@ public final class ScriptEnvironment {
* @param out output print writer
* @param err error print writer
*/
- ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
+ public ScriptEnvironment(final Options options, final PrintWriter out, final PrintWriter err) {
this.out = out;
this.err = err;
this.namespace = new Namespace();
From 2cd9f2dde4ea0d3a831c16d9fc54a274d48da084 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Wed, 22 May 2013 19:33:08 +0530
Subject: [PATCH 036/206] 8014735: Typed Array, BYTES_PER_ELEMENT should be a
class property
Reviewed-by: lagergren, jlaskey
---
.../internal/objects/ArrayBufferView.java | 6 +--
.../internal/objects/NativeFloat32Array.java | 6 ++-
.../internal/objects/NativeFloat64Array.java | 6 ++-
.../internal/objects/NativeInt16Array.java | 6 ++-
.../internal/objects/NativeInt32Array.java | 6 ++-
.../internal/objects/NativeInt8Array.java | 6 ++-
.../internal/objects/NativeUint16Array.java | 6 ++-
.../internal/objects/NativeUint32Array.java | 6 ++-
.../internal/objects/NativeUint8Array.java | 6 ++-
.../objects/NativeUint8ClampedArray.java | 6 ++-
nashorn/test/script/basic/JDK-8014735.js | 43 +++++++++++++++++++
.../test/script/basic/JDK-8014735.js.EXPECTED | 9 ++++
nashorn/test/script/basic/NASHORN-377.js | 4 +-
13 files changed, 100 insertions(+), 16 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8014735.js
create mode 100644 nashorn/test/script/basic/JDK-8014735.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
index a442a3876c7..ebab47b65f0 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/ArrayBufferView.java
@@ -28,6 +28,7 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Getter;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.ScriptRuntime;
@@ -58,11 +59,6 @@ abstract class ArrayBufferView extends ScriptObject {
return factory().bytesPerElement;
}
- @Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
- public static Object BYTES_PER_ELEMENT(final Object self) {
- return ((ArrayBufferView)self).bytesPerElement();
- }
-
@Getter(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE)
public static Object buffer(final Object self) {
return ((ArrayDataImpl)((ArrayBufferView)self).getArray()).buffer;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
index 98db34ba046..33d2d9ecc5d 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -38,7 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Float32Array")
public final class NativeFloat32Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 4;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 4;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
index e2ce624753f..ba6bffe8c38 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -38,7 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Float64Array")
public final class NativeFloat64Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 8;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 8;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
index c5951d91760..9afaf3a7ea0 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -37,7 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Int16Array")
public final class NativeInt16Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 2;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 2;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
index 486e7a61fd5..199d223d25d 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -37,7 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Int32Array")
public final class NativeInt32Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 4;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 4;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
index 9ad7d24c280..25e86c23d35 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -37,7 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Int8Array")
public final class NativeInt8Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 1;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 1;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
index 740bb394511..ec5e99d3718 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -37,7 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint16Array")
public final class NativeUint16Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 2;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 2;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
index 9be0131202c..d8a3f5240f4 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -38,7 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint32Array")
public final class NativeUint32Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 4;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 4;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteBegin, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
index 7d506c1d6b9..d62818a912b 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -37,7 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint8Array")
public final class NativeUint8Array extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 1;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 1;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
index e3bacc2b9db..7eb3e650714 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
@@ -28,7 +28,9 @@ package jdk.nashorn.internal.objects;
import jdk.nashorn.internal.objects.annotations.Attribute;
import jdk.nashorn.internal.objects.annotations.Constructor;
import jdk.nashorn.internal.objects.annotations.Function;
+import jdk.nashorn.internal.objects.annotations.Property;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
+import jdk.nashorn.internal.objects.annotations.Where;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptObject;
import jdk.nashorn.internal.runtime.arrays.ArrayData;
@@ -38,7 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint8ClampedArray")
public final class NativeUint8ClampedArray extends ArrayBufferView {
- private static final int BYTES_PER_ELEMENT = 1;
+ @Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
+ public static final int BYTES_PER_ELEMENT = 1;
+
private static final Factory FACTORY = new Factory(BYTES_PER_ELEMENT) {
@Override
public ArrayBufferView construct(final NativeArrayBuffer buffer, final int byteOffset, final int length) {
diff --git a/nashorn/test/script/basic/JDK-8014735.js b/nashorn/test/script/basic/JDK-8014735.js
new file mode 100644
index 00000000000..0fc367c0e96
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014735.js
@@ -0,0 +1,43 @@
+/*
+ * 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-8014735: Typed Array, BYTES_PER_ELEMENT should be a class property
+ *
+ * @test
+ * @run
+ */
+
+function bytesPerElement(func) {
+ print(func.name + ".BYTES_PER_ELEMENT = " + func.BYTES_PER_ELEMENT);
+}
+
+bytesPerElement(Int8Array);
+bytesPerElement(Int16Array);
+bytesPerElement(Int32Array);
+bytesPerElement(Uint8Array);
+bytesPerElement(Uint8ClampedArray);
+bytesPerElement(Uint16Array);
+bytesPerElement(Uint32Array);
+bytesPerElement(Float32Array);
+bytesPerElement(Float64Array);
diff --git a/nashorn/test/script/basic/JDK-8014735.js.EXPECTED b/nashorn/test/script/basic/JDK-8014735.js.EXPECTED
new file mode 100644
index 00000000000..bae22d618fb
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8014735.js.EXPECTED
@@ -0,0 +1,9 @@
+Int8Array.BYTES_PER_ELEMENT = 1
+Int16Array.BYTES_PER_ELEMENT = 2
+Int32Array.BYTES_PER_ELEMENT = 4
+Uint8Array.BYTES_PER_ELEMENT = 1
+Uint8ClampedArray.BYTES_PER_ELEMENT = 1
+Uint16Array.BYTES_PER_ELEMENT = 2
+Uint32Array.BYTES_PER_ELEMENT = 4
+Float32Array.BYTES_PER_ELEMENT = 4
+Float64Array.BYTES_PER_ELEMENT = 8
diff --git a/nashorn/test/script/basic/NASHORN-377.js b/nashorn/test/script/basic/NASHORN-377.js
index e77be2bf0e9..31d4df4941b 100644
--- a/nashorn/test/script/basic/NASHORN-377.js
+++ b/nashorn/test/script/basic/NASHORN-377.js
@@ -43,7 +43,7 @@ function tohex(d, w) {
function arrstr(a, n, w) {
var s = "";
if (typeof n == "undefined") n = a.length;
- if (typeof w == "undefined") w = a.BYTES_PER_ELEMENT * 2;
+ if (typeof w == "undefined") w = a.constructor.BYTES_PER_ELEMENT * 2;
for (var i = 0; i < n; i++) {
s += tohex(a[i], w);
}
@@ -96,7 +96,7 @@ function fillArray(a, start) {
var b = new ArrayBuffer(8);
for (var i in types) {
var x = new types[i](b);
- print(x.byteOffset, x.byteLength, x.length, x.BYTES_PER_ELEMENT);
+ print(x.byteOffset, x.byteLength, x.length, x.constructor.BYTES_PER_ELEMENT);
assertTrue(function(){ return x.constructor === types[i] });
}
})();
From aab1e4573c6fc749058190b8dd12b3c129149ae6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?=
Date: Wed, 22 May 2013 16:43:48 +0200
Subject: [PATCH 037/206] 8010804: Review long and integer usage conventions
Reviewed-by: jlaskey, sundar
---
.../internal/codegen/FoldConstants.java | 4 +-
.../nashorn/internal/objects/NativeArray.java | 39 ++-------
.../nashorn/internal/objects/NativeDate.java | 2 +-
.../jdk/nashorn/internal/runtime/JSType.java | 14 ++-
nashorn/test/script/basic/JDK-8010804.js | 86 +++++++++++++++++++
.../test/script/basic/JDK-8010804.js.EXPECTED | 42 +++++++++
6 files changed, 148 insertions(+), 39 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8010804.js
create mode 100644 nashorn/test/script/basic/JDK-8010804.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
index 686c9836da6..2e87631c5b6 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/FoldConstants.java
@@ -279,9 +279,9 @@ final class FoldConstants extends NodeVisitor {
isLong &= value != 0.0 && JSType.isRepresentableAsLong(value);
if (isInteger) {
- return LiteralNode.newInstance(token, finish, JSType.toInt32(value));
+ return LiteralNode.newInstance(token, finish, (int)value);
} else if (isLong) {
- return LiteralNode.newInstance(token, finish, JSType.toLong(value));
+ return LiteralNode.newInstance(token, finish, (long)value);
}
return LiteralNode.newInstance(token, finish, value);
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
index c9a71b57a92..6f9fbcec889 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArray.java
@@ -754,25 +754,11 @@ public final class NativeArray extends ScriptObject {
final Object obj = Global.toObject(self);
final ScriptObject sobj = (ScriptObject)obj;
final long len = JSType.toUint32(sobj.getLength());
- final double startNum = JSType.toNumber(start);
- final long relativeStartUint32 = JSType.toUint32(startNum);
- final long relativeStart = JSType.toInteger(startNum);
+ final long relativeStart = JSType.toLong(start);
+ final long relativeEnd = (end == ScriptRuntime.UNDEFINED) ? len : JSType.toLong(end);
- long k = relativeStart < 0 ?
- Math.max(len + relativeStart, 0) :
- Math.min(
- Math.max(relativeStartUint32, relativeStart),
- len);
-
- final double endNum = (end == ScriptRuntime.UNDEFINED)? Double.NaN : JSType.toNumber(end);
- final long relativeEndUint32 = (end == ScriptRuntime.UNDEFINED)? len : JSType.toUint32(endNum);
- final long relativeEnd = (end == ScriptRuntime.UNDEFINED)? len : JSType.toInteger(endNum);
-
- final long finale = relativeEnd < 0 ?
- Math.max(len + relativeEnd, 0) :
- Math.min(
- Math.max(relativeEndUint32, relativeEnd),
- len);
+ long k = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
+ final long finale = relativeEnd < 0 ? Math.max(len + relativeEnd, 0) : Math.min(relativeEnd, len);
if (k >= finale) {
return new NativeArray(0);
@@ -909,21 +895,10 @@ public final class NativeArray extends ScriptObject {
final ScriptObject sobj = (ScriptObject)obj;
final boolean strict = Global.isStrict();
final long len = JSType.toUint32(sobj.getLength());
- final double startNum = JSType.toNumber(start);
- final long relativeStartUint32 = JSType.toUint32(startNum);
- final long relativeStart = JSType.toInteger(startNum);
+ final long relativeStart = JSType.toLong(start);
- //TODO: workaround overflow of relativeStart for start > Integer.MAX_VALUE
- final long actualStart = relativeStart < 0 ?
- Math.max(len + relativeStart, 0) :
- Math.min(
- Math.max(relativeStartUint32, relativeStart),
- len);
-
- final long actualDeleteCount =
- Math.min(
- Math.max(JSType.toInteger(deleteCount), 0),
- len - actualStart);
+ final long actualStart = relativeStart < 0 ? Math.max(len + relativeStart, 0) : Math.min(relativeStart, len);
+ final long actualDeleteCount = Math.min(Math.max(JSType.toLong(deleteCount), 0), len - actualStart);
final NativeArray array = new NativeArray(actualDeleteCount);
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
index c97514a3131..fa2c9d17a81 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
@@ -770,7 +770,7 @@ public final class NativeDate extends ScriptObject {
nd.setTime(NaN);
return nd.getTime();
}
- int yearInt = JSType.toInteger(yearNum);
+ int yearInt = (int)yearNum;
if (0 <= yearInt && yearInt <= 99) {
yearInt += 1900;
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
index e972a99ef63..58669144111 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java
@@ -565,8 +565,11 @@ public enum JSType {
}
/**
- * JavaScript compliant Object to integer conversion
- * See ECMA 9.4 ToInteger
+ * JavaScript compliant Object to integer conversion. See ECMA 9.4 ToInteger
+ *
+ *
Note that this returns {@link java.lang.Integer#MAX_VALUE} or {@link java.lang.Integer#MIN_VALUE}
+ * for double values that exceed the int range, including positive and negative Infinity. It is the
+ * caller's responsibility to handle such values correctly.
*
* @param obj an object
* @return an integer
@@ -576,8 +579,11 @@ public enum JSType {
}
/**
- * JavaScript compliant Object to long conversion
- * See ECMA 9.4 ToInteger
+ * JavaScript compliant Object to long conversion. See ECMA 9.4 ToInteger
+ *
+ *
Note that this returns {@link java.lang.Long#MAX_VALUE} or {@link java.lang.Long#MIN_VALUE}
+ * for double values that exceed the long range, including positive and negative Infinity. It is the
+ * caller's responsibility to handle such values correctly.
*
* @param obj an object
* @return a long
diff --git a/nashorn/test/script/basic/JDK-8010804.js b/nashorn/test/script/basic/JDK-8010804.js
new file mode 100644
index 00000000000..04e216ade24
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8010804.js
@@ -0,0 +1,86 @@
+/*
+ * 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-8010804: Review long and integer usage conventions
+ *
+ * @test
+ * @run
+ */
+
+var x = [];
+print(x.length);
+x[4294967294] = 1;
+print(x.length);
+x[4294967295] = 1;
+print(x.length);
+print(x.slice(4294967293).length);
+print(x.slice(4294967294).length);
+print(x.slice(4294967295).length);
+print(x.slice(4294967296).length);
+
+print(x.slice(-4294967293).length);
+print(x.slice(-4294967294).length);
+print(x.slice(-4294967295).length);
+print(x.slice(-4294967296).length);
+
+print(x.slice(0, 4294967293).length);
+print(x.slice(0, 4294967294).length);
+print(x.slice(0, 4294967295).length);
+print(x.slice(0, 4294967296).length);
+
+print(x.slice(0, -4294967293).length);
+print(x.slice(0, -4294967294).length);
+print(x.slice(0, -4294967295).length);
+print(x.slice(0, -4294967296).length);
+
+print(x.slice(9223371036854775807).length);
+print(x.slice(9223372036854775807).length);
+print(x.slice(9223373036854775807).length);
+print(x.slice(9223374036854775807).length);
+
+print(x.slice(-9223371036854775807).length);
+print(x.slice(-9223372036854775807).length);
+print(x.slice(-9223373036854775807).length);
+print(x.slice(-9223374036854775807).length);
+
+print(x.slice(-9223371036854775807, 1).length);
+print(x.slice(-9223372036854775807, 1).length);
+print(x.slice(-9223373036854775807, 1).length);
+print(x.slice(-9223374036854775807, 1).length);
+
+print(x.slice(-9223371036854775807, -1).length);
+print(x.slice(-9223372036854775807, -1).length);
+print(x.slice(-9223373036854775807, -1).length);
+print(x.slice(-9223374036854775807, -1).length);
+
+print(x.slice(Infinity).length);
+print(x.slice(Infinity, Infinity).length);
+print(x.slice(Infinity, -Infinity).length);
+print(x.slice(-Infinity).length);
+print(x.slice(-Infinity, Infinity).length);
+print(x.slice(-Infinity, -Infinity).length);
+
+var d = new Date();
+d.setYear(Infinity);
+print(d);
\ No newline at end of file
diff --git a/nashorn/test/script/basic/JDK-8010804.js.EXPECTED b/nashorn/test/script/basic/JDK-8010804.js.EXPECTED
new file mode 100644
index 00000000000..1f73ec043f2
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8010804.js.EXPECTED
@@ -0,0 +1,42 @@
+0
+4294967295
+4294967295
+2
+1
+0
+0
+4294967293
+4294967294
+4294967295
+4294967295
+4294967293
+4294967294
+4294967295
+4294967295
+2
+1
+0
+0
+0
+0
+0
+0
+4294967295
+4294967295
+4294967295
+4294967295
+1
+1
+1
+1
+4294967294
+4294967294
+4294967294
+4294967294
+0
+0
+0
+4294967295
+4294967295
+0
+Invalid Date
From 1e80919f4cb97ccd12698f91975afa46d526c05b Mon Sep 17 00:00:00 2001
From: Tao Mao
Date: Wed, 22 May 2013 11:11:47 -0700
Subject: [PATCH 038/206] 8007762: Rename a bunch of methods in size policy
across collectors
Rename: compute_generations_free_space() = compute_eden_space_size() + compute_old_gen_free_space(); update related logging messages
Reviewed-by: jmasa, johnc, tschatzl, brutisso
---
.../concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp | 10 +++++-----
.../concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp | 6 +++---
.../parNew/asParNewGeneration.cpp | 5 ++---
.../parallelScavenge/psAdaptiveSizePolicy.cpp | 12 ++++++------
.../parallelScavenge/psAdaptiveSizePolicy.hpp | 14 +++++++-------
.../psGCAdaptivePolicyCounters.hpp | 4 ++--
.../parallelScavenge/psMarkSweep.cpp | 14 +++++++-------
.../parallelScavenge/psParallelCompact.cpp | 14 +++++++-------
.../shared/adaptiveSizePolicy.cpp | 4 ++--
9 files changed, 41 insertions(+), 42 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp
index 838e35fb599..d60fe806892 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -969,8 +969,8 @@ size_t CMSAdaptiveSizePolicy::promo_increment_aligned_up(size_t cur_promo) {
}
-void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
- size_t max_eden_size)
+void CMSAdaptiveSizePolicy::compute_eden_space_size(size_t cur_eden,
+ size_t max_eden_size)
{
size_t desired_eden_size = cur_eden;
size_t eden_limit = max_eden_size;
@@ -978,7 +978,7 @@ void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
// Printout input
if (PrintGC && PrintAdaptiveSizePolicy) {
gclog_or_tty->print_cr(
- "CMSAdaptiveSizePolicy::compute_young_generation_free_space: "
+ "CMSAdaptiveSizePolicy::compute_eden_space_size: "
"cur_eden " SIZE_FORMAT,
cur_eden);
}
@@ -1024,7 +1024,7 @@ void CMSAdaptiveSizePolicy::compute_young_generation_free_space(size_t cur_eden,
if (PrintGC && PrintAdaptiveSizePolicy) {
gclog_or_tty->print_cr(
- "CMSAdaptiveSizePolicy::compute_young_generation_free_space limits:"
+ "CMSAdaptiveSizePolicy::compute_eden_space_size limits:"
" desired_eden_size: " SIZE_FORMAT
" old_eden_size: " SIZE_FORMAT,
desired_eden_size, cur_eden);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp
index 6053b4323bd..00a4f8fd781 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -436,8 +436,8 @@ class CMSAdaptiveSizePolicy : public AdaptiveSizePolicy {
size_t generation_alignment() { return _generation_alignment; }
- virtual void compute_young_generation_free_space(size_t cur_eden,
- size_t max_eden_size);
+ virtual void compute_eden_space_size(size_t cur_eden,
+ size_t max_eden_size);
// Calculates new survivor space size; returns a new tenuring threshold
// value. Stores new survivor size in _survivor_size.
virtual uint compute_survivor_space_size_and_threshold(
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp
index a18933356a7..2925b9d439d 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/asParNewGeneration.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -585,8 +585,7 @@ void ASParNewGeneration::compute_new_size() {
size_policy->avg_young_live()->sample(used());
size_policy->avg_eden_live()->sample(eden()->used());
- size_policy->compute_young_generation_free_space(eden()->capacity(),
- max_gen_size());
+ size_policy->compute_eden_space_size(eden()->capacity(), max_gen_size());
resize(size_policy->calculated_eden_size_in_bytes(),
size_policy->calculated_survivor_size_in_bytes());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
index 8b3ee26548d..7727017959d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.cpp
@@ -194,7 +194,7 @@ void PSAdaptiveSizePolicy::clear_generation_free_space_flags() {
// If this is not a full GC, only test and modify the young generation.
-void PSAdaptiveSizePolicy::compute_generation_free_space(
+void PSAdaptiveSizePolicy::compute_generations_free_space(
size_t young_live,
size_t eden_live,
size_t old_live,
@@ -729,7 +729,7 @@ void PSAdaptiveSizePolicy::adjust_promo_for_pause_time(bool is_full_gc,
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(
- "PSAdaptiveSizePolicy::compute_old_gen_free_space "
+ "PSAdaptiveSizePolicy::adjust_promo_for_pause_time "
"adjusting gen sizes for major pause (avg %f goal %f). "
"desired_promo_size " SIZE_FORMAT " promo delta " SIZE_FORMAT,
_avg_major_pause->average(), gc_pause_goal_sec(),
@@ -786,7 +786,7 @@ void PSAdaptiveSizePolicy::adjust_eden_for_pause_time(bool is_full_gc,
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(
- "PSAdaptiveSizePolicy::compute_eden_space_size "
+ "PSAdaptiveSizePolicy::adjust_eden_for_pause_time "
"adjusting gen sizes for major pause (avg %f goal %f). "
"desired_eden_size " SIZE_FORMAT " eden delta " SIZE_FORMAT,
_avg_major_pause->average(), gc_pause_goal_sec(),
@@ -1001,7 +1001,7 @@ size_t PSAdaptiveSizePolicy::adjust_promo_for_footprint(
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(
- "AdaptiveSizePolicy::compute_generation_free_space "
+ "AdaptiveSizePolicy::adjust_promo_for_footprint "
"adjusting tenured gen for footprint. "
"starting promo size " SIZE_FORMAT
" reduced promo size " SIZE_FORMAT,
@@ -1025,7 +1025,7 @@ size_t PSAdaptiveSizePolicy::adjust_eden_for_footprint(
if (PrintAdaptiveSizePolicy && Verbose) {
gclog_or_tty->print_cr(
- "AdaptiveSizePolicy::compute_generation_free_space "
+ "AdaptiveSizePolicy::adjust_eden_for_footprint "
"adjusting eden for footprint. "
" starting eden size " SIZE_FORMAT
" reduced eden size " SIZE_FORMAT
@@ -1280,7 +1280,7 @@ void PSAdaptiveSizePolicy::update_averages(bool is_survivor_overflow,
if (PrintAdaptiveSizePolicy) {
gclog_or_tty->print(
- "AdaptiveSizePolicy::compute_survivor_space_size_and_thresh:"
+ "AdaptiveSizePolicy::update_averages:"
" survived: " SIZE_FORMAT
" promoted: " SIZE_FORMAT
" overflow: %s",
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
index 683c6a991fe..b0cb8c7efbf 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psAdaptiveSizePolicy.hpp
@@ -344,13 +344,13 @@ class PSAdaptiveSizePolicy : public AdaptiveSizePolicy {
// Takes current used space in all generations as input, as well
// as an indication if a full gc has just been performed, for use
// in deciding if an OOM error should be thrown.
- void compute_generation_free_space(size_t young_live,
- size_t eden_live,
- size_t old_live,
- size_t cur_eden, // current eden in bytes
- size_t max_old_gen_size,
- size_t max_eden_size,
- bool is_full_gc);
+ void compute_generations_free_space(size_t young_live,
+ size_t eden_live,
+ size_t old_live,
+ size_t cur_eden, // current eden in bytes
+ size_t max_old_gen_size,
+ size_t max_eden_size,
+ bool is_full_gc);
void compute_eden_space_size(size_t young_live,
size_t eden_live,
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp
index c6839705625..1db22443178 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGCAdaptivePolicyCounters.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 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
@@ -119,7 +119,7 @@ class PSGCAdaptivePolicyCounters : public GCAdaptivePolicyCounters {
ps_size_policy()->change_old_gen_for_min_pauses());
}
- // compute_generation_free_space() statistics
+ // compute_generations_free_space() statistics
inline void update_avg_major_pause() {
_avg_major_pause->set_value(
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index e9b8280d921..01b3a5b6d1e 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -290,13 +290,13 @@ bool PSMarkSweep::invoke_no_policy(bool clear_all_softrefs) {
// Used for diagnostics
size_policy->clear_generation_free_space_flags();
- size_policy->compute_generation_free_space(young_live,
- eden_live,
- old_live,
- cur_eden,
- max_old_gen_size,
- max_eden_size,
- true /* full gc*/);
+ size_policy->compute_generations_free_space(young_live,
+ eden_live,
+ old_live,
+ cur_eden,
+ max_old_gen_size,
+ max_eden_size,
+ true /* full gc*/);
size_policy->check_gc_overhead_limit(young_live,
eden_live,
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index d01bdc8b13b..d85f5d3e486 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -2101,13 +2101,13 @@ bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
// Used for diagnostics
size_policy->clear_generation_free_space_flags();
- size_policy->compute_generation_free_space(young_live,
- eden_live,
- old_live,
- cur_eden,
- max_old_gen_size,
- max_eden_size,
- true /* full gc*/);
+ size_policy->compute_generations_free_space(young_live,
+ eden_live,
+ old_live,
+ cur_eden,
+ max_old_gen_size,
+ max_eden_size,
+ true /* full gc*/);
size_policy->check_gc_overhead_limit(young_live,
eden_live,
diff --git a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp
index 90093a2cb2e..3e7c716d481 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -467,7 +467,7 @@ void AdaptiveSizePolicy::check_gc_overhead_limit(
(free_in_old_gen < (size_t) mem_free_old_limit &&
free_in_eden < (size_t) mem_free_eden_limit))) {
gclog_or_tty->print_cr(
- "PSAdaptiveSizePolicy::compute_generation_free_space limits:"
+ "PSAdaptiveSizePolicy::check_gc_overhead_limit:"
" promo_limit: " SIZE_FORMAT
" max_eden_size: " SIZE_FORMAT
" total_free_limit: " SIZE_FORMAT
From 6ed8c8fcea1f1b2549c4b8a09e492b3247e32394 Mon Sep 17 00:00:00 2001
From: Coleen Phillimore
Date: Wed, 22 May 2013 14:37:49 -0400
Subject: [PATCH 039/206] 8003421: NPG: Move oops out of InstanceKlass into
mirror
Inject protection_domain, signers, init_lock into java_lang_Class
Reviewed-by: stefank, dholmes, sla
---
.../jvm/hotspot/memory/DictionaryEntry.java | 7 ++-
.../sun/jvm/hotspot/oops/InstanceKlass.java | 8 ---
.../jvm/hotspot/utilities/HeapGXLWriter.java | 12 ++--
.../hotspot/utilities/HeapHprofBinWriter.java | 8 +--
.../utilities/soql/JSJavaInstanceKlass.java | 8 ---
.../share/vm/classfile/classFileParser.cpp | 14 +----
.../src/share/vm/classfile/javaClasses.cpp | 63 +++++++++++++++----
.../src/share/vm/classfile/javaClasses.hpp | 19 +++++-
hotspot/src/share/vm/classfile/vmSymbols.hpp | 3 +
hotspot/src/share/vm/oops/arrayKlass.cpp | 2 +-
hotspot/src/share/vm/oops/instanceKlass.cpp | 57 ++++++-----------
hotspot/src/share/vm/oops/instanceKlass.hpp | 36 +++--------
hotspot/src/share/vm/oops/klass.cpp | 5 +-
hotspot/src/share/vm/oops/klass.hpp | 2 +-
hotspot/src/share/vm/oops/objArrayKlass.hpp | 2 +-
hotspot/src/share/vm/oops/typeArrayKlass.hpp | 2 +
hotspot/src/share/vm/prims/jvm.cpp | 14 ++---
hotspot/src/share/vm/runtime/vmStructs.cpp | 4 +-
18 files changed, 130 insertions(+), 136 deletions(-)
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java
index be40fd44c51..301410408d2 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/memory/DictionaryEntry.java
@@ -96,9 +96,10 @@ public class DictionaryEntry extends sun.jvm.hotspot.utilities.HashtableEntry {
public boolean containsProtectionDomain(Oop protectionDomain) {
InstanceKlass ik = (InstanceKlass) klass();
- if (protectionDomain.equals(ik.getProtectionDomain())) {
- return true; // Succeeds trivially
- }
+ // Currently unimplemented and not used.
+ // if (protectionDomain.equals(ik.getJavaMirror().getProtectionDomain())) {
+ // return true; // Succeeds trivially
+ // }
for (ProtectionDomainEntry current = pdSet(); current != null;
current = current.next()) {
if (protectionDomain.equals(current.protectionDomain())) {
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
index cfa26eacdbd..80d5b795b3f 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
@@ -75,8 +75,6 @@ public class InstanceKlass extends Klass {
javaFieldsCount = new CIntField(type.getCIntegerField("_java_fields_count"), 0);
constants = new MetadataField(type.getAddressField("_constants"), 0);
classLoaderData = type.getAddressField("_class_loader_data");
- protectionDomain = new OopField(type.getOopField("_protection_domain"), 0);
- signers = new OopField(type.getOopField("_signers"), 0);
sourceFileName = type.getAddressField("_source_file_name");
sourceDebugExtension = type.getAddressField("_source_debug_extension");
innerClasses = type.getAddressField("_inner_classes");
@@ -136,8 +134,6 @@ public class InstanceKlass extends Klass {
private static CIntField javaFieldsCount;
private static MetadataField constants;
private static AddressField classLoaderData;
- private static OopField protectionDomain;
- private static OopField signers;
private static AddressField sourceFileName;
private static AddressField sourceDebugExtension;
private static AddressField innerClasses;
@@ -350,8 +346,6 @@ public class InstanceKlass extends Klass {
public ConstantPool getConstants() { return (ConstantPool) constants.getValue(this); }
public ClassLoaderData getClassLoaderData() { return ClassLoaderData.instantiateWrapperFor(classLoaderData.getValue(getAddress())); }
public Oop getClassLoader() { return getClassLoaderData().getClassLoader(); }
- public Oop getProtectionDomain() { return protectionDomain.getValue(this); }
- public ObjArray getSigners() { return (ObjArray) signers.getValue(this); }
public Symbol getSourceFileName() { return getSymbol(sourceFileName); }
public String getSourceDebugExtension(){ return CStringUtilities.getString(sourceDebugExtension.getValue(getAddress())); }
public long getNonstaticFieldSize() { return nonstaticFieldSize.getValue(this); }
@@ -541,8 +535,6 @@ public class InstanceKlass extends Klass {
// visitor.doOop(methods, true);
// visitor.doOop(localInterfaces, true);
// visitor.doOop(transitiveInterfaces, true);
- visitor.doOop(protectionDomain, true);
- visitor.doOop(signers, true);
visitor.doCInt(nonstaticFieldSize, true);
visitor.doCInt(staticFieldSize, true);
visitor.doCInt(staticOopFieldCount, true);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java
index f5058386662..47494e826b3 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapGXLWriter.java
@@ -204,13 +204,13 @@ public class HeapGXLWriter extends AbstractHeapGraphWriter {
Oop loader = ik.getClassLoader();
writeEdge(instance, loader, "loaded-by");
- // write signers
- Oop signers = ik.getSigners();
- writeEdge(instance, signers, "signed-by");
+ // write signers NYI
+ // Oop signers = ik.getJavaMirror().getSigners();
+ writeEdge(instance, null, "signed-by");
- // write protection domain
- Oop protectionDomain = ik.getProtectionDomain();
- writeEdge(instance, protectionDomain, "protection-domain");
+ // write protection domain NYI
+ // Oop protectionDomain = ik.getJavaMirror().getProtectionDomain();
+ writeEdge(instance, null, "protection-domain");
// write edges for static reference fields from this class
for (Iterator itr = refFields.iterator(); itr.hasNext();) {
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
index 58fd75ee8b8..65299721f17 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HeapHprofBinWriter.java
@@ -477,8 +477,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
if (k instanceof InstanceKlass) {
InstanceKlass ik = (InstanceKlass) k;
writeObjectID(ik.getClassLoader());
- writeObjectID(ik.getSigners());
- writeObjectID(ik.getProtectionDomain());
+ writeObjectID(null); // ik.getJavaMirror().getSigners());
+ writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
// two reserved id fields
writeObjectID(null);
writeObjectID(null);
@@ -516,8 +516,8 @@ public class HeapHprofBinWriter extends AbstractHeapGraphWriter {
if (bottomKlass instanceof InstanceKlass) {
InstanceKlass ik = (InstanceKlass) bottomKlass;
writeObjectID(ik.getClassLoader());
- writeObjectID(ik.getSigners());
- writeObjectID(ik.getProtectionDomain());
+ writeObjectID(null); // ik.getJavaMirror().getSigners());
+ writeObjectID(null); // ik.getJavaMirror().getProtectionDomain());
} else {
writeObjectID(null);
writeObjectID(null);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java
index 7198e5cec14..a76e5ddbf31 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaInstanceKlass.java
@@ -47,8 +47,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
private static final int FIELD_IS_SYNTHETIC = 13;
private static final int FIELD_IS_INTERFACE = 14;
private static final int FIELD_CLASS_LOADER = 15;
- private static final int FIELD_PROTECTION_DOMAIN = 16;
- private static final int FIELD_SIGNERS = 17;
private static final int FIELD_STATICS = 18;
private static final int FIELD_UNDEFINED = -1;
@@ -100,10 +98,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
return Boolean.valueOf(ik.isInterface());
case FIELD_CLASS_LOADER:
return factory.newJSJavaObject(ik.getClassLoader());
- case FIELD_PROTECTION_DOMAIN:
- return factory.newJSJavaObject(ik.getProtectionDomain());
- case FIELD_SIGNERS:
- return factory.newJSJavaObject(ik.getSigners());
case FIELD_STATICS:
return getStatics();
case FIELD_UNDEFINED:
@@ -246,8 +240,6 @@ public class JSJavaInstanceKlass extends JSJavaKlass {
addField("isSynthetic", FIELD_IS_SYNTHETIC);
addField("isInterface", FIELD_IS_INTERFACE);
addField("classLoader", FIELD_CLASS_LOADER);
- addField("protectionDomain", FIELD_PROTECTION_DOMAIN);
- addField("signers", FIELD_SIGNERS);
addField("statics", FIELD_STATICS);
}
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index f7676c0def4..8aa15736447 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -4040,6 +4040,9 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
}
}
+ // Allocate mirror and initialize static fields
+ java_lang_Class::create_mirror(this_klass, protection_domain, CHECK_(nullHandle));
+
#ifdef ASSERT
if (ParseAllGenericSignatures) {
@@ -4055,17 +4058,6 @@ instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
this_klass(), &all_mirandas, CHECK_(nullHandle));
}
- // Allocate mirror and initialize static fields
- java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));
-
- // Allocate a simple java object for locking during class initialization.
- // This needs to be a java object because it can be held across a java call.
- typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
- this_klass->set_init_lock(r);
-
- // TODO: Move these oops to the mirror
- this_klass->set_protection_domain(protection_domain());
-
// Update the loader_data graph.
record_defined_class_dependencies(this_klass, CHECK_NULL);
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
index bb02a6d8694..cbe3581ff4a 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
@@ -512,22 +512,22 @@ void java_lang_Class::fixup_mirror(KlassHandle k, TRAPS) {
// If the offset was read from the shared archive, it was fixed up already
if (!k->is_shared()) {
- if (k->oop_is_instance()) {
- // During bootstrap, java.lang.Class wasn't loaded so static field
- // offsets were computed without the size added it. Go back and
- // update all the static field offsets to included the size.
- for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
- if (fs.access_flags().is_static()) {
- int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
- fs.set_offset(real_offset);
+ if (k->oop_is_instance()) {
+ // During bootstrap, java.lang.Class wasn't loaded so static field
+ // offsets were computed without the size added it. Go back and
+ // update all the static field offsets to included the size.
+ for (JavaFieldStream fs(InstanceKlass::cast(k())); !fs.done(); fs.next()) {
+ if (fs.access_flags().is_static()) {
+ int real_offset = fs.offset() + InstanceMirrorKlass::offset_of_static_fields();
+ fs.set_offset(real_offset);
+ }
}
}
}
- }
- create_mirror(k, CHECK);
+ create_mirror(k, Handle(NULL), CHECK);
}
-oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
+oop java_lang_Class::create_mirror(KlassHandle k, Handle protection_domain, TRAPS) {
assert(k->java_mirror() == NULL, "should only assign mirror once");
// Use this moment of initialization to cache modifier_flags also,
// to support Class.getModifiers(). Instance classes recalculate
@@ -563,6 +563,16 @@ oop java_lang_Class::create_mirror(KlassHandle k, TRAPS) {
set_array_klass(comp_mirror(), k());
} else {
assert(k->oop_is_instance(), "Must be");
+
+ // Allocate a simple java object for a lock.
+ // This needs to be a java object because during class initialization
+ // it can be held across a java call.
+ typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK_NULL);
+ set_init_lock(mirror(), r);
+
+ // Set protection domain also
+ set_protection_domain(mirror(), protection_domain());
+
// Initialize static fields
InstanceKlass::cast(k())->do_local_static_fields(&initialize_static_field, CHECK_NULL);
}
@@ -597,6 +607,34 @@ void java_lang_Class::set_static_oop_field_count(oop java_class, int size) {
java_class->int_field_put(_static_oop_field_count_offset, size);
}
+oop java_lang_Class::protection_domain(oop java_class) {
+ assert(_protection_domain_offset != 0, "must be set");
+ return java_class->obj_field(_protection_domain_offset);
+}
+void java_lang_Class::set_protection_domain(oop java_class, oop pd) {
+ assert(_protection_domain_offset != 0, "must be set");
+ java_class->obj_field_put(_protection_domain_offset, pd);
+}
+
+oop java_lang_Class::init_lock(oop java_class) {
+ assert(_init_lock_offset != 0, "must be set");
+ return java_class->obj_field(_init_lock_offset);
+}
+void java_lang_Class::set_init_lock(oop java_class, oop init_lock) {
+ assert(_init_lock_offset != 0, "must be set");
+ java_class->obj_field_put(_init_lock_offset, init_lock);
+}
+
+objArrayOop java_lang_Class::signers(oop java_class) {
+ assert(_signers_offset != 0, "must be set");
+ return (objArrayOop)java_class->obj_field(_signers_offset);
+}
+void java_lang_Class::set_signers(oop java_class, objArrayOop signers) {
+ assert(_signers_offset != 0, "must be set");
+ java_class->obj_field_put(_signers_offset, (oop)signers);
+}
+
+
oop java_lang_Class::create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS) {
// This should be improved by adding a field at the Java level or by
// introducing a new VM klass (see comment in ClassFileParser)
@@ -2934,6 +2972,9 @@ int java_lang_Class::_klass_offset;
int java_lang_Class::_array_klass_offset;
int java_lang_Class::_oop_size_offset;
int java_lang_Class::_static_oop_field_count_offset;
+int java_lang_Class::_protection_domain_offset;
+int java_lang_Class::_init_lock_offset;
+int java_lang_Class::_signers_offset;
GrowableArray* java_lang_Class::_fixup_mirror_list = NULL;
int java_lang_Throwable::backtrace_offset;
int java_lang_Throwable::detailMessage_offset;
diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp
index 8e4dd46f3e9..e240bc27e43 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp
@@ -208,7 +208,10 @@ class java_lang_String : AllStatic {
macro(java_lang_Class, klass, intptr_signature, false) \
macro(java_lang_Class, array_klass, intptr_signature, false) \
macro(java_lang_Class, oop_size, int_signature, false) \
- macro(java_lang_Class, static_oop_field_count, int_signature, false)
+ macro(java_lang_Class, static_oop_field_count, int_signature, false) \
+ macro(java_lang_Class, protection_domain, object_signature, false) \
+ macro(java_lang_Class, init_lock, object_signature, false) \
+ macro(java_lang_Class, signers, object_signature, false)
class java_lang_Class : AllStatic {
friend class VMStructs;
@@ -222,15 +225,20 @@ class java_lang_Class : AllStatic {
static int _oop_size_offset;
static int _static_oop_field_count_offset;
+ static int _protection_domain_offset;
+ static int _init_lock_offset;
+ static int _signers_offset;
+
static bool offsets_computed;
static int classRedefinedCount_offset;
static GrowableArray* _fixup_mirror_list;
+ static void set_init_lock(oop java_class, oop init_lock);
public:
static void compute_offsets();
// Instance creation
- static oop create_mirror(KlassHandle k, TRAPS);
+ static oop create_mirror(KlassHandle k, Handle protection_domain, TRAPS);
static void fixup_mirror(KlassHandle k, TRAPS);
static oop create_basic_type_mirror(const char* basic_type_name, BasicType type, TRAPS);
// Conversion
@@ -262,6 +270,13 @@ class java_lang_Class : AllStatic {
static int classRedefinedCount(oop the_class_mirror);
static void set_classRedefinedCount(oop the_class_mirror, int value);
+ // Support for embedded per-class oops
+ static oop protection_domain(oop java_class);
+ static void set_protection_domain(oop java_class, oop protection_domain);
+ static oop init_lock(oop java_class);
+ static objArrayOop signers(oop java_class);
+ static void set_signers(oop java_class, objArrayOop signers);
+
static int oop_size(oop java_class);
static void set_oop_size(oop java_class, int size);
static int static_oop_field_count(oop java_class);
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index 9fd9aff5e22..e0bff971d0c 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -392,6 +392,9 @@
template(array_klass_name, "array_klass") \
template(oop_size_name, "oop_size") \
template(static_oop_field_count_name, "static_oop_field_count") \
+ template(protection_domain_name, "protection_domain") \
+ template(init_lock_name, "init_lock") \
+ template(signers_name, "signers_name") \
template(loader_data_name, "loader_data") \
template(dependencies_name, "dependencies") \
\
diff --git a/hotspot/src/share/vm/oops/arrayKlass.cpp b/hotspot/src/share/vm/oops/arrayKlass.cpp
index 9b5ec951bbb..dc2fbe92e2a 100644
--- a/hotspot/src/share/vm/oops/arrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/arrayKlass.cpp
@@ -94,7 +94,7 @@ void ArrayKlass::complete_create_array_klass(ArrayKlass* k, KlassHandle super_kl
ResourceMark rm(THREAD);
k->initialize_supers(super_klass(), CHECK);
k->vtable()->initialize_vtable(false, CHECK);
- java_lang_Class::create_mirror(k, CHECK);
+ java_lang_Class::create_mirror(k, Handle(NULL), CHECK);
}
GrowableArray* ArrayKlass::compute_secondary_supers(int num_extra_slots) {
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 06827e68148..b61f595424e 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -268,8 +268,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_fields(NULL, 0);
set_constants(NULL);
set_class_loader_data(NULL);
- set_protection_domain(NULL);
- set_signers(NULL);
set_source_file_name(NULL);
set_source_debug_extension(NULL, 0);
set_array_name(NULL);
@@ -279,7 +277,6 @@ InstanceKlass::InstanceKlass(int vtable_len,
set_is_marked_dependent(false);
set_init_state(InstanceKlass::allocated);
set_init_thread(NULL);
- set_init_lock(NULL);
set_reference_type(rt);
set_oop_map_cache(NULL);
set_jni_ids(NULL);
@@ -408,12 +405,6 @@ void InstanceKlass::deallocate_contents(ClassLoaderData* loader_data) {
}
set_inner_classes(NULL);
- // Null out Java heap objects, although these won't be walked to keep
- // alive once this InstanceKlass is deallocated.
- set_protection_domain(NULL);
- set_signers(NULL);
- set_init_lock(NULL);
-
// We should deallocate the Annotations instance
MetadataFactory::free_metadata(loader_data, annotations());
set_annotations(NULL);
@@ -451,6 +442,24 @@ void InstanceKlass::eager_initialize(Thread *thread) {
}
}
+// JVMTI spec thinks there are signers and protection domain in the
+// instanceKlass. These accessors pretend these fields are there.
+// The hprof specification also thinks these fields are in InstanceKlass.
+oop InstanceKlass::protection_domain() const {
+ // return the protection_domain from the mirror
+ return java_lang_Class::protection_domain(java_mirror());
+}
+
+// To remove these from requires an incompatible change and CCC request.
+objArrayOop InstanceKlass::signers() const {
+ // return the signers from the mirror
+ return java_lang_Class::signers(java_mirror());
+}
+
+volatile oop InstanceKlass::init_lock() const {
+ // return the init lock from the mirror
+ return java_lang_Class::init_lock(java_mirror());
+}
void InstanceKlass::eager_initialize_impl(instanceKlassHandle this_oop) {
EXCEPTION_MARK;
@@ -1883,16 +1892,6 @@ bool InstanceKlass::is_dependent_nmethod(nmethod* nm) {
// Garbage collection
-void InstanceKlass::oops_do(OopClosure* cl) {
- Klass::oops_do(cl);
-
- cl->do_oop(adr_protection_domain());
- cl->do_oop(adr_signers());
- cl->do_oop(adr_init_lock());
-
- // Don't walk the arrays since they are walked from the ClassLoaderData objects.
-}
-
#ifdef ASSERT
template void assert_is_in(T *p) {
T heap_oop = oopDesc::load_heap_oop(p);
@@ -2241,9 +2240,6 @@ void InstanceKlass::remove_unshareable_info() {
m->remove_unshareable_info();
}
- // Need to reinstate when reading back the class.
- set_init_lock(NULL);
-
// do array classes also.
array_klasses_do(remove_unshareable_in_class);
}
@@ -2275,13 +2271,6 @@ void InstanceKlass::restore_unshareable_info(TRAPS) {
ik->itable()->initialize_itable(false, CHECK);
}
- // Allocate a simple java object for a lock.
- // This needs to be a java object because during class initialization
- // it can be held across a java call.
- typeArrayOop r = oopFactory::new_typeArray(T_INT, 0, CHECK);
- Handle h(THREAD, (oop)r);
- ik->set_init_lock(h());
-
// restore constant pool resolved references
ik->constants()->restore_unshareable_info(CHECK);
@@ -2836,10 +2825,7 @@ void InstanceKlass::print_on(outputStream* st) const {
class_loader_data()->print_value_on(st);
st->cr();
}
- st->print(BULLET"protection domain: "); ((InstanceKlass*)this)->protection_domain()->print_value_on(st); st->cr();
st->print(BULLET"host class: "); host_klass()->print_value_on_maybe_null(st); st->cr();
- st->print(BULLET"signers: "); signers()->print_value_on(st); st->cr();
- st->print(BULLET"init_lock: "); ((oop)_init_lock)->print_value_on(st); st->cr();
if (source_file_name() != NULL) {
st->print(BULLET"source file: ");
source_file_name()->print_value_on(st);
@@ -3040,7 +3026,6 @@ void InstanceKlass::collect_statistics(KlassSizeStats *sz) const {
n += (sz->_method_ordering_bytes = sz->count_array(method_ordering()));
n += (sz->_local_interfaces_bytes = sz->count_array(local_interfaces()));
n += (sz->_transitive_interfaces_bytes = sz->count_array(transitive_interfaces()));
- n += (sz->_signers_bytes = sz->count_array(signers()));
n += (sz->_fields_bytes = sz->count_array(fields()));
n += (sz->_inner_classes_bytes = sz->count_array(inner_classes()));
sz->_ro_bytes += n;
@@ -3206,17 +3191,11 @@ void InstanceKlass::verify_on(outputStream* st) {
guarantee(constants()->is_metadata(), "should be in metaspace");
guarantee(constants()->is_constantPool(), "should be constant pool");
}
- if (protection_domain() != NULL) {
- guarantee(protection_domain()->is_oop(), "should be oop");
- }
const Klass* host = host_klass();
if (host != NULL) {
guarantee(host->is_metadata(), "should be in metaspace");
guarantee(host->is_klass(), "should be klass");
}
- if (signers() != NULL) {
- guarantee(signers()->is_objArray(), "should be obj array");
- }
}
void InstanceKlass::oop_verify_on(oop obj, outputStream* st) {
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 8ee9adc01f1..1a370711fd7 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -58,8 +58,6 @@
// [fields ]
// [constants ]
// [class loader ]
-// [protection domain ]
-// [signers ]
// [source file name ]
// [inner classes ]
// [static field size ]
@@ -180,16 +178,6 @@ class InstanceKlass: public Klass {
static volatile int _total_instanceKlass_count;
protected:
- // Protection domain.
- oop _protection_domain;
- // Class signers.
- objArrayOop _signers;
- // Lock for (1) initialization; (2) access to the ConstantPool of this class.
- // Must be one per class and it has to be a VM internal object so java code
- // cannot lock it (like the mirror).
- // It has to be an object not a Mutex because it's held through java calls.
- volatile oop _init_lock;
-
// Annotations for this class
Annotations* _annotations;
// Array classes holding elements of this class.
@@ -527,8 +515,10 @@ class InstanceKlass: public Klass {
void set_constants(ConstantPool* c) { _constants = c; }
// protection domain
- oop protection_domain() { return _protection_domain; }
- void set_protection_domain(oop pd) { klass_oop_store(&_protection_domain, pd); }
+ oop protection_domain() const;
+
+ // signers
+ objArrayOop signers() const;
// host class
Klass* host_klass() const {
@@ -575,10 +565,6 @@ class InstanceKlass: public Klass {
}
}
- // signers
- objArrayOop signers() const { return _signers; }
- void set_signers(objArrayOop s) { klass_oop_store((oop*)&_signers, s); }
-
// source file name
Symbol* source_file_name() const { return _source_file_name; }
void set_source_file_name(Symbol* n);
@@ -912,8 +898,6 @@ class InstanceKlass: public Klass {
Method* method_at_itable(Klass* holder, int index, TRAPS);
// Garbage collection
- virtual void oops_do(OopClosure* cl);
-
void oop_follow_contents(oop obj);
int oop_adjust_pointers(oop obj);
@@ -999,14 +983,12 @@ private:
// Lock during initialization
public:
- volatile oop init_lock() const {return _init_lock; }
+ // Lock for (1) initialization; (2) access to the ConstantPool of this class.
+ // Must be one per class and it has to be a VM internal object so java code
+ // cannot lock it (like the mirror).
+ // It has to be an object not a Mutex because it's held through java calls.
+ volatile oop init_lock() const;
private:
- void set_init_lock(oop value) { klass_oop_store(&_init_lock, value); }
-
- // Offsets for memory management
- oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
- oop* adr_signers() const { return (oop*)&this->_signers;}
- oop* adr_init_lock() const { return (oop*)&this->_init_lock;}
// Static methods that are used to implement member methods where an exposed this pointer
// is needed due to possible GCs
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index 52dd2645979..5c334206b97 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -511,8 +511,9 @@ void Klass::restore_unshareable_info(TRAPS) {
// (same order as class file parsing)
loader_data->add_class(this);
- // Recreate the class mirror
- java_lang_Class::create_mirror(this, CHECK);
+ // Recreate the class mirror. The protection_domain is always null for
+ // boot loader, for now.
+ java_lang_Class::create_mirror(this, Handle(NULL), CHECK);
}
Klass* Klass::array_klass_or_null(int rank) {
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index acd402c79ad..6b0103abb5e 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -445,7 +445,7 @@ class Klass : public Metadata {
Klass* array_klass_or_null(int rank);
Klass* array_klass_or_null();
- virtual oop protection_domain() { return NULL; }
+ virtual oop protection_domain() const = 0;
oop class_loader() const;
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.hpp b/hotspot/src/share/vm/oops/objArrayKlass.hpp
index 74aa4f8d76d..9905704ccab 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp
@@ -75,7 +75,7 @@ class ObjArrayKlass : public ArrayKlass {
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
// Compute protection domain
- oop protection_domain() { return bottom_klass()->protection_domain(); }
+ oop protection_domain() const { return bottom_klass()->protection_domain(); }
private:
// Either oop or narrowOop depending on UseCompressedOops.
diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.hpp b/hotspot/src/share/vm/oops/typeArrayKlass.hpp
index 3fe8312a0ba..f8bf2ac74c0 100644
--- a/hotspot/src/share/vm/oops/typeArrayKlass.hpp
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.hpp
@@ -67,6 +67,8 @@ class TypeArrayKlass : public ArrayKlass {
typeArrayOop allocate(int length, TRAPS) { return allocate_common(length, true, THREAD); }
oop multi_allocate(int rank, jint* sizes, TRAPS);
+ oop protection_domain() const { return NULL; }
+
// Copying
void copy_array(arrayOop s, int src_pos, arrayOop d, int dst_pos, int length, TRAPS);
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index bedfc619035..733d04a1b69 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -1072,11 +1072,7 @@ JVM_ENTRY(jobjectArray, JVM_GetClassSigners(JNIEnv *env, jclass cls))
return NULL;
}
- Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
- objArrayOop signers = NULL;
- if (k->oop_is_instance()) {
- signers = InstanceKlass::cast(k)->signers();
- }
+ objArrayOop signers = java_lang_Class::signers(JNIHandles::resolve_non_null(cls));
// If there are no signers set in the class, or if the class
// is an array, return NULL.
@@ -1102,7 +1098,7 @@ JVM_ENTRY(void, JVM_SetClassSigners(JNIEnv *env, jclass cls, jobjectArray signer
// be called with an array. Only the bootstrap loader creates arrays.
Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve_non_null(cls));
if (k->oop_is_instance()) {
- InstanceKlass::cast(k)->set_signers(objArrayOop(JNIHandles::resolve(signers)));
+ java_lang_Class::set_signers(k->java_mirror(), objArrayOop(JNIHandles::resolve(signers)));
}
}
JVM_END
@@ -1119,8 +1115,8 @@ JVM_ENTRY(jobject, JVM_GetProtectionDomain(JNIEnv *env, jclass cls))
return NULL;
}
- Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(cls));
- return (jobject) JNIHandles::make_local(env, k->protection_domain());
+ oop pd = java_lang_Class::protection_domain(JNIHandles::resolve(cls));
+ return (jobject) JNIHandles::make_local(env, pd);
JVM_END
@@ -1139,7 +1135,7 @@ JVM_ENTRY(void, JVM_SetProtectionDomain(JNIEnv *env, jclass cls, jobject protect
if (k->oop_is_instance()) {
oop pd = JNIHandles::resolve(protection_domain);
assert(pd == NULL || pd->is_oop(), "just checking");
- InstanceKlass::cast(k)->set_protection_domain(pd);
+ java_lang_Class::set_protection_domain(k->java_mirror(), pd);
}
}
JVM_END
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index b3fdd1e7097..6e12cd447fc 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -292,10 +292,8 @@ typedef BinaryTreeDictionary MetablockTreeDictionary;
nonstatic_field(InstanceKlass, _transitive_interfaces, Array*) \
nonstatic_field(InstanceKlass, _fields, Array*) \
nonstatic_field(InstanceKlass, _java_fields_count, u2) \
- nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
+ nonstatic_field(InstanceKlass, _constants, ConstantPool*) \
nonstatic_field(InstanceKlass, _class_loader_data, ClassLoaderData*) \
- nonstatic_field(InstanceKlass, _protection_domain, oop) \
- nonstatic_field(InstanceKlass, _signers, objArrayOop) \
nonstatic_field(InstanceKlass, _source_file_name, Symbol*) \
nonstatic_field(InstanceKlass, _source_debug_extension, char*) \
nonstatic_field(InstanceKlass, _inner_classes, Array*) \
From 59c9296f63756e4f3309944a66976a2a6fb59962 Mon Sep 17 00:00:00 2001
From: Joe Darcy
Date: Wed, 22 May 2013 13:34:03 -0700
Subject: [PATCH 040/206] 8010680: Clarify "present" and annotation ordering in
javax.lang.model
Reviewed-by: abuckley, jjg
---
.../javax/lang/model/AnnotatedConstruct.java | 101 +++++++++++++-----
.../javax/lang/model/util/Elements.java | 5 +-
2 files changed, 76 insertions(+), 30 deletions(-)
diff --git a/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java
index c96bff48432..f02f5cdbbd0 100644
--- a/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java
+++ b/langtools/src/share/classes/javax/lang/model/AnnotatedConstruct.java
@@ -39,35 +39,76 @@ import javax.lang.model.type.*;
* are on a declaration, whereas annotations on a type are on
* a specific use of a type name.
*
- * The terms directly present and present are used
+ * The terms directly present, present,
+ * indirectly present, and associated are used
* throughout this interface to describe precisely which annotations
- * are returned by methods:
+ * are returned by the methods defined herein.
*
- *
An annotation A is directly present on a
- * construct E if E is annotated, and:
+ *
In the definitions below, an annotation A has an
+ * annotation type AT. If AT is a repeatable annotation
+ * type, the type of the containing annotation is ATC.
+ *
+ *
Annotation A is directly present on a construct
+ * C if either:
*
*
*
- *
for an invocation of {@code getAnnotation(Class)} or
- * {@code getAnnotationMirrors()}, E's annotations contain A.
+ *
A is explicitly or implicitly declared as applying to
+ * the source code representation of C.
*
- *
for an invocation of {@code getAnnotationsByType(Class)},
- * E's annotations either contain A or, if the type of
- * A is repeatable, contain exactly one annotation whose value
- * element contains A and whose type is the containing
- * annotation type of A's type.
+ *
Typically, if exactly one annotation of type AT appears in
+ * the source code of representation of C, then A is
+ * explicitly declared as applying to C.
+ *
+ * If there are multiple annotations of type AT present on
+ * C, then if AT is repeatable annotation type, an
+ * annotation of type ATC is implicitly declared on C.
+ *
+ *
A representation of A appears in the executable output
+ * for C, such as the {@code RuntimeVisibleAnnotations} or
+ * {@code RuntimeVisibleParameterAnnotations} attributes of a class
+ * file.
*
*
*
- *
An annotation A is present on a construct E if either:
+ *
An annotation A is present on a
+ * construct C if either:
+ *
+ *
+ *
A is directly present on C.
+ *
+ *
No annotation of type AT is directly present on
+ * C, and C is a class and AT is inheritable
+ * and A is present on the superclass of C.
+ *
+ *
+ *
+ * An annotation A is indirectly present on a construct
+ * C if both:
*
*
- *
A is directly present on E; or
*
- *
A is not directly present on E, and
- * E is an element representing a class, and A's type
- * is inheritable, and A is present on the element
- * representing the superclass of E.
+ *
AT is a repeatable annotation type with a containing
+ * annotation type ATC.
+ *
+ *
An annotation of type ATC is directly present on
+ * C and A is an annotation included in the result of
+ * calling the {@code value} method of the directly present annotation
+ * of type ATC.
+ *
+ *
+ *
+ * An annotation A is associated with a construct
+ * C if either:
+ *
+ *
+ *
+ *
A is directly or indirectly present on C.
+ *
+ *
No annotation of type AT is directly or indirectly
+ * present on C, and C is a class, and AT is
+ * inheritable, and A is associated with the superclass of
+ * C.
*
*
*
@@ -86,9 +127,8 @@ public interface AnnotatedConstruct {
List extends AnnotationMirror> getAnnotationMirrors();
/**
- * Returns this construct's annotation of the
- * specified type if such an annotation is present, else {@code
- * null}.
+ * Returns this construct's annotation of the specified type if
+ * such an annotation is present, else {@code null}.
*
*
*/
+@SuppressWarnings("javadoc")
public final class JavaAdapterFactory {
/**
* A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterGeneratorBase.java b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterGeneratorBase.java
index 67499cbc58a..ff33ba6ef72 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterGeneratorBase.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterGeneratorBase.java
@@ -33,6 +33,7 @@ import jdk.nashorn.internal.runtime.ScriptObject;
* Base class for both {@link JavaAdapterBytecodeGenerator} and {@link JavaAdapterClassLoader}, containing those
* bytecode types, type names and method descriptor that are used by both.
*/
+@SuppressWarnings("javadoc")
abstract class JavaAdapterGeneratorBase {
static final Type CONTEXT_TYPE = Type.getType(Context.class);
static final Type OBJECT_TYPE = Type.getType(Object.class);
From bd53fa8370d6e4f318c939e6a51c6a9942a39b13 Mon Sep 17 00:00:00 2001
From: Christian Tornqvist
Date: Thu, 23 May 2013 17:39:32 +0200
Subject: [PATCH 045/206] 8009576: Test returns ClassNotFoundException
Small classpath fix and move tests into open
Reviewed-by: mgerdin, zgu
---
.../runtime/Metaspace/FragmentMetaspace.java | 64 ++++++
.../Metaspace/FragmentMetaspaceSimple.java | 69 ++++++
.../runtime/Metaspace/classes/test/Empty.java | 28 +++
.../testlibrary/GeneratedClassLoader.java | 202 ++++++++++++++++++
4 files changed, 363 insertions(+)
create mode 100644 hotspot/test/runtime/Metaspace/FragmentMetaspace.java
create mode 100644 hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java
create mode 100644 hotspot/test/runtime/Metaspace/classes/test/Empty.java
create mode 100644 hotspot/test/runtime/testlibrary/GeneratedClassLoader.java
diff --git a/hotspot/test/runtime/Metaspace/FragmentMetaspace.java b/hotspot/test/runtime/Metaspace/FragmentMetaspace.java
new file mode 100644
index 00000000000..5e1a7200493
--- /dev/null
+++ b/hotspot/test/runtime/Metaspace/FragmentMetaspace.java
@@ -0,0 +1,64 @@
+/*
+ * 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
+ * @library /runtime/testlibrary
+ * @build GeneratedClassLoader
+ * @run main/othervm/timeout=200 FragmentMetaspace
+ */
+
+import java.io.IOException;
+
+/**
+ * Test that tries to fragment the native memory used by class loaders.
+ * This test creates class loaders that load classes of increasing size for every
+ * iteration. By increasing the size of the class meta data needed for every iteration
+ * we stress the subsystem for allocating native memory for meta data.
+ */
+public class FragmentMetaspace {
+
+ public static void main(String... args) {
+ runGrowing(Long.valueOf(System.getProperty("time", "80000")));
+ // try to clean up and unload classes to decrease
+ // class verification time in debug vm
+ System.gc();
+ }
+
+ private static void runGrowing(long time) {
+ long startTime = System.currentTimeMillis();
+ for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+ try {
+ GeneratedClassLoader gcl = new GeneratedClassLoader();
+
+ Class> c = gcl.getGeneratedClasses(i, 100)[0];
+ c.newInstance();
+ c = null;
+
+ gcl = null;
+ } catch (IOException|InstantiationException|IllegalAccessException ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+}
diff --git a/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java b/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java
new file mode 100644
index 00000000000..2e6f7b52c0e
--- /dev/null
+++ b/hotspot/test/runtime/Metaspace/FragmentMetaspaceSimple.java
@@ -0,0 +1,69 @@
+/*
+ * 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
+ * @library /runtime/testlibrary
+ * @library classes
+ * @build test.Empty ClassUnloadCommon
+ * @run main/othervm/timeout=200 FragmentMetaspaceSimple
+ */
+
+import java.util.ArrayList;
+
+/**
+ * Test that tries to fragment the native memory used by class loaders.
+ * Keeps every other class loader alive in order to fragment the memory space
+ * used to store classes and meta data. Since the memory is probably allocated in
+ * chunks per class loader this will cause a lot of fragmentation if not handled
+ * properly since every other chunk will be unused.
+ */
+public class FragmentMetaspaceSimple {
+ public static void main(String... args) {
+ runSimple(Long.valueOf(System.getProperty("time", "80000")));
+ System.gc();
+ }
+
+ private static void runSimple(long time) {
+ long startTime = System.currentTimeMillis();
+ ArrayList cls = new ArrayList<>();
+ for (int i = 0; System.currentTimeMillis() < startTime + time; ++i) {
+ ClassLoader ldr = ClassUnloadCommon.newClassLoader();
+ if (i % 1000 == 0) {
+ cls.clear();
+ }
+ // only keep every other class loader alive
+ if (i % 2 == 1) {
+ cls.add(ldr);
+ }
+ Class> c = null;
+ try {
+ c = ldr.loadClass("test.Empty");
+ } catch (ClassNotFoundException ex) {
+ throw new RuntimeException(ex);
+ }
+ c = null;
+ }
+ cls = null;
+ }
+}
diff --git a/hotspot/test/runtime/Metaspace/classes/test/Empty.java b/hotspot/test/runtime/Metaspace/classes/test/Empty.java
new file mode 100644
index 00000000000..dc02e299af5
--- /dev/null
+++ b/hotspot/test/runtime/Metaspace/classes/test/Empty.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package test;
+
+public class Empty {
+public String toString() { return "nothing"; }
+}
diff --git a/hotspot/test/runtime/testlibrary/GeneratedClassLoader.java b/hotspot/test/runtime/testlibrary/GeneratedClassLoader.java
new file mode 100644
index 00000000000..84a1b7e157d
--- /dev/null
+++ b/hotspot/test/runtime/testlibrary/GeneratedClassLoader.java
@@ -0,0 +1,202 @@
+/*
+ * 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.DataInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.tools.JavaCompiler;
+import javax.tools.ToolProvider;
+
+/**
+ * A class loader that generates new classes.
+ * The generated classes are made by first emitting java sources with nested
+ * static classes, these are then compiled and the class files are read back.
+ * Some efforts are made to make the class instances unique and of not insignificant
+ * size.
+ */
+public class GeneratedClassLoader extends ClassLoader {
+ /**
+ * Holds a pair of class bytecodes and class name (for use with defineClass).
+ */
+ private static class GeneratedClass {
+ public byte[] bytes;
+ public String name;
+ public GeneratedClass(byte[] bytes, String name) {
+ this.bytes = bytes; this.name = name;
+ }
+ }
+
+ /**
+ * Used to uniquely name every class generated.
+ */
+ private static int count = 0;
+ /**
+ * Used to enable/disable keeping the class files and java sources for
+ * the generated classes.
+ */
+ private static boolean deleteFiles = Boolean.parseBoolean(
+ System.getProperty("GeneratedClassLoader.deleteFiles", "true"));
+
+ private static String bigstr =
+ "Lorem ipsum dolor sit amet, consectetur adipiscing elit. "
+ + "In facilisis scelerisque vehicula. Donec congue nisi a "
+ + "leo posuere placerat lobortis felis ultrices. Pellentesque "
+ + "habitant morbi tristique senectus et netus et malesuada "
+ + "fames ac turpis egestas. Nam tristique velit at felis "
+ + "iaculis at tempor sem vestibulum. Sed adipiscing lectus "
+ + "non mi molestie sagittis. Morbi eu purus urna. Nam tempor "
+ + "tristique massa eget semper. Mauris cursus, nulla et ornare "
+ + "vehicula, leo dolor scelerisque metus, sit amet rutrum erat "
+ + "sapien quis dui. Nullam eleifend risus et velit accumsan sed "
+ + "suscipit felis pulvinar. Nullam faucibus suscipit gravida. "
+ + "Pellentesque habitant morbi tristique senectus et netus et "
+ + "malesuada fames ac turpis egestas. Nullam ut massa augue, "
+ + "nec viverra mauris.";
+
+ private static int getNextCount() {
+ return count++;
+ }
+
+ ////// end statics
+
+ private JavaCompiler javac;
+ private String nameBase;
+
+ public GeneratedClassLoader() {
+ javac = ToolProvider.getSystemJavaCompiler();
+ nameBase = "TestSimpleClass";
+ }
+
+ private long getBigValue(int which) {
+ // > 65536 is too large to encode in the bytecode
+ // so this will force us to emit a constant pool entry for this int
+ return (long)which + 65537;
+ }
+
+ private String getBigString(int which) {
+ return bigstr + which;
+ }
+
+ private String getClassName(int count) {
+ return nameBase + count;
+ }
+
+ private String generateSource(int count, int sizeFactor, int numClasses) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("public class ").append(getClassName(count)).append("{\n");
+ for (int j = 0; j < numClasses; ++j) {
+ sb.append("public static class ")
+ .append("Class")
+ .append(j)
+ .append("{\n");
+ for (int i = 0; i < sizeFactor; ++i) {
+ int value = i;
+ sb.append("private long field")
+ .append(i).append(" = ")
+ .append(getBigValue(value++))
+ .append(";\n");
+ sb.append("public long method")
+ .append(i)
+ .append("() {\n");
+ sb.append("return ")
+ .append(getBigValue(value++))
+ .append(";");
+ sb.append("}\n");
+ sb.append("private String str").append(i)
+ .append(" = \"")
+ .append(getBigString(i))
+ .append("\";");
+ }
+ sb.append("\n}");
+ }
+ sb.append("\n}");
+ return sb.toString();
+ }
+
+ private GeneratedClass[] getGeneratedClass(int sizeFactor, int numClasses) throws IOException {
+ int uniqueCount = getNextCount();
+ String src = generateSource(uniqueCount, sizeFactor, numClasses);
+ String className = getClassName(uniqueCount);
+ File file = new File(className + ".java");
+ try (PrintWriter pw = new PrintWriter(new FileWriter(file))) {
+ pw.append(src);
+ pw.flush();
+ }
+ int exitcode = javac.run(null, null, null, file.getCanonicalPath());
+ if (exitcode != 0) {
+ throw new RuntimeException("javac failure when compiling: " +
+ file.getCanonicalPath());
+ } else {
+ if (deleteFiles) {
+ file.delete();
+ }
+ }
+ GeneratedClass[] gc = new GeneratedClass[numClasses];
+ for (int i = 0; i < numClasses; ++i) {
+ String name = className + "$" + "Class" + i;
+ File classFile = new File(name + ".class");
+ byte[] bytes;
+ try (DataInputStream dis = new DataInputStream(new FileInputStream(classFile))) {
+ bytes = new byte[dis.available()];
+ dis.readFully(bytes);
+ }
+ if (deleteFiles) {
+ classFile.delete();
+ }
+ gc[i] = new GeneratedClass(bytes, name);
+ }
+ if (deleteFiles) {
+ new File(className + ".class").delete();
+ }
+ return gc;
+ }
+
+ /**
+ * Generate a single class, compile it and load it.
+ * @param sizeFactor Fuzzy measure of how large the class should be.
+ * @return the Class instance.
+ * @throws IOException
+ */
+ public Class> generateClass(int sizeFactor) throws IOException {
+ return getGeneratedClasses(sizeFactor, 1)[0];
+ }
+
+ /**
+ * Generate several classes, compile and load them.
+ * @param sizeFactor Fuzzy measure of how large each class should be.
+ * @param numClasses The number of classes to create
+ * @return an array of the Class instances.
+ * @throws IOException
+ */
+ public Class>[] getGeneratedClasses(int sizeFactor, int numClasses) throws IOException {
+ GeneratedClass[] gc = getGeneratedClass(sizeFactor, numClasses);
+ Class>[] classes = new Class[numClasses];
+ for (int i = 0; i < numClasses; ++i) {
+ classes[i] = defineClass(gc[i].name, gc[i].bytes, 0 , gc[i].bytes.length);
+ }
+ return classes;
+ }
+}
From b2e43ed612c42a451c28028f9be07bcf65fa1249 Mon Sep 17 00:00:00 2001
From: Serguei Spitsyn
Date: Thu, 23 May 2013 23:04:33 -0700
Subject: [PATCH 046/206] 8014288: perf regression in nashorn JDK-8008448.js
test after 8008511 changes
The fix of perf regression is to use method_idnum() for direct indexing into NMT
Reviewed-by: twisti, kvn, coleenp, dholmes
---
hotspot/src/share/vm/oops/instanceKlass.cpp | 19 +++++++++--
hotspot/src/share/vm/oops/instanceKlass.hpp | 3 +-
hotspot/src/share/vm/prims/methodHandles.cpp | 34 +++++++-------------
hotspot/src/share/vm/prims/methodHandles.hpp | 11 +++----
4 files changed, 35 insertions(+), 32 deletions(-)
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index b61f595424e..562adaae04a 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -2754,15 +2754,28 @@ nmethod* InstanceKlass::lookup_osr_nmethod(const Method* m, int bci, int comp_le
return NULL;
}
-void InstanceKlass::add_member_name(Handle mem_name) {
+void InstanceKlass::add_member_name(int index, Handle mem_name) {
jweak mem_name_wref = JNIHandles::make_weak_global(mem_name);
MutexLocker ml(MemberNameTable_lock);
+ assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
DEBUG_ONLY(No_Safepoint_Verifier nsv);
if (_member_names == NULL) {
- _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable();
+ _member_names = new (ResourceObj::C_HEAP, mtClass) MemberNameTable(idnum_allocated_count());
}
- _member_names->add_member_name(mem_name_wref);
+ _member_names->add_member_name(index, mem_name_wref);
+}
+
+oop InstanceKlass::get_member_name(int index) {
+ MutexLocker ml(MemberNameTable_lock);
+ assert(0 <= index && index < idnum_allocated_count(), "index is out of bounds");
+ DEBUG_ONLY(No_Safepoint_Verifier nsv);
+
+ if (_member_names == NULL) {
+ return NULL;
+ }
+ oop mem_name =_member_names->get_member_name(index);
+ return mem_name;
}
// -----------------------------------------------------------------------------------------------------
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index 1a370711fd7..e158cdf3cf4 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -1022,7 +1022,8 @@ public:
// JSR-292 support
MemberNameTable* member_names() { return _member_names; }
void set_member_names(MemberNameTable* member_names) { _member_names = member_names; }
- void add_member_name(Handle member_name);
+ void add_member_name(int index, Handle member_name);
+ oop get_member_name(int index);
public:
// JVMTI support
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 58957eed067..bb9da0034e4 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -232,7 +232,8 @@ oop MethodHandles::init_method_MemberName(Handle mname, Method* m, bool do_dispa
// This is done eagerly, since it is readily available without
// constructing any new objects.
// TO DO: maybe intern mname_oop
- m->method_holder()->add_member_name(mname);
+ m->method_holder()->add_member_name(m->method_idnum(), mname);
+
return mname();
}
@@ -301,7 +302,6 @@ oop MethodHandles::init_field_MemberName(Handle mname, KlassHandle field_holder,
// Although the fieldDescriptor::_index would also identify the field,
// we do not use it, because it is harder to decode.
// TO DO: maybe intern mname_oop
- InstanceKlass::cast(field_holder())->add_member_name(mname);
return mname();
}
@@ -943,7 +943,8 @@ int MethodHandles::find_MemberNames(KlassHandle k,
// MemberNameTable
//
-MemberNameTable::MemberNameTable() : GrowableArray(10, true) {
+MemberNameTable::MemberNameTable(int methods_cnt)
+ : GrowableArray(methods_cnt, true) {
assert_locked_or_safepoint(MemberNameTable_lock);
}
@@ -957,29 +958,18 @@ MemberNameTable::~MemberNameTable() {
}
}
-// Return entry index if found, return -1 otherwise.
-int MemberNameTable::find_member_name(oop mem_name) {
+void MemberNameTable::add_member_name(int index, jweak mem_name_wref) {
assert_locked_or_safepoint(MemberNameTable_lock);
- int len = this->length();
-
- for (int idx = 0; idx < len; idx++) {
- jweak ref = this->at(idx);
- oop entry = JNIHandles::resolve(ref);
- if (entry == mem_name) {
- return idx;
- }
- }
- return -1;
+ this->at_put_grow(index, mem_name_wref);
}
-void MemberNameTable::add_member_name(jweak mem_name_wref) {
+// Return a member name oop or NULL.
+oop MemberNameTable::get_member_name(int index) {
assert_locked_or_safepoint(MemberNameTable_lock);
- oop mem_name = JNIHandles::resolve(mem_name_wref);
- // Each member name may appear just once: add only if not found
- if (find_member_name(mem_name) == -1) {
- this->append(mem_name_wref);
- }
+ jweak ref = this->at(index);
+ oop mem_name = JNIHandles::resolve(ref);
+ return mem_name;
}
#if INCLUDE_JVMTI
diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp
index f01a3c9fc1b..50ce7af86ea 100644
--- a/hotspot/src/share/vm/prims/methodHandles.hpp
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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
@@ -219,7 +219,6 @@ public:
}
};
-
//------------------------------------------------------------------------------
// MethodHandlesAdapterGenerator
//
@@ -233,13 +232,13 @@ public:
//------------------------------------------------------------------------------
// MemberNameTable
//
+
class MemberNameTable : public GrowableArray {
public:
- MemberNameTable();
+ MemberNameTable(int methods_cnt);
~MemberNameTable();
- void add_member_name(jweak mem_name_ref);
- private:
- int find_member_name(oop mem_name);
+ void add_member_name(int index, jweak mem_name_ref);
+ oop get_member_name(int index);
#if INCLUDE_JVMTI
public:
From cdf1276490361a4d1394edfc304da5a89fab9fde Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?=
Date: Fri, 24 May 2013 13:54:18 +0200
Subject: [PATCH 047/206] 8011630: JSON parsing performance issue
Reviewed-by: lagergren, sundar
---
.../internal/objects/NativeArguments.java | 5 +
.../internal/runtime/AccessorProperty.java | 116 +++++++++++++---
.../internal/runtime/FindProperty.java | 19 +++
.../nashorn/internal/runtime/Property.java | 20 +++
.../internal/runtime/ScriptObject.java | 124 ++----------------
.../internal/runtime/SetMethodCreator.java | 9 +-
.../runtime/UserAccessorProperty.java | 78 ++++++++++-
7 files changed, 231 insertions(+), 140 deletions(-)
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
index afc2b57e090..efab674b1df 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java
@@ -603,6 +603,11 @@ public final class NativeArguments extends ScriptObject {
}
}
+ @Override
+ public Object getLength() {
+ return length;
+ }
+
private Object getArgumentsLength() {
return length;
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
index 38effdafd55..c3bfa697850 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
@@ -75,7 +75,23 @@ public class AccessorProperty extends Property {
private static final MethodType[] ACCESSOR_GETTER_TYPES = new MethodType[NOOF_TYPES];
private static final MethodType[] ACCESSOR_SETTER_TYPES = new MethodType[NOOF_TYPES];
- private static final MethodHandle SPILLGETTER = MH.asType(MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class), Lookup.GET_OBJECT_TYPE);
+ private static final MethodHandle SPILL_ELEMENT_GETTER;
+ private static final MethodHandle SPILL_ELEMENT_SETTER;
+
+ private static final int SPILL_CACHE_SIZE = 8;
+ private static final MethodHandle[] SPILL_ACCESSORS = new MethodHandle[SPILL_CACHE_SIZE * 2];
+
+ static {
+ for (int i = 0; i < NOOF_TYPES; i++) {
+ final Type type = ACCESSOR_TYPES.get(i);
+ ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
+ ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
+ }
+
+ final MethodHandle spillGetter = MH.getter(MethodHandles.lookup(), ScriptObject.class, "spill", Object[].class);
+ SPILL_ELEMENT_GETTER = MH.filterArguments(MH.arrayElementGetter(Object[].class), 0, spillGetter);
+ SPILL_ELEMENT_SETTER = MH.filterArguments(MH.arrayElementSetter(Object[].class), 0, spillGetter);
+ }
/** Seed getter for the primitive version of this field (in -Dnashorn.fields.dual=true mode) */
private MethodHandle primitiveGetter;
@@ -96,14 +112,6 @@ public class AccessorProperty extends Property {
*/
private Class> currentType;
- static {
- for (int i = 0; i < NOOF_TYPES; i++) {
- final Type type = ACCESSOR_TYPES.get(i);
- ACCESSOR_GETTER_TYPES[i] = MH.type(type.getTypeClass(), Object.class);
- ACCESSOR_SETTER_TYPES[i] = MH.type(void.class, Object.class, type.getTypeClass());
- }
- }
-
/**
* Delegate constructor. This is used when adding properties to the Global scope, which
* is necessary for outermost levels in a script (the ScriptObject is represented by
@@ -114,18 +122,30 @@ public class AccessorProperty extends Property {
* @param delegate delegate script object to rebind receiver to
*/
public AccessorProperty(final AccessorProperty property, final ScriptObject delegate) {
- this(property);
+ super(property);
- this.getters = new MethodHandle[NOOF_TYPES];
-
- this.primitiveGetter = bindTo(primitiveGetter, delegate);
- this.primitiveSetter = bindTo(primitiveSetter, delegate);
- this.objectGetter = bindTo(objectGetter, delegate);
- this.objectSetter = bindTo(objectSetter, delegate);
+ this.primitiveGetter = bindTo(property.primitiveGetter, delegate);
+ this.primitiveSetter = bindTo(property.primitiveSetter, delegate);
+ this.objectGetter = bindTo(property.objectGetter, delegate);
+ this.objectSetter = bindTo(property.objectSetter, delegate);
setCurrentType(property.getCurrentType());
}
+ /**
+ * Constructor for spill properties. Array getters and setters will be created on demand.
+ *
+ * @param key the property key
+ * @param flags the property flags
+ * @param slot spill slot
+ */
+ public AccessorProperty(final String key, final int flags, final int slot) {
+ super(key, flags, slot);
+ assert (flags & IS_SPILL) == IS_SPILL;
+
+ setCurrentType(Object.class);
+ }
+
/**
* Constructor. Similar to the constructor with both primitive getters and setters, the difference
* here being that only one getter and setter (setter is optional for non writable fields) is given
@@ -267,8 +287,41 @@ public class AccessorProperty extends Property {
return new AccessorProperty(this);
}
+ @Override
+ protected void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
+ if (isSpill()) {
+ self.spill[getSlot()] = value;
+ } else {
+ try {
+ getSetter(Object.class, self.getMap()).invokeExact((Object)self, value);
+ } catch (final Error|RuntimeException e) {
+ throw e;
+ } catch (final Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ @Override
+ protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
+ if (isSpill()) {
+ return self.spill[getSlot()];
+ } else {
+ try {
+ return getGetter(Object.class).invokeExact((Object)self);
+ } catch (final Error|RuntimeException e) {
+ throw e;
+ } catch (final Throwable e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
@Override
public MethodHandle getGetter(final Class> type) {
+ if (isSpill() && objectGetter == null) {
+ objectGetter = getSpillGetter();
+ }
final int i = getAccessorTypeIndex(type);
if (getters[i] == null) {
getters[i] = debug(
@@ -284,7 +337,7 @@ public class AccessorProperty extends Property {
"get");
}
- return isSpill() ? MH.filterArguments(getters[i], 0, SPILLGETTER) : getters[i];
+ return getters[i];
}
private Property getWiderProperty(final Class> type) {
@@ -313,6 +366,9 @@ public class AccessorProperty extends Property {
}
private MethodHandle generateSetter(final Class> forType, final Class> type) {
+ if (isSpill() && objectSetter == null) {
+ objectSetter = getSpillSetter();
+ }
MethodHandle mh = createSetter(forType, type, primitiveSetter, objectSetter);
mh = MH.asType(mh, ACCESSOR_SETTER_TYPES[getAccessorTypeIndex(type)]); //has to be the case for invokeexact to work in ScriptObject
mh = debug(mh, currentType, type, "set");
@@ -343,7 +399,7 @@ public class AccessorProperty extends Property {
mh = generateSetter(forType, type);
}
- return isSpill() ? MH.filterArguments(mh, 0, SPILLGETTER) : mh;
+ return mh;
}
@Override
@@ -363,6 +419,30 @@ public class AccessorProperty extends Property {
setCurrentType(newType);
}
+ private MethodHandle getSpillGetter() {
+ final int slot = getSlot();
+ MethodHandle getter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2] : null;
+ if (getter == null) {
+ getter = MH.asType(MH.insertArguments(SPILL_ELEMENT_GETTER, 1, slot), Lookup.GET_OBJECT_TYPE);
+ if (slot < SPILL_CACHE_SIZE) {
+ SPILL_ACCESSORS[slot * 2] = getter;
+ }
+ }
+ return getter;
+ }
+
+ private MethodHandle getSpillSetter() {
+ final int slot = getSlot();
+ MethodHandle setter = slot < SPILL_CACHE_SIZE ? SPILL_ACCESSORS[slot * 2 + 1] : null;
+ if (setter == null) {
+ setter = MH.asType(MH.insertArguments(SPILL_ELEMENT_SETTER, 1, slot), Lookup.SET_OBJECT_TYPE);
+ if (slot < SPILL_CACHE_SIZE) {
+ SPILL_ACCESSORS[slot * 2 + 1] = setter;
+ }
+ }
+ return setter;
+ }
+
private static void finest(final String str) {
if (DEBUG_FIELDS) {
LOG.finest(str);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
index 903d1d5d524..16165fe9caa 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/FindProperty.java
@@ -153,5 +153,24 @@ public final class FindProperty {
return prototype.isScope();
}
+ /**
+ * Get the property value from self as object.
+ *
+ * @return the property value
+ */
+ public Object getObjectValue() {
+ return property.getObjectValue(getGetterReceiver(), getOwner());
+ }
+
+ /**
+ * Set the property value in self.
+ *
+ * @param value the new value
+ * @param strict strict flag
+ */
+ public void setObjectValue(final Object value, final boolean strict) {
+ property.setObjectValue(getSetterReceiver(), getOwner(), value, strict);
+ }
+
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
index 585fc4b3113..6441b8c4f41 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -351,6 +351,26 @@ public abstract class Property {
return slot;
}
+ /**
+ * Set the value of this property in {@code owner}. This allows to bypass creation of the
+ * setter MethodHandle for spill and user accessor properties.
+ *
+ * @param self the this object
+ * @param owner the owner object
+ * @param value the new property value
+ */
+ protected abstract void setObjectValue(ScriptObject self, ScriptObject owner, Object value, boolean strict);
+
+ /**
+ * Set the Object value of this property from {@code owner}. This allows to bypass creation of the
+ * getter MethodHandle for spill and user accessor properties.
+ *
+ * @param self the this object
+ * @param owner the owner object
+ * @return the property value
+ */
+ protected abstract Object getObjectValue(ScriptObject self, ScriptObject owner);
+
/**
* Abstract method for retrieving the setter for the property. We do not know
* anything about the internal representation when we request the setter, we only
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
index 61cce7b127a..cf89c545f98 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java
@@ -25,7 +25,6 @@
package jdk.nashorn.internal.runtime;
-import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCall;
import static jdk.nashorn.internal.codegen.CompilerConstants.virtualCallNoLookup;
import static jdk.nashorn.internal.lookup.Lookup.MH;
@@ -151,17 +150,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
/** Method handle for setting the user accessors of a ScriptObject */
public static final Call SET_USER_ACCESSORS = virtualCall(ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
- /** Method handle for getter for {@link UserAccessorProperty}, given a slot */
- static final Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), ScriptObject.class, "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
-
- /** Method handle for setter for {@link UserAccessorProperty}, given a slot */
- static final Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), ScriptObject.class, "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
-
- private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
- Object.class, Object.class);
- private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
- Object.class, Object.class, Object.class);
-
/**
* Constructor
*/
@@ -699,17 +687,9 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @return New property.
*/
public final Property addOwnProperty(final String key, final int propertyFlags, final Object value) {
- final MethodHandle setter = addSpill(key, propertyFlags);
-
- try {
- setter.invokeExact((Object)this, value);
- } catch (final Error|RuntimeException e) {
- throw e;
- } catch (final Throwable e) {
- throw new RuntimeException(e);
- }
-
- return getMap().findProperty(key);
+ final Property property = addSpillProperty(key, propertyFlags);
+ property.setObjectValue(this, this, value, false);
+ return property;
}
/**
@@ -744,15 +724,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
// Erase the property field value with undefined. If the property is defined
// by user-defined accessors, we don't want to call the setter!!
if (!(property instanceof UserAccessorProperty)) {
- try {
- // make the property value to be undefined
- //TODO specproperties
- property.getSetter(Object.class, getMap()).invokeExact((Object)this, (Object)UNDEFINED);
- } catch (final RuntimeException | Error e) {
- throw e;
- } catch (final Throwable t) {
- throw new RuntimeException(t);
- }
+ property.setObjectValue(this, this, UNDEFINED, false);
}
}
@@ -948,18 +920,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
* @return the value of the property
*/
protected static Object getObjectValue(final FindProperty find) {
- final MethodHandle getter = find.getGetter(Object.class);
- if (getter != null) {
- try {
- return getter.invokeExact((Object)find.getGetterReceiver());
- } catch (final Error|RuntimeException e) {
- throw e;
- } catch (final Throwable e) {
- throw new RuntimeException(e);
- }
- }
-
- return UNDEFINED;
+ return find.getObjectValue();
}
/**
@@ -2087,11 +2048,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
property = addOwnProperty(property);
} else {
int i = getMap().getSpillLength();
- MethodHandle getter = MH.arrayElementGetter(Object[].class);
- MethodHandle setter = MH.arrayElementSetter(Object[].class);
- getter = MH.asType(MH.insertArguments(getter, 1, i), Lookup.GET_OBJECT_TYPE);
- setter = MH.asType(MH.insertArguments(setter, 1, i), Lookup.SET_OBJECT_TYPE);
- property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i, getter, setter);
+ property = new AccessorProperty(key, propertyFlags | Property.IS_SPILL, i);
notifyPropertyAdded(this, property);
property = addOwnProperty(property);
i = property.getSlot();
@@ -2115,20 +2072,15 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
/**
* Add a spill entry for the given key.
- * @param key Property key.
- * @param propertyFlags Property flags.
+ * @param key Property key.
* @return Setter method handle.
*/
- private MethodHandle addSpill(final String key, final int propertyFlags) {
- final Property spillProperty = addSpillProperty(key, propertyFlags);
+ MethodHandle addSpill(final String key) {
+ final Property spillProperty = addSpillProperty(key, 0);
final Class> type = Object.class;
return spillProperty.getSetter(type, getMap()); //TODO specfields
}
- MethodHandle addSpill(final String key) {
- return addSpill(key, 0);
- }
-
/**
* Make sure arguments are paired correctly, with respect to more parameters than declared,
* fewer parameters than declared and other things that JavaScript allows. This might involve
@@ -2659,14 +2611,8 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
return;
}
- try {
- final MethodHandle setter = f.getSetter(Object.class, strict); //TODO specfields
- setter.invokeExact((Object)f.getSetterReceiver(), value);
- } catch (final Error|RuntimeException e) {
- throw e;
- } catch (final Throwable e) {
- throw new RuntimeException(e);
- }
+ f.setObjectValue(value, strict);
+
} else if (!isExtensible()) {
if (strict) {
throw typeError("object.non.extensible", key, ScriptRuntime.safeToString(this));
@@ -2677,13 +2623,7 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
}
private void spill(final String key, final Object value) {
- try {
- addSpill(key).invokeExact((Object)this, value);
- } catch (final Error|RuntimeException e) {
- throw e;
- } catch (final Throwable e) {
- throw new RuntimeException(e);
- }
+ addSpillProperty(key, 0).setObjectValue(this, this, value, false);
}
@@ -3217,46 +3157,6 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
return (index < 0 || (index >= spill.length)) ? null : spill[index];
}
- // User defined getter and setter are always called by "dyn:call". Note that the user
- // getter/setter may be inherited. If so, proto is bound during lookup. In either
- // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
- // to be called is retrieved everytime and applied.
- @SuppressWarnings("unused")
- private static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
- final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
- final Object func = container.getSpill(slot);
-
- if (func instanceof ScriptFunction) {
- try {
- return INVOKE_UA_GETTER.invokeExact(func, self);
- } catch(final Error|RuntimeException t) {
- throw t;
- } catch(final Throwable t) {
- throw new RuntimeException(t);
- }
- }
-
- return UNDEFINED;
- }
-
- @SuppressWarnings("unused")
- private static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
- final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
- final Object func = container.getSpill(slot);
-
- if (func instanceof ScriptFunction) {
- try {
- INVOKE_UA_SETTER.invokeExact(func, self, value);
- } catch(final Error|RuntimeException t) {
- throw t;
- } catch(final Throwable t) {
- throw new RuntimeException(t);
- }
- } else if (name != null) {
- throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
- }
- }
-
private static MethodHandle findOwnMH(final String name, final Class> rtype, final Class>... types) {
final Class> own = ScriptObject.class;
final MethodType mt = MH.type(rtype, types);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
index 5ff321fc9a0..a6dfce0f5fd 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/SetMethodCreator.java
@@ -183,17 +183,10 @@ final class SetMethodCreator {
private SetMethod createNewSpillPropertySetter() {
final int nextSpill = getMap().getSpillLength();
- final Property property = createSpillProperty(nextSpill);
+ final Property property = new AccessorProperty(getName(), Property.IS_SPILL, nextSpill);
return new SetMethod(createSpillMethodHandle(nextSpill, property), property);
}
- private Property createSpillProperty(final int nextSpill) {
- final MethodHandle getter = MH.asType(MH.insertArguments(MH.arrayElementGetter(Object[].class), 1, nextSpill), Lookup.GET_OBJECT_TYPE);
- final MethodHandle setter = MH.asType(MH.insertArguments(MH.arrayElementSetter(Object[].class), 1, nextSpill), Lookup.SET_OBJECT_TYPE);
-
- return new AccessorProperty(getName(), Property.IS_SPILL, nextSpill, getter, setter);
- }
-
private MethodHandle createSpillMethodHandle(final int nextSpill, Property property) {
final PropertyMap oldMap = getMap();
final PropertyMap newMap = getNewMap(property);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
index 75c285a6fc8..fac505ceff5 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
@@ -26,7 +26,15 @@
package jdk.nashorn.internal.runtime;
import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+
+import jdk.nashorn.internal.codegen.CompilerConstants;
import jdk.nashorn.internal.lookup.Lookup;
+import jdk.nashorn.internal.runtime.linker.Bootstrap;
+
+import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
+import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import static jdk.nashorn.internal.runtime.ScriptRuntime.UNDEFINED;
/**
* Property with user defined getters/setters. Actual getter and setter
@@ -51,6 +59,22 @@ public final class UserAccessorProperty extends Property {
/** User defined setter function slot. */
private final int setterSlot;
+ /** Getter method handle */
+ private final static CompilerConstants.Call USER_ACCESSOR_GETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
+ "userAccessorGetter", Object.class, ScriptObject.class, int.class, Object.class);
+
+ /** Setter method handle */
+ private final static CompilerConstants.Call USER_ACCESSOR_SETTER = staticCall(MethodHandles.lookup(), UserAccessorProperty.class,
+ "userAccessorSetter", void.class, ScriptObject.class, int.class, String.class, Object.class, Object.class);
+
+ /** Dynamic invoker for getter */
+ private static final MethodHandle INVOKE_UA_GETTER = Bootstrap.createDynamicInvoker("dyn:call", Object.class,
+ Object.class, Object.class);
+
+ /** Dynamic invoker for setter */
+ private static final MethodHandle INVOKE_UA_SETTER = Bootstrap.createDynamicInvoker("dyn:call", void.class,
+ Object.class, Object.class, Object.class);
+
/**
* Constructor
*
@@ -133,9 +157,19 @@ public final class UserAccessorProperty extends Property {
return setterSlot > -1;
}
+ @Override
+ protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
+ return userAccessorGetter(owner, getGetterSlot(), self);
+ }
+
+ @Override
+ protected void setObjectValue(final ScriptObject self, final ScriptObject owner, final Object value, final boolean strict) {
+ userAccessorSetter(owner, getSetterSlot(), strict ? getKey() : null, self, value);
+ }
+
@Override
public MethodHandle getGetter(final Class> type) {
- return Lookup.filterReturnType(ScriptObject.USER_ACCESSOR_GETTER.methodHandle(), type);
+ return Lookup.filterReturnType(USER_ACCESSOR_GETTER.methodHandle(), type);
}
@Override
@@ -146,7 +180,7 @@ public final class UserAccessorProperty extends Property {
@Override
public MethodHandle getSetter(final Class> type, final PropertyMap currentMap) {
- return ScriptObject.USER_ACCESSOR_SETTER.methodHandle();
+ return USER_ACCESSOR_SETTER.methodHandle();
}
@Override
@@ -155,4 +189,44 @@ public final class UserAccessorProperty extends Property {
return (value instanceof ScriptFunction) ? (ScriptFunction) value : null;
}
+ // User defined getter and setter are always called by "dyn:call". Note that the user
+ // getter/setter may be inherited. If so, proto is bound during lookup. In either
+ // inherited or self case, slot is also bound during lookup. Actual ScriptFunction
+ // to be called is retrieved everytime and applied.
+ @SuppressWarnings("unused")
+ static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
+ final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
+ final Object func = container.getSpill(slot);
+
+ if (func instanceof ScriptFunction) {
+ try {
+ return INVOKE_UA_GETTER.invokeExact(func, self);
+ } catch(final Error|RuntimeException t) {
+ throw t;
+ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ }
+
+ return UNDEFINED;
+ }
+
+ @SuppressWarnings("unused")
+ static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
+ final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
+ final Object func = container.getSpill(slot);
+
+ if (func instanceof ScriptFunction) {
+ try {
+ INVOKE_UA_SETTER.invokeExact(func, self, value);
+ } catch(final Error|RuntimeException t) {
+ throw t;
+ } catch(final Throwable t) {
+ throw new RuntimeException(t);
+ }
+ } else if (name != null) {
+ throw typeError("property.has.no.setter", name, ScriptRuntime.safeToString(self));
+ }
+ }
+
}
From f86162c90c62fe002c7760f1d1afe03812cdcd4d Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Fri, 24 May 2013 18:39:25 +0530
Subject: [PATCH 048/206] 8015354: JSON.parse should not use [[Put]] but use
[[DefineOwnProperty]] instead
Reviewed-by: lagergren, hannesw
---
.../internal/objects/NativeFloat32Array.java | 3 ++
.../internal/objects/NativeFloat64Array.java | 3 ++
.../internal/objects/NativeInt16Array.java | 3 ++
.../internal/objects/NativeInt32Array.java | 3 ++
.../internal/objects/NativeInt8Array.java | 3 ++
.../internal/objects/NativeUint16Array.java | 3 ++
.../internal/objects/NativeUint32Array.java | 3 ++
.../internal/objects/NativeUint8Array.java | 3 ++
.../objects/NativeUint8ClampedArray.java | 3 ++
.../internal/runtime/JSONFunctions.java | 25 ++++++++--
.../nashorn/internal/runtime/Property.java | 2 +
nashorn/test/script/basic/JDK-8015354.js | 46 +++++++++++++++++++
12 files changed, 97 insertions(+), 3 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8015354.js
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
index 33d2d9ecc5d..d59a4d6fdb9 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat32Array.java
@@ -40,6 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Float32Array")
public final class NativeFloat32Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 4;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
index ba6bffe8c38..0f10a867d81 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeFloat64Array.java
@@ -40,6 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Float64Array")
public final class NativeFloat64Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 8;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
index 9afaf3a7ea0..d6c5349efd5 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt16Array.java
@@ -39,6 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Int16Array")
public final class NativeInt16Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 2;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
index 199d223d25d..a814eb61de1 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt32Array.java
@@ -39,6 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Int32Array")
public final class NativeInt32Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 4;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
index 25e86c23d35..ec43bfc8e18 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeInt8Array.java
@@ -39,6 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Int8Array")
public final class NativeInt8Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 1;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
index ec5e99d3718..13ce347461e 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint16Array.java
@@ -39,6 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint16Array")
public final class NativeUint16Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 2;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
index d8a3f5240f4..fb45c2821be 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint32Array.java
@@ -40,6 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint32Array")
public final class NativeUint32Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 4;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
index d62818a912b..6cebcdb9c5f 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8Array.java
@@ -39,6 +39,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint8Array")
public final class NativeUint8Array extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 1;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
index 7eb3e650714..de171caa8a4 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeUint8ClampedArray.java
@@ -40,6 +40,9 @@ import jdk.nashorn.internal.runtime.arrays.ArrayData;
*/
@ScriptClass("Uint8ClampedArray")
public final class NativeUint8ClampedArray extends ArrayBufferView {
+ /**
+ * The size in bytes of each element in the array.
+ */
@Property(attributes = Attribute.NOT_ENUMERABLE | Attribute.NOT_WRITABLE | Attribute.NOT_CONFIGURABLE, where = Where.CONSTRUCTOR)
public static final int BYTES_PER_ELEMENT = 1;
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
index 6106a314da2..ed4d8653425 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSONFunctions.java
@@ -36,6 +36,8 @@ import jdk.nashorn.internal.ir.UnaryNode;
import jdk.nashorn.internal.parser.JSONParser;
import jdk.nashorn.internal.parser.TokenType;
import jdk.nashorn.internal.runtime.linker.Bootstrap;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.getArrayIndexNoThrow;
+import static jdk.nashorn.internal.runtime.arrays.ArrayIndex.isValidArrayIndex;
/**
* Utilities used by "JSON" object implementation.
@@ -94,7 +96,7 @@ public final class JSONFunctions {
if (reviver instanceof ScriptFunction) {
assert global instanceof GlobalObject;
final ScriptObject root = ((GlobalObject)global).newObject();
- root.set("", unfiltered, root.isStrictContext());
+ root.addOwnProperty("", Property.WRITABLE_ENUMERABLE_CONFIGURABLE, unfiltered);
return walk(root, "", (ScriptFunction)reviver);
}
return unfiltered;
@@ -115,7 +117,7 @@ public final class JSONFunctions {
if (newElement == ScriptRuntime.UNDEFINED) {
valueObj.delete(key, strict);
} else {
- valueObj.set(key, newElement, strict);
+ setPropertyValue(valueObj, key, newElement, strict);
}
}
}
@@ -175,7 +177,9 @@ public final class JSONFunctions {
final PropertyNode pNode = (PropertyNode) elem;
final Node valueNode = pNode.getValue();
- object.set(pNode.getKeyName(), convertNode(global, valueNode), strict);
+ final String name = pNode.getKeyName();
+ final Object value = convertNode(global, valueNode);
+ setPropertyValue(object, name, value, strict);
}
return object;
@@ -188,6 +192,21 @@ public final class JSONFunctions {
}
}
+ // add a new property if does not exist already, or else set old property
+ private static void setPropertyValue(final ScriptObject sobj, final String name, final Object value, final boolean strict) {
+ final int index = getArrayIndexNoThrow(name);
+ if (isValidArrayIndex(index)) {
+ // array index key
+ sobj.defineOwnProperty(index, value);
+ } else if (sobj.getMap().findProperty(name) != null) {
+ // pre-existing non-inherited property, call set
+ sobj.set(name, value, strict);
+ } else {
+ // add new property
+ sobj.addOwnProperty(name, Property.WRITABLE_ENUMERABLE_CONFIGURABLE, value);
+ }
+ }
+
// does the given IR node represent a numeric array?
private static boolean isNumericArray(final Node[] values) {
for (final Node node : values) {
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
index 6441b8c4f41..433bc2c3048 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -52,6 +52,8 @@ public abstract class Property {
* we can use leave flag byte initialized with (the default) zero value.
*/
+ 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;
diff --git a/nashorn/test/script/basic/JDK-8015354.js b/nashorn/test/script/basic/JDK-8015354.js
new file mode 100644
index 00000000000..3cbe676e8b9
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015354.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015354: JSON.parse should not use [[Put]] but use [[DefineOwnProperty]] instead
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(Object.prototype,
+ "", {
+ set: function(v) {
+ throw "set called";
+ }
+});
+
+JSON.parse('{}',function(){});
+
+Object.defineProperty(Object.prototype,
+ "foo",{
+ set: function(v) {
+ throw "set called";
+ }
+});
+JSON.parse('{"foo": 1}');
From 372fabc4763c2f59ce2fbe4045b9c15fdd44102d Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Fri, 24 May 2013 15:26:57 +0100
Subject: [PATCH 049/206] 8014643: Parser regression in JDK 8 when compiling
super.x
Fixed latent bug in JavacParser.analyzeParens()
Reviewed-by: jjg, vromero
---
.../sun/tools/javac/parser/JavacParser.java | 11 ++++-
.../tools/javac/parser/8014643/T8014643.java | 41 +++++++++++++++++++
2 files changed, 50 insertions(+), 2 deletions(-)
create mode 100644 langtools/test/tools/javac/parser/8014643/T8014643.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
index bdd79d04392..5b5ba0bb3f3 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/parser/JavacParser.java
@@ -1535,11 +1535,18 @@ public class JavacParser implements Parser {
outer: for (int lookahead = 0 ; ; lookahead++) {
TokenKind tk = S.token(lookahead).kind;
switch (tk) {
- case EXTENDS: case SUPER: case COMMA:
+ case COMMA:
type = true;
- case QUES: case DOT: case AMP:
+ case EXTENDS: case SUPER: case DOT: case AMP:
//skip
break;
+ case QUES:
+ if (peekToken(lookahead, EXTENDS) ||
+ peekToken(lookahead, SUPER)) {
+ //wildcards
+ type = true;
+ }
+ break;
case BYTE: case SHORT: case INT: case LONG: case FLOAT:
case DOUBLE: case BOOLEAN: case CHAR:
if (peekToken(lookahead, RPAREN)) {
diff --git a/langtools/test/tools/javac/parser/8014643/T8014643.java b/langtools/test/tools/javac/parser/8014643/T8014643.java
new file mode 100644
index 00000000000..ab4eaf2c99c
--- /dev/null
+++ b/langtools/test/tools/javac/parser/8014643/T8014643.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8014643
+ * @summary Parser regression in JDK 8 when compiling super.x
+ * @compile T8014643.java
+ */
+class T8014643 {
+
+ static class A {
+ int b = 1;
+ }
+
+ static class B extends A {
+ int b = 12;
+
+ int m() { return (super.b); }
+ }
+}
From 9d588c1a23d9eb6d779c052e9f5c68efc7216226 Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Fri, 24 May 2013 15:27:12 +0100
Subject: [PATCH 050/206] 8014649: Regression: bug in Resolve.resolveOperator
Missing curly braces causes Resolve.findMethod to be called spuriously
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Resolve.java | 32 +++++----
.../tools/javac/resolve/ResolveHarness.java | 49 +++++++++++--
.../resolve/tests/PrimitiveBinopOverload.java | 71 +++++++++++++++++++
3 files changed, 134 insertions(+), 18 deletions(-)
create mode 100644 langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index de949a7a243..09b1d4c92f2 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -1343,7 +1343,7 @@ public class Resolve {
try {
Type mt = rawInstantiate(env, site, sym, null, argtypes, typeargtypes,
allowBoxing, useVarargs, types.noWarnings);
- if (!operator)
+ if (!operator || verboseResolutionMode.contains(VerboseResolutionMode.PREDEF))
currentResolutionContext.addApplicableCandidate(sym, mt);
} catch (InapplicableMethodException ex) {
if (!operator)
@@ -2500,17 +2500,21 @@ public class Resolve {
try {
currentResolutionContext = new MethodResolutionContext();
Name name = treeinfo.operatorName(optag);
- env.info.pendingResolutionPhase = currentResolutionContext.step = BASIC;
- Symbol sym = findMethod(env, syms.predefClass.type, name, argtypes,
- null, false, false, true);
- if (boxingEnabled && sym.kind >= WRONG_MTHS)
- env.info.pendingResolutionPhase = currentResolutionContext.step = BOX;
- sym = findMethod(env, syms.predefClass.type, name, argtypes,
- null, true, false, true);
- return accessMethod(sym, pos, env.enclClass.sym.type, name,
+ return lookupMethod(env, pos, syms.predefClass, currentResolutionContext,
+ new BasicLookupHelper(name, syms.predefClass.type, argtypes, null, BOX) {
+ @Override
+ Symbol lookup(Env env, MethodResolutionPhase phase) {
+ return findMethod(env, site, name, argtypes, typeargtypes,
+ phase.isBoxingRequired(),
+ phase.isVarargsRequired(), true);
+ }
+ @Override
+ Symbol access(Env env, DiagnosticPosition pos, Symbol location, Symbol sym) {
+ return accessMethod(sym, pos, env.enclClass.sym.type, name,
false, argtypes, null);
- }
- finally {
+ }
+ });
+ } finally {
currentResolutionContext = prevResolutionContext;
}
}
@@ -2673,7 +2677,11 @@ public class Resolve {
abstract class BasicLookupHelper extends LookupHelper {
BasicLookupHelper(Name name, Type site, List argtypes, List typeargtypes) {
- super(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
+ this(name, site, argtypes, typeargtypes, MethodResolutionPhase.VARARITY);
+ }
+
+ BasicLookupHelper(Name name, Type site, List argtypes, List typeargtypes, MethodResolutionPhase maxPhase) {
+ super(name, site, argtypes, typeargtypes, maxPhase);
}
@Override
diff --git a/langtools/test/tools/javac/resolve/ResolveHarness.java b/langtools/test/tools/javac/resolve/ResolveHarness.java
index b9998f05eeb..8db063cdf09 100644
--- a/langtools/test/tools/javac/resolve/ResolveHarness.java
+++ b/langtools/test/tools/javac/resolve/ResolveHarness.java
@@ -43,6 +43,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
+import java.util.Locale;
import java.util.Map;
import javax.annotation.processing.AbstractProcessor;
@@ -85,6 +86,7 @@ public class ResolveHarness implements javax.tools.DiagnosticListener declaredKeys = new HashSet<>();
List> diags = new ArrayList<>();
List seenCandidates = new ArrayList<>();
+ Map predefTranslationMap = new HashMap<>();
protected ResolveHarness(JavaFileObject jfo) {
this.jfo = jfo;
@@ -93,12 +95,36 @@ public class ResolveHarness implements javax.tools.DiagnosticListener>", "_rshift");
+ predefTranslationMap.put("<<<", "_lshiftshift");
+ predefTranslationMap.put(">>>", "_rshiftshift");
+ predefTranslationMap.put("<", "_lt");
+ predefTranslationMap.put(">", "_gt");
+ predefTranslationMap.put("<=", "_lteq");
+ predefTranslationMap.put(">=", "_gteq");
+ predefTranslationMap.put("==", "_eq");
+ predefTranslationMap.put("!=", "_neq");
+ predefTranslationMap.put("&&", "_andand");
+ predefTranslationMap.put("||", "_oror");
}
protected void check() throws Exception {
String[] options = {
"-XDshouldStopPolicy=ATTR",
- "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference"
+ "-XDverboseResolution=success,failure,applicable,inapplicable,deferred-inference,predef"
};
AbstractProcessor[] processors = { new ResolveCandidateFinder(), null };
@@ -223,7 +249,8 @@ public class ResolveHarness implements javax.tools.DiagnosticListener diagnostic) {
Element siteSym = getSiteSym(diagnostic);
- if (siteSym.getAnnotation(TraceResolve.class) == null) {
+ if (siteSym.getSimpleName().length() != 0 &&
+ siteSym.getAnnotation(TraceResolve.class) == null) {
return;
}
int candidateIdx = 0;
@@ -307,7 +334,7 @@ public class ResolveHarness implements javax.tools.DiagnosticListener.");
+ String replacedName = predefTranslationMap.get(e.getSimpleName().toString());
+ buf.append(e.toString().replace(e.getSimpleName().toString(), replacedName));
+ } else if (e.getSimpleName().toString().startsWith("_")) {
+ buf.append(".");
buf.append(e.toString());
- e = e.getEnclosingElement();
+ } else {
+ while (e != null) {
+ buf.append(e.toString());
+ e = e.getEnclosingElement();
+ }
+ buf.append(jfo.getName());
}
- buf.append(jfo.getName());
return buf.toString();
}
diff --git a/langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java b/langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java
new file mode 100644
index 00000000000..a66da7e8670
--- /dev/null
+++ b/langtools/test/tools/javac/resolve/tests/PrimitiveBinopOverload.java
@@ -0,0 +1,71 @@
+/*
+ * 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.
+ */
+
+@TraceResolve
+class PrimitiveBinopOverload {
+
+ @Candidate(applicable=Phase.BASIC, mostSpecific=true)
+ int _plus(int x, int y) { return -1; }
+ @Candidate(applicable=Phase.BASIC)
+ long _plus(long x, long y) { return -1; }
+ @Candidate(applicable=Phase.BASIC)
+ float _plus(float x, float y) { return -1; }
+ @Candidate(applicable=Phase.BASIC)
+ double _plus(double x, double y) { return -1; }
+ //not a candidate
+ Object _plus(Object x, Object y) { return -1; }
+
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
+ int _minus(int x, int y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ long _minus(long x, long y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ float _minus(float x, float y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ double _minus(double x, double y) { return -1; }
+
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
+ int _mul(int x, int y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ long _mul(long x, long y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ float _mul(float x, float y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ double _mul(double x, double y) { return -1; }
+
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX }, mostSpecific=true)
+ int _div(int x, int y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ long _div(long x, long y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ float _div(float x, float y) { return -1; }
+ @Candidate(applicable= { Phase.BASIC, Phase.BOX })
+ double _div(double x, double y) { return -1; }
+
+ {
+ int i1 = 1 + 1;
+ int i2 = 5 - new Integer(3);
+ int i3 = new Integer(5) * 3;
+ int i4 = new Integer(6) / new Integer(2);
+ }
+}
From d176f2abdf9b99693e80996dc4742faee1d820be Mon Sep 17 00:00:00 2001
From: Maurizio Cimadamore
Date: Fri, 24 May 2013 15:27:27 +0100
Subject: [PATCH 051/206] 8014494: javac crashes when varargs element of a
method reference is inferred from the context
Varargs element is not refreshed after type-inference
Reviewed-by: jjg, vromero
---
.../com/sun/tools/javac/comp/Attr.java | 2 +-
.../com/sun/tools/javac/comp/Check.java | 16 ++++++-
.../test/tools/javac/lambda/TargetType73.java | 47 +++++++++++++++++++
3 files changed, 62 insertions(+), 3 deletions(-)
create mode 100644 langtools/test/tools/javac/lambda/TargetType73.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 bff462f8f29..98195d2622a 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
@@ -3732,7 +3732,7 @@ public class Attr extends JCTree.Visitor {
noteWarner);
return chk.checkMethod(owntype, sym, env, argtrees, argtypes, env.info.lastResolveVarargs(),
- noteWarner.hasNonSilentLint(LintCategory.UNCHECKED));
+ noteWarner.hasNonSilentLint(LintCategory.UNCHECKED), resultInfo.checkContext.inferenceContext());
} catch (Infer.InferenceException ex) {
//invalid target type - propagate exception outwards or report error
//depending on the current check context
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index cd550d6edaf..dad29a3a016 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -853,7 +853,8 @@ public class Check {
final List argtrees,
List argtypes,
boolean useVarargs,
- boolean unchecked) {
+ boolean unchecked,
+ InferenceContext inferenceContext) {
// System.out.println("call : " + env.tree);
// System.out.println("method : " + owntype);
// System.out.println("actuals: " + argtypes);
@@ -917,7 +918,7 @@ public class Check {
argtype);
}
if (!((MethodSymbol)sym.baseSymbol()).isSignaturePolymorphic(types)) {
- TreeInfo.setVarargsElement(env.tree, types.elemtype(argtype));
+ setVarargsElement(env, types.elemtype(argtype), inferenceContext);
}
}
PolyKind pkind = (sym.type.hasTag(FORALL) &&
@@ -927,6 +928,17 @@ public class Check {
return owntype;
}
//where
+ private void setVarargsElement(final Env env, final Type elemtype, InferenceContext inferenceContext) {
+ if (inferenceContext.free(elemtype)) {
+ inferenceContext.addFreeTypeListener(List.of(elemtype), new FreeTypeListener() {
+ public void typesInferred(InferenceContext inferenceContext) {
+ setVarargsElement(env, inferenceContext.asInstType(elemtype), inferenceContext);
+ }
+ });
+ }
+ TreeInfo.setVarargsElement(env.tree, elemtype);
+ }
+
private void assertConvertible(JCTree tree, Type actual, Type formal, Warner warn) {
if (types.isConvertible(actual, formal, warn))
return;
diff --git a/langtools/test/tools/javac/lambda/TargetType73.java b/langtools/test/tools/javac/lambda/TargetType73.java
new file mode 100644
index 00000000000..36e5684387d
--- /dev/null
+++ b/langtools/test/tools/javac/lambda/TargetType73.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8014494
+ * @summary javac crashes when varargs element of a method reference is inferred from the context
+ * @compile TargetType73.java
+ */
+import java.util.List;
+
+class TargetType73 {
+
+ interface Function {
+ Y m(X x);
+ }
+
+ static void test() {
+ m(TargetType73::g);
+ }
+
+ public static List g(T... a) {
+ return null;
+ }
+
+ public static void m(Function zipper) { }
+}
From ddea5b012c37425c1e8d0c97f01c400d733807d0 Mon Sep 17 00:00:00 2001
From: Alejandro Murillo
Date: Fri, 24 May 2013 09:35:10 -0700
Subject: [PATCH 052/206] 8015305: new hotspot build - hs25-b35
Reviewed-by: jcoomes
---
hotspot/make/hotspot_version | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index db74b20d81b..815215f44ec 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -35,7 +35,7 @@ HOTSPOT_VM_COPYRIGHT=Copyright 2013
HS_MAJOR_VER=25
HS_MINOR_VER=0
-HS_BUILD_NUMBER=34
+HS_BUILD_NUMBER=35
JDK_MAJOR_VER=1
JDK_MINOR_VER=8
From 5bf7dac8d724820cbf61c2e4f41c9d30e9159ab3 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Fri, 24 May 2013 23:27:52 +0530
Subject: [PATCH 053/206] 8015351: Nashorn shell does not start with Turkish
locale
Reviewed-by: jlaskey
---
nashorn/make/project.properties | 6 +++++-
.../nashorn/internal/runtime/options/OptionTemplate.java | 3 ++-
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index 9ed8125e14a..839d7486c72 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -214,9 +214,13 @@ test.src.dir=test/src
run.test.xmx=3G
run.test.xms=2G
+run.test.user.language=tr
+run.test.user.country=TR
+
# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
# add '-Dtest.js.outofprocess' to run each test in a new sub-process
-run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8
+run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country}
+
#-XX:+HeapDumpOnOutOfMemoryError -XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
index 16ff04eaa41..30e0401e62e 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.runtime.options;
+import java.util.Locale;
import java.util.TimeZone;
import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
@@ -263,7 +264,7 @@ public class OptionTemplate implements Comparable {
this.params = arg;
break;
case "type":
- this.type = arg.toLowerCase();
+ this.type = arg.toLowerCase(Locale.ROOT);
break;
case "default":
this.defaultValue = arg;
From b4854e299c08c660d2b29188ade282db80ab768d Mon Sep 17 00:00:00 2001
From: Joe Darcy
Date: Fri, 24 May 2013 11:26:17 -0700
Subject: [PATCH 054/206] 8014836: Have GenericDeclaration extend
AnnotatedElement
Reviewed-by: jfranck
---
.../language/model/CoreReflectionFactory.java | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/langtools/src/share/sample/language/model/CoreReflectionFactory.java b/langtools/src/share/sample/language/model/CoreReflectionFactory.java
index e51cff74ee0..033765f2667 100644
--- a/langtools/src/share/sample/language/model/CoreReflectionFactory.java
+++ b/langtools/src/share/sample/language/model/CoreReflectionFactory.java
@@ -439,15 +439,11 @@ public class CoreReflectionFactory {
ReflectionElement getGenericElement();
// Functionality specific to the specialization
-
- // Conceptually should have an override for getSource
- // returning GenericDeclaration, but GenericDeclaration
- // doesn't currently implement AnnotatedElement.
-// /**
-// * {@inheritDoc}
-// */
-// @Override
-// java.lang.reflect.GenericDeclaration getSource();
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ java.lang.reflect.TypeVariable> getSource();
}
/**
@@ -1296,8 +1292,8 @@ public class CoreReflectionFactory {
}
@Override
- public AnnotatedElement getSource() {
- return (AnnotatedElement)source;
+ public java.lang.reflect.TypeVariable> getSource() {
+ return sourceTypeVar;
}
protected java.lang.reflect.TypeVariable> getSourceTypeVar() {
From 7cb20773ad93f884d0398a4f11a3dd80089a02fc Mon Sep 17 00:00:00 2001
From: Calvin Cheung
Date: Fri, 24 May 2013 17:19:56 -0700
Subject: [PATCH 055/206] 8015265: revise the fix for 8007037
Reviewed-by: sspitsyn, dholmes, dcubed
---
hotspot/src/share/vm/oops/constantPool.cpp | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp
index 5c5ae945bda..fe1d7340e47 100644
--- a/hotspot/src/share/vm/oops/constantPool.cpp
+++ b/hotspot/src/share/vm/oops/constantPool.cpp
@@ -1063,9 +1063,10 @@ bool ConstantPool::compare_entry_to(int index1, constantPoolHandle cp2,
int k2 = cp2->invoke_dynamic_name_and_type_ref_index_at(index2);
int i1 = invoke_dynamic_bootstrap_specifier_index(index1);
int i2 = cp2->invoke_dynamic_bootstrap_specifier_index(index2);
- bool match = compare_entry_to(k1, cp2, k2, CHECK_false) &&
- compare_operand_to(i1, cp2, i2, CHECK_false);
- return match;
+ // separate statements and variables because CHECK_false is used
+ bool match_entry = compare_entry_to(k1, cp2, k2, CHECK_false);
+ bool match_operand = compare_operand_to(i1, cp2, i2, CHECK_false);
+ return (match_entry && match_operand);
} break;
case JVM_CONSTANT_String:
From fb0022c7b1d6a9f313451fe311aaed8e62b10583 Mon Sep 17 00:00:00 2001
From: Serguei Spitsyn
Date: Fri, 24 May 2013 17:36:12 -0700
Subject: [PATCH 056/206] 8013945: CMS fatal error: must own lock
MemberNameTable_lock
The "delete mnt" needs to grab MemberNameTable_lock if !SafepointSynchronize::is_at_safepoint()
Reviewed-by: sla, mgerdin, dholmes, jmasa
---
hotspot/src/share/vm/oops/instanceKlass.cpp | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index 562adaae04a..84f1cdd3e6d 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -2320,10 +2320,15 @@ void InstanceKlass::release_C_heap_structures() {
FreeHeap(jmeths);
}
- MemberNameTable* mnt = member_names();
- if (mnt != NULL) {
- delete mnt;
- set_member_names(NULL);
+ // Deallocate MemberNameTable
+ {
+ Mutex* lock_or_null = SafepointSynchronize::is_at_safepoint() ? NULL : MemberNameTable_lock;
+ MutexLockerEx ml(lock_or_null, Mutex::_no_safepoint_check_flag);
+ MemberNameTable* mnt = member_names();
+ if (mnt != NULL) {
+ delete mnt;
+ set_member_names(NULL);
+ }
}
int* indices = methods_cached_itable_indices_acquire();
From 6e76fe0cf24b111e99bcd4cf6efcd1284493eda5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?=
Date: Mon, 27 May 2013 12:26:39 +0200
Subject: [PATCH 057/206] 8015348: RegExp("[") results in StackOverflowError
Reviewed-by: sundar, attila
---
.../runtime/regexp/RegExpScanner.java | 3 ++
nashorn/test/script/basic/JDK-8015348.js | 35 +++++++++++++++++++
.../test/script/basic/JDK-8015348.js.EXPECTED | 1 +
3 files changed, 39 insertions(+)
create mode 100644 nashorn/test/script/basic/JDK-8015348.js
create mode 100644 nashorn/test/script/basic/JDK-8015348.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
index 956a99d7cf4..52829fac099 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/RegExpScanner.java
@@ -868,6 +868,9 @@ final class RegExpScanner extends Scanner {
* \ ClassEscape
*/
private boolean classAtomNoDash() {
+ if (atEOF()) {
+ return false;
+ }
final int startIn = position;
final int startOut = sb.length();
diff --git a/nashorn/test/script/basic/JDK-8015348.js b/nashorn/test/script/basic/JDK-8015348.js
new file mode 100644
index 00000000000..77ff6031c56
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015348.js
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015348: RegExp("[") results in StackOverflowError
+ *
+ * @test
+ * @run
+ */
+
+try {
+ new RegExp('[');
+} catch (error) {
+ print(error.name);
+}
diff --git a/nashorn/test/script/basic/JDK-8015348.js.EXPECTED b/nashorn/test/script/basic/JDK-8015348.js.EXPECTED
new file mode 100644
index 00000000000..8729fc43437
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015348.js.EXPECTED
@@ -0,0 +1 @@
+SyntaxError
From 2ccd92e927b867586bc145495ed924c8eb85f676 Mon Sep 17 00:00:00 2001
From: Stefan Karlsson
Date: Mon, 27 May 2013 15:22:59 +0200
Subject: [PATCH 058/206] 8015268: NPG: 2.5% regression in young GC times on
CRM Sales Opty
Split SystemDictionary and ClassLoaderDataGraph root processing to help load balancing.
Reviewed-by: tschatzl, johnc
---
.../gc_implementation/parallelScavenge/pcTasks.cpp | 3 +++
.../gc_implementation/parallelScavenge/pcTasks.hpp | 3 ++-
.../parallelScavenge/psParallelCompact.cpp | 1 +
.../parallelScavenge/psScavenge.cpp | 1 +
.../gc_implementation/parallelScavenge/psTasks.cpp | 13 +++++++------
.../gc_implementation/parallelScavenge/psTasks.hpp | 7 ++++---
hotspot/src/share/vm/memory/sharedHeap.cpp | 11 +++++++++--
7 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
index ed91fe2588e..fa3cf7bccdc 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.cpp
@@ -120,6 +120,9 @@ void MarkFromRootsTask::do_it(GCTaskManager* manager, uint which) {
case system_dictionary:
SystemDictionary::always_strong_oops_do(&mark_and_push_closure);
+ break;
+
+ case class_loader_data:
ClassLoaderDataGraph::always_strong_oops_do(&mark_and_push_closure, &follow_klass_closure, true);
break;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp
index c79bc7c3a14..f966ccf23e2 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/pcTasks.hpp
@@ -98,7 +98,8 @@ class MarkFromRootsTask : public GCTask {
management = 6,
jvmti = 7,
system_dictionary = 8,
- code_cache = 9
+ class_loader_data = 9,
+ code_cache = 10
};
private:
RootType _root_type;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index d85f5d3e486..3e649ddf702 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -2338,6 +2338,7 @@ void PSParallelCompact::marking_phase(ParCompactionManager* cm,
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::flat_profiler));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::management));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::system_dictionary));
+ q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::class_loader_data));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::jvmti));
q->enqueue(new MarkFromRootsTask(MarkFromRootsTask::code_cache));
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 2a718e4bf6d..72d2df4b91f 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -408,6 +408,7 @@ bool PSScavenge::invoke_no_policy() {
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::flat_profiler));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::management));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::system_dictionary));
+ q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::class_loader_data));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::jvmti));
q->enqueue(new ScavengeRootsTask(ScavengeRootsTask::code_cache));
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
index ccad48f358b..00e466a3ea4 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.cpp
@@ -79,15 +79,16 @@ void ScavengeRootsTask::do_it(GCTaskManager* manager, uint which) {
break;
case system_dictionary:
- {
SystemDictionary::oops_do(&roots_closure);
-
- // Move this to another root_type?
- PSScavengeKlassClosure klass_closure(pm);
- ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
- }
break;
+ case class_loader_data:
+ {
+ PSScavengeKlassClosure klass_closure(pm);
+ ClassLoaderDataGraph::oops_do(&roots_closure, &klass_closure, false);
+ }
+ break;
+
case management:
Management::oops_do(&roots_closure);
break;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp
index 7769fddf7c4..7ae1f8a0c28 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psTasks.hpp
@@ -59,9 +59,10 @@ class ScavengeRootsTask : public GCTask {
object_synchronizer = 4,
flat_profiler = 5,
system_dictionary = 6,
- management = 7,
- jvmti = 8,
- code_cache = 9
+ class_loader_data = 7,
+ management = 8,
+ jvmti = 9,
+ code_cache = 10
};
private:
RootType _root_type;
diff --git a/hotspot/src/share/vm/memory/sharedHeap.cpp b/hotspot/src/share/vm/memory/sharedHeap.cpp
index edc1a670a11..1dfccd0b519 100644
--- a/hotspot/src/share/vm/memory/sharedHeap.cpp
+++ b/hotspot/src/share/vm/memory/sharedHeap.cpp
@@ -45,6 +45,7 @@ enum SH_process_strong_roots_tasks {
SH_PS_FlatProfiler_oops_do,
SH_PS_Management_oops_do,
SH_PS_SystemDictionary_oops_do,
+ SH_PS_ClassLoaderDataGraph_oops_do,
SH_PS_jvmti_oops_do,
SH_PS_StringTable_oops_do,
SH_PS_CodeCache_oops_do,
@@ -173,15 +174,21 @@ void SharedHeap::process_strong_roots(bool activate_scope,
if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) {
if (so & SO_AllClasses) {
SystemDictionary::oops_do(roots);
- ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
} else if (so & SO_SystemClasses) {
SystemDictionary::always_strong_oops_do(roots);
- ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
} else {
fatal("We should always have selected either SO_AllClasses or SO_SystemClasses");
}
}
+ if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) {
+ if (so & SO_AllClasses) {
+ ClassLoaderDataGraph::oops_do(roots, klass_closure, !is_scavenging);
+ } else if (so & SO_SystemClasses) {
+ ClassLoaderDataGraph::always_strong_oops_do(roots, klass_closure, !is_scavenging);
+ }
+ }
+
if (!_process_strong_tasks->is_task_claimed(SH_PS_StringTable_oops_do)) {
if (so & SO_Strings) {
StringTable::oops_do(roots);
From 8b7d3c5d3b514a63b877ad26ececc6bff6415cb8 Mon Sep 17 00:00:00 2001
From: Stefan Karlsson
Date: Mon, 27 May 2013 12:56:34 +0200
Subject: [PATCH 059/206] 8015428: Remove unused CDS support from StringTable
The string in StringTable is not used by CDS anymore. Remove the unnecessary code in preparation for 8015422: Large performance hit when the StringTable is walked twice in Parallel Scavenge
Reviewed-by: pliden, tschatzl, coleenp
---
.../src/share/vm/classfile/symbolTable.cpp | 27 +++++--------------
1 file changed, 7 insertions(+), 20 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
index 5fbd184a421..f4590c62fb5 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
@@ -745,41 +745,28 @@ void StringTable::unlink(BoolObjectClosure* is_alive) {
HashtableEntry** p = the_table()->bucket_addr(i);
HashtableEntry* entry = the_table()->bucket(i);
while (entry != NULL) {
- // Shared entries are normally at the end of the bucket and if we run into
- // a shared entry, then there is nothing more to remove. However, if we
- // have rehashed the table, then the shared entries are no longer at the
- // end of the bucket.
- if (entry->is_shared() && !use_alternate_hashcode()) {
- break;
- }
- assert(entry->literal() != NULL, "just checking");
- if (entry->is_shared() || is_alive->do_object_b(entry->literal())) {
+ assert(!entry->is_shared(), "CDS not used for the StringTable");
+
+ if (is_alive->do_object_b(entry->literal())) {
p = entry->next_addr();
} else {
*p = entry->next();
the_table()->free_entry(entry);
}
- entry = (HashtableEntry*)HashtableEntry::make_ptr(*p);
+ entry = *p;
}
}
}
void StringTable::oops_do(OopClosure* f) {
for (int i = 0; i < the_table()->table_size(); ++i) {
- HashtableEntry** p = the_table()->bucket_addr(i);
HashtableEntry* entry = the_table()->bucket(i);
while (entry != NULL) {
+ assert(!entry->is_shared(), "CDS not used for the StringTable");
+
f->do_oop((oop*)entry->literal_addr());
- // Did the closure remove the literal from the table?
- if (entry->literal() == NULL) {
- assert(!entry->is_shared(), "immutable hashtable entry?");
- *p = entry->next();
- the_table()->free_entry(entry);
- } else {
- p = entry->next_addr();
- }
- entry = (HashtableEntry*)HashtableEntry::make_ptr(*p);
+ entry = entry->next();
}
}
}
From c13149ab8d83abe24a1bb16bf446554f114b6ac3 Mon Sep 17 00:00:00 2001
From: Stefan Karlsson
Date: Mon, 27 May 2013 12:58:42 +0200
Subject: [PATCH 060/206] 8015422: Large performance hit when the StringTable
is walked twice in Parallel Scavenge
Combine the calls to StringTable::unlink and StringTable::oops_do in Parallel Scavenge.
Reviewed-by: pliden, coleenp
---
hotspot/src/share/vm/classfile/symbolTable.cpp | 5 ++++-
hotspot/src/share/vm/classfile/symbolTable.hpp | 5 ++++-
.../vm/gc_implementation/parallelScavenge/psScavenge.cpp | 8 +++-----
3 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
index f4590c62fb5..c78ea2d3576 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
@@ -737,7 +737,7 @@ oop StringTable::intern(const char* utf8_string, TRAPS) {
return result;
}
-void StringTable::unlink(BoolObjectClosure* is_alive) {
+void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f) {
// Readers of the table are unlocked, so we should only be removing
// entries at a safepoint.
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
@@ -748,6 +748,9 @@ void StringTable::unlink(BoolObjectClosure* is_alive) {
assert(!entry->is_shared(), "CDS not used for the StringTable");
if (is_alive->do_object_b(entry->literal())) {
+ if (f != NULL) {
+ f->do_oop((oop*)entry->literal_addr());
+ }
p = entry->next_addr();
} else {
*p = entry->next();
diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp
index a2896382f63..4701e74b553 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp
@@ -272,7 +272,10 @@ public:
// GC support
// Delete pointers to otherwise-unreachable objects.
- static void unlink(BoolObjectClosure* cl);
+ static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f);
+ static void unlink(BoolObjectClosure* cl) {
+ unlink_or_oops_do(cl, NULL);
+ }
// Invoke "f->do_oop" on the locations of all oops in the table.
static void oops_do(OopClosure* f);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 72d2df4b91f..f209a802b3d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -450,11 +450,9 @@ bool PSScavenge::invoke_no_policy() {
reference_processor()->enqueue_discovered_references(NULL);
}
- // Unlink any dead interned Strings
- StringTable::unlink(&_is_alive_closure);
- // Process the remaining live ones
- PSScavengeRootsClosure root_closure(promotion_manager);
- StringTable::oops_do(&root_closure);
+ // Unlink any dead interned Strings and process the remaining live ones.
+ PSScavengeRootsClosure root_closure(promotion_manager);
+ StringTable::unlink_or_oops_do(&_is_alive_closure, &root_closure);
// Finally, flush the promotion_manager's labs, and deallocate its stacks.
PSPromotionManager::post_scavenge();
From a34fd412c5243585c79d53c541be94d927e6dd10 Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Mon, 27 May 2013 13:11:13 +0200
Subject: [PATCH 061/206] 8014219: Make the run-octane harness more
deterministic by not measuring elapsed time every iteration. Also got rid of
most of the run logic in base.js and call benchmarks directly for the same
purpose
Reviewed-by: jlaskey, attila
---
nashorn/make/build-benchmark.xml | 91 ++++----
.../internal/runtime/AccessorProperty.java | 16 +-
.../nashorn/internal/runtime/Property.java | 2 +
.../runtime/UserAccessorProperty.java | 2 -
.../script/basic/compile-octane.js.EXPECTED | 52 ++---
nashorn/test/script/basic/run-octane.js | 213 +++++++++---------
6 files changed, 177 insertions(+), 199 deletions(-)
diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml
index d28de93df79..47064e24d35 100644
--- a/nashorn/make/build-benchmark.xml
+++ b/nashorn/make/build-benchmark.xml
@@ -32,250 +32,263 @@
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
+
-
+
-
+
-
+
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
index c3bfa697850..13e9e1ce3bd 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/AccessorProperty.java
@@ -306,14 +306,14 @@ public class AccessorProperty extends Property {
protected Object getObjectValue(final ScriptObject self, final ScriptObject owner) {
if (isSpill()) {
return self.spill[getSlot()];
- } else {
- try {
- return getGetter(Object.class).invokeExact((Object)self);
- } catch (final Error|RuntimeException e) {
- throw e;
- } catch (final Throwable e) {
- throw new RuntimeException(e);
- }
+ }
+
+ try {
+ return getGetter(Object.class).invokeExact((Object)self);
+ } catch (final Error|RuntimeException e) {
+ throw e;
+ } catch (final Throwable e) {
+ throw new RuntimeException(e);
}
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/Property.java b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
index 433bc2c3048..a5e46016a00 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/Property.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Property.java
@@ -52,6 +52,7 @@ public abstract class Property {
* we can use leave flag byte initialized with (the default) zero value.
*/
+ /** Mask for property being both writable, enumerable and configurable */
public static final int WRITABLE_ENUMERABLE_CONFIGURABLE = 0b0000_0000_0000;
/** ECMA 8.6.1 - Is this property not writable? */
@@ -360,6 +361,7 @@ public abstract class Property {
* @param self the this object
* @param owner the owner object
* @param value the new property value
+ * @param strict is this a strict setter?
*/
protected abstract void setObjectValue(ScriptObject self, ScriptObject owner, Object value, boolean strict);
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
index fac505ceff5..5159e6537b0 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/UserAccessorProperty.java
@@ -193,7 +193,6 @@ public final class UserAccessorProperty extends Property {
// getter/setter may be inherited. If so, proto is bound during lookup. In either
// inherited or self case, slot is also bound during lookup. Actual ScriptFunction
// to be called is retrieved everytime and applied.
- @SuppressWarnings("unused")
static Object userAccessorGetter(final ScriptObject proto, final int slot, final Object self) {
final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
final Object func = container.getSpill(slot);
@@ -211,7 +210,6 @@ public final class UserAccessorProperty extends Property {
return UNDEFINED;
}
- @SuppressWarnings("unused")
static void userAccessorSetter(final ScriptObject proto, final int slot, final String name, final Object self, final Object value) {
final ScriptObject container = (proto != null) ? proto : (ScriptObject)self;
final Object func = container.getSpill(slot);
diff --git a/nashorn/test/script/basic/compile-octane.js.EXPECTED b/nashorn/test/script/basic/compile-octane.js.EXPECTED
index 39f866c2d17..153524c70b4 100644
--- a/nashorn/test/script/basic/compile-octane.js.EXPECTED
+++ b/nashorn/test/script/basic/compile-octane.js.EXPECTED
@@ -1,39 +1,13 @@
-Compiling... box2d.js
-Compiled OK: box2d.js
-
-Compiling... code-load.js
-Compiled OK: code-load.js
-
-Compiling... crypto.js
-Compiled OK: crypto.js
-
-Compiling... deltablue.js
-Compiled OK: deltablue.js
-
-Compiling... earley-boyer.js
-Compiled OK: earley-boyer.js
-
-Compiling... gbemu.js
-Compiled OK: gbemu.js
-
-Compiling... mandreel.js
-Compiled OK: mandreel.js
-
-Compiling... navier-stokes.js
-Compiled OK: navier-stokes.js
-
-Compiling... pdfjs.js
-Compiled OK: pdfjs.js
-
-Compiling... raytrace.js
-Compiled OK: raytrace.js
-
-Compiling... regexp.js
-Compiled OK: regexp.js
-
-Compiling... richards.js
-Compiled OK: richards.js
-
-Compiling... splay.js
-Compiled OK: splay.js
-
+Compiled OK: box2d
+Compiled OK: code-load
+Compiled OK: crypto
+Compiled OK: deltablue
+Compiled OK: earley-boyer
+Compiled OK: gbemu
+Compiled OK: mandreel
+Compiled OK: navier-stokes
+Compiled OK: pdfjs
+Compiled OK: raytrace
+Compiled OK: regexp
+Compiled OK: richards
+Compiled OK: splay
diff --git a/nashorn/test/script/basic/run-octane.js b/nashorn/test/script/basic/run-octane.js
index 315451cbee8..5739000a991 100644
--- a/nashorn/test/script/basic/run-octane.js
+++ b/nashorn/test/script/basic/run-octane.js
@@ -26,36 +26,20 @@
*/
var tests = [
- "box2d.js",
- "code-load.js",
- "crypto.js",
- "deltablue.js",
- "earley-boyer.js",
- "gbemu.js",
- "mandreel.js",
- "navier-stokes.js",
- "pdfjs.js",
- "raytrace.js",
- "regexp.js",
- "richards.js",
- "splay.js"
+ {file:"box2d",suite:"Box2DBenchmark"},
+ {file:"code-load",suite:"CodeLoad"},
+ {file:"crypto",suite:"Crypto"},
+ {file:"deltablue",suite:"DeltaBlue"},
+ {file:"earley-boyer", suite:"EarleyBoyer"},
+ {file:"gbemu", suite:"GameboyBenchmark"},
+ {file:"mandreel", suite:"MandreelBenchmark"},
+ {file:"navier-stokes", suite:"NavierStokes"},
+ {file:"pdfjs", suite:"PdfJS"},
+ {file:"raytrace", suite:"RayTrace"},
+ {file:"regexp", suite:"RegExpSuite"},
+ {file:"richards", suite:"Richards"},
+ {file:"splay", suite:"Splay"}
];
-
-// hack, teardown breaks things defined in the global space, making it impossible
-// to do multiple consecutive benchmark runs with the same harness. I think it's a bug
-// that the setup and teardown aren't each others constructor and destructor but rather
-// that the benchmarks rely on partial global state. For shame, Octane!
-var ignoreTeardown = [
- { name: "box2d.js" },
- { name: "gbemu.js" },
-];
-
-
-//TODO mandreel can be compiled as a test, but not run multiple times unless modified to not have global state
-var compileOnly = {
- "mandreel.js" : true
-};
-
var dir = (typeof(__DIR__) == 'undefined') ? "test/script/basic/" : __DIR__;
// TODO: why is this path hard coded when it's defined in project properties?
@@ -71,110 +55,96 @@ function endsWith(str, suffix) {
}
function should_compile_only(name) {
- return (typeof compile_only !== 'undefined') || compileOnly[name] === true;
+ return (typeof compile_only !== 'undefined')
}
function run_one_benchmark(arg, iters) {
-
var file_name;
- var file = arg.split('/');
- if (file.length == 1) {
- file = arg.split('\\');
- }
-
- //trim off trailing path separators
- while (file[file.length - 1].indexOf(".js") == -1) {
- file.pop();
- }
- file_name = file[file.length - 1];
-
+ var file = (arg.file + ".js").split('/');
+
+ file_name = path + file[file.length - 1];
+
var compile_and_return = should_compile_only(file_name);
if (compile_and_return) {
if (typeof compile_only === 'undefined') { //for a run, skip compile onlies, don't even compile them
return;
}
- print("Compiling... " + file_name);
}
-
- load(path + 'base.js');
- load(arg);
+
+ print_verbose("Loading... " + file_name);
+ load(file_name);
if (compile_and_return) {
- print("Compiled OK: " + file_name);
- print("");
+ print_always("Compiled OK: " + arg.file);
return;
}
var success = true;
- var hiscore = 0;
- var loscore = 10e8;
var current_name;
- function PrintResult(name, result) {
- current_name = name;
- }
-
- function PrintError(name, error) {
- current_name = name;
- PrintResult(name, error);
- success = false;
- }
-
- function PrintScore(score) {
- if (success) {
- if (+score >= hiscore) {
- hiscore = +score;
- }
- if (+score <= loscore) {
- loscore = +score;
- }
- }
-
- if (verbose) {
- print("Score: " + score);
- }
- }
-
if (iters == undefined) {
iters = numberOfIterations;
} else {
numberOfIterations = iters;
}
-
- print(runtime + ": running " + file_name + "...");
-
- for (var i = 0; i < numberOfIterations; i++) {
- var callbacks =
- { NotifyResult: PrintResult,
- NotifyError: PrintError,
- NotifyScore: PrintScore };
-
- for (j in ignoreTeardown) {
- var ignore = ignoreTeardown[j];
- if (endsWith(arg, ignore.name)) {
- var teardownOverride = ignore.teardown;
- if (!teardownOverride) {
- teardownOverride = function() {};
- }
-
- for (k in BenchmarkSuite.suites) {
- var benchmarks = BenchmarkSuite.suites[k].benchmarks;
- for (l in benchmarks) {
- benchmarks[l].TearDown = teardownOverride;
- }
- }
- break;
- }
- }
-
- BenchmarkSuite.RunSuites(callbacks);
- }
- var start = "Score: ";
- if (runtime != "") {
- start = runtime + ": ";
- }
- print(start + current_name + ' (version ' + BenchmarkSuite.version + '): ' + loscore + '-' + hiscore);
+ var benchmarks = eval(arg.suite + ".benchmarks");
+ for (var x = 0; x < benchmarks.length ; x++) {
+ benchmarks[x].Setup();
+ }
+ print_verbose("Running '" + arg.file + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
+
+ var scores = [];
+
+ var min_time_ms = min_time * 1000;
+ var len = benchmarks.length;
+
+ for (var it = 0; it < iters + 1; it++) {
+ //every iteration must take a minimum of 10 secs
+ var ops = 0;
+ var elapsed = 0;
+ var start = new Date;
+ do {
+ for (var i = 0; i < len; i++) {
+ benchmarks[i].run();
+ }
+ ops += len;
+ elapsed = new Date - start;
+ } while (elapsed < min_time * 1000);
+
+ var score = ops / elapsed * 1000 * 60;
+ scores.push(score);
+ var name = it == 0 ? "warmup" : "iteration " + it;
+ print_verbose("[" + arg.file + "] " + name + " finished " + score.toFixed(0) + " ops/minute");
+ }
+ for (var x = 0; x < benchmarks.length ; x++) {
+ benchmarks[x].TearDown();
+ }
+
+ var min_score = 1e9;
+ var max_score = 0;
+ var mean_score = 0;
+ for (var x = 1; x < iters + 1 ; x++) {
+ mean_score += scores[x];
+ min_score = Math.min(min_score, scores[x]);
+ max_score = Math.max(max_score, scores[x]);
+ }
+ mean_score /= iters;
+ var res = "[" + arg.file + "] " + mean_score.toFixed(0);
+ if (verbose) {
+ res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
+ }
+ print_always(res);
+}
+
+function print_always(x) {
+ print(x);
+}
+
+function print_verbose(x) {
+ if (verbose) {
+ print(x);
+ }
}
function run_suite(tests, iters) {
@@ -211,6 +181,7 @@ if (new_args.length != 0) {
var tests_found = [];
var iters = undefined;
+var min_time = 5;
for (var i = 0; i < args.length; i++) {
arg = args[i];
@@ -220,21 +191,41 @@ for (var i = 0; i < args.length; i++) {
runtime = args[++i];
} else if (arg == "--verbose") {
verbose = true;
+ } else if (arg == "--min-time") {
+ min_time = +args[++i];
} else if (arg == "") {
continue; //skip
} else {
- tests_found.push(arg);
+ var found = false;
+ for (j in tests) {
+ if (tests[j].file === arg) {
+ tests_found.push(tests[j]);
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ var str = "unknown test name: '" + arg + "' -- valid names are: ";
+ for (j in tests) {
+ if (j != 0) {
+ str += ", ";
+ }
+ str += "'" + tests[j].file + "'";
+ }
+ throw str;
+ }
}
}
if (tests_found.length == 0) {
for (i in tests) {
- tests_found.push(path + tests[i]);
+ tests_found.push(tests[i]);
}
}
tests_found.sort();
+load(path + 'base.js');
run_suite(tests_found, iters);
From fb25dcbb05044910c9e497c5f857ccf58bad369e Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Mon, 27 May 2013 13:44:14 +0100
Subject: [PATCH 062/206] 7030476: Fix conflicting use of JCTree/JCExpression
Reviewed-by: mcimadamore
---
.../share/classes/com/sun/tools/javac/comp/Lower.java | 2 +-
.../share/classes/com/sun/tools/javac/tree/JCTree.java | 10 +++++-----
.../classes/com/sun/tools/javac/tree/TreeCopier.java | 2 +-
.../classes/com/sun/tools/javac/tree/TreeMaker.java | 2 +-
4 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 7ed28941fb7..98ee76968d2 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -2002,7 +2002,7 @@ public class Lower extends TreeTranslator {
JCStatement rethrow;
if (target.hasInitCause()) {
// rethrow = "throw new NoClassDefFoundError().initCause(e);
- JCTree throwExpr =
+ JCExpression throwExpr =
makeCall(makeNewClass(syms.noClassDefFoundErrorType,
List.nil()),
names.initCause,
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
index 1ab8051279b..191dda07adf 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
@@ -700,7 +700,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
public List getTypeParameters() {
return typarams;
}
- public JCTree getExtendsClause() { return extending; }
+ public JCExpression getExtendsClause() { return extending; }
public List getImplementsClause() {
return implementing;
}
@@ -1175,7 +1175,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
return v.visitTry(this, d);
}
@Override
- public List extends JCTree> getResources() {
+ public List getResources() {
return resources;
}
@Override
@@ -1392,8 +1392,8 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
*/
public static class JCThrow extends JCStatement implements ThrowTree {
public JCExpression expr;
- protected JCThrow(JCTree expr) {
- this.expr = (JCExpression)expr;
+ protected JCThrow(JCExpression expr) {
+ this.expr = expr;
}
@Override
public void accept(Visitor v) { v.visitThrow(this); }
@@ -2466,7 +2466,7 @@ public abstract class JCTree implements Tree, Cloneable, DiagnosticPosition {
JCBreak Break(Name label);
JCContinue Continue(Name label);
JCReturn Return(JCExpression expr);
- JCThrow Throw(JCTree expr);
+ JCThrow Throw(JCExpression expr);
JCAssert Assert(JCExpression cond, JCExpression detail);
JCMethodInvocation Apply(List typeargs,
JCExpression fn,
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
index a06fa349156..aa2ce423b4b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java
@@ -340,7 +340,7 @@ public class TreeCopier
implements TreeVisitor {
public JCTree visitThrow(ThrowTree node, P p) {
JCThrow t = (JCThrow) node;
- JCTree expr = copy(t.expr, p);
+ JCExpression expr = copy(t.expr, p);
return M.at(t.pos).Throw(expr);
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
index c2757c7d05d..e0b74340b77 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java
@@ -332,7 +332,7 @@ public class TreeMaker implements JCTree.Factory {
return tree;
}
- public JCThrow Throw(JCTree expr) {
+ public JCThrow Throw(JCExpression expr) {
JCThrow tree = new JCThrow(expr);
tree.pos = pos;
return tree;
From bca9af88dac3cabdbf4ebdd203a9d803fb0c6a87 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Mon, 27 May 2013 20:41:34 +0530
Subject: [PATCH 063/206] =?UTF-8?q?8015352:=20"i".toUpperCase()=20=3D>=20c?=
=?UTF-8?q?urrently=20returns=20"=C4=B0",=20but=20should=20be=20"I"=20(wit?=
=?UTF-8?q?h=20Turkish=20locale)?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Reviewed-by: jlaskey, lagergren
---
.../internal/objects/NativeString.java | 5 +-
.../internal/runtime/ScriptEnvironment.java | 13 ++++--
.../runtime/options/OptionTemplate.java | 3 ++
.../internal/runtime/options/Options.java | 2 +
.../runtime/resources/Options.properties | 9 ++++
nashorn/test/script/basic/JDK-8015352.js | 46 +++++++++++++++++++
6 files changed, 72 insertions(+), 6 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8015352.js
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
index 2715d4f4cde..adbef5cb633 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
@@ -38,6 +38,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import jdk.internal.dynalink.CallSiteDescriptor;
import jdk.internal.dynalink.linker.GuardedInvocation;
import jdk.internal.dynalink.linker.LinkRequest;
@@ -997,7 +998,7 @@ public final class NativeString extends ScriptObject {
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object toLowerCase(final Object self) {
- return checkObjectToString(self).toLowerCase();
+ return checkObjectToString(self).toLowerCase(Locale.ROOT);
}
/**
@@ -1017,7 +1018,7 @@ public final class NativeString extends ScriptObject {
*/
@Function(attributes = Attribute.NOT_ENUMERABLE)
public static Object toUpperCase(final Object self) {
- return checkObjectToString(self).toUpperCase();
+ return checkObjectToString(self).toUpperCase(Locale.ROOT);
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
index c1c25b3eecc..2ca897db98a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptEnvironment.java
@@ -262,14 +262,19 @@ public final class ScriptEnvironment {
}
this._callsite_flags = callSiteFlags;
- final Option> option = options.get("timezone");
- if (option != null) {
- this._timezone = (TimeZone)option.getValue();
+ final Option> timezoneOption = options.get("timezone");
+ if (timezoneOption != null) {
+ this._timezone = (TimeZone)timezoneOption.getValue();
} else {
this._timezone = TimeZone.getDefault();
}
- this._locale = Locale.getDefault();
+ final Option> localeOption = options.get("locale");
+ if (localeOption != null) {
+ this._locale = (Locale)localeOption.getValue();
+ } else {
+ this._locale = Locale.getDefault();
+ }
}
/**
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
index 30e0401e62e..62dcbb8d3f0 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/OptionTemplate.java
@@ -152,6 +152,9 @@ public class OptionTemplate implements Comparable {
case "timezone":
this.defaultValue = TimeZone.getDefault().getID();
break;
+ case "locale":
+ this.defaultValue = Locale.getDefault().toLanguageTag();
+ break;
default:
break;
}
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
index 52864a6652a..737c56b4b1a 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java
@@ -499,6 +499,8 @@ public final class Options {
case "timezone":
// default value "TimeZone.getDefault()"
return new Option<>(TimeZone.getTimeZone(value));
+ case "locale":
+ return new Option<>(Locale.forLanguageTag(value));
case "keyvalues":
return new KeyValueOption(value);
case "log":
diff --git a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
index 59e971917eb..4dd6df6f75c 100644
--- a/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
+++ b/nashorn/src/jdk/nashorn/internal/runtime/resources/Options.properties
@@ -332,6 +332,15 @@ nashorn.option.timezone = { \
type=TimeZone \
}
+nashorn.option.locale = { \
+ name="--locale", \
+ short_name="-l", \
+ is_undocumented=true, \
+ params="", \
+ desc="Set Locale for script execution.", \
+ type=Locale \
+}
+
nashorn.option.trace.callsites = { \
name="--trace-callsites", \
short_name="-tcs", \
diff --git a/nashorn/test/script/basic/JDK-8015352.js b/nashorn/test/script/basic/JDK-8015352.js
new file mode 100644
index 00000000000..b40e6461049
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015352.js
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015352: "i".toUpperCase() => currently returns "İ", but should be "I" (with Turkish locale)
+ *
+ * @test
+ * @option --locale=tr-TR
+ * @run
+ */
+
+if ("i".toUpperCase() != "I") {
+ fail("'i'.toUpperCase() is not 'I'");
+}
+
+if ("i".toUpperCase() == "i".toLocaleUpperCase()) {
+ fail("'i'.toUpperCase() == 'i'.toLocaleUpperCase()");
+}
+
+if ("I".toLowerCase() != "i") {
+ fail("'I'.toLowerCase() is not 'i'");
+}
+
+if ("I".toLowerCase() == "I".toLocaleLowerCase()) {
+ fail("'i'.toLowerCase() == 'i'.toLocaleLowerCase()");
+}
From d1cfaae2c635890d2978cdba76f7dd61dc5aedba Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Mon, 27 May 2013 17:57:07 +0200
Subject: [PATCH 064/206] 8015447: Octane harness fixes for rhino and entire
test runs: ant octane, ant octane-v8, ant octane-rhino
Reviewed-by: sundar, jlaskey
---
nashorn/make/build-benchmark.xml | 15 ++---
nashorn/test/script/basic/run-octane.js | 85 ++++++++++++++-----------
2 files changed, 55 insertions(+), 45 deletions(-)
diff --git a/nashorn/make/build-benchmark.xml b/nashorn/make/build-benchmark.xml
index 47064e24d35..f1ce180a844 100644
--- a/nashorn/make/build-benchmark.xml
+++ b/nashorn/make/build-benchmark.xml
@@ -24,14 +24,13 @@
-
-
-
-
+
+
+
+
+
+
-
@@ -320,7 +319,7 @@
-
+
diff --git a/nashorn/test/script/basic/run-octane.js b/nashorn/test/script/basic/run-octane.js
index 5739000a991..b730040e4c5 100644
--- a/nashorn/test/script/basic/run-octane.js
+++ b/nashorn/test/script/basic/run-octane.js
@@ -89,47 +89,57 @@ function run_one_benchmark(arg, iters) {
}
var benchmarks = eval(arg.suite + ".benchmarks");
- for (var x = 0; x < benchmarks.length ; x++) {
- benchmarks[x].Setup();
- }
- print_verbose("Running '" + arg.file + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
-
- var scores = [];
-
- var min_time_ms = min_time * 1000;
- var len = benchmarks.length;
-
- for (var it = 0; it < iters + 1; it++) {
- //every iteration must take a minimum of 10 secs
- var ops = 0;
- var elapsed = 0;
- var start = new Date;
- do {
- for (var i = 0; i < len; i++) {
- benchmarks[i].run();
- }
- ops += len;
- elapsed = new Date - start;
- } while (elapsed < min_time * 1000);
-
- var score = ops / elapsed * 1000 * 60;
- scores.push(score);
- var name = it == 0 ? "warmup" : "iteration " + it;
- print_verbose("[" + arg.file + "] " + name + " finished " + score.toFixed(0) + " ops/minute");
- }
- for (var x = 0; x < benchmarks.length ; x++) {
- benchmarks[x].TearDown();
- }
-
var min_score = 1e9;
var max_score = 0;
var mean_score = 0;
- for (var x = 1; x < iters + 1 ; x++) {
- mean_score += scores[x];
- min_score = Math.min(min_score, scores[x]);
- max_score = Math.max(max_score, scores[x]);
+
+ try {
+ for (var x = 0; x < benchmarks.length ; x++) {
+ benchmarks[x].Setup();
+ }
+ print_verbose("Running '" + arg.file + "' for " + iters + " iterations of no less than " + min_time + " seconds (" + runtime + ")");
+
+ var scores = [];
+
+ var min_time_ms = min_time * 1000;
+ var len = benchmarks.length;
+
+ for (var it = 0; it < iters + 1; it++) {
+ //every iteration must take a minimum of 10 secs
+ var ops = 0;
+ var elapsed = 0;
+ var start = new Date;
+ do {
+ for (var i = 0; i < len; i++) {
+ benchmarks[i].run();
+ }
+ ops += len;
+ elapsed = new Date - start;
+ } while (elapsed < min_time * 1000);
+
+ var score = ops / elapsed * 1000 * 60;
+ scores.push(score);
+ var name = it == 0 ? "warmup" : "iteration " + it;
+ print_verbose("[" + arg.file + "] " + name + " finished " + score.toFixed(0) + " ops/minute");
+ }
+
+ for (var x = 0; x < benchmarks.length ; x++) {
+ benchmarks[x].TearDown();
+ }
+
+ for (var x = 1; x < iters + 1 ; x++) {
+ mean_score += scores[x];
+ min_score = Math.min(min_score, scores[x]);
+ max_score = Math.max(max_score, scores[x]);
+ }
+ mean_score /= iters;
+
+ } catch (e) {
+ print_always("*** Aborted and setting score to zero. Reason: " + e);
+ mean_score = min_score = max_score = 0;
+ scores = [0];
}
- mean_score /= iters;
+
var res = "[" + arg.file + "] " + mean_score.toFixed(0);
if (verbose) {
res += " ops/minute (" + min_score.toFixed(0) + "-" + max_score.toFixed(0) + "), warmup=" + scores[0].toFixed(0);
@@ -156,6 +166,7 @@ function run_suite(tests, iters) {
runtime = "command line";
var args = [];
+
if (typeof $ARGS !== 'undefined') {
args = $ARGS;
} else if (typeof arguments !== 'undefined' && arguments.length != 0) {
From 375e12feb95368849df2e8ec48c13608aff1a605 Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev
Date: Mon, 27 May 2013 12:49:08 -0700
Subject: [PATCH 065/206] 8015270: @Contended: fix multiple issues in the
layout code
Field count handling fixed, has_nonstatic_fields invariant fixed, oop map overrun fixed; new asserts
Reviewed-by: kvn, dcubed, coleenp
---
.../share/vm/classfile/classFileParser.cpp | 64 ++++---
.../test/runtime/contended/HasNonStatic.java | 75 ++++++++
hotspot/test/runtime/contended/OopMaps.java | 164 ++++++++++++++++++
3 files changed, 283 insertions(+), 20 deletions(-)
create mode 100644 hotspot/test/runtime/contended/HasNonStatic.java
create mode 100644 hotspot/test/runtime/contended/OopMaps.java
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 8aa15736447..263409f15d8 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -3152,7 +3152,6 @@ void ClassFileParser::layout_fields(Handle class_loader,
}
}
}
- int contended_count = nonstatic_contended_count;
// Calculate the starting byte offsets
@@ -3177,35 +3176,52 @@ void ClassFileParser::layout_fields(Handle class_loader,
next_nonstatic_field_offset = nonstatic_fields_start;
+ bool is_contended_class = parsed_annotations->is_contended();
+
// Class is contended, pad before all the fields
- if (parsed_annotations->is_contended()) {
+ if (is_contended_class) {
next_nonstatic_field_offset += ContendedPaddingWidth;
}
- // Compute the non-contended fields count
+ // Compute the non-contended fields count.
+ // The packing code below relies on these counts to determine if some field
+ // can be squeezed into the alignment gap. Contended fields are obviously
+ // exempt from that.
unsigned int nonstatic_double_count = fac->count[NONSTATIC_DOUBLE] - fac_contended.count[NONSTATIC_DOUBLE];
unsigned int nonstatic_word_count = fac->count[NONSTATIC_WORD] - fac_contended.count[NONSTATIC_WORD];
unsigned int nonstatic_short_count = fac->count[NONSTATIC_SHORT] - fac_contended.count[NONSTATIC_SHORT];
unsigned int nonstatic_byte_count = fac->count[NONSTATIC_BYTE] - fac_contended.count[NONSTATIC_BYTE];
unsigned int nonstatic_oop_count = fac->count[NONSTATIC_OOP] - fac_contended.count[NONSTATIC_OOP];
+ // Total non-static fields count, including every contended field
+ unsigned int nonstatic_fields_count = fac->count[NONSTATIC_DOUBLE] + fac->count[NONSTATIC_WORD] +
+ fac->count[NONSTATIC_SHORT] + fac->count[NONSTATIC_BYTE] +
+ fac->count[NONSTATIC_OOP];
+
bool super_has_nonstatic_fields =
(_super_klass() != NULL && _super_klass->has_nonstatic_fields());
- bool has_nonstatic_fields = super_has_nonstatic_fields ||
- ((nonstatic_double_count + nonstatic_word_count +
- nonstatic_short_count + nonstatic_byte_count +
- nonstatic_oop_count) != 0);
+ bool has_nonstatic_fields = super_has_nonstatic_fields || (nonstatic_fields_count != 0);
// Prepare list of oops for oop map generation.
+ //
+ // "offset" and "count" lists are describing the set of contiguous oop
+ // regions. offset[i] is the start of the i-th region, which then has
+ // count[i] oops following. Before we know how many regions are required,
+ // we pessimistically allocate the maps to fit all the oops into the
+ // distinct regions.
+ //
+ // TODO: We add +1 to always allocate non-zero resource arrays; we need
+ // to figure out if we still need to do this.
int* nonstatic_oop_offsets;
unsigned int* nonstatic_oop_counts;
unsigned int nonstatic_oop_map_count = 0;
+ unsigned int max_nonstatic_oop_maps = fac->count[NONSTATIC_OOP] + 1;
nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
- THREAD, int, nonstatic_oop_count + 1);
+ THREAD, int, max_nonstatic_oop_maps);
nonstatic_oop_counts = NEW_RESOURCE_ARRAY_IN_THREAD(
- THREAD, unsigned int, nonstatic_oop_count + 1);
+ THREAD, unsigned int, max_nonstatic_oop_maps);
first_nonstatic_oop_offset = 0; // will be set for first oop field
@@ -3392,9 +3408,11 @@ void ClassFileParser::layout_fields(Handle class_loader,
int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
heapOopSize ) {
// Extend current oop map
+ assert(nonstatic_oop_map_count - 1 < max_nonstatic_oop_maps, "range check");
nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
} else {
// Create new oop map
+ assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
nonstatic_oop_map_count += 1;
@@ -3452,12 +3470,10 @@ void ClassFileParser::layout_fields(Handle class_loader,
//
// Additionally, this should not break alignment for the fields, so we round the alignment up
// for each field.
- if (contended_count > 0) {
+ if (nonstatic_contended_count > 0) {
// if there is at least one contended field, we need to have pre-padding for them
- if (nonstatic_contended_count > 0) {
- next_nonstatic_padded_offset += ContendedPaddingWidth;
- }
+ next_nonstatic_padded_offset += ContendedPaddingWidth;
// collect all contended groups
BitMap bm(_cp->size());
@@ -3518,6 +3534,7 @@ void ClassFileParser::layout_fields(Handle class_loader,
next_nonstatic_padded_offset += heapOopSize;
// Create new oop map
+ assert(nonstatic_oop_map_count < max_nonstatic_oop_maps, "range check");
nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
nonstatic_oop_map_count += 1;
@@ -3554,18 +3571,17 @@ void ClassFileParser::layout_fields(Handle class_loader,
// handle static fields
}
- // Size of instances
- int notaligned_offset = next_nonstatic_padded_offset;
-
// Entire class is contended, pad in the back.
// This helps to alleviate memory contention effects for subclass fields
// and/or adjacent object.
- if (parsed_annotations->is_contended()) {
- notaligned_offset += ContendedPaddingWidth;
+ if (is_contended_class) {
+ next_nonstatic_padded_offset += ContendedPaddingWidth;
}
- int nonstatic_fields_end = align_size_up(notaligned_offset, heapOopSize);
- int instance_end = align_size_up(notaligned_offset, wordSize);
+ int notaligned_nonstatic_fields_end = next_nonstatic_padded_offset;
+
+ int nonstatic_fields_end = align_size_up(notaligned_nonstatic_fields_end, heapOopSize);
+ int instance_end = align_size_up(notaligned_nonstatic_fields_end, wordSize);
int static_fields_end = align_size_up(next_static_byte_offset, wordSize);
int static_field_size = (static_fields_end -
@@ -3579,6 +3595,14 @@ void ClassFileParser::layout_fields(Handle class_loader,
(instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize),
wordSize) / wordSize), "consistent layout helper value");
+ // Invariant: nonstatic_field end/start should only change if there are
+ // nonstatic fields in the class, or if the class is contended. We compare
+ // against the non-aligned value, so that end alignment will not fail the
+ // assert without actually having the fields.
+ assert((notaligned_nonstatic_fields_end == nonstatic_fields_start) ||
+ is_contended_class ||
+ (nonstatic_fields_count > 0), "double-check nonstatic start/end");
+
// Number of non-static oop map blocks allocated at end of klass.
const unsigned int total_oop_map_count =
compute_oop_map_count(_super_klass, nonstatic_oop_map_count,
diff --git a/hotspot/test/runtime/contended/HasNonStatic.java b/hotspot/test/runtime/contended/HasNonStatic.java
new file mode 100644
index 00000000000..6792adf6abb
--- /dev/null
+++ b/hotspot/test/runtime/contended/HasNonStatic.java
@@ -0,0 +1,75 @@
+/*
+ * 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.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug 8015270
+ * @summary \@Contended: fix multiple issues in the layout code
+ *
+ * @run main/othervm -XX:-RestrictContended HasNonStatic
+ */
+public class HasNonStatic {
+
+ public static void main(String[] args) throws Exception {
+ R1 r1 = new R1();
+ R2 r2 = new R2();
+ R3 r3 = new R3();
+ R4 r4 = new R4();
+ }
+
+ public static class R1 {
+ @Contended
+ Object o;
+ }
+
+ @Contended
+ public static class R2 {
+ Object o;
+ }
+
+ @Contended
+ public static class R3 {
+ }
+
+ public static class R4 extends R3 {
+ }
+
+}
+
diff --git a/hotspot/test/runtime/contended/OopMaps.java b/hotspot/test/runtime/contended/OopMaps.java
new file mode 100644
index 00000000000..b8dfbba416b
--- /dev/null
+++ b/hotspot/test/runtime/contended/OopMaps.java
@@ -0,0 +1,164 @@
+/*
+ * 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.BufferedReader;
+import java.io.InputStreamReader;
+import java.lang.Class;
+import java.lang.String;
+import java.lang.System;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.CyclicBarrier;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import sun.misc.Unsafe;
+import sun.misc.Contended;
+
+/*
+ * @test
+ * @bug 8015270
+ * @summary \@Contended: fix multiple issues in the layout code
+ *
+ * @run main/othervm -XX:-RestrictContended OopMaps
+ */
+public class OopMaps {
+
+ public static void main(String[] args) throws Exception {
+ Object o01 = new Object();
+ Object o02 = new Object();
+ Object o03 = new Object();
+ Object o04 = new Object();
+ Object o05 = new Object();
+ Object o06 = new Object();
+ Object o07 = new Object();
+ Object o08 = new Object();
+ Object o09 = new Object();
+ Object o10 = new Object();
+ Object o11 = new Object();
+ Object o12 = new Object();
+ Object o13 = new Object();
+ Object o14 = new Object();
+
+ final int COUNT = 100000;
+ R1[] rs = new R1[COUNT];
+
+ for (int i = 0; i < COUNT; i++) {
+ R1 r1 = new R1();
+ r1.o01 = o01;
+ r1.o02 = o02;
+ r1.o03 = o03;
+ r1.o04 = o04;
+ r1.o05 = o05;
+ r1.o06 = o06;
+ r1.o07 = o07;
+ r1.o08 = o08;
+ r1.o09 = o09;
+ r1.o10 = o10;
+ r1.o11 = o11;
+ r1.o12 = o12;
+ r1.o13 = o13;
+ r1.o14 = o14;
+ r1.i1 = 1;
+ r1.i2 = 2;
+ r1.i3 = 3;
+ r1.i4 = 4;
+ rs[i] = r1;
+ }
+
+ System.gc();
+
+ for (int i = 0; i < COUNT; i++) {
+ R1 r1 = rs[i];
+ if (r1.o01 != o01) throw new Error("Test Error: o01");
+ if (r1.o02 != o02) throw new Error("Test Error: o02");
+ if (r1.o03 != o03) throw new Error("Test Error: o03");
+ if (r1.o04 != o04) throw new Error("Test Error: o04");
+ if (r1.o05 != o05) throw new Error("Test Error: o05");
+ if (r1.o06 != o06) throw new Error("Test Error: o06");
+ if (r1.o07 != o07) throw new Error("Test Error: o07");
+ if (r1.o08 != o08) throw new Error("Test Error: o08");
+ if (r1.o09 != o09) throw new Error("Test Error: o09");
+ if (r1.o10 != o10) throw new Error("Test Error: o10");
+ if (r1.o11 != o11) throw new Error("Test Error: o11");
+ if (r1.o12 != o12) throw new Error("Test Error: o12");
+ if (r1.o13 != o13) throw new Error("Test Error: o13");
+ if (r1.o14 != o14) throw new Error("Test Error: o14");
+ if (r1.i1 != 1) throw new Error("Test Error: i1");
+ if (r1.i2 != 2) throw new Error("Test Error: i2");
+ if (r1.i3 != 3) throw new Error("Test Error: i3");
+ if (r1.i4 != 4) throw new Error("Test Error: i4");
+ }
+ }
+
+ public static class R0 {
+ int i1;
+ int i2;
+
+ Object o01;
+ Object o02;
+
+ @Contended
+ Object o03;
+
+ @Contended
+ Object o04;
+
+ @Contended
+ Object o05;
+
+ @Contended
+ Object o06;
+
+ @Contended
+ Object o07;
+ }
+
+ public static class R1 extends R0 {
+ int i3;
+ int i4;
+
+ Object o08;
+ Object o09;
+
+ @Contended
+ Object o10;
+
+ @Contended
+ Object o11;
+
+ @Contended
+ Object o12;
+
+ @Contended
+ Object o13;
+
+ @Contended
+ Object o14;
+ }
+
+}
+
From de314e391b4d8865a049810bc570ddf9c39795e5 Mon Sep 17 00:00:00 2001
From: John Coomes
Date: Thu, 30 May 2013 13:04:51 -0700
Subject: [PATCH 066/206] 6725714: par compact - add a table to speed up bitmap
searches
Reviewed-by: jmasa, tschatzl
---
.../parallelScavenge/parallelScavengeHeap.hpp | 2 +-
.../parallelScavenge/psParallelCompact.cpp | 202 ++++++++++++++----
.../parallelScavenge/psParallelCompact.hpp | 157 +++++++++++++-
3 files changed, 309 insertions(+), 52 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
index c0933fe16c6..98e9c0435ab 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
@@ -116,7 +116,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.
- size_t intra_heap_alignment() const { return 64 * K; }
+ size_t intra_heap_alignment() const { return 64 * K * HeapWordSize; }
size_t capacity() const;
size_t used() const;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index 3e649ddf702..be437f3272f 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -59,13 +59,25 @@
#include
// All sizes are in HeapWords.
-const size_t ParallelCompactData::Log2RegionSize = 9; // 512 words
+const size_t ParallelCompactData::Log2RegionSize = 16; // 64K words
const size_t ParallelCompactData::RegionSize = (size_t)1 << Log2RegionSize;
const size_t ParallelCompactData::RegionSizeBytes =
RegionSize << LogHeapWordSize;
const size_t ParallelCompactData::RegionSizeOffsetMask = RegionSize - 1;
const size_t ParallelCompactData::RegionAddrOffsetMask = RegionSizeBytes - 1;
-const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask;
+const size_t ParallelCompactData::RegionAddrMask = ~RegionAddrOffsetMask;
+
+const size_t ParallelCompactData::Log2BlockSize = 7; // 128 words
+const size_t ParallelCompactData::BlockSize = (size_t)1 << Log2BlockSize;
+const size_t ParallelCompactData::BlockSizeBytes =
+ BlockSize << LogHeapWordSize;
+const size_t ParallelCompactData::BlockSizeOffsetMask = BlockSize - 1;
+const size_t ParallelCompactData::BlockAddrOffsetMask = BlockSizeBytes - 1;
+const size_t ParallelCompactData::BlockAddrMask = ~BlockAddrOffsetMask;
+
+const size_t ParallelCompactData::BlocksPerRegion = RegionSize / BlockSize;
+const size_t ParallelCompactData::Log2BlocksPerRegion =
+ Log2RegionSize - Log2BlockSize;
const ParallelCompactData::RegionData::region_sz_t
ParallelCompactData::RegionData::dc_shift = 27;
@@ -359,6 +371,10 @@ ParallelCompactData::ParallelCompactData()
_reserved_byte_size = 0;
_region_data = 0;
_region_count = 0;
+
+ _block_vspace = 0;
+ _block_data = 0;
+ _block_count = 0;
}
bool ParallelCompactData::initialize(MemRegion covered_region)
@@ -372,8 +388,7 @@ bool ParallelCompactData::initialize(MemRegion covered_region)
assert((region_size & RegionSizeOffsetMask) == 0,
"region size not a multiple of RegionSize");
- bool result = initialize_region_data(region_size);
-
+ bool result = initialize_region_data(region_size) && initialize_block_data();
return result;
}
@@ -418,17 +433,36 @@ bool ParallelCompactData::initialize_region_data(size_t region_size)
return false;
}
+bool ParallelCompactData::initialize_block_data()
+{
+ assert(_region_count != 0, "region data must be initialized first");
+ const size_t count = _region_count << Log2BlocksPerRegion;
+ _block_vspace = create_vspace(count, sizeof(BlockData));
+ if (_block_vspace != 0) {
+ _block_data = (BlockData*)_block_vspace->reserved_low_addr();
+ _block_count = count;
+ return true;
+ }
+ return false;
+}
+
void ParallelCompactData::clear()
{
memset(_region_data, 0, _region_vspace->committed_size());
+ memset(_block_data, 0, _block_vspace->committed_size());
}
void ParallelCompactData::clear_range(size_t beg_region, size_t end_region) {
assert(beg_region <= _region_count, "beg_region out of range");
assert(end_region <= _region_count, "end_region out of range");
+ assert(RegionSize % BlockSize == 0, "RegionSize not a multiple of BlockSize");
const size_t region_cnt = end_region - beg_region;
memset(_region_data + beg_region, 0, region_cnt * sizeof(RegionData));
+
+ const size_t beg_block = beg_region * BlocksPerRegion;
+ const size_t block_cnt = region_cnt * BlocksPerRegion;
+ memset(_block_data + beg_block, 0, block_cnt * sizeof(BlockData));
}
HeapWord* ParallelCompactData::partial_obj_end(size_t region_idx) const
@@ -707,49 +741,48 @@ bool ParallelCompactData::summarize(SplitInfo& split_info,
HeapWord* ParallelCompactData::calc_new_pointer(HeapWord* addr) {
assert(addr != NULL, "Should detect NULL oop earlier");
- assert(PSParallelCompact::gc_heap()->is_in(addr), "addr not in heap");
-#ifdef ASSERT
- if (PSParallelCompact::mark_bitmap()->is_unmarked(addr)) {
- gclog_or_tty->print_cr("calc_new_pointer:: addr " PTR_FORMAT, addr);
- }
-#endif
- assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "obj not marked");
+ assert(PSParallelCompact::gc_heap()->is_in(addr), "not in heap");
+ assert(PSParallelCompact::mark_bitmap()->is_marked(addr), "not marked");
// Region covering the object.
- size_t region_index = addr_to_region_idx(addr);
- const RegionData* const region_ptr = region(region_index);
- HeapWord* const region_addr = region_align_down(addr);
-
- assert(addr < region_addr + RegionSize, "Region does not cover object");
- assert(addr_to_region_ptr(region_addr) == region_ptr, "sanity check");
-
+ RegionData* const region_ptr = addr_to_region_ptr(addr);
HeapWord* result = region_ptr->destination();
- // If all the data in the region is live, then the new location of the object
- // can be calculated from the destination of the region plus the offset of the
- // object in the region.
+ // If the entire Region is live, the new location is region->destination + the
+ // offset of the object within in the Region.
+
+ // Run some performance tests to determine if this special case pays off. It
+ // is worth it for pointers into the dense prefix. If the optimization to
+ // avoid pointer updates in regions that only point to the dense prefix is
+ // ever implemented, this should be revisited.
if (region_ptr->data_size() == RegionSize) {
- result += pointer_delta(addr, region_addr);
- DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);)
+ result += region_offset(addr);
return result;
}
- // The new location of the object is
- // region destination +
- // size of the partial object extending onto the region +
- // sizes of the live objects in the Region that are to the left of addr
- const size_t partial_obj_size = region_ptr->partial_obj_size();
- HeapWord* const search_start = region_addr + partial_obj_size;
+ // Otherwise, the new location is region->destination + block offset + the
+ // number of live words in the Block that are (a) to the left of addr and (b)
+ // due to objects that start in the Block.
+
+ // Fill in the block table if necessary. This is unsynchronized, so multiple
+ // threads may fill the block table for a region (harmless, since it is
+ // idempotent).
+ if (!region_ptr->blocks_filled()) {
+ PSParallelCompact::fill_blocks(addr_to_region_idx(addr));
+ region_ptr->set_blocks_filled();
+ }
+
+ HeapWord* const search_start = block_align_down(addr);
+ const size_t block_offset = addr_to_block_ptr(addr)->offset();
const ParMarkBitMap* bitmap = PSParallelCompact::mark_bitmap();
- size_t live_to_left = bitmap->live_words_in_range(search_start, oop(addr));
-
- result += partial_obj_size + live_to_left;
- DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result);)
+ const size_t live = bitmap->live_words_in_range(search_start, oop(addr));
+ result += block_offset + live;
+ DEBUG_ONLY(PSParallelCompact::check_new_location(addr, result));
return result;
}
-#ifdef ASSERT
+#ifdef ASSERT
void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace)
{
const size_t* const beg = (const size_t*)vspace->committed_low_addr();
@@ -762,16 +795,10 @@ void ParallelCompactData::verify_clear(const PSVirtualSpace* vspace)
void ParallelCompactData::verify_clear()
{
verify_clear(_region_vspace);
+ verify_clear(_block_vspace);
}
#endif // #ifdef ASSERT
-#ifdef NOT_PRODUCT
-ParallelCompactData::RegionData* debug_region(size_t region_index) {
- ParallelCompactData& sd = PSParallelCompact::summary_data();
- return sd.region(region_index);
-}
-#endif
-
elapsedTimer PSParallelCompact::_accumulated_time;
unsigned int PSParallelCompact::_total_invocations = 0;
unsigned int PSParallelCompact::_maximum_compaction_gc_num = 0;
@@ -1961,11 +1988,6 @@ void PSParallelCompact::invoke(bool maximum_heap_compaction) {
maximum_heap_compaction);
}
-bool ParallelCompactData::region_contains(size_t region_index, HeapWord* addr) {
- size_t addr_region_index = addr_to_region_idx(addr);
- return region_index == addr_region_index;
-}
-
// This method contains no policy. You should probably
// be calling invoke() instead.
bool PSParallelCompact::invoke_no_policy(bool maximum_heap_compaction) {
@@ -2627,6 +2649,41 @@ void PSParallelCompact::enqueue_region_stealing_tasks(
}
}
+#ifdef ASSERT
+// Write a histogram of the number of times the block table was filled for a
+// region.
+void PSParallelCompact::write_block_fill_histogram(outputStream* const out)
+{
+ if (!TraceParallelOldGCCompactionPhase) return;
+
+ typedef ParallelCompactData::RegionData rd_t;
+ ParallelCompactData& sd = summary_data();
+
+ for (unsigned int id = old_space_id; id < last_space_id; ++id) {
+ MutableSpace* const spc = _space_info[id].space();
+ if (spc->bottom() != spc->top()) {
+ const rd_t* const beg = sd.addr_to_region_ptr(spc->bottom());
+ HeapWord* const top_aligned_up = sd.region_align_up(spc->top());
+ const rd_t* const end = sd.addr_to_region_ptr(top_aligned_up);
+
+ size_t histo[5] = { 0, 0, 0, 0, 0 };
+ const size_t histo_len = sizeof(histo) / sizeof(size_t);
+ const size_t region_cnt = pointer_delta(end, beg, sizeof(rd_t));
+
+ for (const rd_t* cur = beg; cur < end; ++cur) {
+ ++histo[MIN2(cur->blocks_filled_count(), histo_len - 1)];
+ }
+ out->print("%u %-4s" SIZE_FORMAT_W(5), id, space_names[id], region_cnt);
+ for (size_t i = 0; i < histo_len; ++i) {
+ out->print(" " SIZE_FORMAT_W(5) " %5.1f%%",
+ histo[i], 100.0 * histo[i] / region_cnt);
+ }
+ out->cr();
+ }
+ }
+}
+#endif // #ifdef ASSERT
+
void PSParallelCompact::compact() {
// trace("5");
TraceTime tm("compaction phase", print_phases(), true, gclog_or_tty);
@@ -2666,6 +2723,8 @@ void PSParallelCompact::compact() {
update_deferred_objects(cm, SpaceId(id));
}
}
+
+ DEBUG_ONLY(write_block_fill_histogram(gclog_or_tty));
}
#ifdef ASSERT
@@ -3130,6 +3189,57 @@ void PSParallelCompact::fill_region(ParCompactionManager* cm, size_t region_idx)
} while (true);
}
+void PSParallelCompact::fill_blocks(size_t region_idx)
+{
+ // Fill in the block table elements for the specified region. Each block
+ // table element holds the number of live words in the region that are to the
+ // left of the first object that starts in the block. Thus only blocks in
+ // which an object starts need to be filled.
+ //
+ // The algorithm scans the section of the bitmap that corresponds to the
+ // region, keeping a running total of the live words. When an object start is
+ // found, if it's the first to start in the block that contains it, the
+ // current total is written to the block table element.
+ const size_t Log2BlockSize = ParallelCompactData::Log2BlockSize;
+ const size_t Log2RegionSize = ParallelCompactData::Log2RegionSize;
+ const size_t RegionSize = ParallelCompactData::RegionSize;
+
+ ParallelCompactData& sd = summary_data();
+ const size_t partial_obj_size = sd.region(region_idx)->partial_obj_size();
+ if (partial_obj_size >= RegionSize) {
+ return; // No objects start in this region.
+ }
+
+ // Ensure the first loop iteration decides that the block has changed.
+ size_t cur_block = sd.block_count();
+
+ const ParMarkBitMap* const bitmap = mark_bitmap();
+
+ const size_t Log2BitsPerBlock = Log2BlockSize - LogMinObjAlignment;
+ assert((size_t)1 << Log2BitsPerBlock ==
+ bitmap->words_to_bits(ParallelCompactData::BlockSize), "sanity");
+
+ size_t beg_bit = bitmap->words_to_bits(region_idx << Log2RegionSize);
+ const size_t range_end = beg_bit + bitmap->words_to_bits(RegionSize);
+ size_t live_bits = bitmap->words_to_bits(partial_obj_size);
+ beg_bit = bitmap->find_obj_beg(beg_bit + live_bits, range_end);
+ while (beg_bit < range_end) {
+ const size_t new_block = beg_bit >> Log2BitsPerBlock;
+ if (new_block != cur_block) {
+ cur_block = new_block;
+ sd.block(cur_block)->set_offset(bitmap->bits_to_words(live_bits));
+ }
+
+ const size_t end_bit = bitmap->find_obj_end(beg_bit, range_end);
+ if (end_bit < range_end - 1) {
+ live_bits += end_bit - beg_bit + 1;
+ beg_bit = bitmap->find_obj_beg(end_bit + 1, range_end);
+ } else {
+ return;
+ }
+ }
+}
+
void
PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) {
const MutableSpace* sp = space(space_id);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
index 79cd3f8933b..c3a00c7e232 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.hpp
@@ -220,6 +220,17 @@ public:
// Mask for the bits in a pointer to get the address of the start of a region.
static const size_t RegionAddrMask;
+ static const size_t Log2BlockSize;
+ static const size_t BlockSize;
+ static const size_t BlockSizeBytes;
+
+ static const size_t BlockSizeOffsetMask;
+ static const size_t BlockAddrOffsetMask;
+ static const size_t BlockAddrMask;
+
+ static const size_t BlocksPerRegion;
+ static const size_t Log2BlocksPerRegion;
+
class RegionData
{
public:
@@ -272,6 +283,12 @@ public:
inline uint destination_count() const;
inline uint destination_count_raw() const;
+ // Whether the block table for this region has been filled.
+ inline bool blocks_filled() const;
+
+ // Number of times the block table was filled.
+ DEBUG_ONLY(inline size_t blocks_filled_count() const;)
+
// The location of the java heap data that corresponds to this region.
inline HeapWord* data_location() const;
@@ -296,6 +313,7 @@ public:
void set_partial_obj_size(size_t words) {
_partial_obj_size = (region_sz_t) words;
}
+ inline void set_blocks_filled();
inline void set_destination_count(uint count);
inline void set_live_obj_size(size_t words);
@@ -328,7 +346,11 @@ public:
HeapWord* _partial_obj_addr;
region_sz_t _partial_obj_size;
region_sz_t volatile _dc_and_los;
+ bool _blocks_filled;
+
#ifdef ASSERT
+ size_t _blocks_filled_count; // Number of block table fills.
+
// These enable optimizations that are only partially implemented. Use
// debug builds to prevent the code fragments from breaking.
HeapWord* _data_location;
@@ -337,11 +359,26 @@ public:
#ifdef ASSERT
public:
- uint _pushed; // 0 until region is pushed onto a worker's stack
+ uint _pushed; // 0 until region is pushed onto a stack
private:
#endif
};
+ // "Blocks" allow shorter sections of the bitmap to be searched. Each Block
+ // holds an offset, which is the amount of live data in the Region to the left
+ // of the first live object that starts in the Block.
+ class BlockData
+ {
+ public:
+ typedef unsigned short int blk_ofs_t;
+
+ blk_ofs_t offset() const { return _offset; }
+ void set_offset(size_t val) { _offset = (blk_ofs_t)val; }
+
+ private:
+ blk_ofs_t _offset;
+ };
+
public:
ParallelCompactData();
bool initialize(MemRegion covered_region);
@@ -353,8 +390,9 @@ public:
inline RegionData* region(size_t region_idx) const;
inline size_t region(const RegionData* const region_ptr) const;
- // Returns true if the given address is contained within the region
- bool region_contains(size_t region_index, HeapWord* addr);
+ size_t block_count() const { return _block_count; }
+ inline BlockData* block(size_t block_idx) const;
+ inline size_t block(const BlockData* block_ptr) const;
void add_obj(HeapWord* addr, size_t len);
void add_obj(oop p, size_t len) { add_obj((HeapWord*)p, len); }
@@ -394,11 +432,24 @@ public:
inline HeapWord* region_align_up(HeapWord* addr) const;
inline bool is_region_aligned(HeapWord* addr) const;
+ // Analogous to region_offset() for blocks.
+ size_t block_offset(const HeapWord* addr) const;
+ size_t addr_to_block_idx(const HeapWord* addr) const;
+ size_t addr_to_block_idx(const oop obj) const {
+ return addr_to_block_idx((HeapWord*) obj);
+ }
+ inline BlockData* addr_to_block_ptr(const HeapWord* addr) const;
+ inline HeapWord* block_to_addr(size_t block) const;
+ inline size_t region_to_block_idx(size_t region) const;
+
+ inline HeapWord* block_align_down(HeapWord* addr) const;
+ inline HeapWord* block_align_up(HeapWord* addr) const;
+ inline bool is_block_aligned(HeapWord* addr) const;
+
// Return the address one past the end of the partial object.
HeapWord* partial_obj_end(size_t region_idx) const;
- // Return the new location of the object p after the
- // the compaction.
+ // Return the location of the object after compaction.
HeapWord* calc_new_pointer(HeapWord* addr);
HeapWord* calc_new_pointer(oop p) {
@@ -411,6 +462,7 @@ public:
#endif // #ifdef ASSERT
private:
+ bool initialize_block_data();
bool initialize_region_data(size_t region_size);
PSVirtualSpace* create_vspace(size_t count, size_t element_size);
@@ -424,6 +476,10 @@ private:
size_t _reserved_byte_size;
RegionData* _region_data;
size_t _region_count;
+
+ PSVirtualSpace* _block_vspace;
+ BlockData* _block_data;
+ size_t _block_count;
};
inline uint
@@ -438,6 +494,28 @@ ParallelCompactData::RegionData::destination_count() const
return destination_count_raw() >> dc_shift;
}
+inline bool
+ParallelCompactData::RegionData::blocks_filled() const
+{
+ return _blocks_filled;
+}
+
+#ifdef ASSERT
+inline size_t
+ParallelCompactData::RegionData::blocks_filled_count() const
+{
+ return _blocks_filled_count;
+}
+#endif // #ifdef ASSERT
+
+inline void
+ParallelCompactData::RegionData::set_blocks_filled()
+{
+ _blocks_filled = true;
+ // Debug builds count the number of times the table was filled.
+ DEBUG_ONLY(Atomic::inc_ptr(&_blocks_filled_count));
+}
+
inline void
ParallelCompactData::RegionData::set_destination_count(uint count)
{
@@ -532,6 +610,12 @@ ParallelCompactData::region(const RegionData* const region_ptr) const
return pointer_delta(region_ptr, _region_data, sizeof(RegionData));
}
+inline ParallelCompactData::BlockData*
+ParallelCompactData::block(size_t n) const {
+ assert(n < block_count(), "bad arg");
+ return _block_data + n;
+}
+
inline size_t
ParallelCompactData::region_offset(const HeapWord* addr) const
{
@@ -598,6 +682,63 @@ ParallelCompactData::is_region_aligned(HeapWord* addr) const
return region_offset(addr) == 0;
}
+inline size_t
+ParallelCompactData::block_offset(const HeapWord* addr) const
+{
+ assert(addr >= _region_start, "bad addr");
+ assert(addr <= _region_end, "bad addr");
+ return (size_t(addr) & BlockAddrOffsetMask) >> LogHeapWordSize;
+}
+
+inline size_t
+ParallelCompactData::addr_to_block_idx(const HeapWord* addr) const
+{
+ assert(addr >= _region_start, "bad addr");
+ assert(addr <= _region_end, "bad addr");
+ return pointer_delta(addr, _region_start) >> Log2BlockSize;
+}
+
+inline ParallelCompactData::BlockData*
+ParallelCompactData::addr_to_block_ptr(const HeapWord* addr) const
+{
+ return block(addr_to_block_idx(addr));
+}
+
+inline HeapWord*
+ParallelCompactData::block_to_addr(size_t block) const
+{
+ assert(block < _block_count, "block out of range");
+ return _region_start + (block << Log2BlockSize);
+}
+
+inline size_t
+ParallelCompactData::region_to_block_idx(size_t region) const
+{
+ return region << Log2BlocksPerRegion;
+}
+
+inline HeapWord*
+ParallelCompactData::block_align_down(HeapWord* addr) const
+{
+ assert(addr >= _region_start, "bad addr");
+ assert(addr < _region_end + RegionSize, "bad addr");
+ return (HeapWord*)(size_t(addr) & BlockAddrMask);
+}
+
+inline HeapWord*
+ParallelCompactData::block_align_up(HeapWord* addr) const
+{
+ assert(addr >= _region_start, "bad addr");
+ assert(addr <= _region_end, "bad addr");
+ return block_align_down(addr + BlockSizeOffsetMask);
+}
+
+inline bool
+ParallelCompactData::is_block_aligned(HeapWord* addr) const
+{
+ return block_offset(addr) == 0;
+}
+
// Abstract closure for use with ParMarkBitMap::iterate(), which will invoke the
// do_addr() method.
//
@@ -775,6 +916,7 @@ class PSParallelCompact : AllStatic {
// Convenient access to type names.
typedef ParMarkBitMap::idx_t idx_t;
typedef ParallelCompactData::RegionData RegionData;
+ typedef ParallelCompactData::BlockData BlockData;
typedef enum {
old_space_id, eden_space_id,
@@ -962,6 +1104,8 @@ class PSParallelCompact : AllStatic {
// Adjust addresses in roots. Does not adjust addresses in heap.
static void adjust_roots();
+ DEBUG_ONLY(static void write_block_fill_histogram(outputStream* const out);)
+
// Move objects to new locations.
static void compact_perm(ParCompactionManager* cm);
static void compact();
@@ -1128,6 +1272,9 @@ class PSParallelCompact : AllStatic {
fill_region(cm, region);
}
+ // Fill in the block table for the specified region.
+ static void fill_blocks(size_t region_idx);
+
// Update the deferred objects in the space.
static void update_deferred_objects(ParCompactionManager* cm, SpaceId id);
From c39235c3779e48cc4d8c6ef147ab7af307d00faa Mon Sep 17 00:00:00 2001
From: Stefan Karlsson
Date: Thu, 30 May 2013 10:58:16 +0200
Subject: [PATCH 067/206] 8015486: PSScavenge::is_obj_in_young is unnecessarily
slow with UseCompressedOops
Compare compressed oops to a compressed young gen boundary instead of uncompressing the oops before doing the young gen boundary check.
Reviewed-by: brutisso, jmasa
---
.../psPromotionManager.inline.hpp | 2 +-
.../parallelScavenge/psScavenge.cpp | 5 ++-
.../parallelScavenge/psScavenge.hpp | 42 ++++++++++++-------
.../parallelScavenge/psScavenge.inline.hpp | 8 ++--
4 files changed, 35 insertions(+), 22 deletions(-)
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
index 8822a481b3d..96cd4cec706 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
@@ -42,7 +42,7 @@ inline void PSPromotionManager::claim_or_forward_internal_depth(T* p) {
if (o->is_forwarded()) {
o = o->forwardee();
// Card mark
- if (PSScavenge::is_obj_in_young((HeapWord*) o)) {
+ if (PSScavenge::is_obj_in_young(o)) {
PSScavenge::card_table()->inline_write_ref_field_gc(p, o);
}
oopDesc::encode_store_heap_oop_not_null(p, o);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index f209a802b3d..96a679a6654 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -61,6 +61,7 @@ CardTableExtension* PSScavenge::_card_table = NULL;
bool PSScavenge::_survivor_overflow = false;
uint PSScavenge::_tenuring_threshold = 0;
HeapWord* PSScavenge::_young_generation_boundary = NULL;
+uintptr_t PSScavenge::_young_generation_boundary_compressed = 0;
elapsedTimer PSScavenge::_accumulated_time;
Stack PSScavenge::_preserved_mark_stack;
Stack PSScavenge::_preserved_oop_stack;
@@ -71,7 +72,7 @@ bool PSScavenge::_promotion_failed = false;
class PSIsAliveClosure: public BoolObjectClosure {
public:
bool do_object_b(oop p) {
- return (!PSScavenge::is_obj_in_young((HeapWord*) p)) || p->is_forwarded();
+ return (!PSScavenge::is_obj_in_young(p)) || p->is_forwarded();
}
};
@@ -815,7 +816,7 @@ void PSScavenge::initialize() {
// Set boundary between young_gen and old_gen
assert(old_gen->reserved().end() <= young_gen->eden_space()->bottom(),
"old above young");
- _young_generation_boundary = young_gen->eden_space()->bottom();
+ set_young_generation_boundary(young_gen->eden_space()->bottom());
// Initialize ref handling object for scavenging.
MemRegion mr = young_gen->reserved();
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
index 43e59ac9cfb..7523f5bf603 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
@@ -62,19 +62,22 @@ class PSScavenge: AllStatic {
protected:
// Flags/counters
- static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
- static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
- static CardTableExtension* _card_table; // We cache the card table for fast access.
- static bool _survivor_overflow; // Overflow this collection
- static uint _tenuring_threshold; // tenuring threshold for next scavenge
- static elapsedTimer _accumulated_time; // total time spent on scavenge
- static HeapWord* _young_generation_boundary; // The lowest address possible for the young_gen.
- // This is used to decide if an oop should be scavenged,
- // cards should be marked, etc.
+ static ReferenceProcessor* _ref_processor; // Reference processor for scavenging.
+ static PSIsAliveClosure _is_alive_closure; // Closure used for reference processing
+ static CardTableExtension* _card_table; // We cache the card table for fast access.
+ static bool _survivor_overflow; // Overflow this collection
+ static uint _tenuring_threshold; // tenuring threshold for next scavenge
+ static elapsedTimer _accumulated_time; // total time spent on scavenge
+ // The lowest address possible for the young_gen.
+ // This is used to decide if an oop should be scavenged,
+ // cards should be marked, etc.
+ static HeapWord* _young_generation_boundary;
+ // Used to optimize compressed oops young gen boundary checking.
+ static uintptr_t _young_generation_boundary_compressed;
static Stack _preserved_mark_stack; // List of marks to be restored after failed promotion
static Stack _preserved_oop_stack; // List of oops that need their mark restored.
- static CollectorCounters* _counters; // collector performance counters
- static bool _promotion_failed;
+ static CollectorCounters* _counters; // collector performance counters
+ static bool _promotion_failed;
static void clean_up_failed_promotion();
@@ -112,6 +115,9 @@ class PSScavenge: AllStatic {
// boundary moves, _young_generation_boundary must be reset
static void set_young_generation_boundary(HeapWord* v) {
_young_generation_boundary = v;
+ if (UseCompressedOops) {
+ _young_generation_boundary_compressed = (uintptr_t)oopDesc::encode_heap_oop((oop)v);
+ }
}
// Called by parallelScavengeHeap to init the tenuring threshold
@@ -140,11 +146,19 @@ class PSScavenge: AllStatic {
static void copy_and_push_safe_barrier_from_klass(PSPromotionManager* pm, oop* p);
// Is an object in the young generation
- // This assumes that the HeapWord argument is in the heap,
+ // This assumes that the 'o' is in the heap,
// so it only checks one side of the complete predicate.
+
+ inline static bool is_obj_in_young(oop o) {
+ return (HeapWord*)o >= _young_generation_boundary;
+ }
+
+ inline static bool is_obj_in_young(narrowOop o) {
+ return (uintptr_t)o >= _young_generation_boundary_compressed;
+ }
+
inline static bool is_obj_in_young(HeapWord* o) {
- const bool result = (o >= _young_generation_boundary);
- return result;
+ return o >= _young_generation_boundary;
}
};
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp
index de015e8eb3d..e67dedf98d4 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.inline.hpp
@@ -39,9 +39,7 @@ inline void PSScavenge::save_to_space_top_before_gc() {
template inline bool PSScavenge::should_scavenge(T* p) {
T heap_oop = oopDesc::load_heap_oop(p);
- if (oopDesc::is_null(heap_oop)) return false;
- oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
- return PSScavenge::is_obj_in_young((HeapWord*)obj);
+ return PSScavenge::is_obj_in_young(heap_oop);
}
template
@@ -94,7 +92,7 @@ inline void PSScavenge::copy_and_push_safe_barrier(PSPromotionManager* pm,
// or from metadata.
if ((!PSScavenge::is_obj_in_young((HeapWord*)p)) &&
Universe::heap()->is_in_reserved(p)) {
- if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
+ if (PSScavenge::is_obj_in_young(new_obj)) {
card_table()->inline_write_ref_field_gc(p, new_obj);
}
}
@@ -147,7 +145,7 @@ class PSScavengeFromKlassClosure: public OopClosure {
}
oopDesc::encode_store_heap_oop_not_null(p, new_obj);
- if (PSScavenge::is_obj_in_young((HeapWord*)new_obj)) {
+ if (PSScavenge::is_obj_in_young(new_obj)) {
do_klass_barrier();
}
}
From 54964edefa5660b8252626d3e506d7b092718b73 Mon Sep 17 00:00:00 2001
From: Thomas Schatzl
Date: Tue, 28 May 2013 09:32:06 +0200
Subject: [PATCH 068/206] 8013895: G1: G1SummarizeRSetStats output on Linux
needs improvemen
Fixed the output of G1SummarizeRSetStats: too small datatype for the number of concurrently processed cards, added concurrent remembered set thread time retrieval for Linux and Windows (BSD uses os::elapsedTime() now), and other cleanup. The information presented during VM operation is now relative to the previous output, not always cumulative if G1SummarizeRSetStatsPeriod > 0. At VM exit, the code prints a cumulative summary.
Reviewed-by: johnc, jwilhelm
---
hotspot/make/excludeSrc.make | 2 +-
hotspot/src/os/bsd/vm/os_bsd.cpp | 4 +-
hotspot/src/os/linux/vm/os_linux.cpp | 22 +-
hotspot/src/os/windows/vm/os_windows.cpp | 18 +-
.../g1/concurrentG1Refine.cpp | 12 +
.../g1/concurrentG1Refine.hpp | 9 +-
.../gc_implementation/g1/g1CollectedHeap.cpp | 14 +-
.../vm/gc_implementation/g1/g1RemSet.cpp | 102 ++-------
.../vm/gc_implementation/g1/g1RemSet.hpp | 17 +-
.../gc_implementation/g1/g1RemSetSummary.cpp | 205 ++++++++++++++++++
.../gc_implementation/g1/g1RemSetSummary.hpp | 118 ++++++++++
.../test/gc/g1/TestSummarizeRSetStats.java | 164 ++++++++++++++
12 files changed, 585 insertions(+), 102 deletions(-)
create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp
create mode 100644 hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp
create mode 100644 hotspot/test/gc/g1/TestSummarizeRSetStats.java
diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make
index df9bc302165..2ce60e0a656 100644
--- a/hotspot/make/excludeSrc.make
+++ b/hotspot/make/excludeSrc.make
@@ -87,7 +87,7 @@ ifeq ($(INCLUDE_ALL_GCS), false)
g1BlockOffsetTable.cpp g1CardCounts.cpp g1CollectedHeap.cpp g1CollectorPolicy.cpp \
g1ErgoVerbose.cpp g1GCPhaseTimes.cpp g1HRPrinter.cpp g1HotCardCache.cpp g1Log.cpp \
g1MMUTracker.cpp g1MarkSweep.cpp g1MemoryPool.cpp g1MonitoringSupport.cpp \
- g1RemSet.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
+ g1RemSet.cpp g1RemSetSummary.cpp g1SATBCardTableModRefBS.cpp g1_globals.cpp heapRegion.cpp \
heapRegionRemSet.cpp heapRegionSeq.cpp heapRegionSet.cpp heapRegionSets.cpp \
ptrQueue.cpp satbQueue.cpp sparsePRT.cpp survRateGroup.cpp vm_operations_g1.cpp \
adjoiningGenerations.cpp adjoiningVirtualSpaces.cpp asPSOldGen.cpp asPSYoungGen.cpp \
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index f0b32196f5d..220a5e74655 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -935,10 +935,10 @@ jlong os::elapsed_frequency() {
return (1000 * 1000);
}
-// XXX: For now, code this as if BSD does not support vtime.
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
+
double os::elapsedVTime() {
// better than nothing, but not much
return elapsedTime();
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 4ca47019569..dbf30c48178 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -101,6 +101,12 @@
# include
# include
+// if RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling
+// getrusage() is prepared to handle the associated failure.
+#ifndef RUSAGE_THREAD
+#define RUSAGE_THREAD (1) /* only the calling thread */
+#endif
+
#define MAX_PATH (2 * K)
// for timer info max values which include all bits
@@ -1336,15 +1342,19 @@ jlong os::elapsed_frequency() {
return (1000 * 1000);
}
-// For now, we say that linux does not support vtime. I have no idea
-// whether it can actually be made to (DLD, 9/13/05).
-
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
+
double os::elapsedVTime() {
- // better than nothing, but not much
- return elapsedTime();
+ struct rusage usage;
+ int retval = getrusage(RUSAGE_THREAD, &usage);
+ if (retval == 0) {
+ return (double) (usage.ru_utime.tv_sec + usage.ru_stime.tv_sec) + (double) (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000 * 1000);
+ } else {
+ // better than nothing, but not much
+ return elapsedTime();
+ }
}
jlong os::javaTimeMillis() {
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 275dc3b809a..33ebe5987a1 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -813,15 +813,21 @@ FILETIME java_to_windows_time(jlong l) {
return result;
}
-// For now, we say that Windows does not support vtime. I have no idea
-// whether it can actually be made to (DLD, 9/13/05).
-
-bool os::supports_vtime() { return false; }
+bool os::supports_vtime() { return true; }
bool os::enable_vtime() { return false; }
bool os::vtime_enabled() { return false; }
+
double os::elapsedVTime() {
- // better than nothing, but not much
- return elapsedTime();
+ FILETIME created;
+ FILETIME exited;
+ FILETIME kernel;
+ FILETIME user;
+ if (GetThreadTimes(GetCurrentThread(), &created, &exited, &kernel, &user) != 0) {
+ // the resolution of windows_to_java_time() should be sufficient (ms)
+ return (double) (windows_to_java_time(kernel) + windows_to_java_time(user)) / MILLIUNITS;
+ } else {
+ return elapsedTime();
+ }
}
jlong os::javaTimeMillis() {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
index 5f049209e29..f0b4da8a885 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
@@ -114,6 +114,14 @@ void ConcurrentG1Refine::threads_do(ThreadClosure *tc) {
}
}
+void ConcurrentG1Refine::worker_threads_do(ThreadClosure * tc) {
+ if (_threads != NULL) {
+ for (int i = 0; i < worker_thread_num(); i++) {
+ tc->do_thread(_threads[i]);
+ }
+ }
+}
+
int ConcurrentG1Refine::thread_num() {
int n_threads = (G1ConcRefinementThreads > 0) ? G1ConcRefinementThreads
: ParallelGCThreads;
@@ -126,3 +134,7 @@ void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
st->cr();
}
}
+
+ConcurrentG1RefineThread * ConcurrentG1Refine::sampling_thread() const {
+ return _threads[worker_thread_num()];
+}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
index 46e6622eee7..3dc7c62423b 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
@@ -35,6 +35,7 @@ class ConcurrentG1RefineThread;
class G1CollectedHeap;
class G1HotCardCache;
class G1RemSet;
+class DirtyCardQueue;
class ConcurrentG1Refine: public CHeapObj {
ConcurrentG1RefineThread** _threads;
@@ -78,9 +79,15 @@ class ConcurrentG1Refine: public CHeapObj {
void reinitialize_threads();
- // Iterate over the conc refine threads
+ // Iterate over all concurrent refinement threads
void threads_do(ThreadClosure *tc);
+ // Iterate over all worker refinement threads
+ void worker_threads_do(ThreadClosure * tc);
+
+ // The RS sampling thread
+ ConcurrentG1RefineThread * sampling_thread() const;
+
static int thread_num();
void print_worker_threads_on(outputStream* st) const;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index c95cf0a0452..aff2d5da607 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -3539,6 +3539,14 @@ void G1CollectedHeap::gc_prologue(bool full /* Ignored */) {
}
void G1CollectedHeap::gc_epilogue(bool full /* Ignored */) {
+
+ if (G1SummarizeRSetStats &&
+ (G1SummarizeRSetStatsPeriod > 0) &&
+ // we are at the end of the GC. Total collections has already been increased.
+ ((total_collections() - 1) % G1SummarizeRSetStatsPeriod == 0)) {
+ g1_rem_set()->print_periodic_summary_info();
+ }
+
// FIXME: what is this about?
// I'm ignoring the "fill_newgen()" call if "alloc_event_enabled"
// is set.
@@ -4093,12 +4101,6 @@ G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
g1mm()->update_sizes();
}
- if (G1SummarizeRSetStats &&
- (G1SummarizeRSetStatsPeriod > 0) &&
- (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
- g1_rem_set()->print_summary_info();
- }
-
// It should now be safe to tell the concurrent mark thread to start
// without its logging output interfering with the logging output
// that came from the pause.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
index d527a3fc61d..ae4c6b63510 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
@@ -34,6 +34,7 @@
#include "gc_implementation/g1/g1OopClosures.inline.hpp"
#include "gc_implementation/g1/g1RemSet.inline.hpp"
#include "gc_implementation/g1/heapRegionSeq.inline.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
#include "memory/iterator.hpp"
#include "oops/oop.inline.hpp"
#include "utilities/intHisto.hpp"
@@ -73,7 +74,8 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
_ct_bs(ct_bs), _g1p(_g1->g1_policy()),
_cg1r(g1->concurrent_g1_refine()),
_cset_rs_update_cl(NULL),
- _cards_scanned(NULL), _total_cards_scanned(0)
+ _cards_scanned(NULL), _total_cards_scanned(0),
+ _prev_period_summary()
{
_seq_task = new SubTasksDone(NumSeqTasks);
guarantee(n_workers() > 0, "There should be some workers");
@@ -81,6 +83,7 @@ G1RemSet::G1RemSet(G1CollectedHeap* g1, CardTableModRefBS* ct_bs)
for (uint i = 0; i < n_workers(); i++) {
_cset_rs_update_cl[i] = NULL;
}
+ _prev_period_summary.initialize(this, n_workers());
}
G1RemSet::~G1RemSet() {
@@ -697,47 +700,29 @@ bool G1RemSet::refine_card(jbyte* card_ptr, int worker_i,
return has_refs_into_cset;
}
-class HRRSStatsIter: public HeapRegionClosure {
- size_t _occupied;
- size_t _total_mem_sz;
- size_t _max_mem_sz;
- HeapRegion* _max_mem_sz_region;
-public:
- HRRSStatsIter() :
- _occupied(0),
- _total_mem_sz(0),
- _max_mem_sz(0),
- _max_mem_sz_region(NULL)
- {}
+void G1RemSet::print_periodic_summary_info() {
+ G1RemSetSummary current;
+ current.initialize(this, n_workers());
- bool doHeapRegion(HeapRegion* r) {
- if (r->continuesHumongous()) return false;
- size_t mem_sz = r->rem_set()->mem_size();
- if (mem_sz > _max_mem_sz) {
- _max_mem_sz = mem_sz;
- _max_mem_sz_region = r;
- }
- _total_mem_sz += mem_sz;
- size_t occ = r->rem_set()->occupied();
- _occupied += occ;
- return false;
- }
- size_t total_mem_sz() { return _total_mem_sz; }
- size_t max_mem_sz() { return _max_mem_sz; }
- size_t occupied() { return _occupied; }
- HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
-};
+ _prev_period_summary.subtract_from(¤t);
+ print_summary_info(&_prev_period_summary);
-class PrintRSThreadVTimeClosure : public ThreadClosure {
-public:
- virtual void do_thread(Thread *t) {
- ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
- gclog_or_tty->print(" %5.2f", crt->vtime_accum());
- }
-};
+ _prev_period_summary.set(¤t);
+}
void G1RemSet::print_summary_info() {
- G1CollectedHeap* g1 = G1CollectedHeap::heap();
+ G1RemSetSummary current;
+ current.initialize(this, n_workers());
+
+ print_summary_info(¤t, " Cumulative RS summary");
+}
+
+void G1RemSet::print_summary_info(G1RemSetSummary * summary, const char * header) {
+ assert(summary != NULL, "just checking");
+
+ if (header != NULL) {
+ gclog_or_tty->print_cr("%s", header);
+ }
#if CARD_REPEAT_HISTO
gclog_or_tty->print_cr("\nG1 card_repeat count histogram: ");
@@ -745,46 +730,7 @@ void G1RemSet::print_summary_info() {
card_repeat_count.print_on(gclog_or_tty);
#endif
- gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
- _conc_refine_cards);
- DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
- jint tot_processed_buffers =
- dcqs.processed_buffers_mut() + dcqs.processed_buffers_rs_thread();
- gclog_or_tty->print_cr(" Of %d completed buffers:", tot_processed_buffers);
- gclog_or_tty->print_cr(" %8d (%5.1f%%) by conc RS threads.",
- dcqs.processed_buffers_rs_thread(),
- 100.0*(float)dcqs.processed_buffers_rs_thread()/
- (float)tot_processed_buffers);
- gclog_or_tty->print_cr(" %8d (%5.1f%%) by mutator threads.",
- dcqs.processed_buffers_mut(),
- 100.0*(float)dcqs.processed_buffers_mut()/
- (float)tot_processed_buffers);
- gclog_or_tty->print_cr(" Conc RS threads times(s)");
- PrintRSThreadVTimeClosure p;
- gclog_or_tty->print(" ");
- g1->concurrent_g1_refine()->threads_do(&p);
- gclog_or_tty->print_cr("");
-
- HRRSStatsIter blk;
- g1->heap_region_iterate(&blk);
- gclog_or_tty->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K."
- " Max = "SIZE_FORMAT"K.",
- blk.total_mem_sz()/K, blk.max_mem_sz()/K);
- gclog_or_tty->print_cr(" Static structures = "SIZE_FORMAT"K,"
- " free_lists = "SIZE_FORMAT"K.",
- HeapRegionRemSet::static_mem_size() / K,
- HeapRegionRemSet::fl_mem_size() / K);
- gclog_or_tty->print_cr(" "SIZE_FORMAT" occupied cards represented.",
- blk.occupied());
- HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
- HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
- gclog_or_tty->print_cr(" Max size region = "HR_FORMAT", "
- "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
- HR_FORMAT_PARAMS(max_mem_sz_region),
- (rem_set->mem_size() + K - 1)/K,
- (rem_set->occupied() + K - 1)/K);
- gclog_or_tty->print_cr(" Did %d coarsenings.",
- HeapRegionRemSet::n_coarsenings());
+ summary->print_on(gclog_or_tty);
}
void G1RemSet::prepare_for_verify() {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
index 7444ae819fc..954381f9138 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
@@ -25,6 +25,8 @@
#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
#define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSET_HPP
+#include "gc_implementation/g1/g1RemSetSummary.hpp"
+
// A G1RemSet provides ways of iterating over pointers into a selected
// collection set.
@@ -37,9 +39,11 @@ class ConcurrentG1Refine;
// so that they can be used to update the individual region remsets.
class G1RemSet: public CHeapObj {
+private:
+ G1RemSetSummary _prev_period_summary;
protected:
G1CollectedHeap* _g1;
- unsigned _conc_refine_cards;
+ size_t _conc_refine_cards;
uint n_workers();
protected:
@@ -66,6 +70,8 @@ protected:
// references into the collection set.
OopsInHeapRegionClosure** _cset_rs_update_cl;
+ // Print the given summary info
+ virtual void print_summary_info(G1RemSetSummary * summary, const char * header = NULL);
public:
// This is called to reset dual hash tables after the gc pause
// is finished and the initial hash table is no longer being
@@ -123,11 +129,18 @@ public:
int worker_i,
bool check_for_refs_into_cset);
- // Print any relevant summary info.
+ // Print accumulated summary info from the start of the VM.
virtual void print_summary_info();
+ // Print accumulated summary info from the last time called.
+ virtual void print_periodic_summary_info();
+
// Prepare remembered set for verification.
virtual void prepare_for_verify();
+
+ size_t conc_refine_cards() const {
+ return _conc_refine_cards;
+ }
};
class CountNonCleanMemRegionClosure: public MemRegionClosure {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp
new file mode 100644
index 00000000000..13acd1b0da8
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.cpp
@@ -0,0 +1,205 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/concurrentG1Refine.hpp"
+#include "gc_implementation/g1/concurrentG1RefineThread.hpp"
+#include "gc_implementation/g1/heapRegion.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1RemSet.inline.hpp"
+#include "gc_implementation/g1/g1RemSetSummary.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
+#include "runtime/thread.inline.hpp"
+
+class GetRSThreadVTimeClosure : public ThreadClosure {
+private:
+ G1RemSetSummary* _summary;
+ uint _counter;
+
+public:
+ GetRSThreadVTimeClosure(G1RemSetSummary * summary) : ThreadClosure(), _summary(summary), _counter(0) {
+ assert(_summary != NULL, "just checking");
+ }
+
+ virtual void do_thread(Thread* t) {
+ ConcurrentG1RefineThread* crt = (ConcurrentG1RefineThread*) t;
+ _summary->set_rs_thread_vtime(_counter, crt->vtime_accum());
+ _counter++;
+ }
+};
+
+void G1RemSetSummary::update() {
+ _num_refined_cards = remset()->conc_refine_cards();
+ DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
+ _num_processed_buf_mutator = dcqs.processed_buffers_mut();
+ _num_processed_buf_rs_threads = dcqs.processed_buffers_rs_thread();
+
+ _num_coarsenings = HeapRegionRemSet::n_coarsenings();
+
+ ConcurrentG1Refine * cg1r = G1CollectedHeap::heap()->concurrent_g1_refine();
+ if (_rs_threads_vtimes != NULL) {
+ GetRSThreadVTimeClosure p(this);
+ cg1r->worker_threads_do(&p);
+ }
+ set_sampling_thread_vtime(cg1r->sampling_thread()->vtime_accum());
+}
+
+void G1RemSetSummary::set_rs_thread_vtime(uint thread, double value) {
+ assert(_rs_threads_vtimes != NULL, "just checking");
+ assert(thread < _num_vtimes, "just checking");
+ _rs_threads_vtimes[thread] = value;
+}
+
+double G1RemSetSummary::rs_thread_vtime(uint thread) const {
+ assert(_rs_threads_vtimes != NULL, "just checking");
+ assert(thread < _num_vtimes, "just checking");
+ return _rs_threads_vtimes[thread];
+}
+
+void G1RemSetSummary::initialize(G1RemSet* remset, uint num_workers) {
+ assert(_rs_threads_vtimes == NULL, "just checking");
+ assert(remset != NULL, "just checking");
+
+ _remset = remset;
+ _num_vtimes = num_workers;
+ _rs_threads_vtimes = NEW_C_HEAP_ARRAY(double, _num_vtimes, mtGC);
+ memset(_rs_threads_vtimes, 0, sizeof(double) * _num_vtimes);
+
+ update();
+}
+
+void G1RemSetSummary::set(G1RemSetSummary* other) {
+ assert(other != NULL, "just checking");
+ assert(remset() == other->remset(), "just checking");
+ assert(_num_vtimes == other->_num_vtimes, "just checking");
+
+ _num_refined_cards = other->num_concurrent_refined_cards();
+
+ _num_processed_buf_mutator = other->num_processed_buf_mutator();
+ _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads();
+
+ _num_coarsenings = other->_num_coarsenings;
+
+ memcpy(_rs_threads_vtimes, other->_rs_threads_vtimes, sizeof(double) * _num_vtimes);
+
+ set_sampling_thread_vtime(other->sampling_thread_vtime());
+}
+
+void G1RemSetSummary::subtract_from(G1RemSetSummary* other) {
+ assert(other != NULL, "just checking");
+ assert(remset() == other->remset(), "just checking");
+ assert(_num_vtimes == other->_num_vtimes, "just checking");
+
+ _num_refined_cards = other->num_concurrent_refined_cards() - _num_refined_cards;
+
+ _num_processed_buf_mutator = other->num_processed_buf_mutator() - _num_processed_buf_mutator;
+ _num_processed_buf_rs_threads = other->num_processed_buf_rs_threads() - _num_processed_buf_rs_threads;
+
+ _num_coarsenings = other->num_coarsenings() - _num_coarsenings;
+
+ for (uint i = 0; i < _num_vtimes; i++) {
+ set_rs_thread_vtime(i, other->rs_thread_vtime(i) - rs_thread_vtime(i));
+ }
+
+ _sampling_thread_vtime = other->sampling_thread_vtime() - _sampling_thread_vtime;
+}
+
+class HRRSStatsIter: public HeapRegionClosure {
+ size_t _occupied;
+ size_t _total_mem_sz;
+ size_t _max_mem_sz;
+ HeapRegion* _max_mem_sz_region;
+public:
+ HRRSStatsIter() :
+ _occupied(0),
+ _total_mem_sz(0),
+ _max_mem_sz(0),
+ _max_mem_sz_region(NULL)
+ {}
+
+ bool doHeapRegion(HeapRegion* r) {
+ size_t mem_sz = r->rem_set()->mem_size();
+ if (mem_sz > _max_mem_sz) {
+ _max_mem_sz = mem_sz;
+ _max_mem_sz_region = r;
+ }
+ _total_mem_sz += mem_sz;
+ size_t occ = r->rem_set()->occupied();
+ _occupied += occ;
+ return false;
+ }
+ size_t total_mem_sz() { return _total_mem_sz; }
+ size_t max_mem_sz() { return _max_mem_sz; }
+ size_t occupied() { return _occupied; }
+ HeapRegion* max_mem_sz_region() { return _max_mem_sz_region; }
+};
+
+double calc_percentage(size_t numerator, size_t denominator) {
+ if (denominator != 0) {
+ return (double)numerator / denominator * 100.0;
+ } else {
+ return 0.0f;
+ }
+}
+
+void G1RemSetSummary::print_on(outputStream* out) {
+ out->print_cr("\n Concurrent RS processed "SIZE_FORMAT" cards",
+ num_concurrent_refined_cards());
+ out->print_cr(" Of %d completed buffers:", num_processed_buf_total());
+ out->print_cr(" %8d (%5.1f%%) by concurrent RS threads.",
+ num_processed_buf_total(),
+ calc_percentage(num_processed_buf_rs_threads(), num_processed_buf_total()));
+ out->print_cr(" %8d (%5.1f%%) by mutator threads.",
+ num_processed_buf_mutator(),
+ calc_percentage(num_processed_buf_mutator(), num_processed_buf_total()));
+ out->print_cr(" Concurrent RS threads times (s)");
+ out->print(" ");
+ for (uint i = 0; i < _num_vtimes; i++) {
+ out->print(" %5.2f", rs_thread_vtime(i));
+ }
+ out->cr();
+ out->print_cr(" Concurrent sampling threads times (s)");
+ out->print_cr(" %5.2f", sampling_thread_vtime());
+
+ HRRSStatsIter blk;
+ G1CollectedHeap::heap()->heap_region_iterate(&blk);
+ out->print_cr(" Total heap region rem set sizes = "SIZE_FORMAT"K."
+ " Max = "SIZE_FORMAT"K.",
+ blk.total_mem_sz()/K, blk.max_mem_sz()/K);
+ out->print_cr(" Static structures = "SIZE_FORMAT"K,"
+ " free_lists = "SIZE_FORMAT"K.",
+ HeapRegionRemSet::static_mem_size() / K,
+ HeapRegionRemSet::fl_mem_size() / K);
+ out->print_cr(" "SIZE_FORMAT" occupied cards represented.",
+ blk.occupied());
+ HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
+ HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
+ out->print_cr(" Max size region = "HR_FORMAT", "
+ "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
+ HR_FORMAT_PARAMS(max_mem_sz_region),
+ (rem_set->mem_size() + K - 1)/K,
+ (rem_set->occupied() + K - 1)/K);
+
+ out->print_cr(" Did %d coarsenings.", num_coarsenings());
+}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp
new file mode 100644
index 00000000000..7f5f377637a
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSetSummary.hpp
@@ -0,0 +1,118 @@
+/*
+ * 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
+
+#include "utilities/ostream.hpp"
+
+class G1RemSet;
+
+// A G1RemSetSummary manages statistical information about the G1RemSet
+
+class G1RemSetSummary VALUE_OBJ_CLASS_SPEC {
+private:
+ friend class GetRSThreadVTimeClosure;
+
+ G1RemSet* _remset;
+
+ G1RemSet* remset() const {
+ return _remset;
+ }
+
+ size_t _num_refined_cards;
+ size_t _num_processed_buf_mutator;
+ size_t _num_processed_buf_rs_threads;
+
+ size_t _num_coarsenings;
+
+ double* _rs_threads_vtimes;
+ size_t _num_vtimes;
+
+ double _sampling_thread_vtime;
+
+ void set_rs_thread_vtime(uint thread, double value);
+ void set_sampling_thread_vtime(double value) {
+ _sampling_thread_vtime = value;
+ }
+
+ void free_and_null() {
+ if (_rs_threads_vtimes) {
+ FREE_C_HEAP_ARRAY(double, _rs_threads_vtimes, mtGC);
+ _rs_threads_vtimes = NULL;
+ _num_vtimes = 0;
+ }
+ }
+
+ // update this summary with current data from various places
+ void update();
+
+public:
+ G1RemSetSummary() : _remset(NULL), _num_refined_cards(0),
+ _num_processed_buf_mutator(0), _num_processed_buf_rs_threads(0), _num_coarsenings(0),
+ _rs_threads_vtimes(NULL), _num_vtimes(0), _sampling_thread_vtime(0.0f) {
+ }
+
+ ~G1RemSetSummary() {
+ free_and_null();
+ }
+
+ // set the counters in this summary to the values of the others
+ void set(G1RemSetSummary* other);
+ // subtract all counters from the other summary, and set them in the current
+ void subtract_from(G1RemSetSummary* other);
+
+ // initialize and get the first sampling
+ void initialize(G1RemSet* remset, uint num_workers);
+
+ void print_on(outputStream* out);
+
+ double rs_thread_vtime(uint thread) const;
+
+ double sampling_thread_vtime() const {
+ return _sampling_thread_vtime;
+ }
+
+ size_t num_concurrent_refined_cards() const {
+ return _num_refined_cards;
+ }
+
+ size_t num_processed_buf_mutator() const {
+ return _num_processed_buf_mutator;
+ }
+
+ size_t num_processed_buf_rs_threads() const {
+ return _num_processed_buf_rs_threads;
+ }
+
+ size_t num_processed_buf_total() const {
+ return num_processed_buf_mutator() + num_processed_buf_rs_threads();
+ }
+
+ size_t num_coarsenings() const {
+ return _num_coarsenings;
+ }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1REMSETSUMMARY_HPP
diff --git a/hotspot/test/gc/g1/TestSummarizeRSetStats.java b/hotspot/test/gc/g1/TestSummarizeRSetStats.java
new file mode 100644
index 00000000000..1990d4c6f39
--- /dev/null
+++ b/hotspot/test/gc/g1/TestSummarizeRSetStats.java
@@ -0,0 +1,164 @@
+/*
+ * 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 TestSummarizeRSetStats.java
+ * @bug 8013895
+ * @library /testlibrary
+ * @build TestSummarizeRSetStats
+ * @summary Verify output of -XX:+G1SummarizeRSetStats
+ * @run main TestSummarizeRSetStats
+ *
+ * Test the output of G1SummarizeRSetStats in conjunction with G1SummarizeRSetStatsPeriod.
+ */
+
+import com.oracle.java.testlibrary.*;
+import java.lang.Thread;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+class RunSystemGCs {
+ // 4M size, both are directly allocated into the old gen
+ static Object[] largeObject1 = new Object[1024 * 1024];
+ static Object[] largeObject2 = new Object[1024 * 1024];
+
+ static int[] temp;
+
+ public static void main(String[] args) {
+ // create some cross-references between these objects
+ for (int i = 0; i < largeObject1.length; i++) {
+ largeObject1[i] = largeObject2;
+ }
+
+ for (int i = 0; i < largeObject2.length; i++) {
+ largeObject2[i] = largeObject1;
+ }
+
+ int numGCs = Integer.parseInt(args[0]);
+
+ if (numGCs > 0) {
+ // try to force a minor collection: the young gen is 4M, the
+ // amount of data allocated below is roughly that (4*1024*1024 +
+ // some header data)
+ for (int i = 0; i < 1024 ; i++) {
+ temp = new int[1024];
+ }
+ }
+
+ for (int i = 0; i < numGCs - 1; i++) {
+ System.gc();
+ }
+ }
+}
+
+public class TestSummarizeRSetStats {
+
+ public static String runTest(String[] additionalArgs, int numGCs) throws Exception {
+ ArrayList finalargs = new ArrayList();
+ String[] defaultArgs = new String[] {
+ "-XX:+UseG1GC",
+ "-Xmn4m",
+ "-Xmx20m",
+ "-XX:InitiatingHeapOccupancyPercent=100", // we don't want the additional GCs due to initial marking
+ "-XX:+PrintGC",
+ "-XX:+UnlockDiagnosticVMOptions",
+ "-XX:G1HeapRegionSize=1M",
+ };
+
+ finalargs.addAll(Arrays.asList(defaultArgs));
+
+ if (additionalArgs != null) {
+ finalargs.addAll(Arrays.asList(additionalArgs));
+ }
+
+ finalargs.add(RunSystemGCs.class.getName());
+ finalargs.add(String.valueOf(numGCs));
+
+ ProcessBuilder pb = ProcessTools.createJavaProcessBuilder(
+ finalargs.toArray(new String[0]));
+ OutputAnalyzer output = new OutputAnalyzer(pb.start());
+
+ output.shouldHaveExitValue(0);
+
+ String result = output.getStdout();
+ return result;
+ }
+
+ private static void expectStatistics(String result, int expectedCumulative, int expectedPeriodic) throws Exception {
+ int actualTotal = result.split("Concurrent RS processed").length - 1;
+ int actualCumulative = result.split("Cumulative RS summary").length - 1;
+
+ if (expectedCumulative != actualCumulative) {
+ throw new Exception("Incorrect amount of RSet summaries at the end. Expected " + expectedCumulative + ", got " + actualCumulative);
+ }
+
+ if (expectedPeriodic != (actualTotal - actualCumulative)) {
+ throw new Exception("Incorrect amount of per-period RSet summaries at the end. Expected " + expectedPeriodic + ", got " + (actualTotal - actualCumulative));
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ String result;
+
+ // no RSet statistics output
+ result = runTest(null, 0);
+ expectStatistics(result, 0, 0);
+
+ // no RSet statistics output
+ result = runTest(null, 2);
+ expectStatistics(result, 0, 0);
+
+ // no RSet statistics output
+ result = runTest(new String[] { "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+ expectStatistics(result, 0, 0);
+
+ // single RSet statistics output at the end
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 0);
+ expectStatistics(result, 1, 0);
+
+ // single RSet statistics output at the end
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats" }, 2);
+ expectStatistics(result, 1, 0);
+
+ // single RSet statistics output
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 0);
+ expectStatistics(result, 1, 0);
+
+ // two times RSet statistics output
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 1);
+ expectStatistics(result, 1, 1);
+
+ // four times RSet statistics output
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=1" }, 3);
+ expectStatistics(result, 1, 3);
+
+ // three times RSet statistics output
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=2" }, 3);
+ expectStatistics(result, 1, 2);
+
+ // single RSet statistics output
+ result = runTest(new String[] { "-XX:+G1SummarizeRSetStats", "-XX:G1SummarizeRSetStatsPeriod=100" }, 3);
+ expectStatistics(result, 1, 1);
+ }
+}
+
From d2583c85157ed7e30fcb741459f56d36c1360d81 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Tue, 28 May 2013 16:37:11 +0530
Subject: [PATCH 069/206] 8015459: Octane test run fails on Turkish locale
Reviewed-by: lagergren, attila
---
nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java | 3 ++-
nashorn/src/jdk/nashorn/internal/objects/DateParser.java | 5 +++--
nashorn/src/jdk/nashorn/internal/parser/TokenType.java | 3 ++-
.../src/jdk/nashorn/internal/runtime/GlobalFunctions.java | 5 +++--
nashorn/src/jdk/nashorn/internal/runtime/JSType.java | 3 ++-
nashorn/src/jdk/nashorn/internal/runtime/Logging.java | 3 ++-
nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java | 3 ++-
.../jdk/nashorn/internal/runtime/options/OptionTemplate.java | 2 +-
8 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
index aae2fd2df7c..21b61cd8ec5 100644
--- a/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CodeGenerator.java
@@ -58,6 +58,7 @@ import java.util.EnumSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
+import java.util.Locale;
import java.util.TreeMap;
import jdk.nashorn.internal.codegen.ClassEmitter.Flag;
@@ -2220,7 +2221,7 @@ final class CodeGenerator extends NodeOperatorVisitor {
this.params = arg;
break;
case "type":
- this.type = arg.toLowerCase(Locale.ROOT);
+ this.type = arg.toLowerCase(Locale.ENGLISH);
break;
case "default":
this.defaultValue = arg;
From e58031cebaedb81897301900e64d72745e498c6f Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 28 May 2013 12:46:10 +0100
Subject: [PATCH 070/206] 6970173: Debug pointer at bad position
Reviewed-by: mcimadamore
---
.../com/sun/tools/javac/comp/Lower.java | 2 +-
.../DebugPointerAtBadPositionTest.java | 112 ++++++++++++++++++
2 files changed, 113 insertions(+), 1 deletion(-)
create mode 100644 langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 98ee76968d2..2e08b47b618 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -2931,7 +2931,7 @@ public class Lower extends TreeTranslator {
}
result =
make.If(cond,
- make_at(detailPos).
+ make_at(tree).
Throw(makeNewClass(syms.assertionErrorType, exnArgs)),
null);
} else {
diff --git a/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java b/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java
new file mode 100644
index 00000000000..a66f7ca93d1
--- /dev/null
+++ b/langtools/test/tools/javac/T6970173/DebugPointerAtBadPositionTest.java
@@ -0,0 +1,112 @@
+/*
+ * 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 6970173
+ * @summary Debug pointer at bad position
+ * @library /tools/javac/lib
+ * @build ToolBox
+ * @run main DebugPointerAtBadPositionTest
+ */
+
+import java.io.File;
+import java.nio.file.Paths;
+
+import com.sun.tools.classfile.ClassFile;
+import com.sun.tools.classfile.Code_attribute;
+import com.sun.tools.classfile.LineNumberTable_attribute;
+import com.sun.tools.classfile.Method;
+import com.sun.tools.javac.util.Assert;
+
+public class DebugPointerAtBadPositionTest {
+
+ static final String testSource =
+ "public class AssertionTest {\n" +
+ " void lookForThisMethod() {\n" +
+ " int i;\n" +
+ " i = 33;\n" +
+ " assert // line 5\n" +
+ " i < 89:\n" +
+ " i < 100; // line 7\n" +
+ " }\n" +
+ "}";
+
+ static final int[][] expectedLNT = {
+ {4, 0},
+ {5, 3},
+ {8, 34}
+ };
+
+ static final String methodToLookFor = "lookForThisMethod";
+ static final String seekMethodNotFoundMsg =
+ "The seek method was not found";
+ static final String foundLNTLengthDifferentThanExpMsg =
+ "The LineNumberTable found has a length different to the expected one";
+
+ public static void main(String[] args) throws Exception {
+ new DebugPointerAtBadPositionTest().run();
+ }
+
+ void run() throws Exception {
+ compileTestClass();
+ checkClassFile(new File(Paths.get(System.getProperty("user.dir"),
+ "AssertionTest.class").toUri()), methodToLookFor);
+ }
+
+ void compileTestClass() throws Exception {
+ ToolBox.JavaToolArgs javacSuccessArgs =
+ new ToolBox.JavaToolArgs().setSources(testSource);
+ ToolBox.javac(javacSuccessArgs);
+ }
+
+ void checkClassFile(final File cfile, String methodToFind) throws Exception {
+ ClassFile classFile = ClassFile.read(cfile);
+ boolean methodFound = false;
+ for (Method method : classFile.methods) {
+ if (method.getName(classFile.constant_pool).equals(methodToFind)) {
+ methodFound = true;
+ Code_attribute code = (Code_attribute) method.attributes.get("Code");
+ LineNumberTable_attribute lnt =
+ (LineNumberTable_attribute) code.attributes.get("LineNumberTable");
+ Assert.check(lnt.line_number_table_length == expectedLNT.length,
+ foundLNTLengthDifferentThanExpMsg);
+ int i = 0;
+ for (LineNumberTable_attribute.Entry entry: lnt.line_number_table) {
+ Assert.check(entry.line_number == expectedLNT[i][0] &&
+ entry.start_pc == expectedLNT[i][1],
+ "LNT entry at pos " + i + " differ from expected." +
+ "Found " + entry.line_number + ":" + entry.start_pc +
+ ". Expected " + expectedLNT[i][0] + ":" + expectedLNT[i][1]);
+ i++;
+ }
+ }
+ }
+ Assert.check(methodFound, seekMethodNotFoundMsg);
+ }
+
+ void error(String msg) {
+ throw new AssertionError(msg);
+ }
+
+}
From 7f2a2f1460e0c397e9a867ccd2efe382f4093535 Mon Sep 17 00:00:00 2001
From: Christian Tornqvist
Date: Tue, 28 May 2013 15:08:57 +0200
Subject: [PATCH 071/206] 8015329: Print reason for failed MiniDumpWriteDump()
call
Printing both result from GetLastError and text representation of error. Also changed so that we produce dumps by default on client versions of Windows when running with a debug build. Also reviewed by peter.allwin@oracle.com
Reviewed-by: sla, dholmes
---
hotspot/src/os/windows/vm/os_windows.cpp | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index 5a05d416a98..275dc3b809a 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -944,6 +944,8 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
MINIDUMP_TYPE dumpType;
static const char* cwd;
+// Default is to always create dump for debug builds, on product builds only dump on server versions of Windows.
+#ifndef ASSERT
// If running on a client version of Windows and user has not explicitly enabled dumping
if (!os::win32::is_windows_server() && !CreateMinidumpOnCrash) {
VMError::report_coredump_status("Minidumps are not enabled by default on client versions of Windows", false);
@@ -953,6 +955,12 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
VMError::report_coredump_status("Minidump has been disabled from the command line", false);
return;
}
+#else
+ if (!FLAG_IS_DEFAULT(CreateMinidumpOnCrash) && !CreateMinidumpOnCrash) {
+ VMError::report_coredump_status("Minidump has been disabled from the command line", false);
+ return;
+ }
+#endif
dbghelp = os::win32::load_Windows_dll("DBGHELP.DLL", NULL, 0);
@@ -1004,7 +1012,21 @@ void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char*
// the dump types we really want. If first call fails, lets fall back to just use MiniDumpWithFullMemory then.
if (_MiniDumpWriteDump(hProcess, processId, dumpFile, dumpType, pmei, NULL, NULL) == false &&
_MiniDumpWriteDump(hProcess, processId, dumpFile, (MINIDUMP_TYPE)MiniDumpWithFullMemory, pmei, NULL, NULL) == false) {
- VMError::report_coredump_status("Call to MiniDumpWriteDump() failed", false);
+ DWORD error = GetLastError();
+ LPTSTR msgbuf = NULL;
+
+ if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, error, 0, (LPTSTR)&msgbuf, 0, NULL) != 0) {
+
+ jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x: %s)", error, msgbuf);
+ LocalFree(msgbuf);
+ } else {
+ // Call to FormatMessage failed, just include the result from GetLastError
+ jio_snprintf(buffer, bufferSize, "Call to MiniDumpWriteDump() failed (Error 0x%x)", error);
+ }
+ VMError::report_coredump_status(buffer, false);
} else {
VMError::report_coredump_status(buffer, true);
}
From b0dcc34e06089cd76a0c85f39b0ed0d88418c33c Mon Sep 17 00:00:00 2001
From: Joseph Provino
Date: Tue, 28 May 2013 11:17:16 -0400
Subject: [PATCH 072/206] 8013461: There is a symbol AsyncGetCallTrace in
libjvm.symbols that does not exist in minimal/libjvm.a when DEBUG_LEVEL ==
release
AsyncGetCallTrace is needed in libjvm.symbols so that programs which reference it can build correctly.
Reviewed-by: dholmes, bobv
---
hotspot/make/excludeSrc.make | 2 +-
hotspot/src/share/vm/prims/forte.cpp | 38 ++++++++++++++++++----------
2 files changed, 25 insertions(+), 15 deletions(-)
diff --git a/hotspot/make/excludeSrc.make b/hotspot/make/excludeSrc.make
index 93f68ee41c0..df9bc302165 100644
--- a/hotspot/make/excludeSrc.make
+++ b/hotspot/make/excludeSrc.make
@@ -25,7 +25,7 @@ ifeq ($(INCLUDE_JVMTI), false)
CXXFLAGS += -DINCLUDE_JVMTI=0
CFLAGS += -DINCLUDE_JVMTI=0
- Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp forte.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
+ Src_Files_EXCLUDE += jvmtiGetLoadedClasses.cpp jvmtiThreadState.cpp jvmtiExtensions.cpp \
jvmtiImpl.cpp jvmtiManageCapabilities.cpp jvmtiRawMonitor.cpp jvmtiUtil.cpp jvmtiTrace.cpp \
jvmtiCodeBlobEvents.cpp jvmtiEnv.cpp jvmtiRedefineClasses.cpp jvmtiEnvBase.cpp jvmtiEnvThreadState.cpp \
jvmtiTagMap.cpp jvmtiEventController.cpp evmCompat.cpp jvmtiEnter.xsl jvmtiExport.cpp \
diff --git a/hotspot/src/share/vm/prims/forte.cpp b/hotspot/src/share/vm/prims/forte.cpp
index 33419f29836..737dcecd0e1 100644
--- a/hotspot/src/share/vm/prims/forte.cpp
+++ b/hotspot/src/share/vm/prims/forte.cpp
@@ -35,6 +35,19 @@
#include "runtime/vframe.hpp"
#include "runtime/vframeArray.hpp"
+// call frame copied from old .h file and renamed
+typedef struct {
+ jint lineno; // line number in the source file
+ jmethodID method_id; // method executed in this frame
+} ASGCT_CallFrame;
+
+// call trace copied from old .h file and renamed
+typedef struct {
+ JNIEnv *env_id; // Env where trace was recorded
+ jint num_frames; // number of frames in this trace
+ ASGCT_CallFrame *frames; // frames
+} ASGCT_CallTrace;
+
// These name match the names reported by the forte quality kit
enum {
ticks_no_Java_frame = 0,
@@ -50,6 +63,8 @@ enum {
ticks_safepoint = -10
};
+#if INCLUDE_JVMTI
+
//-------------------------------------------------------
// Native interfaces for use by Forte tools.
@@ -360,20 +375,6 @@ static bool find_initial_Java_frame(JavaThread* thread,
}
-
-// call frame copied from old .h file and renamed
-typedef struct {
- jint lineno; // line number in the source file
- jmethodID method_id; // method executed in this frame
-} ASGCT_CallFrame;
-
-// call trace copied from old .h file and renamed
-typedef struct {
- JNIEnv *env_id; // Env where trace was recorded
- jint num_frames; // number of frames in this trace
- ASGCT_CallFrame *frames; // frames
-} ASGCT_CallTrace;
-
static void forte_fill_call_trace_given_top(JavaThread* thd,
ASGCT_CallTrace* trace,
int depth,
@@ -634,3 +635,12 @@ void Forte::register_stub(const char* name, address start, address end) {
pointer_delta(end, start, sizeof(jbyte)), 0, NULL);
#endif // !_WINDOWS && !IA64
}
+
+#else // INCLUDE_JVMTI
+extern "C" {
+ JNIEXPORT
+ void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext) {
+ trace->num_frames = ticks_no_class_load; // -1
+ }
+}
+#endif // INCLUDE_JVMTI
From 8d4061812f566f10543125e7dd12f0aa932c856c Mon Sep 17 00:00:00 2001
From: Joseph Provino
Date: Tue, 28 May 2013 11:32:46 -0400
Subject: [PATCH 073/206] 8011064: Some tests have failed with SIGSEGV on
arm-hflt on build b82
NMT_detail is only supported when frame pointers are not omitted (-fno-omit-frame-pointer).
Reviewed-by: dholmes, cjplummer
---
hotspot/src/share/vm/services/memTracker.cpp | 11 ++++++++++-
hotspot/src/share/vm/utilities/globalDefinitions.hpp | 8 ++++++++
2 files changed, 18 insertions(+), 1 deletion(-)
diff --git a/hotspot/src/share/vm/services/memTracker.cpp b/hotspot/src/share/vm/services/memTracker.cpp
index a89de2f40af..0e6f7c42e57 100644
--- a/hotspot/src/share/vm/services/memTracker.cpp
+++ b/hotspot/src/share/vm/services/memTracker.cpp
@@ -34,6 +34,7 @@
#include "services/memReporter.hpp"
#include "services/memTracker.hpp"
#include "utilities/decoder.hpp"
+#include "utilities/defaultStream.hpp"
#include "utilities/globalDefinitions.hpp"
bool NMT_track_callsite = false;
@@ -77,7 +78,15 @@ void MemTracker::init_tracking_options(const char* option_line) {
if (strcmp(option_line, "=summary") == 0) {
_tracking_level = NMT_summary;
} else if (strcmp(option_line, "=detail") == 0) {
- _tracking_level = NMT_detail;
+ // detail relies on a stack-walking ability that may not
+ // be available depending on platform and/or compiler flags
+ if (PLATFORM_NMT_DETAIL_SUPPORTED) {
+ _tracking_level = NMT_detail;
+ } else {
+ jio_fprintf(defaultStream::error_stream(),
+ "NMT detail is not supported on this platform. Using NMT summary instead.");
+ _tracking_level = NMT_summary;
+ }
} else if (strcmp(option_line, "=off") != 0) {
vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
}
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index 5609ffdf431..d9088307a97 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -380,6 +380,14 @@ const uint64_t KlassEncodingMetaspaceMax = (uint64_t(max_juint) + 1) << LogKlass
# include "globalDefinitions_ppc.hpp"
#endif
+/*
+ * If a platform does not support NMT_detail
+ * the platform specific globalDefinitions (above)
+ * can set PLATFORM_NMT_DETAIL_SUPPORTED to false
+ */
+#ifndef PLATFORM_NMT_DETAIL_SUPPORTED
+#define PLATFORM_NMT_DETAIL_SUPPORTED true
+#endif
// The byte alignment to be used by Arena::Amalloc. See bugid 4169348.
// Note: this value must be a power of 2
From 0793ab7e650022fa61ef49a27021ecc5218e12bd Mon Sep 17 00:00:00 2001
From: Aleksey Shipilev
Date: Tue, 28 May 2013 19:54:18 +0400
Subject: [PATCH 074/206] 8015493: runtime/contended/OopMaps.java fails with
OutOfMemory
Limit the memory footprint to dodge OutOfMemory errors.
Reviewed-by: dcubed, ctornqvi, iignatyev
---
hotspot/test/runtime/contended/OopMaps.java | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/hotspot/test/runtime/contended/OopMaps.java b/hotspot/test/runtime/contended/OopMaps.java
index b8dfbba416b..8faa0bee2ac 100644
--- a/hotspot/test/runtime/contended/OopMaps.java
+++ b/hotspot/test/runtime/contended/OopMaps.java
@@ -41,12 +41,15 @@ import sun.misc.Contended;
/*
* @test
* @bug 8015270
+ * @bug 8015493
* @summary \@Contended: fix multiple issues in the layout code
*
- * @run main/othervm -XX:-RestrictContended OopMaps
+ * @run main/othervm -XX:-RestrictContended -XX:ContendedPaddingWidth=128 -Xmx128m OopMaps
*/
public class OopMaps {
+ public static final int COUNT = 10000;
+
public static void main(String[] args) throws Exception {
Object o01 = new Object();
Object o02 = new Object();
@@ -63,7 +66,6 @@ public class OopMaps {
Object o13 = new Object();
Object o14 = new Object();
- final int COUNT = 100000;
R1[] rs = new R1[COUNT];
for (int i = 0; i < COUNT; i++) {
From bbae50582f86f8da3e13b8479a1a36e285be831b Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Tue, 28 May 2013 17:39:41 +0100
Subject: [PATCH 075/206] 8012333: javac, ClassFile should have a read(Path)
method
Reviewed-by: jjg
---
.../share/classes/com/sun/tools/classfile/ClassFile.java | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java
index 9a68f617365..e8b5fc8d85a 100644
--- a/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java
+++ b/langtools/src/share/classes/com/sun/tools/classfile/ClassFile.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.nio.file.Path;
import static com.sun.tools.classfile.AccessFlags.*;
@@ -46,6 +47,11 @@ public class ClassFile {
return read(file, new Attribute.Factory());
}
+ public static ClassFile read(Path path)
+ throws IOException, ConstantPoolException {
+ return read(path.toFile(), new Attribute.Factory());
+ }
+
public static ClassFile read(File file, Attribute.Factory attributeFactory)
throws IOException, ConstantPoolException {
FileInputStream in = new FileInputStream(file);
From ee0d343130f058a87a008c402c747f0f375fb99a Mon Sep 17 00:00:00 2001
From: Klara Ward
Date: Tue, 28 May 2013 20:03:21 +0200
Subject: [PATCH 076/206] 8014762: Add JMC configure option mapping to Jprt.gmk
Need to add the mapping between JPRT env var and configure flag for JMC, from ALT_JMC_ZIP_DIR to --with-jmc-zip-dir (same pattern as for Javafx)
Reviewed-by: tbell, erikj
---
common/autoconf/generated-configure.sh | 38 +++++++++++++-------------
common/makefiles/Jprt.gmk | 3 ++
2 files changed, 22 insertions(+), 19 deletions(-)
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 832b6410016..8fb1be7c79a 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -2844,7 +2844,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;}
|| { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "failed to load site script $ac_site_file
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
done
@@ -3775,7 +3775,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1367502949
+DATE_WHEN_GENERATED=1369764185
###############################################################################
#
@@ -6608,7 +6608,7 @@ fi
$as_echo "$ac_cv_build" >&6; }
case $ac_cv_build in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;;
esac
build=$ac_cv_build
ac_save_IFS=$IFS; IFS='-'
@@ -6641,7 +6641,7 @@ fi
$as_echo "$ac_cv_host" >&6; }
case $ac_cv_host in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;;
esac
host=$ac_cv_host
ac_save_IFS=$IFS; IFS='-'
@@ -6674,7 +6674,7 @@ fi
$as_echo "$ac_cv_target" >&6; }
case $ac_cv_target in
*-*-*) ;;
-*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5 ;;
+*) as_fn_error $? "invalid value of canonical target" "$LINENO" 5;;
esac
target=$ac_cv_target
ac_save_IFS=$IFS; IFS='-'
@@ -19747,7 +19747,7 @@ fi
test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "no acceptable C compiler found in \$PATH
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
@@ -19862,7 +19862,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "C compiler cannot create executables
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
$as_echo "yes" >&6; }
@@ -19905,7 +19905,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest conftest$ac_cv_exeext
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -19964,7 +19964,7 @@ $as_echo "$ac_try_echo"; } >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot run C compiled programs.
If you meant to cross compile, use \`--host'.
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
fi
fi
@@ -20016,7 +20016,7 @@ sed 's/^/| /' conftest.$ac_ext >&5
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
@@ -24191,7 +24191,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=cpp
@@ -24591,7 +24591,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error $? "C++ preprocessor \"$CXXCPP\" fails sanity check
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=cpp
@@ -28426,7 +28426,7 @@ else
{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
as_fn_error 77 "cannot compute sizeof (int *)
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
ac_cv_sizeof_int_p=0
fi
@@ -29640,7 +29640,7 @@ if test "x$with_x" = xno; then
have_x=disabled
else
case $x_includes,$x_libraries in #(
- *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5 ;; #(
+ *\'*) as_fn_error $? "cannot use X directory names containing '" "$LINENO" 5;; #(
*,NONE | NONE,*) if test "${ac_cv_have_x+set}" = set; then :
$as_echo_n "(cached) " >&6
else
@@ -32295,7 +32295,7 @@ and LIBFFI_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.
To get pkg-config, see .
-See \`config.log' for more details" "$LINENO" 5 ; }
+See \`config.log' for more details" "$LINENO" 5; }
else
LIBFFI_CFLAGS=$pkg_cv_LIBFFI_CFLAGS
LIBFFI_LIBS=$pkg_cv_LIBFFI_LIBS
@@ -33825,7 +33825,7 @@ do
"$OUTPUT_ROOT/spec.sh") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/spec.sh:$AUTOCONF_DIR/spec.sh.in" ;;
"$OUTPUT_ROOT/Makefile") CONFIG_FILES="$CONFIG_FILES $OUTPUT_ROOT/Makefile:$AUTOCONF_DIR/Makefile.in" ;;
- *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5 ;;
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
@@ -34140,7 +34140,7 @@ do
esac
case $ac_mode$ac_tag in
:[FHL]*:*);;
- :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5 ;;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
:[FH]-) ac_tag=-:-;;
:[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
esac
@@ -34168,7 +34168,7 @@ do
[\\/$]*) false;;
*) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
esac ||
- as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5 ;;
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
esac
case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
as_fn_append ac_file_inputs " '$ac_f'"
@@ -34195,7 +34195,7 @@ $as_echo "$as_me: creating $ac_file" >&6;}
case $ac_tag in
*:-:* | *:-) cat >"$tmp/stdin" \
- || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
esac
;;
esac
diff --git a/common/makefiles/Jprt.gmk b/common/makefiles/Jprt.gmk
index c38dedce1f5..576f34d4b4d 100644
--- a/common/makefiles/Jprt.gmk
+++ b/common/makefiles/Jprt.gmk
@@ -127,6 +127,9 @@ else
ifdef ALT_JAVAFX_ZIP_DIR
@$(ECHO) " --with-javafx-zip-dir=$(call UnixPath,$(ALT_JAVAFX_ZIP_DIR)) " >> $@.tmp
endif
+ ifdef ALT_JMC_ZIP_DIR
+ @$(ECHO) " --with-jmc-zip-dir=$(call UnixPath,$(ALT_JMC_ZIP_DIR)) " >> $@.tmp
+ endif
ifdef ALT_WIXDIR
@$(ECHO) " --with-wix=$(call UnixPath,$(ALT_WIXDIR)) " >> $@.tmp
endif
From 9dc36eb9234346e83d1fb2f95265719eac891bf1 Mon Sep 17 00:00:00 2001
From: Ioi Lam
Date: Tue, 28 May 2013 16:36:19 -0700
Subject: [PATCH 077/206] 8014912: Restore PrintSharedSpaces functionality
after NPG
Added dumping of object sizes in CDS archive, sorted by MetaspaceObj::Type
Reviewed-by: coleenp, acorn
---
hotspot/src/share/vm/memory/allocation.cpp | 5 +-
hotspot/src/share/vm/memory/allocation.hpp | 49 +++++-
hotspot/src/share/vm/memory/metaspace.cpp | 80 +++++++---
hotspot/src/share/vm/memory/metaspace.hpp | 30 +++-
.../src/share/vm/memory/metaspaceShared.cpp | 149 ++++++++++++++++++
hotspot/src/share/vm/oops/annotations.cpp | 2 +-
hotspot/src/share/vm/oops/constMethod.cpp | 2 +-
hotspot/src/share/vm/oops/constantPool.cpp | 2 +-
hotspot/src/share/vm/oops/cpCache.cpp | 3 +-
hotspot/src/share/vm/oops/klass.cpp | 2 +-
hotspot/src/share/vm/oops/method.cpp | 2 +-
hotspot/src/share/vm/oops/methodCounters.cpp | 2 +-
hotspot/src/share/vm/oops/methodData.cpp | 3 +-
hotspot/src/share/vm/oops/symbol.cpp | 2 +-
hotspot/src/share/vm/utilities/array.hpp | 4 +-
15 files changed, 301 insertions(+), 36 deletions(-)
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index a6721c9e76f..6b08c13e5f4 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -60,10 +60,11 @@ void* _ValueObj::operator new [](size_t size) { ShouldNotCallThis(); return 0;
void _ValueObj::operator delete [](void* p) { ShouldNotCallThis(); }
void* MetaspaceObj::operator new(size_t size, ClassLoaderData* loader_data,
- size_t word_size, bool read_only, TRAPS) {
+ size_t word_size, bool read_only,
+ MetaspaceObj::Type type, TRAPS) {
// Klass has it's own operator new
return Metaspace::allocate(loader_data, word_size, read_only,
- Metaspace::NonClassType, CHECK_NULL);
+ type, CHECK_NULL);
}
bool MetaspaceObj::is_shared() const {
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index 2955943b3f6..ebdb29cd26c 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -268,8 +268,55 @@ class MetaspaceObj {
bool is_shared() const;
void print_address_on(outputStream* st) const; // nonvirtual address printing
+#define METASPACE_OBJ_TYPES_DO(f) \
+ f(Unknown) \
+ f(Class) \
+ f(Symbol) \
+ f(TypeArrayU1) \
+ f(TypeArrayU2) \
+ f(TypeArrayU4) \
+ f(TypeArrayU8) \
+ f(TypeArrayOther) \
+ f(Method) \
+ f(ConstMethod) \
+ f(MethodData) \
+ f(ConstantPool) \
+ f(ConstantPoolCache) \
+ f(Annotation) \
+ f(MethodCounters)
+
+#define METASPACE_OBJ_TYPE_DECLARE(name) name ## Type,
+#define METASPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
+
+ enum Type {
+ // Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
+ METASPACE_OBJ_TYPES_DO(METASPACE_OBJ_TYPE_DECLARE)
+ _number_of_types
+ };
+
+ static const char * type_name(Type type) {
+ switch(type) {
+ METASPACE_OBJ_TYPES_DO(METASPACE_OBJ_TYPE_NAME_CASE)
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+ }
+
+ static MetaspaceObj::Type array_type(size_t elem_size) {
+ switch (elem_size) {
+ case 1: return TypeArrayU1Type;
+ case 2: return TypeArrayU2Type;
+ case 4: return TypeArrayU4Type;
+ case 8: return TypeArrayU8Type;
+ default:
+ return TypeArrayOtherType;
+ }
+ }
+
void* operator new(size_t size, ClassLoaderData* loader_data,
- size_t word_size, bool read_only, Thread* thread);
+ size_t word_size, bool read_only,
+ Type type, Thread* thread);
// can't use TRAPS from this header file.
void operator delete(void* p) { ShouldNotCallThis(); }
};
diff --git a/hotspot/src/share/vm/memory/metaspace.cpp b/hotspot/src/share/vm/memory/metaspace.cpp
index 4be4658cad9..c840b9363ef 100644
--- a/hotspot/src/share/vm/memory/metaspace.cpp
+++ b/hotspot/src/share/vm/memory/metaspace.cpp
@@ -713,6 +713,23 @@ class SpaceManager : public CHeapObj {
#ifdef ASSERT
void verify_allocated_blocks_words();
#endif
+
+ size_t get_raw_word_size(size_t word_size) {
+ // If only the dictionary is going to be used (i.e., no
+ // indexed free list), then there is a minimum size requirement.
+ // MinChunkSize is a placeholder for the real minimum size JJJ
+ size_t byte_size = word_size * BytesPerWord;
+
+ size_t byte_size_with_overhead = byte_size + Metablock::overhead();
+
+ size_t raw_bytes_size = MAX2(byte_size_with_overhead,
+ Metablock::min_block_byte_size());
+ raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
+ size_t raw_word_size = raw_bytes_size / BytesPerWord;
+ assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
+
+ return raw_word_size;
+ }
};
uint const SpaceManager::_small_chunk_limit = 4;
@@ -2320,19 +2337,7 @@ Metachunk* SpaceManager::get_new_chunk(size_t word_size,
MetaWord* SpaceManager::allocate(size_t word_size) {
MutexLockerEx cl(lock(), Mutex::_no_safepoint_check_flag);
- // If only the dictionary is going to be used (i.e., no
- // indexed free list), then there is a minimum size requirement.
- // MinChunkSize is a placeholder for the real minimum size JJJ
- size_t byte_size = word_size * BytesPerWord;
-
- size_t byte_size_with_overhead = byte_size + Metablock::overhead();
-
- size_t raw_bytes_size = MAX2(byte_size_with_overhead,
- Metablock::min_block_byte_size());
- raw_bytes_size = ARENA_ALIGN(raw_bytes_size);
- size_t raw_word_size = raw_bytes_size / BytesPerWord;
- assert(raw_word_size * BytesPerWord == raw_bytes_size, "Size problem");
-
+ size_t raw_word_size = get_raw_word_size(word_size);
BlockFreelist* fl = block_freelists();
MetaWord* p = NULL;
// Allocation from the dictionary is expensive in the sense that
@@ -2896,6 +2901,9 @@ void Metaspace::initialize(Mutex* lock,
if (class_chunk != NULL) {
class_vsm()->add_chunk(class_chunk, true);
}
+
+ _alloc_record_head = NULL;
+ _alloc_record_tail = NULL;
}
size_t Metaspace::align_word_size_up(size_t word_size) {
@@ -3000,12 +3008,14 @@ void Metaspace::deallocate(MetaWord* ptr, size_t word_size, bool is_class) {
}
Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
- bool read_only, MetadataType mdtype, TRAPS) {
+ bool read_only, MetaspaceObj::Type type, TRAPS) {
if (HAS_PENDING_EXCEPTION) {
assert(false, "Should not allocate with exception pending");
return NULL; // caller does a CHECK_NULL too
}
+ MetadataType mdtype = (type == MetaspaceObj::ClassType) ? ClassType : NonClassType;
+
// SSS: Should we align the allocations and make sure the sizes are aligned.
MetaWord* result = NULL;
@@ -3015,13 +3025,13 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
// with the SymbolTable_lock. Dumping is single threaded for now. We'll have
// to revisit this for application class data sharing.
if (DumpSharedSpaces) {
- if (read_only) {
- result = loader_data->ro_metaspace()->allocate(word_size, NonClassType);
- } else {
- result = loader_data->rw_metaspace()->allocate(word_size, NonClassType);
- }
+ assert(type > MetaspaceObj::UnknownType && type < MetaspaceObj::_number_of_types, "sanity");
+ Metaspace* space = read_only ? loader_data->ro_metaspace() : loader_data->rw_metaspace();
+ result = space->allocate(word_size, NonClassType);
if (result == NULL) {
report_out_of_shared_space(read_only ? SharedReadOnly : SharedReadWrite);
+ } else {
+ space->record_allocation(result, type, space->vsm()->get_raw_word_size(word_size));
}
return Metablock::initialize(result, word_size);
}
@@ -3056,6 +3066,38 @@ Metablock* Metaspace::allocate(ClassLoaderData* loader_data, size_t word_size,
return Metablock::initialize(result, word_size);
}
+void Metaspace::record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size) {
+ assert(DumpSharedSpaces, "sanity");
+
+ AllocRecord *rec = new AllocRecord((address)ptr, type, (int)word_size * HeapWordSize);
+ if (_alloc_record_head == NULL) {
+ _alloc_record_head = _alloc_record_tail = rec;
+ } else {
+ _alloc_record_tail->_next = rec;
+ _alloc_record_tail = rec;
+ }
+}
+
+void Metaspace::iterate(Metaspace::AllocRecordClosure *closure) {
+ assert(DumpSharedSpaces, "unimplemented for !DumpSharedSpaces");
+
+ address last_addr = (address)bottom();
+
+ for (AllocRecord *rec = _alloc_record_head; rec; rec = rec->_next) {
+ address ptr = rec->_ptr;
+ if (last_addr < ptr) {
+ closure->doit(last_addr, MetaspaceObj::UnknownType, ptr - last_addr);
+ }
+ closure->doit(ptr, rec->_type, rec->_byte_size);
+ last_addr = ptr + rec->_byte_size;
+ }
+
+ address top = ((address)bottom()) + used_bytes_slow(Metaspace::NonClassType);
+ if (last_addr < top) {
+ closure->doit(last_addr, MetaspaceObj::UnknownType, top - last_addr);
+ }
+}
+
void Metaspace::purge() {
MutexLockerEx cl(SpaceManager::expand_lock(),
Mutex::_no_safepoint_check_flag);
diff --git a/hotspot/src/share/vm/memory/metaspace.hpp b/hotspot/src/share/vm/memory/metaspace.hpp
index 7d8e0d9410e..70acbb1667f 100644
--- a/hotspot/src/share/vm/memory/metaspace.hpp
+++ b/hotspot/src/share/vm/memory/metaspace.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -127,6 +127,23 @@ class Metaspace : public CHeapObj {
static VirtualSpaceList* space_list() { return _space_list; }
static VirtualSpaceList* class_space_list() { return _class_space_list; }
+ // This is used by DumpSharedSpaces only, where only _vsm is used. So we will
+ // maintain a single list for now.
+ void record_allocation(void* ptr, MetaspaceObj::Type type, size_t word_size);
+
+ class AllocRecord : public CHeapObj {
+ public:
+ AllocRecord(address ptr, MetaspaceObj::Type type, int byte_size)
+ : _next(NULL), _ptr(ptr), _type(type), _byte_size(byte_size) {}
+ AllocRecord *_next;
+ address _ptr;
+ MetaspaceObj::Type _type;
+ int _byte_size;
+ };
+
+ AllocRecord * _alloc_record_head;
+ AllocRecord * _alloc_record_tail;
+
public:
Metaspace(Mutex* lock, MetaspaceType type);
@@ -148,8 +165,8 @@ class Metaspace : public CHeapObj {
size_t used_bytes_slow(MetadataType mdtype) const;
size_t capacity_bytes_slow(MetadataType mdtype) const;
- static Metablock* allocate(ClassLoaderData* loader_data, size_t size,
- bool read_only, MetadataType mdtype, TRAPS);
+ static Metablock* allocate(ClassLoaderData* loader_data, size_t word_size,
+ bool read_only, MetaspaceObj::Type type, TRAPS);
void deallocate(MetaWord* ptr, size_t byte_size, bool is_class);
MetaWord* expand_and_allocate(size_t size,
@@ -166,6 +183,13 @@ class Metaspace : public CHeapObj {
void print_on(outputStream* st) const;
// Debugging support
void verify();
+
+ class AllocRecordClosure : public StackObj {
+ public:
+ virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) = 0;
+ };
+
+ void iterate(AllocRecordClosure *closure);
};
class MetaspaceAux : AllStatic {
diff --git a/hotspot/src/share/vm/memory/metaspaceShared.cpp b/hotspot/src/share/vm/memory/metaspaceShared.cpp
index 5f0f152e975..d2c91827485 100644
--- a/hotspot/src/share/vm/memory/metaspaceShared.cpp
+++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp
@@ -243,6 +243,147 @@ public:
bool reading() const { return false; }
};
+// This is for dumping detailed statistics for the allocations
+// in the shared spaces.
+class DumpAllocClosure : public Metaspace::AllocRecordClosure {
+public:
+
+ // Here's poor man's enum inheritance
+#define SHAREDSPACE_OBJ_TYPES_DO(f) \
+ METASPACE_OBJ_TYPES_DO(f) \
+ f(SymbolHashentry) \
+ f(SymbolBuckets) \
+ f(Other)
+
+#define SHAREDSPACE_OBJ_TYPE_DECLARE(name) name ## Type,
+#define SHAREDSPACE_OBJ_TYPE_NAME_CASE(name) case name ## Type: return #name;
+
+ enum Type {
+ // Types are MetaspaceObj::ClassType, MetaspaceObj::SymbolType, etc
+ SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_DECLARE)
+ _number_of_types
+ };
+
+ static const char * type_name(Type type) {
+ switch(type) {
+ SHAREDSPACE_OBJ_TYPES_DO(SHAREDSPACE_OBJ_TYPE_NAME_CASE)
+ default:
+ ShouldNotReachHere();
+ return NULL;
+ }
+ }
+
+public:
+ enum {
+ RO = 0,
+ RW = 1
+ };
+
+ int _counts[2][_number_of_types];
+ int _bytes [2][_number_of_types];
+ int _which;
+
+ DumpAllocClosure() {
+ memset(_counts, 0, sizeof(_counts));
+ memset(_bytes, 0, sizeof(_bytes));
+ };
+
+ void iterate_metaspace(Metaspace* space, int which) {
+ assert(which == RO || which == RW, "sanity");
+ _which = which;
+ space->iterate(this);
+ }
+
+ virtual void doit(address ptr, MetaspaceObj::Type type, int byte_size) {
+ assert(int(type) >= 0 && type < MetaspaceObj::_number_of_types, "sanity");
+ _counts[_which][type] ++;
+ _bytes [_which][type] += byte_size;
+ }
+
+ void dump_stats(int ro_all, int rw_all, int md_all, int mc_all);
+};
+
+void DumpAllocClosure::dump_stats(int ro_all, int rw_all, int md_all, int mc_all) {
+ rw_all += (md_all + mc_all); // md and mc are all mapped Read/Write
+ int other_bytes = md_all + mc_all;
+
+ // Calculate size of data that was not allocated by Metaspace::allocate()
+ int symbol_count = _counts[RO][MetaspaceObj::SymbolType];
+ int symhash_bytes = symbol_count * sizeof (HashtableEntry);
+ int symbuck_count = SymbolTable::the_table()->table_size();
+ int symbuck_bytes = symbuck_count * sizeof(HashtableBucket);
+
+ _counts[RW][SymbolHashentryType] = symbol_count;
+ _bytes [RW][SymbolHashentryType] = symhash_bytes;
+ other_bytes -= symhash_bytes;
+
+ _counts[RW][SymbolBucketsType] = symbuck_count;
+ _bytes [RW][SymbolBucketsType] = symbuck_bytes;
+ other_bytes -= symbuck_bytes;
+
+ // TODO: count things like dictionary, vtable, etc
+ _bytes[RW][OtherType] = other_bytes;
+
+ // prevent divide-by-zero
+ if (ro_all < 1) {
+ ro_all = 1;
+ }
+ if (rw_all < 1) {
+ rw_all = 1;
+ }
+
+ int all_ro_count = 0;
+ int all_ro_bytes = 0;
+ int all_rw_count = 0;
+ int all_rw_bytes = 0;
+
+ const char *fmt = "%-20s: %8d %10d %5.1f | %8d %10d %5.1f | %8d %10d %5.1f";
+ const char *sep = "--------------------+---------------------------+---------------------------+--------------------------";
+ const char *hdr = " ro_cnt ro_bytes % | rw_cnt rw_bytes % | all_cnt all_bytes %";
+
+ tty->print_cr("Detailed metadata info (rw includes md and mc):");
+ tty->print_cr(hdr);
+ tty->print_cr(sep);
+ for (int type = 0; type < int(_number_of_types); type ++) {
+ const char *name = type_name((Type)type);
+ int ro_count = _counts[RO][type];
+ int ro_bytes = _bytes [RO][type];
+ int rw_count = _counts[RW][type];
+ int rw_bytes = _bytes [RW][type];
+ int count = ro_count + rw_count;
+ int bytes = ro_bytes + rw_bytes;
+
+ double ro_perc = 100.0 * double(ro_bytes) / double(ro_all);
+ double rw_perc = 100.0 * double(rw_bytes) / double(rw_all);
+ double perc = 100.0 * double(bytes) / double(ro_all + rw_all);
+
+ tty->print_cr(fmt, name,
+ ro_count, ro_bytes, ro_perc,
+ rw_count, rw_bytes, rw_perc,
+ count, bytes, perc);
+
+ all_ro_count += ro_count;
+ all_ro_bytes += ro_bytes;
+ all_rw_count += rw_count;
+ all_rw_bytes += rw_bytes;
+ }
+
+ int all_count = all_ro_count + all_rw_count;
+ int all_bytes = all_ro_bytes + all_rw_bytes;
+
+ double all_ro_perc = 100.0 * double(all_ro_bytes) / double(ro_all);
+ double all_rw_perc = 100.0 * double(all_rw_bytes) / double(rw_all);
+ double all_perc = 100.0 * double(all_bytes) / double(ro_all + rw_all);
+
+ tty->print_cr(sep);
+ tty->print_cr(fmt, "Total",
+ all_ro_count, all_ro_bytes, all_ro_perc,
+ all_rw_count, all_rw_bytes, all_rw_perc,
+ all_count, all_bytes, all_perc);
+
+ assert(all_ro_bytes == ro_all, "everything should have been counted");
+ assert(all_rw_bytes == rw_all, "everything should have been counted");
+}
// Populate the shared space.
@@ -454,6 +595,14 @@ void VM_PopulateDumpSharedSpace::doit() {
mapinfo->close();
memmove(vtbl_list, saved_vtbl, vtbl_list_size * sizeof(void*));
+
+ if (PrintSharedSpaces) {
+ DumpAllocClosure dac;
+ dac.iterate_metaspace(_loader_data->ro_metaspace(), DumpAllocClosure::RO);
+ dac.iterate_metaspace(_loader_data->rw_metaspace(), DumpAllocClosure::RW);
+
+ dac.dump_stats(int(ro_bytes), int(rw_bytes), int(md_bytes), int(mc_bytes));
+ }
}
static void link_shared_classes(Klass* obj, TRAPS) {
diff --git a/hotspot/src/share/vm/oops/annotations.cpp b/hotspot/src/share/vm/oops/annotations.cpp
index 546257a17df..1eb3afbb740 100644
--- a/hotspot/src/share/vm/oops/annotations.cpp
+++ b/hotspot/src/share/vm/oops/annotations.cpp
@@ -33,7 +33,7 @@
// Allocate annotations in metadata area
Annotations* Annotations::allocate(ClassLoaderData* loader_data, TRAPS) {
- return new (loader_data, size(), true, THREAD) Annotations();
+ return new (loader_data, size(), true, MetaspaceObj::AnnotationType, THREAD) Annotations();
}
// helper
diff --git a/hotspot/src/share/vm/oops/constMethod.cpp b/hotspot/src/share/vm/oops/constMethod.cpp
index 1d0376a0b74..22f3b87da5a 100644
--- a/hotspot/src/share/vm/oops/constMethod.cpp
+++ b/hotspot/src/share/vm/oops/constMethod.cpp
@@ -40,7 +40,7 @@ ConstMethod* ConstMethod::allocate(ClassLoaderData* loader_data,
MethodType method_type,
TRAPS) {
int size = ConstMethod::size(byte_code_size, sizes);
- return new (loader_data, size, true, THREAD) ConstMethod(
+ return new (loader_data, size, true, MetaspaceObj::ConstMethodType, THREAD) ConstMethod(
byte_code_size, sizes, method_type, size);
}
diff --git a/hotspot/src/share/vm/oops/constantPool.cpp b/hotspot/src/share/vm/oops/constantPool.cpp
index fe1d7340e47..c2879e2d02a 100644
--- a/hotspot/src/share/vm/oops/constantPool.cpp
+++ b/hotspot/src/share/vm/oops/constantPool.cpp
@@ -55,7 +55,7 @@ ConstantPool* ConstantPool::allocate(ClassLoaderData* loader_data, int length, T
// the resolved_references array, which is recreated at startup time.
// But that could be moved to InstanceKlass (although a pain to access from
// assembly code). Maybe it could be moved to the cpCache which is RW.
- return new (loader_data, size, false, THREAD) ConstantPool(tags);
+ return new (loader_data, size, false, MetaspaceObj::ConstantPoolType, THREAD) ConstantPool(tags);
}
ConstantPool::ConstantPool(Array* tags) {
diff --git a/hotspot/src/share/vm/oops/cpCache.cpp b/hotspot/src/share/vm/oops/cpCache.cpp
index bc15e282b77..9e2b83c2caf 100644
--- a/hotspot/src/share/vm/oops/cpCache.cpp
+++ b/hotspot/src/share/vm/oops/cpCache.cpp
@@ -542,7 +542,8 @@ ConstantPoolCache* ConstantPoolCache::allocate(ClassLoaderData* loader_data,
const intStack& invokedynamic_map, TRAPS) {
int size = ConstantPoolCache::size(length);
- return new (loader_data, size, false, THREAD) ConstantPoolCache(length, index_map, invokedynamic_map);
+ return new (loader_data, size, false, MetaspaceObj::ConstantPoolCacheType, THREAD)
+ ConstantPoolCache(length, index_map, invokedynamic_map);
}
void ConstantPoolCache::initialize(const intArray& inverse_index_map,
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index 5c334206b97..f7a7334afb1 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -140,7 +140,7 @@ Method* Klass::uncached_lookup_method(Symbol* name, Symbol* signature) const {
void* Klass::operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, TRAPS) {
return Metaspace::allocate(loader_data, word_size, /*read_only*/false,
- Metaspace::ClassType, CHECK_NULL);
+ MetaspaceObj::ClassType, CHECK_NULL);
}
Klass::Klass() {
diff --git a/hotspot/src/share/vm/oops/method.cpp b/hotspot/src/share/vm/oops/method.cpp
index 62b81ea4e93..1e8b1c3bb41 100644
--- a/hotspot/src/share/vm/oops/method.cpp
+++ b/hotspot/src/share/vm/oops/method.cpp
@@ -74,7 +74,7 @@ Method* Method::allocate(ClassLoaderData* loader_data,
int size = Method::size(access_flags.is_native());
- return new (loader_data, size, false, THREAD) Method(cm, access_flags, size);
+ return new (loader_data, size, false, MetaspaceObj::MethodType, THREAD) Method(cm, access_flags, size);
}
Method::Method(ConstMethod* xconst, AccessFlags access_flags, int size) {
diff --git a/hotspot/src/share/vm/oops/methodCounters.cpp b/hotspot/src/share/vm/oops/methodCounters.cpp
index 53d3e682b77..1ee8eb17001 100644
--- a/hotspot/src/share/vm/oops/methodCounters.cpp
+++ b/hotspot/src/share/vm/oops/methodCounters.cpp
@@ -26,7 +26,7 @@
#include "runtime/thread.inline.hpp"
MethodCounters* MethodCounters::allocate(ClassLoaderData* loader_data, TRAPS) {
- return new(loader_data, size(), false, THREAD) MethodCounters();
+ return new(loader_data, size(), false, MetaspaceObj::MethodCountersType, THREAD) MethodCounters();
}
void MethodCounters::clear_counters() {
diff --git a/hotspot/src/share/vm/oops/methodData.cpp b/hotspot/src/share/vm/oops/methodData.cpp
index 73f70bac9d3..89a4cd4aa6b 100644
--- a/hotspot/src/share/vm/oops/methodData.cpp
+++ b/hotspot/src/share/vm/oops/methodData.cpp
@@ -388,7 +388,8 @@ void ArgInfoData::print_data_on(outputStream* st) {
MethodData* MethodData::allocate(ClassLoaderData* loader_data, methodHandle method, TRAPS) {
int size = MethodData::compute_allocation_size_in_words(method);
- return new (loader_data, size, false, THREAD) MethodData(method(), size, CHECK_NULL);
+ return new (loader_data, size, false, MetaspaceObj::MethodDataType, THREAD)
+ MethodData(method(), size, CHECK_NULL);
}
int MethodData::bytecode_cell_count(Bytecodes::Code code) {
diff --git a/hotspot/src/share/vm/oops/symbol.cpp b/hotspot/src/share/vm/oops/symbol.cpp
index 253d0df887c..8ee933bf135 100644
--- a/hotspot/src/share/vm/oops/symbol.cpp
+++ b/hotspot/src/share/vm/oops/symbol.cpp
@@ -55,7 +55,7 @@ void* Symbol::operator new(size_t sz, int len, ClassLoaderData* loader_data, TRA
address res;
int alloc_size = size(len)*HeapWordSize;
res = (address) Metaspace::allocate(loader_data, size(len), true,
- Metaspace::NonClassType, CHECK_NULL);
+ MetaspaceObj::SymbolType, CHECK_NULL);
return res;
}
diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp
index 5578ed9b61f..048a5781269 100644
--- a/hotspot/src/share/vm/utilities/array.hpp
+++ b/hotspot/src/share/vm/utilities/array.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 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
@@ -320,7 +320,7 @@ protected:
void* operator new(size_t size, ClassLoaderData* loader_data, int length, bool read_only, TRAPS) {
size_t word_size = Array::size(length);
return (void*) Metaspace::allocate(loader_data, word_size, read_only,
- Metaspace::NonClassType, CHECK_NULL);
+ MetaspaceObj::array_type(sizeof(T)), CHECK_NULL);
}
static size_t byte_sizeof(int length) { return sizeof(Array) + MAX2(length - 1, 0) * sizeof(T); }
From 33f5aae0ffb362d954b35d8203072757adec02e2 Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Wed, 29 May 2013 10:56:29 +0100
Subject: [PATCH 078/206] 7053059: VerifyError with double Assignment using a
Generic Member of a Superclass
Reviewed-by: mcimadamore
---
.../com/sun/tools/javac/comp/TransTypes.java | 11 ++--
.../VerifyErrorWithDoubleAssignmentTest.java | 51 +++++++++++++++++++
2 files changed, 58 insertions(+), 4 deletions(-)
create mode 100644 langtools/test/tools/javac/T7053059/VerifyErrorWithDoubleAssignmentTest.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
index a58dec6f7f1..4c227425149 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/TransTypes.java
@@ -172,10 +172,13 @@ public class TransTypes extends TreeTranslator {
JCExpression retype(JCExpression tree, Type erasedType, Type target) {
// System.err.println("retype " + tree + " to " + erasedType);//DEBUG
if (!erasedType.isPrimitive()) {
- if (target != null && target.isPrimitive())
+ if (target != null && target.isPrimitive()) {
target = erasure(tree.type);
+ }
tree.type = erasedType;
- if (target != null) return coerce(tree, target);
+ if (target != null) {
+ return coerce(tree, target);
+ }
}
return tree;
}
@@ -686,8 +689,8 @@ public class TransTypes extends TreeTranslator {
public void visitAssign(JCAssign tree) {
tree.lhs = translate(tree.lhs, null);
tree.rhs = translate(tree.rhs, erasure(tree.lhs.type));
- tree.type = erasure(tree.type);
- result = tree;
+ tree.type = erasure(tree.lhs.type);
+ result = retype(tree, tree.type, pt);
}
public void visitAssignop(JCAssignOp tree) {
diff --git a/langtools/test/tools/javac/T7053059/VerifyErrorWithDoubleAssignmentTest.java b/langtools/test/tools/javac/T7053059/VerifyErrorWithDoubleAssignmentTest.java
new file mode 100644
index 00000000000..e03b1a54874
--- /dev/null
+++ b/langtools/test/tools/javac/T7053059/VerifyErrorWithDoubleAssignmentTest.java
@@ -0,0 +1,51 @@
+/*
+ * 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 7053059
+ * @summary VerifyError with double Assignment using a Generic Member of a Superclass
+ * @run main VerifyErrorWithDoubleAssignmentTest
+ */
+
+public class VerifyErrorWithDoubleAssignmentTest {
+
+ static class A {
+ D d;
+
+ D getD() {
+ return null;
+ }
+ }
+
+ static class B extends A {
+ Integer y;
+ B() {
+ y = d = getD();
+ }
+ }
+
+ public static void main(String[] args) {
+ new B();
+ }
+}
From 993430afb0ca57b1079caa08f7cbfc7efc00459e Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Wed, 29 May 2013 15:41:07 +0530
Subject: [PATCH 079/206] 8005979: A lot of tests are named "runTest" in
reports
Reviewed-by: jlaskey
---
nashorn/make/project.properties | 1 +
1 file changed, 1 insertion(+)
diff --git a/nashorn/make/project.properties b/nashorn/make/project.properties
index 839d7486c72..2e3839b6732 100644
--- a/nashorn/make/project.properties
+++ b/nashorn/make/project.properties
@@ -87,6 +87,7 @@ testng.verbose=2
testng.listeners=\
org.testng.reporters.SuiteHTMLReporter, \
+ org.testng.reporters.TestHTMLReporter, \
org.testng.reporters.jq.Main, \
org.testng.reporters.FailedReporter, \
org.testng.reporters.XMLReporter \
From 9a455252720998b09d658c0daca84de896f2a8cd Mon Sep 17 00:00:00 2001
From: Erik Joelsson
Date: Wed, 29 May 2013 13:58:40 +0200
Subject: [PATCH 080/206] 8013920: Configure sets JOBS to 0 if memory is too
low
Reviewed-by: tbell
---
common/autoconf/build-performance.m4 | 3 +++
common/autoconf/generated-configure.sh | 5 ++++-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/common/autoconf/build-performance.m4 b/common/autoconf/build-performance.m4
index e7d6364edff..a1abced459d 100644
--- a/common/autoconf/build-performance.m4
+++ b/common/autoconf/build-performance.m4
@@ -145,6 +145,9 @@ AC_DEFUN_ONCE([BPERF_SETUP_BUILD_JOBS],
if test "$JOBS" -gt "16"; then
JOBS=16
fi
+ if test "$JOBS" -eq "0"; then
+ JOBS=1
+ fi
AC_MSG_RESULT([$JOBS])
else
JOBS=$with_jobs
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 87b75cb6cd7..90e29e63de5 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -3780,7 +3780,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1369723814
+DATE_WHEN_GENERATED=1369828684
###############################################################################
#
@@ -32933,6 +32933,9 @@ $as_echo_n "checking for appropriate number of jobs to run in parallel... " >&6;
if test "$JOBS" -gt "16"; then
JOBS=16
fi
+ if test "$JOBS" -eq "0"; then
+ JOBS=1
+ fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $JOBS" >&5
$as_echo "$JOBS" >&6; }
else
From 4f1888c9fc5c64f2124b5d3a7e540a5054820eb1 Mon Sep 17 00:00:00 2001
From: Erik Joelsson
Date: Wed, 29 May 2013 14:01:04 +0200
Subject: [PATCH 081/206] 8013489: New build system does not run codesign on
SA-related launchers on OS X
Reviewed-by: sla, tbell
---
common/autoconf/basics.m4 | 14 ++++++
common/autoconf/generated-configure.sh | 59 +++++++++++++++++++++++++-
common/autoconf/spec.gmk.in | 1 +
common/makefiles/MakeBase.gmk | 4 +-
common/makefiles/NativeCompilation.gmk | 14 ++++--
5 files changed, 85 insertions(+), 7 deletions(-)
diff --git a/common/autoconf/basics.m4 b/common/autoconf/basics.m4
index 305424db718..c4768b02acf 100644
--- a/common/autoconf/basics.m4
+++ b/common/autoconf/basics.m4
@@ -617,6 +617,20 @@ fi
if test "x$OPENJDK_TARGET_OS" = "xmacosx"; then
BASIC_REQUIRE_PROG(XATTR, xattr)
+ AC_PATH_PROG(CODESIGN, codesign)
+ if test "x$CODESIGN" != "x"; then
+ # Verify that the openjdk_codesign certificate is present
+ AC_MSG_CHECKING([if openjdk_codesign certificate is present])
+ rm -f codesign-testfile
+ touch codesign-testfile
+ codesign -s openjdk_codesign codesign-testfile 2>&AS_MESSAGE_LOG_FD >&AS_MESSAGE_LOG_FD || CODESIGN=
+ rm -f codesign-testfile
+ if test "x$CODESIGN" = x; then
+ AC_MSG_RESULT([no])
+ else
+ AC_MSG_RESULT([yes])
+ fi
+ fi
fi
])
diff --git a/common/autoconf/generated-configure.sh b/common/autoconf/generated-configure.sh
index 90e29e63de5..f723c40f0a9 100644
--- a/common/autoconf/generated-configure.sh
+++ b/common/autoconf/generated-configure.sh
@@ -797,6 +797,7 @@ OS_VERSION_MICRO
OS_VERSION_MINOR
OS_VERSION_MAJOR
PKG_CONFIG
+CODESIGN
XATTR
TIME
STAT
@@ -3780,7 +3781,7 @@ fi
#CUSTOM_AUTOCONF_INCLUDE
# Do not change or remove the following line, it is needed for consistency checks:
-DATE_WHEN_GENERATED=1369828684
+DATE_WHEN_GENERATED=1369828849
###############################################################################
#
@@ -10493,6 +10494,62 @@ $as_echo "$as_me: Could not find $PROG_NAME!" >&6;}
fi
+ # Extract the first word of "codesign", so it can be a program name with args.
+set dummy codesign; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_CODESIGN+set}" = set; then :
+ $as_echo_n "(cached) " >&6
+else
+ case $CODESIGN in
+ [\\/]* | ?:[\\/]*)
+ ac_cv_path_CODESIGN="$CODESIGN" # Let the user override the test with a path.
+ ;;
+ *)
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+ ac_cv_path_CODESIGN="$as_dir/$ac_word$ac_exec_ext"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+fi
+CODESIGN=$ac_cv_path_CODESIGN
+if test -n "$CODESIGN"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CODESIGN" >&5
+$as_echo "$CODESIGN" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ if test "x$CODESIGN" != "x"; then
+ # Verify that the openjdk_codesign certificate is present
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if openjdk_codesign certificate is present" >&5
+$as_echo_n "checking if openjdk_codesign certificate is present... " >&6; }
+ rm -f codesign-testfile
+ touch codesign-testfile
+ codesign -s openjdk_codesign codesign-testfile 2>&5 >&5 || CODESIGN=
+ rm -f codesign-testfile
+ if test "x$CODESIGN" = x; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ fi
+ fi
fi
diff --git a/common/autoconf/spec.gmk.in b/common/autoconf/spec.gmk.in
index 8705a2a0114..1ebf89d827d 100644
--- a/common/autoconf/spec.gmk.in
+++ b/common/autoconf/spec.gmk.in
@@ -478,6 +478,7 @@ CCACHE:=@CCACHE@
# CD is going away, but remains to cater for legacy makefiles.
CD:=cd
CHMOD:=@CHMOD@
+CODESIGN:=@CODESIGN@
COMM:=@COMM@
CP:=@CP@
CPIO:=@CPIO@
diff --git a/common/makefiles/MakeBase.gmk b/common/makefiles/MakeBase.gmk
index 3cbdf79bae9..98a56f86cd1 100644
--- a/common/makefiles/MakeBase.gmk
+++ b/common/makefiles/MakeBase.gmk
@@ -361,8 +361,8 @@ $(eval $(call SetupLogging))
# This is to be called by all SetupFoo macros
define LogSetupMacroEntry
- $(if $(26),$(error Internal makefile error: Too many arguments to LogSetupMacroEntry, please update MakeBase.gmk))
- $(if $(findstring $(LOG_LEVEL),debug trace), $(info $1 $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25,$(if $($i),$(NEWLINE) $(strip [$i] $($i))))))
+ $(if $(27),$(error Internal makefile error: Too many arguments to LogSetupMacroEntry, please update MakeBase.gmk))
+ $(if $(findstring $(LOG_LEVEL),debug trace), $(info $1 $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26,$(if $($i),$(NEWLINE) $(strip [$i] $($i))))))
endef
# Make directory without forking mkdir if not needed
diff --git a/common/makefiles/NativeCompilation.gmk b/common/makefiles/NativeCompilation.gmk
index c3b276609c3..227832c4c43 100644
--- a/common/makefiles/NativeCompilation.gmk
+++ b/common/makefiles/NativeCompilation.gmk
@@ -147,9 +147,9 @@ define SetupNativeCompilation
# CC the compiler to use, default is $(CC)
# LDEXE the linker to use for linking executables, default is $(LDEXE)
# OPTIMIZATION sets optimization level to NONE, LOW, HIGH, HIGHEST
- $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25, $(if $($i),$1_$(strip $($i)))$(NEWLINE))
- $(call LogSetupMacroEntry,SetupNativeCompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15),$(16),$(17),$(18),$(19),$(20),$(21),$(22),$(23),$(24),$(25))
- $(if $(26),$(error Internal makefile error: Too many arguments to SetupNativeCompilation, please update NativeCompilation.gmk))
+ $(foreach i,2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26, $(if $($i),$1_$(strip $($i)))$(NEWLINE))
+ $(call LogSetupMacroEntry,SetupNativeCompilation($1),$2,$3,$4,$5,$6,$7,$8,$9,$(10),$(11),$(12),$(13),$(14),$(15),$(16),$(17),$(18),$(19),$(20),$(21),$(22),$(23),$(24),$(25),$(26))
+ $(if $(27),$(error Internal makefile error: Too many arguments to SetupNativeCompilation, please update NativeCompilation.gmk))
ifneq (,$$($1_BIN))
$$(error BIN has been replaced with OBJECT_DIR)
@@ -567,6 +567,12 @@ define SetupNativeCompilation
ifneq (,$$($1_GEN_MANIFEST))
$(MT) -nologo -manifest $$($1_GEN_MANIFEST) -outputresource:$$@;#1
endif
-
+ # This only works if the openjdk_codesign identity is present on the system. Let
+ # silently fail otherwise.
+ ifneq (,$(CODESIGN))
+ ifneq (,$$($1_CODESIGN))
+ $(CODESIGN) -s openjdk_codesign $$@
+ endif
+ endif
endif
endef
From e4879cb3e6c773cb41068b8c2ffde9724f75d334 Mon Sep 17 00:00:00 2001
From: Erik Joelsson
Date: Wed, 29 May 2013 14:01:24 +0200
Subject: [PATCH 082/206] 8013489: New build system does not run codesign on
SA-related launchers on OS X
Reviewed-by: sla, tbell
---
jdk/makefiles/CompileLaunchers.gmk | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/jdk/makefiles/CompileLaunchers.gmk b/jdk/makefiles/CompileLaunchers.gmk
index 0621f4ce38b..90348b6360f 100644
--- a/jdk/makefiles/CompileLaunchers.gmk
+++ b/jdk/makefiles/CompileLaunchers.gmk
@@ -95,6 +95,9 @@ define SetupLauncher
$1_PLIST_FILE:=Info-cmdline.plist
ifneq ($(11),)
$1_PLIST_FILE:=$(11)
+ ifneq ($$(findstring privileged,$$($1_PLIST_FILE)),)
+ $1_CODESIGN:=true
+ endif
endif
$1_LDFLAGS += -Wl,-all_load $(JDK_OUTPUTDIR)/objs/libjli_static.a \
@@ -174,7 +177,8 @@ define SetupLauncher
-D "JDK_INTERNAL_NAME=$1" \
-D "JDK_FTYPE=0x1L" \
$7,\
- MANIFEST:=$(JDK_TOPDIR)/src/windows/resource/java.manifest)
+ MANIFEST:=$(JDK_TOPDIR)/src/windows/resource/java.manifest,\
+ CODESIGN:=$$($1_CODESIGN))
BUILD_LAUNCHERS += $$(BUILD_LAUNCHER_$1)
From 14cc2ba534f4c9ddeda159070400659769c557d0 Mon Sep 17 00:00:00 2001
From: Marcus Lagergren
Date: Wed, 29 May 2013 14:08:00 +0200
Subject: [PATCH 083/206] 8011023: Math round didn't conform to ECMAScript 5
spec
Reviewed-by: jlaskey, attila
---
.../nashorn/internal/objects/NativeMath.java | 10 +++---
nashorn/test/script/basic/JDK-8011023.js | 34 +++++++++++++++++++
.../test/script/basic/JDK-8011023.js.EXPECTED | 3 ++
3 files changed, 41 insertions(+), 6 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8011023.js
create mode 100644 nashorn/test/script/basic/JDK-8011023.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
index 7f330efc103..50a2d864f29 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeMath.java
@@ -611,13 +611,11 @@ public final class NativeMath extends ScriptObject {
*/
@Function(attributes = Attribute.NOT_ENUMERABLE, where = Where.CONSTRUCTOR)
public static Object round(final Object self, final Object x) {
- if (GlobalFunctions.isNaN(self, x)) {
- return Double.NaN;
- } else if (!GlobalFunctions.isFinite(self, x)) {
- return x;
+ final double d = JSType.toNumber(x);
+ if (Math.getExponent(d) >= 52) {
+ return d;
}
-
- return Math.round(JSType.toNumber(x));
+ return Math.copySign(Math.floor(d + 0.5), d);
}
/**
diff --git a/nashorn/test/script/basic/JDK-8011023.js b/nashorn/test/script/basic/JDK-8011023.js
new file mode 100644
index 00000000000..fbc2ca96782
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8011023.js
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * Round should be ecma compliant
+ *
+ * @test
+ * @run
+ */
+
+print(1/Math.round(-0.5));
+print(Math.round(9007199254740991));
+print(Math.round(9223372036854775807*2));
+
diff --git a/nashorn/test/script/basic/JDK-8011023.js.EXPECTED b/nashorn/test/script/basic/JDK-8011023.js.EXPECTED
new file mode 100644
index 00000000000..f7e1ef45f1c
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8011023.js.EXPECTED
@@ -0,0 +1,3 @@
+-Infinity
+9007199254740991
+18446744073709552000
From 4e5a976adf1ccc1994f487f62029ad3488c739f2 Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Wed, 29 May 2013 21:27:10 +0530
Subject: [PATCH 084/206] 8015349: "abc".lastIndexOf("a",-1) should evaluate to
0 and not -1
Reviewed-by: lagergren, attila, jlaskey
---
.../internal/objects/NativeString.java | 15 +++++--
nashorn/test/script/basic/JDK-8015349.js | 43 +++++++++++++++++++
.../test/script/basic/JDK-8015349.js.EXPECTED | 9 ++++
3 files changed, 63 insertions(+), 4 deletions(-)
create mode 100644 nashorn/test/script/basic/JDK-8015349.js
create mode 100644 nashorn/test/script/basic/JDK-8015349.js.EXPECTED
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
index adbef5cb633..df4aa1bff38 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeString.java
@@ -631,17 +631,24 @@ public final class NativeString extends ScriptObject {
final String str = checkObjectToString(self);
final String searchStr = JSType.toString(search);
+ final int length = str.length();
- int from;
+ int end;
if (pos == UNDEFINED) {
- from = str.length();
+ end = length;
} else {
final double numPos = JSType.toNumber(pos);
- from = !Double.isNaN(numPos) ? (int)numPos : (int)Double.POSITIVE_INFINITY;
+ end = Double.isNaN(numPos) ? length : (int)numPos;
+ if (end < 0) {
+ end = 0;
+ } else if (end > length) {
+ end = length;
+ }
}
- return str.lastIndexOf(searchStr, from);
+
+ return str.lastIndexOf(searchStr, end);
}
/**
diff --git a/nashorn/test/script/basic/JDK-8015349.js b/nashorn/test/script/basic/JDK-8015349.js
new file mode 100644
index 00000000000..7588a651d60
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015349.js
@@ -0,0 +1,43 @@
+/*
+ * 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-8015349: "abc".lastIndexOf("a",-1) should evaluate to 0 and not -1
+ *
+ * @test
+ * @run
+ */
+
+function printEval(code) {
+ print(code + " = " + eval(code));
+}
+
+printEval("'abc'.lastIndexOf('a', 4)");
+printEval("'abc'.lastIndexOf('b', Infinity)");
+printEval("'abc'.lastIndexOf('a', -1)");
+printEval("'abc'.lastIndexOf('a', -Infinity)");
+printEval("'oracle'.lastIndexOf('u')");
+printEval("'hello'.lastIndexOf('l')");
+printEval("'hello'.lastIndexOf('l', 2)");
+printEval("'hello'.lastIndexOf('l', 3)");
+printEval("'hello'.lastIndexOf('l', 1)");
diff --git a/nashorn/test/script/basic/JDK-8015349.js.EXPECTED b/nashorn/test/script/basic/JDK-8015349.js.EXPECTED
new file mode 100644
index 00000000000..f743dc4c1df
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015349.js.EXPECTED
@@ -0,0 +1,9 @@
+'abc'.lastIndexOf('a', 4) = 0
+'abc'.lastIndexOf('b', Infinity) = 1
+'abc'.lastIndexOf('a', -1) = 0
+'abc'.lastIndexOf('a', -Infinity) = 0
+'oracle'.lastIndexOf('u') = -1
+'hello'.lastIndexOf('l') = 3
+'hello'.lastIndexOf('l', 2) = 2
+'hello'.lastIndexOf('l', 3) = 3
+'hello'.lastIndexOf('l', 1) = -1
From a3f6ca8aed38328bb86568e608f94b3e66776b24 Mon Sep 17 00:00:00 2001
From: James Laskey
Date: Wed, 29 May 2013 16:23:50 -0300
Subject: [PATCH 085/206] 8015636: Add more typed arrays code coverage tests
Reviewed-by: sundar
---
nashorn/test/script/basic/typedarrays.js | 96 ++++++++++++++++++++++++
1 file changed, 96 insertions(+)
create mode 100644 nashorn/test/script/basic/typedarrays.js
diff --git a/nashorn/test/script/basic/typedarrays.js b/nashorn/test/script/basic/typedarrays.js
new file mode 100644
index 00000000000..0854bea9d19
--- /dev/null
+++ b/nashorn/test/script/basic/typedarrays.js
@@ -0,0 +1,96 @@
+/*
+ * 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.
+ */
+
+/**
+ * typedarray test.
+ *
+ * @test
+ * @run
+ */
+
+
+var typeDefinitions = [
+Int8Array,
+Uint8Array,
+Uint8ClampedArray,
+Int16Array,
+Uint16Array,
+Int32Array,
+Uint32Array,
+Float32Array,
+Float64Array,
+];
+
+var mem1 = new ArrayBuffer(1024);
+mem1.byteLength;
+mem1.slice(512);
+mem1.slice(512, 748);
+
+var size = 128;
+var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
+var arr2 = [99, 89];
+var partial = [];
+var all = [];
+
+typeDefinitions.forEach(function(arrayDef) {
+ var p = arrayDef.prototype;
+ var sub = [];
+ sub.push(new arrayDef(mem1, arrayDef.BYTES_PER_ELEMENT, 3));
+ sub.push(new arrayDef(size));
+ sub.push(new arrayDef(arr));
+ //push the instances, they will be reused to do instance based construction
+ partial.push({
+ instances:sub,
+ type:arrayDef
+ });
+
+ all.concat(all, sub);
+
+});
+
+partial.forEach(function(inst) {
+ // build new instances with TypeArray instance as parameter.
+ partial.forEach(function(other) {
+ other.instances.forEach(function(otherInstance) {
+ var ii = new inst.type(otherInstance);
+ all.push(ii);
+ });
+ })
+});
+
+all.forEach(function(instance) {
+ // cover instance props and functions
+ var arr = Object.getOwnPropertyNames(instance);
+ arr.forEach(function(p) {
+ var val = instance[p];
+ if(!isNaN(p)){
+ val[p] = 99;
+ }
+ });
+
+ instance.set(instance, 0);
+ instance.set(instance);
+ instance.set(arr2);
+ instance.subarray(5, 9);
+ instance.subarray(5);
+});
From dd5dcda9077271b756f41eb5bf2114da14c03853 Mon Sep 17 00:00:00 2001
From: Jonathan Gibbons
Date: Wed, 29 May 2013 15:34:56 -0700
Subject: [PATCH 086/206] 8015641: genstubs needs to cope with static interface
methods
Reviewed-by: ksrini
---
langtools/make/tools/genstubs/GenStubs.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/langtools/make/tools/genstubs/GenStubs.java b/langtools/make/tools/genstubs/GenStubs.java
index 0ff475c9473..ffa95c97792 100644
--- a/langtools/make/tools/genstubs/GenStubs.java
+++ b/langtools/make/tools/genstubs/GenStubs.java
@@ -230,9 +230,9 @@ public class GenStubs {
tree.typarams = translateTypeParams(tree.typarams);
tree.params = translateVarDefs(tree.params);
tree.thrown = translate(tree.thrown);
- if (tree.restype != null && tree.body != null) {
+ if (tree.body != null) {
if ((currClassMods & Flags.INTERFACE) != 0) {
- tree.mods.flags &= ~Flags.DEFAULT;
+ tree.mods.flags &= ~(Flags.DEFAULT | Flags.STATIC);
} else {
tree.mods.flags |= Flags.NATIVE;
}
From 91a299799ef6720995468b94b1bf525a0def4d1e Mon Sep 17 00:00:00 2001
From: Athijegannathan Sundararajan
Date: Thu, 30 May 2013 16:49:46 +0530
Subject: [PATCH 087/206] 8015353: Date.parse illegal string parsing issues
Reviewed-by: jlaskey, lagergren
---
.../nashorn/internal/objects/NativeDate.java | 1 +
.../{objects => parser}/DateParser.java | 12 +++++-
nashorn/test/script/basic/JDK-8015353.js | 38 +++++++++++++++++++
3 files changed, 50 insertions(+), 1 deletion(-)
rename nashorn/src/jdk/nashorn/internal/{objects => parser}/DateParser.java (98%)
create mode 100644 nashorn/test/script/basic/JDK-8015353.js
diff --git a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
index fa2c9d17a81..ef01d74b252 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDate.java
@@ -39,6 +39,7 @@ import jdk.nashorn.internal.objects.annotations.Function;
import jdk.nashorn.internal.objects.annotations.ScriptClass;
import jdk.nashorn.internal.objects.annotations.SpecializedConstructor;
import jdk.nashorn.internal.objects.annotations.Where;
+import jdk.nashorn.internal.parser.DateParser;
import jdk.nashorn.internal.runtime.ConsString;
import jdk.nashorn.internal.runtime.JSType;
import jdk.nashorn.internal.runtime.ScriptEnvironment;
diff --git a/nashorn/src/jdk/nashorn/internal/objects/DateParser.java b/nashorn/src/jdk/nashorn/internal/parser/DateParser.java
similarity index 98%
rename from nashorn/src/jdk/nashorn/internal/objects/DateParser.java
rename to nashorn/src/jdk/nashorn/internal/parser/DateParser.java
index b66d3dc99c1..34832bb1b44 100644
--- a/nashorn/src/jdk/nashorn/internal/objects/DateParser.java
+++ b/nashorn/src/jdk/nashorn/internal/parser/DateParser.java
@@ -23,7 +23,7 @@
* questions.
*/
-package jdk.nashorn.internal.objects;
+package jdk.nashorn.internal.parser;
import static java.lang.Character.DECIMAL_DIGIT_NUMBER;
import static java.lang.Character.LOWERCASE_LETTER;
@@ -196,6 +196,11 @@ public class DateParser {
break;
case SIGN:
+ if (peek() == -1) {
+ // END after sign - wrong!
+ return false;
+ }
+
if (currentField == YEAR) {
yearSign = numValue;
} else if (currentField < SECOND || !setTimezone(readTimeZoneOffset(), true)) {
@@ -297,6 +302,11 @@ public class DateParser {
break;
case SIGN:
+ if (peek() == -1) {
+ // END after sign - wrong!
+ return false;
+ }
+
if (!setTimezone(readTimeZoneOffset(), true)) {
return false;
}
diff --git a/nashorn/test/script/basic/JDK-8015353.js b/nashorn/test/script/basic/JDK-8015353.js
new file mode 100644
index 00000000000..a9baa4691ae
--- /dev/null
+++ b/nashorn/test/script/basic/JDK-8015353.js
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8015353: Date.parse illegal string parsing issues
+ *
+ * @test
+ * @run
+ */
+
+function checkDate(str) {
+ if (! isNaN(Date.parse(str))) {
+ fail(str + " is parsed as legal Date");
+ }
+}
+
+checkDate("2012-01-10T00:00:00.000-");
+checkDate("2012-01-01T00:00+");
From 36b5e14b3106294d4150ff6a9b39fefb0d299983 Mon Sep 17 00:00:00 2001
From: James Tomson
Date: Thu, 30 May 2013 18:10:26 +0400
Subject: [PATCH 088/206] 8015303: [macosx] Application launched via custom URL
Scheme does not receive URL
Make copies of event parameters
Reviewed-by: anthony, swingler, serb
---
.../macosx/native/sun/osxapp/QueuingApplicationDelegate.m | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/jdk/src/macosx/native/sun/osxapp/QueuingApplicationDelegate.m b/jdk/src/macosx/native/sun/osxapp/QueuingApplicationDelegate.m
index 5b71d8ab96c..736155fdc01 100644
--- a/jdk/src/macosx/native/sun/osxapp/QueuingApplicationDelegate.m
+++ b/jdk/src/macosx/native/sun/osxapp/QueuingApplicationDelegate.m
@@ -110,8 +110,14 @@
- (void)_handleOpenURLEvent:(NSAppleEventDescriptor *)openURLEvent withReplyEvent:(NSAppleEventDescriptor *)replyEvent
{
+ // Make an explicit copy of the passed events as they may be invalidated by the time they're processed
+ NSAppleEventDescriptor *openURLEventCopy = [openURLEvent copy];
+ NSAppleEventDescriptor *replyEventCopy = [replyEvent copy];
+
[self.queue addObject:[^(){
- [self.realDelegate _handleOpenURLEvent:openURLEvent withReplyEvent:replyEvent];
+ [self.realDelegate _handleOpenURLEvent:openURLEventCopy withReplyEvent:replyEventCopy];
+ [openURLEventCopy release];
+ [replyEventCopy release];
} copy]];
}
From e460380426d3e91ef4891b7f410801f796549d79 Mon Sep 17 00:00:00 2001
From: Anton Tarasov
Date: Thu, 30 May 2013 18:23:21 +0400
Subject: [PATCH 089/206] 8013424: Regression:
java.awt.datatransfer.FlavorListeners not notified on Linux/Java 7
Reviewed-by: anthony
---
jdk/src/solaris/classes/sun/awt/X11/XClipboard.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java b/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java
index 44ee617783b..6293bc52573 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XClipboard.java
@@ -179,6 +179,7 @@ public final class XClipboard extends SunClipboard implements OwnershipListener
}
synchronized (XClipboard.classLock) {
if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
+ // The viewer is still registered, schedule next poll.
XToolkit.schedule(this, XClipboard.getPollInterval());
}
}
@@ -191,7 +192,8 @@ public final class XClipboard extends SunClipboard implements OwnershipListener
final XSelectionEvent xse = ev.get_xselection();
XClipboard clipboard = null;
synchronized (XClipboard.classLock) {
- if (targetsAtom2Clipboard != null && !targetsAtom2Clipboard.isEmpty()) {
+ if (targetsAtom2Clipboard != null && targetsAtom2Clipboard.isEmpty()) {
+ // The viewer was unregistered, remove the dispatcher.
XToolkit.removeEventDispatcher(XWindow.getXAWTRootWindow().getWindow(), this);
return;
}
From 833d23804d16304e03fd9766df08a82643cf68c6 Mon Sep 17 00:00:00 2001
From: Anton Tarasov
Date: Thu, 30 May 2013 18:31:33 +0400
Subject: [PATCH 090/206] 8013773: requestFocusInWindow to a disabled component
prevents window of getting focused
Reviewed-by: leonidr, alexsch
---
.../java/awt/DefaultKeyboardFocusManager.java | 1 +
.../ResetMostRecentFocusOwnerTest.java | 121 ++++++++++++++++++
2 files changed, 122 insertions(+)
create mode 100644 jdk/test/java/awt/Focus/ResetMostRecentFocusOwnerTest/ResetMostRecentFocusOwnerTest.java
diff --git a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
index 68e1f52a221..f4199881989 100644
--- a/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
+++ b/jdk/src/share/classes/java/awt/DefaultKeyboardFocusManager.java
@@ -559,6 +559,7 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager {
} else {
restoreFocus(fe, newFocusedWindow);
}
+ setMostRecentFocusOwner(newFocusedWindow, null); // see: 8013773
}
break;
}
diff --git a/jdk/test/java/awt/Focus/ResetMostRecentFocusOwnerTest/ResetMostRecentFocusOwnerTest.java b/jdk/test/java/awt/Focus/ResetMostRecentFocusOwnerTest/ResetMostRecentFocusOwnerTest.java
new file mode 100644
index 00000000000..f98bbdf7386
--- /dev/null
+++ b/jdk/test/java/awt/Focus/ResetMostRecentFocusOwnerTest/ResetMostRecentFocusOwnerTest.java
@@ -0,0 +1,121 @@
+/*
+ * 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 8013773
+ @summary Tests that disabled component is not retained as most recent focus owner.
+ @author Anton.Tarasov: area=awt.focus
+ @library ../../regtesthelpers
+ @build Util
+ @run main ResetMostRecentFocusOwnerTest
+*/
+
+import java.applet.Applet;
+import java.awt.AWTEvent;
+import java.awt.FlowLayout;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.AWTEventListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.WindowEvent;
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import test.java.awt.regtesthelpers.Util;
+
+public class ResetMostRecentFocusOwnerTest extends Applet {
+
+ public static void main(String[] args) {
+ ResetMostRecentFocusOwnerTest app = new ResetMostRecentFocusOwnerTest();
+ app.init();
+ app.start();
+ }
+
+ @Override
+ public void start() {
+
+ Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+ public void eventDispatched(AWTEvent e) {
+ System.err.println(e);
+ }
+ }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK);
+
+ boolean gained = false;
+ final Robot robot = Util.createRobot();
+
+ JFrame frame1 = new JFrame("Main Frame");
+ final JButton b1 = new JButton("button1");
+ frame1.add(b1);
+ frame1.pack();
+ frame1.setLocation(0, 300);
+
+ Util.showWindowWait(frame1);
+
+ final JFrame frame2 = new JFrame("Test Frame");
+ final JButton b2 = new JButton("button2");
+ frame2.add(b2);
+ frame2.pack();
+ frame2.setLocation(300, 300);
+
+ b2.setEnabled(false);
+ b2.requestFocus();
+
+ Util.showWindowWait(frame2);
+
+ robot.delay(500);
+
+ //
+ // It's expeced that the focus is restored to .
+ // If not, click to set focus on it.
+ //
+ if (!b1.hasFocus()) {
+ gained = Util.trackFocusGained(b1, new Runnable() {
+ public void run() {
+ Util.clickOnComp(b1, robot);
+ }
+ }, 5000, false);
+
+ if (!gained) {
+ throw new RuntimeException("Unexpected state: focus is not on ");
+ }
+ }
+
+ robot.delay(500);
+
+ //
+ // Click , check that focus is set on the parent frame.
+ //
+ gained = false;
+ gained = Util.trackFocusGained(frame2, new Runnable() {
+ public void run() {
+ Util.clickOnComp(b2, robot);
+ }
+ }, 5000, false);
+
+ if (!gained) {
+ throw new RuntimeException("Test failed: focus wasn't set to ");
+ }
+
+ System.out.println("Test passed.");
+ }
+}
From 2ab206de9e05b8ef480df87253dbf70fb616acec Mon Sep 17 00:00:00 2001
From: Jiri Vanek
Date: Thu, 30 May 2013 16:50:31 +0100
Subject: [PATCH 091/206] 8011693: Remove redundant fontconfig files
Remove unused fontconfig files from OpenJDK GNU/Linux builds
Reviewed-by: andrew, prr
---
jdk/make/sun/awt/Makefile | 17 +-
jdk/makefiles/GendataFontConfig.gmk | 8 +-
.../linux.fontconfig.Fedora.properties | 377 ------------------
.../linux.fontconfig.SuSE.properties | 154 -------
.../linux.fontconfig.Ubuntu.properties | 348 ----------------
.../fontconfigs/linux.fontconfig.properties | 189 ---------
6 files changed, 14 insertions(+), 1079 deletions(-)
delete mode 100644 jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Fedora.properties
delete mode 100644 jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.SuSE.properties
delete mode 100644 jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Ubuntu.properties
delete mode 100644 jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.properties
diff --git a/jdk/make/sun/awt/Makefile b/jdk/make/sun/awt/Makefile
index ed9361294a4..5ac9d64c773 100644
--- a/jdk/make/sun/awt/Makefile
+++ b/jdk/make/sun/awt/Makefile
@@ -390,12 +390,9 @@ ifeq ($(PLATFORM), linux)
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv LINUX
ifdef OPENJDK
-FONTCONFIGS_SRC = $(PLATFORM_SRC)/classes/sun/awt/fontconfigs
-_FONTCONFIGS = \
- fontconfig.properties \
- fontconfig.SuSE.properties \
- fontconfig.Ubuntu.properties \
- fontconfig.Fedora.properties
+FONTCONFIGS_SRC =
+_FONTCONFIGS =
+
else
FONTCONFIGS_SRC = $(CLOSED_SRC)/solaris/classes/sun/awt/fontconfigs
@@ -441,7 +438,11 @@ endif # PLATFORM
FONTCONFIGS = $(_FONTCONFIGS:%=$(LIBDIR)/%.src)
BINARYFONTCONFIGS = $(_FONTCONFIGS:%.properties=$(LIBDIR)/%.bfc)
+ifneq ("x$(_FONTCONFIGS)", "x")
fontconfigs: $(FONTCONFIGS) $(BINARYFONTCONFIGS)
+else
+fontconfigs:
+endif
$(LIBDIR)/%.src: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%
$(install-file)
@@ -455,9 +456,13 @@ $(LIBDIR)/%.bfc: $(FONTCONFIGS_SRC)/$(FONTCONFIGS_SRC_PREFIX)%.properties \
$(call chmod-file, 444)
@$(java-vm-cleanup)
+ifneq ("x$(_FONTCONFIGS)", "x")
fontconfigs.clean :
$(RM) $(FONTCONFIGS)
$(RM) $(BINARYFONTCONFIGS)
+else
+fontconfigs.clean :
+endif
ifeq ($(PLATFORM), windows)
# vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv WINDOWS
diff --git a/jdk/makefiles/GendataFontConfig.gmk b/jdk/makefiles/GendataFontConfig.gmk
index 189a7327a1d..08d30faeacb 100644
--- a/jdk/makefiles/GendataFontConfig.gmk
+++ b/jdk/makefiles/GendataFontConfig.gmk
@@ -36,11 +36,9 @@ ifeq ($(OPENJDK_TARGET_OS), linux)
ifdef OPENJDK
GENDATA_FONT_CONFIG_SRC_DIR := \
$(JDK_TOPDIR)/src/solaris/classes/sun/awt/fontconfigs
- GENDATA_FONT_CONFIG_SRC_FILES := \
- fontconfig.properties \
- fontconfig.SuSE.properties \
- fontconfig.Ubuntu.properties \
- fontconfig.Fedora.properties
+ # This is placeholder for possible fonconfig files which may
+ # useful for some highly specialized Linux distributions
+ GENDATA_FONT_CONFIG_SRC_FILES :=
else
GENDATA_FONT_CONFIG_SRC_DIR := \
$(JDK_TOPDIR)/src/closed/solaris/classes/sun/awt/fontconfigs
diff --git a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Fedora.properties b/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Fedora.properties
deleted file mode 100644
index e9f3a4912e3..00000000000
--- a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Fedora.properties
+++ /dev/null
@@ -1,377 +0,0 @@
-#
-#
-# Copyright (c) 2007, 2010, 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.
-#
-
-# Version
-
-# Uses Fedora 9 fonts and file paths.
-version=1
-
-# Component Font Mappings
-
-dialog.plain.latin-1=DejaVu Sans
-dialog.plain.japanese-x0208=Sazanami Gothic
-dialog.plain.korean=Baekmuk Gulim
-dialog.plain.chinese-big5=AR PL ShanHeiSun Uni
-dialog.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-dialog.plain.bengali=Lohit Bengali
-dialog.plain.gujarati=Lohit Gujarati
-dialog.plain.hindi=Lohit Hindi
-dialog.plain.malayalam=Lohit Malayalam
-dialog.plain.oriya=Lohit Oriya
-dialog.plain.punjabi=Lohit Punjabi
-dialog.plain.tamil=Lohit Tamil
-dialog.plain.telugu=Lohit Telugu
-dialog.plain.sinhala=LKLUG
-
-dialog.bold.latin-1=DejaVu Sans Bold
-dialog.bold.japanese-x0208=Sazanami Gothic
-dialog.bold.korean=Baekmuk Gulim
-dialog.bold.chinese-big5=AR PL ShanHeiSun Uni
-dialog.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-dialog.bold.bengali=Lohit Bengali
-dialog.bold.gujarati=Lohit Gujarati
-dialog.bold.hindi=Lohit Hindi
-dialog.bold.malayalam=Lohit Malayalam
-dialog.bold.oriya=Lohit Oriya
-dialog.bold.punjabi=Lohit Punjabi
-dialog.bold.tamil=Lohit Tamil
-dialog.bold.telugu=Lohit Telugu
-dialog.bold.sinhala=LKLUG
-
-dialog.italic.latin-1=DejaVu Sans Oblique
-dialog.italic.japanese-x0208=Sazanami Gothic
-dialog.italic.korean=Baekmuk Gulim
-dialog.italic.chinese-big5=AR PL ShanHeiSun Uni
-dialog.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-dialog.italic.bengali=Lohit Bengali
-dialog.italic.gujarati=Lohit Gujarati
-dialog.italic.hindi=Lohit Hindi
-dialog.italic.malayalam=Lohit Malayalam
-dialog.italic.oriya=Lohit Oriya
-dialog.italic.punjabi=Lohit Punjabi
-dialog.italic.tamil=Lohit Tamil
-dialog.italic.telugu=Lohit Telugu
-dialog.italic.sinhala=LKLUG
-
-dialog.bolditalic.latin-1=DejaVu Sans Bold Oblique
-dialog.bolditalic.japanese-x0208=Sazanami Gothic
-dialog.bolditalic.korean=Baekmuk Gulim
-dialog.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-dialog.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-dialog.bolditalic.bengali=Lohit Bengali
-dialog.bolditalic.gujarati=Lohit Gujarati
-dialog.bolditalic.hindi=Lohit Hindi
-dialog.bolditalic.malayalam=Lohit Malayalam
-dialog.bolditalic.oriya=Lohit Oriya
-dialog.bolditalic.punjabi=Lohit Punjabi
-dialog.bolditalic.tamil=Lohit Tamil
-dialog.bolditalic.telugu=Lohit Telugu
-dialog.bolditalic.sinhala=LKLUG
-
-sansserif.plain.latin-1=DejaVu Sans
-sansserif.plain.japanese-x0208=Sazanami Gothic
-sansserif.plain.korean=Baekmuk Gulim
-sansserif.plain.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-sansserif.plain.bengali=Lohit Bengali
-sansserif.plain.gujarati=Lohit Gujarati
-sansserif.plain.hindi=Lohit Hindi
-sansserif.plain.malayalam=Lohit Malayalam
-sansserif.plain.oriya=Lohit Oriya
-sansserif.plain.punjabi=Lohit Punjabi
-sansserif.plain.tamil=Lohit Tamil
-sansserif.plain.telugu=Lohit Telugu
-sansserif.plain.sinhala=LKLUG
-
-sansserif.bold.latin-1=DejaVu Sans Bold
-sansserif.bold.japanese-x0208=Sazanami Gothic
-sansserif.bold.korean=Baekmuk Gulim
-sansserif.bold.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-sansserif.bold.bengali=Lohit Bengali
-sansserif.bold.gujarati=Lohit Gujarati
-sansserif.bold.hindi=Lohit Hindi
-sansserif.bold.malayalam=Lohit Malayalam
-sansserif.bold.oriya=Lohit Oriya
-sansserif.bold.punjabi=Lohit Punjabi
-sansserif.bold.tamil=Lohit Tamil
-sansserif.bold.telugu=Lohit Telugu
-sansserif.bold.sinhala=LKLUG
-
-sansserif.italic.latin-1=DejaVu Sans Oblique
-sansserif.italic.japanese-x0208=Sazanami Gothic
-sansserif.italic.korean=Baekmuk Gulim
-sansserif.italic.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-sansserif.italic.bengali=Lohit Bengali
-sansserif.italic.gujarati=Lohit Gujarati
-sansserif.italic.hindi=Lohit Hindi
-sansserif.italic.malayalam=Lohit Malayalam
-sansserif.italic.oriya=Lohit Oriya
-sansserif.italic.punjabi=Lohit Punjabi
-sansserif.italic.tamil=Lohit Tamil
-sansserif.italic.telugu=Lohit Telugu
-sansserif.italic.sinhala=LKLUG
-
-sansserif.bolditalic.latin-1=DejaVu Sans Bold Oblique
-sansserif.bolditalic.japanese-x0208=Sazanami Gothic
-sansserif.bolditalic.korean=Baekmuk Gulim
-sansserif.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-sansserif.bolditalic.bengali=Lohit Bengali
-sansserif.bolditalic.gujarati=Lohit Gujarati
-sansserif.bolditalic.hindi=Lohit Hindi
-sansserif.bolditalic.malayalam=Lohit Malayalam
-sansserif.bolditalic.oriya=Lohit Oriya
-sansserif.bolditalic.punjabi=Lohit Punjabi
-sansserif.bolditalic.tamil=Lohit Tamil
-sansserif.bolditalic.telugu=Lohit Telugu
-sansserif.bolditalic.sinhala=LKLUG
-
-serif.plain.latin-1=DejaVu Serif
-serif.plain.japanese-x0208=Sazanami Mincho
-serif.plain.korean=Baekmuk Batang
-serif.plain.chinese-big5=AR PL ZenKai Uni
-serif.plain.chinese-gb18030=AR PL ZenKai Uni
-serif.plain.bengali=Lohit Bengali
-serif.plain.gujarati=Lohit Gujarati
-serif.plain.hindi=Lohit Hindi
-serif.plain.malayalam=Lohit Malayalam
-serif.plain.oriya=Lohit Oriya
-serif.plain.punjabi=Lohit Punjabi
-serif.plain.tamil=Lohit Tamil
-serif.plain.telugu=Lohit Telugu
-serif.plain.sinhala=LKLUG
-
-serif.bold.latin-1=DejaVu Serif Bold
-serif.bold.japanese-x0208=Sazanami Mincho
-serif.bold.korean=Baekmuk Batang
-serif.bold.chinese-big5=AR PL ZenKai Uni
-serif.bold.chinese-gb18030=AR PL ZenKai Uni
-serif.bold.bengali=Lohit Bengali
-serif.bold.gujarati=Lohit Gujarati
-serif.bold.hindi=Lohit Hindi
-serif.bold.malayalam=Lohit Malayalam
-serif.bold.oriya=Lohit Oriya
-serif.bold.punjabi=Lohit Punjabi
-serif.bold.tamil=Lohit Tamil
-serif.bold.telugu=Lohit Telugu
-serif.bold.sinhala=LKLUG
-
-serif.italic.latin-1=DejaVu Serif Oblique
-serif.italic.japanese-x0208=Sazanami Mincho
-serif.italic.korean=Baekmuk Batang
-serif.italic.chinese-big5=AR PL ZenKai Uni
-serif.italic.chinese-gb18030=AR PL ZenKai Uni
-serif.italic.bengali=Lohit Bengali
-serif.italic.gujarati=Lohit Gujarati
-serif.italic.hindi=Lohit Hindi
-serif.italic.malayalam=Lohit Malayalam
-serif.italic.oriya=Lohit Oriya
-serif.italic.punjabi=Lohit Punjabi
-serif.italic.tamil=Lohit Tamil
-serif.italic.telugu=Lohit Telugu
-serif.italic.sinhala=LKLUG
-
-serif.bolditalic.latin-1=DejaVu Serif Bold Oblique
-serif.bolditalic.japanese-x0208=Sazanami Mincho
-serif.bolditalic.korean=Baekmuk Batang
-serif.bolditalic.chinese-big5=AR PL ZenKai Uni
-serif.bolditalic.chinese-gb18030=AR PL ZenKai Uni
-serif.bolditalic.bengali=Lohit Bengali
-serif.bolditalic.gujarati=Lohit Gujarati
-serif.bolditalic.hindi=Lohit Hindi
-serif.bolditalic.malayalam=Lohit Malayalam
-serif.bolditalic.oriya=Lohit Oriya
-serif.bolditalic.punjabi=Lohit Punjabi
-serif.bolditalic.tamil=Lohit Tamil
-serif.bolditalic.telugu=Lohit Telugu
-serif.bolditalic.sinhala=LKLUG
-
-monospaced.plain.latin-1=DejaVu Sans Mono
-monospaced.plain.japanese-x0208=Sazanami Gothic
-monospaced.plain.korean=Baekmuk Gulim
-monospaced.plain.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-monospaced.plain.bengali=Lohit Bengali
-monospaced.plain.gujarati=Lohit Gujarati
-monospaced.plain.hindi=Lohit Hindi
-monospaced.plain.malayalam=Lohit Malayalam
-monospaced.plain.oriya=Lohit Oriya
-monospaced.plain.punjabi=Lohit Punjabi
-monospaced.plain.tamil=Lohit Tamil
-monospaced.plain.telugu=Lohit Telugu
-monospaced.plain.sinhala=LKLUG
-
-monospaced.bold.latin-1=DejaVu Sans Mono Bold
-monospaced.bold.japanese-x0208=Sazanami Gothic
-monospaced.bold.korean=Baekmuk Gulim
-monospaced.bold.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-monospaced.bold.bengali=Lohit Bengali
-monospaced.bold.gujarati=Lohit Gujarati
-monospaced.bold.hindi=Lohit Hindi
-monospaced.bold.malayalam=Lohit Malayalam
-monospaced.bold.oriya=Lohit Oriya
-monospaced.bold.punjabi=Lohit Punjabi
-monospaced.bold.tamil=Lohit Tamil
-monospaced.bold.telugu=Lohit Telugu
-monospaced.bold.sinhala=LKLUG
-
-monospaced.italic.latin-1=DejaVu Sans Mono Oblique
-monospaced.italic.japanese-x0208=Sazanami Gothic
-monospaced.italic.korean=Baekmuk Gulim
-monospaced.italic.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-monospaced.italic.bengali=Lohit Bengali
-monospaced.italic.gujarati=Lohit Gujarati
-monospaced.italic.hindi=Lohit Hindi
-monospaced.italic.malayalam=Lohit Malayalam
-monospaced.italic.oriya=Lohit Oriya
-monospaced.italic.punjabi=Lohit Punjabi
-monospaced.italic.tamil=Lohit Tamil
-monospaced.italic.telugu=Lohit Telugu
-monospaced.italic.sinhala=LKLUG
-
-monospaced.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
-monospaced.bolditalic.japanese-x0208=Sazanami Gothic
-monospaced.bolditalic.korean=Baekmuk Gulim
-monospaced.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-monospaced.bolditalic.bengali=Lohit Bengali
-monospaced.bolditalic.gujarati=Lohit Gujarati
-monospaced.bolditalic.hindi=Lohit Hindi
-monospaced.bolditalic.malayalam=Lohit Malayalam
-monospaced.bolditalic.oriya=Lohit Oriya
-monospaced.bolditalic.punjabi=Lohit Punjabi
-monospaced.bolditalic.tamil=Lohit Tamil
-monospaced.bolditalic.telugu=Lohit Telugu
-monospaced.bolditalic.sinhala=LKLUG
-
-dialoginput.plain.latin-1=DejaVu Sans Mono
-dialoginput.plain.japanese-x0208=Sazanami Gothic
-dialoginput.plain.korean=Baekmuk Gulim
-dialoginput.plain.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-dialoginput.plain.bengali=Lohit Bengali
-dialoginput.plain.gujarati=Lohit Gujarati
-dialoginput.plain.hindi=Lohit Hindi
-dialoginput.plain.malayalam=Lohit Malayalam
-dialoginput.plain.oriya=Lohit Oriya
-dialoginput.plain.punjabi=Lohit Punjabi
-dialoginput.plain.tamil=Lohit Tamil
-dialoginput.plain.telugu=Lohit Telugu
-dialoginput.plain.sinhala=LKLUG
-
-dialoginput.bold.latin-1=DejaVu Sans Mono Bold
-dialoginput.bold.japanese-x0208=Sazanami Gothic
-dialoginput.bold.korean=Baekmuk Gulim
-dialoginput.bold.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-dialoginput.bold.bengali=Lohit Bengali
-dialoginput.bold.gujarati=Lohit Gujarati
-dialoginput.bold.hindi=Lohit Hindi
-dialoginput.bold.malayalam=Lohit Malayalam
-dialoginput.bold.oriya=Lohit Oriya
-dialoginput.bold.punjabi=Lohit Punjabi
-dialoginput.bold.tamil=Lohit Tamil
-dialoginput.bold.telugu=Lohit Telugu
-dialoginput.bold.sinhala=LKLUG
-
-dialoginput.italic.latin-1=DejaVu Sans Mono Oblique
-dialoginput.italic.japanese-x0208=Sazanami Gothic
-dialoginput.italic.korean=Baekmuk Gulim
-dialoginput.italic.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-dialoginput.italic.bengali=Lohit Bengali
-dialoginput.italic.gujarati=Lohit Gujarati
-dialoginput.italic.hindi=Lohit Hindi
-dialoginput.italic.malayalam=Lohit Malayalam
-dialoginput.italic.oriya=Lohit Oriya
-dialoginput.italic.punjabi=Lohit Punjabi
-dialoginput.italic.tamil=Lohit Tamil
-dialoginput.italic.telugu=Lohit Telugu
-dialoginput.italic.sinhala=LKLUG
-
-dialoginput.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
-dialoginput.bolditalic.japanese-x0208=Sazanami Gothic
-dialoginput.bolditalic.korean=Baekmuk Gulim
-dialoginput.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-dialoginput.bolditalic.bengali=Lohit Bengali
-dialoginput.bolditalic.gujarati=Lohit Gujarati
-dialoginput.bolditalic.hindi=Lohit Hindi
-dialoginput.bolditalic.malayalam=Lohit Malayalam
-dialoginput.bolditalic.oriya=Lohit Oriya
-dialoginput.bolditalic.punjabi=Lohit Punjabi
-dialoginput.bolditalic.tamil=Lohit Tamil
-dialoginput.bolditalic.telugu=Lohit Telugu
-dialoginput.bolditalic.sinhala=LKLUG
-
-# Search Sequences
-
-sequence.allfonts=latin-1
-sequence.allfonts.Big5=chinese-big5,latin-1
-sequence.allfonts.x-euc-jp-linux=japanese-x0208,latin-1
-sequence.allfonts.EUC-KR=korean,latin-1
-sequence.allfonts.GB18030=chinese-gb18030,latin-1
-sequence.fallback=chinese-big5,chinese-gb18030,japanese-x0208,korean,bengali,gujarati,hindi,oriya,punjabi,malayalam,tamil,telugu,sinhala
-
-# Font File Names
-
-filename.DejaVu_Sans=/usr/share/fonts/dejavu/DejaVuSans.ttf
-filename.DejaVu_Sans_Bold=/usr/share/fonts/dejavu/DejaVuSans-Bold.ttf
-filename.DejaVu_Sans_Oblique=/usr/share/fonts/dejavu/DejaVuSans-Oblique.ttf
-filename.DejaVu_Sans_Bold_Oblique=/usr/share/fonts/dejavu/DejaVuSans-BoldOblique.ttf
-
-filename.DejaVu_Sans_Mono=/usr/share/fonts/dejavu/DejaVuSansMono.ttf
-filename.DejaVu_Sans_Mono_Bold=/usr/share/fonts/dejavu/DejaVuSansMono-Bold.ttf
-filename.DejaVu_Sans_Mono_Oblique=/usr/share/fonts/dejavu/DejaVuSansMono-Oblique.ttf
-filename.DejaVu_Sans_Mono_Bold_Oblique=/usr/share/fonts/dejavu/DejaVuSansMono-BoldOblique.ttf
-
-filename.DejaVu_Serif=/usr/share/fonts/dejavu/DejaVuSerif.ttf
-filename.DejaVu_Serif_Bold=/usr/share/fonts/dejavu/DejaVuSerif-Bold.ttf
-filename.DejaVu_Serif_Oblique=/usr/share/fonts/dejavu/DejaVuSerif-Oblique.ttf
-filename.DejaVu_Serif_Bold_Oblique=/usr/share/fonts/dejavu/DejaVuSerif-BoldOblique.ttf
-
-filename.Sazanami_Gothic=/usr/share/fonts/sazanami-fonts-gothic/sazanami-gothic.ttf
-filename.Sazanami_Mincho=/usr/share/fonts/sazanami-fonts-mincho/sazanami-mincho.ttf
-filename.AR_PL_ShanHeiSun_Uni=/usr/share/fonts/cjkunifonts-uming/uming.ttc
-filename.AR_PL_ZenKai_Uni=/usr/share/fonts/cjkunifonts-ukai/ukai.ttc
-filename.Baekmuk_Gulim=/usr/share/fonts/baekmuk-ttf-gulim/gulim.ttf
-filename.Baekmuk_Batang=/usr/share/fonts/baekmuk-ttf-batang/batang.ttf
-
-filename.Lohit_Bengali=/usr/share/fonts/lohit-bengali/lohit_bn.ttf
-filename.Lohit_Gujarati=/usr/share/fonts/lohit-gujarati/lohit_gu.ttf
-filename.Lohit_Hindi=/usr/share/fonts/lohit-hindi/lohit_hi.ttf
-filename.Lohit_Kannda=/usr/share/fonts/lohit-kannada/lohit_kn.ttf
-filename.Lohit_Malayalam=/usr/share/fonts/lohit-malayalam/lohit_ml.ttf
-filename.Lohit_Oriya=/usr/share/fonts/lohit-oriya/lohit_or.ttf
-filename.Lohit_Punjabi=/usr/share/fonts/lohit-punjabi/lohit_pa.ttf
-filename.Lohit_Tamil=/usr/share/fonts/lohit-tamil/lohit_ta.ttf
-filename.Lohit_Telugu=/usr/share/fonts/lohit-telugu/lohit_te.ttf
-filename.LKLUG=/usr/share/fonts/lklug/lklug.ttf
-
diff --git a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.SuSE.properties b/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.SuSE.properties
deleted file mode 100644
index fb86ded9afc..00000000000
--- a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.SuSE.properties
+++ /dev/null
@@ -1,154 +0,0 @@
-#
-#
-# Copyright (c) 2007, 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.
-#
-
-# Version
-
-# Uses SuSE 10.2 fonts and file paths.
-version=1
-
-# Component Font Mappings
-
-dialog.plain.latin-1=Albany AMT
-dialog.plain.japanese-x0208=Sazanami Gothic
-dialog.plain.korean=UnDotum
-
-dialog.bold.latin-1=Albany AMT Bold
-dialog.bold.japanese-x0208=Sazanami Gothic
-dialog.bold.korean=UnDotum Bold
-
-dialog.italic.latin-1=Albany AMT Italic
-dialog.italic.japanese-x0208=Sazanami Gothic
-dialog.italic.korean=UnDotum
-
-dialog.bolditalic.latin-1=Albany AMT Bold Italic
-dialog.bolditalic.japanese-x0208=Sazanami Gothic
-dialog.bolditalic.korean=UnDotum Bold
-
-
-sansserif.plain.latin-1=Albany AMT
-sansserif.plain.japanese-x0208=Sazanami Gothic
-sansserif.plain.korean=UnDotum
-
-sansserif.bold.latin-1=Albany AMT Bold
-sansserif.bold.japanese-x0208=Sazanami Gothic
-sansserif.bold.korean=UnDotum Bold
-
-sansserif.italic.latin-1=Albany AMT Italic
-sansserif.italic.japanese-x0208=Sazanami Gothic
-sansserif.italic.korean=UnDotum
-
-sansserif.bolditalic.latin-1=Albany AMT Bold Italic
-sansserif.bolditalic.japanese-x0208=Sazanami Gothic
-sansserif.bolditalic.korean=UnDotum Bold
-
-
-serif.plain.latin-1=Thorndale AMT
-serif.plain.japanese-x0208=Sazanami Mincho
-serif.plain.korean=UnBatang
-
-serif.bold.latin-1=Thorndale AMT Bold
-serif.bold.japanese-x0208=Sazanami Mincho
-serif.bold.korean=UnBatang Bold
-
-serif.italic.latin-1=Thorndale AMT Italic
-serif.italic.japanese-x0208=Sazanami Mincho
-serif.italic.korean=UnBatang
-
-serif.bolditalic.latin-1=Thorndale AMT Bold Italic
-serif.bolditalic.japanese-x0208=Sazanami Mincho
-serif.bolditalic.korean=UnBatang Bold
-
-
-monospaced.plain.latin-1=Cumberland AMT
-monospaced.plain.japanese-x0208=Sazanami Gothic
-monospaced.plain.korean=UnDotum
-
-monospaced.bold.latin-1=Cumberland AMT Bold
-monospaced.bold.japanese-x0208=Sazanami Gothic
-monospaced.bold.korean=UnDotum Bold
-
-monospaced.italic.latin-1=Cumberland AMT Italic
-monospaced.italic.japanese-x0208=Sazanami Gothic
-monospaced.italic.korean=UnDotum
-
-monospaced.bolditalic.latin-1=Cumberland AMT Bold Italic
-monospaced.bolditalic.japanese-x0208=Sazanami Gothic
-monospaced.bolditalic.korean=UnDotum Bold
-
-
-dialoginput.plain.latin-1=Cumberland AMT
-dialoginput.plain.japanese-x0208=Sazanami Gothic
-dialoginput.plain.korean=UnDotum
-
-dialoginput.bold.latin-1=Cumberland AMT Bold
-dialoginput.bold.japanese-x0208=Sazanami Gothic
-dialoginput.bold.korean=UnDotum Bold
-
-dialoginput.italic.latin-1=Cumberland AMT Italic
-dialoginput.italic.japanese-x0208=Sazanami Gothic
-dialoginput.italic.korean=UnDotum
-
-dialoginput.bolditalic.latin-1=Cumberland AMT Bold Italic
-dialoginput.bolditalic.japanese-x0208=Sazanami Gothic
-dialoginput.bolditalic.korean=UnDotum Bold
-
-allfonts.chinese-big5=AR PL Mingti2L Big5
-allfonts.chinese-gb18030=AR PL SungtiL GB
-
-# Search Sequences
-
-sequence.allfonts=latin-1
-sequence.allfonts.Big5=chinese-big5,latin-1
-sequence.allfonts.x-euc-jp-linux=japanese-x0208,latin-1
-sequence.allfonts.EUC-KR=korean,latin-1
-sequence.allfonts.GB18030=chinese-gb18030,latin-1
-sequence.fallback=chinese-big5,chinese-gb18030,japanese-x0208,korean
-
-# Font File Names
-
-filename.Albany_AMT=/usr/share/fonts/truetype/albw.ttf
-filename.Albany_AMT_Bold=/usr/share/fonts/truetype/albwb.ttf
-filename.Albany_AMT_Italic=/usr/share/fonts/truetype/albwb.ttf
-filename.Albany_AMT_Bold_Italic=/usr/share/fonts/truetype/albwbi.ttf
-
-filename.Thorndale_AMT=/usr/share/fonts/truetype/thowr___.ttf
-filename.Thorndale_AMT_Bold=/usr/share/fonts/truetype/thowb___.ttf
-filename.Thorndale_AMT_Italic=/usr/share/fonts/truetype/thowi___.ttf
-filename.Thorndale_AMT_Bold_Italic=/usr/share/fonts/truetype/thowbi__.ttf
-
-filename.Cumberland_AMT=/usr/share/fonts/truetype/cumbwr__.ttf
-filename.Cumberland_AMT_Bold=/usr/share/fonts/truetype/cumbwb__.ttf
-filename.Cumberland_AMT_Italic=/usr/share/fonts/truetype/cumbwi__.ttf
-filename.Cumberland_AMT_Bold_Italic=/usr/share/fonts/truetype/cumbwbi_.ttf
-
-filename.Sazanami_Gothic=/usr/share/fonts/truetype/sazanami-gothic.ttf
-filename.Sazanami_Mincho=/usr/share/fonts/truetype/sazanami-mincho.ttf
-filename.AR_PL_SungtiL_GB=/usr/share/fonts/truetype/gbsn00lp.ttf
-filename.AR_PL_Mingti2L_Big5=/usr/share/fonts/truetype/bsmi00lp.ttf
-filename.UnDotum=/usr/share/fonts/truetype/UnDotum.ttf
-filename.UnDotum_Bold=/usr/share/fonts/truetype/UnDotumBold.ttf
-filename.UnBatang=/usr/share/fonts/truetype/UnBatang.ttf
-filename.UnBatang_Bold=/usr/share/fonts/truetype/UnBatangBold.ttf
diff --git a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Ubuntu.properties b/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Ubuntu.properties
deleted file mode 100644
index e1817934138..00000000000
--- a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.Ubuntu.properties
+++ /dev/null
@@ -1,348 +0,0 @@
-#
-#
-# Copyright (c) 2007, 2010, 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.
-#
-
-# Version
-
-# Uses Ubuntu 8.04 (hardy), Debian 6.0 (Squeeze) (and more recent releases) fonts and file paths.
-version=1
-
-# Component Font Mappings
-
-# Chinese fonts
-allfonts.umingcn=AR PL UMing CN
-#allfonts.umingcn.motif=AR PL UMing CN
-allfonts.uminghk=AR PL UMing HK
-#allfonts.uminghk.motif=AR PL UMing HK
-allfonts.umingtw=AR PL UMing TW
-#allfonts.umingtw.motif=AR PL UMing TW
-allfonts.wqy-zenhei=WenQuanYi Zen Hei
-#allfonts.wqy-zenhei.motif=WenQuanYi Zen Hei
-allfonts.shanheisun=AR PL ShanHeiSun Uni
-#allfonts.shanheisun.motif=AR PL ShanHeiSun Uni
-
-# Indic scripts
-allfonts.bengali=Lohit Bengali
-allfonts.gujarati=Lohit Gujarati
-allfonts.hindi=Lohit Hindi
-#allfonts.malayalam=Lohit Malayalam
-allfonts.oriya=Lohit Oriya
-allfonts.punjabi=Lohit Punjabi
-allfonts.tamil=Lohit Tamil
-allfonts.telugu=Lohit Telugu
-allfonts.sinhala=LKLUG
-
-
-serif.plain.latin-1=DejaVu Serif
-#serif.plain.latin-1.motif=LuxiSerif-Regular
-serif.plain.japanese-kochi=Kochi Mincho
-serif.plain.japanese-sazanami=Sazanami Mincho
-serif.plain.japanese-vlgothic=Sazanami Mincho
-serif.plain.korean-baekmuk=Baekmuk Batang
-#serif.plain.korean-baekmuk.motif=Baekmuk Batang
-serif.plain.korean-un=UnBatang
-#serif.plain.korean-un.motif=UnBatang
-
-serif.bold.latin-1=DejaVu Serif Bold
-#serif.bold.latin-1.motif=LuxiSerif-Bold
-serif.bold.japanese-kochi=Kochi Mincho
-serif.bold.japanese-sazanami=Sazanami Mincho
-serif.bold.japanese-vlgothic=Sazanami Mincho
-serif.bold.korean-baekmuk=Baekmuk Batang
-#serif.bold.korean-baekmuk.motif=Baekmuk Batang
-serif.bold.korean-un=UnBatang Bold
-#serif.bold.korean-un.motif=UnBatang Bold
-
-serif.italic.latin-1=DejaVu Serif Oblique
-#serif.italic.latin-1.motif=LuxiSerif-Oblique
-serif.italic.japanese-kochi=Kochi Mincho
-serif.italic.japanese-sazanami=Sazanami Mincho
-serif.italic.japanese-vlgothic=Sazanami Mincho
-serif.italic.korean-baekmuk=Baekmuk Batang
-#serif.italic.korean-baekmuk.motif=Baekmuk Batang
-serif.italic.korean-un=UnBatang
-#serif.italic.korean-un.motif=UnBatang
-
-serif.bolditalic.latin-1=DejaVu Serif Bold Oblique
-#serif.bolditalic.latin-1.motif=LuxiSerif-BoldOblique
-serif.bolditalic.japanese-kochi=Kochi Mincho
-serif.bolditalic.japanese-sazanami=Sazanami Mincho
-serif.bolditalic.japanese-vlgothic=Sazanami Mincho
-serif.bolditalic.korean-baekmuk=Baekmuk Batang
-#serif.bolditalic.korean-baekmuk.motif=Baekmuk Batang
-serif.bolditalic.korean-un=UnBatang Bold
-#serif.bolditalic.korean-un.motif=UnBatang Bold
-
-sansserif.plain.latin-1=DejaVu Sans
-#sansserif.plain.latin-1.motif=LuxiSans-Regular
-sansserif.plain.japanese-kochi=Kochi Gothic
-sansserif.plain.japanese-sazanami=Sazanami Gothic
-sansserif.plain.japanese-vlgothic=VL PGothic
-sansserif.plain.korean-baekmuk=Baekmuk Gulim
-#sansserif.plain.korean-baekmuk.motif=Baekmuk Gulim
-sansserif.plain.korean-un=UnDotum
-#sansserif.plain.korean-un.motif=UnDotum
-
-sansserif.bold.latin-1=DejaVu Sans Bold
-#sansserif.bold.latin-1.motif=LuxiSans-Bold
-sansserif.bold.japanese-kochi=Kochi Gothic
-sansserif.bold.japanese-sazanami=Sazanami Gothic
-sansserif.bold.japanese-vlgothic=VL PGothic
-sansserif.bold.korean-baekmuk=Baekmuk Gulim
-#sansserif.bold.korean-baekmuk.motif=Baekmuk Gulim
-sansserif.bold.korean-un=UnDotum Bold
-#sansserif.bold.korean-un.motif=UnDotum Bold
-
-sansserif.italic.latin-1=DejaVu Sans Oblique
-#sansserif.italic.latin-1.motif=LuxiSans-Oblique
-sansserif.italic.japanese-kochi=Kochi Gothic
-sansserif.italic.japanese-sazanami=Sazanami Gothic
-sansserif.italic.japanese-vlgothic=VL PGothic
-sansserif.italic.korean-baekmuk=Baekmuk Gulim
-#sansserif.italic.korean-baekmuk.motif=Baekmuk Gulim
-sansserif.italic.korean-un=UnDotum
-#sansserif.italic.korean-un.motif=UnDotum
-
-sansserif.bolditalic.latin-1=DejaVu Sans Bold Oblique
-#sansserif.bolditalic.latin-1.motif=LuxiSans-BoldOblique
-sansserif.bolditalic.japanese-kochi=Kochi Gothic
-sansserif.bolditalic.japanese-sazanami=Sazanami Gothic
-sansserif.bolditalic.japanese-vlgothic=VL PGothic
-sansserif.bolditalic.korean-baekmuk=Baekmuk Gulim
-#sansserif.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
-sansserif.bolditalic.korean-un=UnDotum Bold
-#sansserif.bolditalic.korean-un.motif=UnDotum Bold
-
-monospaced.plain.latin-1=DejaVu Sans Mono
-#monospaced.plain.latin-1.motif=LuxiMono-Regular
-monospaced.plain.japanese-kochi=Kochi Gothic
-monospaced.plain.japanese-sazanami=Sazanami Gothic
-monospaced.plain.japanese-vlgothic=VL Gothic
-monospaced.plain.korean-baekmuk=Baekmuk Gulim
-#monospaced.plain.korean-baekmuk.motif=Baekmuk Gulim
-monospaced.plain.korean-un=UnDotum
-#monospaced.plain.korean-un.motif=UnDotum
-
-monospaced.bold.latin-1=DejaVu Sans Mono Bold
-#monospaced.bold.latin-1.motif=LuxiMono-Bold
-monospaced.bold.japanese-kochi=Kochi Gothic
-monospaced.bold.japanese-sazanami=Sazanami Gothic
-monospaced.bold.japanese-vlgothic=VL Gothic
-monospaced.bold.korean-baekmuk=Baekmuk Gulim
-#monospaced.bold.korean-baekmuk.motif=Baekmuk Gulim
-monospaced.bold.korean-un=UnDotum Bold
-#monospaced.bold.korean-un.motif=UnDotum Bold
-
-monospaced.italic.latin-1=DejaVu Sans Mono Oblique
-#monospaced.italic.latin-1.motif=LuxiMono-Oblique
-monospaced.italic.japanese-kochi=Kochi Gothic
-monospaced.italic.japanese-sazanami=Sazanami Gothic
-monospaced.italic.japanese-vlgothic=VL Gothic
-monospaced.italic.korean-baekmuk=Baekmuk Gulim
-#monospaced.italic.korean-baekmuk.motif=Baekmuk Gulim
-monospaced.italic.korean-un=UnDotum
-#monospaced.italic.korean-un.motif=UnDotum
-
-monospaced.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
-#monospaced.bolditalic.latin-1.motif=LuxiMono-BoldOblique
-monospaced.bolditalic.japanese-kochi=Kochi Gothic
-monospaced.bolditalic.japanese-sazanami=Sazanami Gothic
-monospaced.bolditalic.japanese-vlgothic=VL Gothic
-monospaced.bolditalic.korean-baekmuk=Baekmuk Gulim
-#monospaced.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
-monospaced.bolditalic.korean-un=UnDotum Bold
-#monospaced.bolditalic.korean-un.motif=UnDotum Bold
-
-dialog.plain.latin-1=DejaVu Sans
-#dialog.plain.latin-1.motif=LuxiSans-Regular
-dialog.plain.japanese-kochi=Kochi Gothic
-dialog.plain.japanese-sazanami=Sazanami Gothic
-dialog.plain.japanese-vlgothic=VL PGothic
-dialog.plain.korean-baekmuk=Baekmuk Gulim
-#dialog.plain.korean-baekmuk.motif=Baekmuk Gulim
-dialog.plain.korean-un=UnDotum
-#dialog.plain.korean-un.motif=UnDotum
-
-dialog.bold.latin-1=DejaVu Sans Bold
-#dialog.bold.latin-1.motif=LuxiSans-Bold
-dialog.bold.japanese-kochi=Kochi Gothic
-dialog.bold.japanese-sazanami=Sazanami Gothic
-dialog.bold.japanese-vlgothic=VL PGothic
-dialog.bold.korean-baekmuk=Baekmuk Gulim
-#dialog.bold.korean-baekmuk.motif=Baekmuk Gulim
-dialog.bold.korean-un=UnDotum Bold
-#dialog.bold.korean-un.motif=UnDotum Bold
-
-dialog.italic.latin-1=DejaVu Sans Oblique
-#dialog.italic.latin-1.motif=LuxiSans-Oblique
-dialog.italic.japanese-kochi=Kochi Gothic
-dialog.italic.japanese-sazanami=Sazanami Gothic
-dialog.italic.japanese-vlgothic=VL PGothic
-dialog.italic.korean-baekmuk=Baekmuk Gulim
-#dialog.italic.korean-baekmuk.motif=Baekmuk Gulim
-dialog.italic.korean-un=UnDotum
-#dialog.italic.korean-un.motif=UnDotum
-
-dialog.bolditalic.latin-1=DejaVu Sans Bold Oblique
-#dialog.bolditalic.latin-1.motif=LuxiSans-BoldOblique
-dialog.bolditalic.japanese-kochi=Kochi Gothic
-dialog.bolditalic.japanese-sazanami=Sazanami Gothic
-dialog.bolditalic.japanese-vlgothic=VL PGothic
-dialog.bolditalic.korean-baekmuk=Baekmuk Gulim
-#dialog.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
-dialog.bolditalic.korean-un=UnDotum Bold
-#dialog.bolditalic.korean-un.motif=UnDotum Bold
-
-dialoginput.plain.latin-1=DejaVu Sans Mono
-#dialoginput.plain.latin-1.motif=LuxiMono-Regular
-dialoginput.plain.japanese-kochi=Kochi Gothic
-dialoginput.plain.japanese-sazanami=Sazanami Gothic
-dialoginput.plain.japanese-vlgothic=VL Gothic
-dialoginput.plain.korean-baekmuk=Baekmuk Gulim
-#dialoginput.plain.korean-baekmuk.motif=Baekmuk Gulim
-dialoginput.plain.korean-un=UnDotum
-#dialoginput.plain.korean-un.motif=UnDotum
-
-dialoginput.bold.latin-1=DejaVu Sans Mono Bold
-#dialoginput.bold.latin-1.motif=LuxiMono-Bold
-dialoginput.bold.japanese-kochi=Kochi Gothic
-dialoginput.bold.japanese-sazanami=Sazanami Gothic
-dialoginput.bold.japanese-vlgothic=VL Gothic
-dialoginput.bold.korean-baekmuk=Baekmuk Gulim
-#dialoginput.bold.korean-baekmuk.motif=Baekmuk Gulim
-dialoginput.bold.korean-un=UnDotum Bold
-#dialoginput.bold.korean-un.motif=UnDotum Bold
-
-dialoginput.italic.latin-1=DejaVu Sans Mono Oblique
-#dialoginput.italic.latin-1.motif=LuxiMono-Oblique
-dialoginput.italic.japanese-kochi=Kochi Gothic
-dialoginput.italic.japanese-sazanami=Sazanami Gothic
-dialoginput.italic.japanese-vlgothic=VL Gothic
-dialoginput.italic.korean-baekmuk=Baekmuk Gulim
-#dialoginput.italic.korean-baekmuk.motif=Baekmuk Gulim
-dialoginput.italic.korean-un=UnDotum
-#dialoginput.italic.korean-un.motif=UnDotum
-
-dialoginput.bolditalic.latin-1=DejaVu Sans Mono Bold Oblique
-#dialoginput.bolditalic.latin-1.motif=LuxiMono-BoldOblique
-dialoginput.bolditalic.japanese-kochi=Kochi Gothic
-dialoginput.bolditalic.japanese-sazanami=Sazanami Gothic
-dialoginput.bolditalic.japanese-vlgothic=VL Gothic
-dialoginput.bolditalic.korean-baekmuk=Baekmuk Gulim
-#dialoginput.bolditalic.korean-baekmuk.motif=Baekmuk Gulim
-dialoginput.bolditalic.korean-un=UnDotum Bold
-#dialoginput.bolditalic.korean-un.motif=UnDotum Bold
-
-# Search Sequences
-
-sequence.allfonts=latin-1
-sequence.allfonts.GB18030=latin-1,umingcn,shanheisun,wqy-zenhei
-sequence.allfonts.GB2312=latin-1,umingcn,shanheisun,wqy-zenhei
-sequence.allfonts.GBK=latin-1,umingcn,shanheisun,wqy-zenhei
-sequence.allfonts.x-euc-jp-linux=latin-1,japanese-vlgothic,japanese-sazanami,japanese-kochi
-sequence.allfonts.EUC-KR=latin-1,korean-un,korean-baekmuk
-sequence.allfonts.Big5=latin-1,umingtw,shanheisun,wqy-zenhei
-sequence.allfonts.Big5-HKSCS=latin-1,uminghk,shanheisun,wqy-zenhei
-#sequence.fallback=uminghk,shanheisun,wqy-zenhei,japanese-vlgothic,japanese-kochi,japanese-sazanami,korean-un,korean-baekmuk,bengali,gujarati,hindi,oriya,punjabi,malayalam,tamil,telugu,sinhala
-sequence.fallback=uminghk,shanheisun,wqy-zenhei,japanese-vlgothic,japanese-sazanami,japanese-kochi,korean-un,korean-baekmuk,bengali,gujarati,hindi,oriya,punjabi,tamil,telugu
-
-# Exclusion Ranges
-
-exclusion.japanese-kochi=0390-03d6,2200-22ef,2701-27be
-exclusion.japanese-sazanami=0390-03d6,2200-22ef,2701-27be
-exclusion.japanese-vlgothic=0390-03d6,2200-22ef,2701-27be
-
-# Font File Names
-
-filename.DejaVu_Sans=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf
-filename.DejaVu_Sans_Bold=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf
-filename.DejaVu_Sans_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Oblique.ttf
-filename.DejaVu_Sans_Bold_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-BoldOblique.ttf
-
-filename.DejaVu_Sans_Mono=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf
-filename.DejaVu_Sans_Mono_Bold=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono-Bold.ttf
-filename.DejaVu_Sans_Mono_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono-Oblique.ttf
-filename.DejaVu_Sans_Mono_Bold_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono-BoldOblique.ttf
-
-filename.DejaVu_Serif=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif.ttf
-filename.DejaVu_Serif_Bold=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Bold.ttf
-filename.DejaVu_Serif_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-Oblique.ttf
-filename.DejaVu_Serif_Bold_Oblique=/usr/share/fonts/truetype/ttf-dejavu/DejaVuSerif-BoldOblique.ttf
-
-filename.AR_PL_UMing_CN=/usr/share/fonts/truetype/arphic/uming.ttc
-filename.AR_PL_UMing_HK=/usr/share/fonts/truetype/arphic/uming.ttc
-filename.AR_PL_UMing_TW=/usr/share/fonts/truetype/arphic/uming.ttc
-filename.AR_PL_ShanHeiSun_Uni=/usr/share/fonts/truetype/arphic/uming.ttf
-
-filename.WenQuanYi_Zen_Hei=/usr/share/fonts/truetype/wqy/wqy-zenhei.ttf
-filename.Baekmuk_Batang=/usr/share/fonts/truetype/baekmuk/batang.ttf
-filename.UnBatang=/usr/share/fonts/truetype/unfonts/UnBatang.ttf
-filename.UnBatang_Bold=/usr/share/fonts/truetype/unfonts/UnBatangBold.ttf
-filename.Baekmuk_Gulim=/usr/share/fonts/truetype/baekmuk/gulim.ttf
-filename.UnDotum=/usr/share/fonts/truetype/unfonts/UnDotum.ttf
-filename.UnDotum_Bold=/usr/share/fonts/truetype/unfonts/UnDotumBold.ttf
-filename.Kochi_Gothic=/usr/share/fonts/truetype/kochi/kochi-gothic.ttf
-filename.Sazanami_Gothic=/usr/share/fonts/truetype/sazanami/sazanami-gothic.ttf
-filename.Kochi_Mincho=/usr/share/fonts/truetype/kochi/kochi-mincho.ttf
-filename.Sazanami_Mincho=/usr/share/fonts/truetype/sazanami/sazanami-mincho.ttf
-filename.VL_Gothic=/usr/share/fonts/truetype/vlgothic/VL-Gothic-Regular.ttf
-filename.VL_PGothic=/usr/share/fonts/truetype/vlgothic/VL-PGothic-Regular.ttf
-
-filename.Lohit_Bengali=/usr/share/fonts/truetype/ttf-bengali-fonts/lohit_bn.ttf
-filename.Lohit_Gujarati=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_gu.ttf
-filename.Lohit_Hindi=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_hi.ttf
-filename.Lohit_Kannda=/usr/share/fonts/truetype/ttf-kannada-fonts/lohit_kn.ttf
-#filename.Lohit_Malayalam=/usr/share/fonts/lohit-malayalam/lohit_ml.ttf
-filename.Lohit_Oriya=/usr/share/fonts/truetype/ttf-oriya-fonts/lohit_or.ttf
-filename.Lohit_Punjabi=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_pa.ttf
-filename.Lohit_Tamil=/usr/share/fonts/truetype/ttf-indic-fonts-core/lohit_ta.ttf
-filename.Lohit_Telugu=/usr/share/fonts/truetype/ttf-telugu-fonts/lohit_te.ttf
-filename.LKLUG=/usr/share/fonts/truetype/ttf-sinhala-lklug/lklug.ttf
-
-filename.LuxiSans-Regular=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisr.ttf
-filename.LuxiSans-Bold=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisb.ttf
-filename.LuxiSans-Oblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisri.ttf
-filename.LuxiSans-BoldOblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxisbi.ttf
-filename.LuxiMono-Regular=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximr.ttf
-filename.LuxiMono-Bold=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximb.ttf
-filename.LuxiMono-Oblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximri.ttf
-filename.LuxiMono-BoldOblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luximbi.ttf
-filename.LuxiSerif-Regular=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirr.ttf
-filename.LuxiSerif-Bold=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirb.ttf
-filename.LuxiSerif-Oblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirri.ttf
-filename.LuxiSerif-BoldOblique=/usr/share/fonts/truetype/ttf-xfree86-nonfree/luxirbi.ttf
-
-# AWT X11 font paths
-awtfontpath.latin-1=/usr/share/fonts/X11/Type1
-awtfontpath.umingcn=/usr/share/fonts/truetype/arphic
-awtfontpath.uminghk=/usr/share/fonts/truetype/arphic
-awtfontpath.umingtw=/usr/share/fonts/truetype/arphic
-awtfontpath.shanheisun=/usr/share/fonts/truetype/arphic
-awtfontpath.wqy-zenhei=/usr/share/fonts/truetype/wqy
-awtfontpath.japanese-kochi=/usr/share/fonts/truetype/kochi
-awtfontpath.japanese-sazanami=/usr/share/fonts/truetype/sazanami
-awtfontpath.japanese-vlgothic=/usr/share/fonts/truetype/vlgothic
-awtfontpath.korean-baekmuk=/usr/share/fonts/truetype/baekmuk
-awtfontpath.korean-un=/usr/share/fonts/truetype/unfonts
diff --git a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.properties b/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.properties
deleted file mode 100644
index da4cf8d7225..00000000000
--- a/jdk/src/solaris/classes/sun/awt/fontconfigs/linux.fontconfig.properties
+++ /dev/null
@@ -1,189 +0,0 @@
-#
-#
-# Copyright (c) 2007, 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.
-#
-
-# Version
-
-# Uses Fedora Core 6 fonts and file paths.
-version=1
-
-# Component Font Mappings
-
-dialog.plain.latin-1=DejaVu LGC Sans
-dialog.plain.japanese-x0208=Sazanami Gothic
-dialog.plain.korean=Baekmuk Gulim
-dialog.plain.chinese-big5=AR PL ShanHeiSun Uni
-dialog.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-
-dialog.bold.latin-1=DejaVu LGC Sans Bold
-dialog.bold.japanese-x0208=Sazanami Gothic
-dialog.bold.korean=Baekmuk Gulim
-dialog.bold.chinese-big5=AR PL ShanHeiSun Uni
-dialog.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-
-dialog.italic.latin-1=DejaVu LGC Sans Oblique
-dialog.italic.japanese-x0208=Sazanami Gothic
-dialog.italic.korean=Baekmuk Gulim
-dialog.italic.chinese-big5=AR PL ShanHeiSun Uni
-dialog.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-dialog.bolditalic.latin-1=DejaVu LGC Sans Bold Oblique
-dialog.bolditalic.japanese-x0208=Sazanami Gothic
-dialog.bolditalic.korean=Baekmuk Gulim
-dialog.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-dialog.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-
-sansserif.plain.latin-1=DejaVu LGC Sans
-sansserif.plain.japanese-x0208=Sazanami Gothic
-sansserif.plain.korean=Baekmuk Gulim
-sansserif.plain.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-
-sansserif.bold.latin-1=DejaVu LGC Sans Bold
-sansserif.bold.japanese-x0208=Sazanami Gothic
-sansserif.bold.korean=Baekmuk Gulim
-sansserif.bold.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-
-sansserif.italic.latin-1=DejaVu LGC Sans Oblique
-sansserif.italic.japanese-x0208=Sazanami Gothic
-sansserif.italic.korean=Baekmuk Gulim
-sansserif.italic.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-sansserif.bolditalic.latin-1=DejaVu LGC Sans Bold Oblique
-sansserif.bolditalic.japanese-x0208=Sazanami Gothic
-sansserif.bolditalic.korean=Baekmuk Gulim
-sansserif.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-sansserif.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-
-serif.plain.latin-1=DejaVu LGC Serif
-serif.plain.japanese-x0208=Sazanami Mincho
-serif.plain.korean=Baekmuk Batang
-serif.plain.chinese-big5=AR PL ZenKai Uni
-serif.plain.chinese-gb18030=AR PL ZenKai Uni
-
-serif.bold.latin-1=DejaVu LGC Serif Bold
-serif.bold.japanese-x0208=Sazanami Mincho
-serif.bold.korean=Baekmuk Batang
-serif.bold.chinese-big5=AR PL ZenKai Uni
-serif.bold.chinese-gb18030=AR PL ZenKai Uni
-
-serif.italic.latin-1=DejaVu LGC Serif Oblique
-serif.italic.japanese-x0208=Sazanami Mincho
-serif.italic.korean=Baekmuk Batang
-serif.italic.chinese-big5=AR PL ZenKai Uni
-serif.italic.chinese-gb18030=AR PL ZenKai Uni
-
-serif.bolditalic.latin-1=DejaVu LGC Serif Bold Oblique
-serif.bolditalic.japanese-x0208=Sazanami Mincho
-serif.bolditalic.korean=Baekmuk Batang
-serif.bolditalic.chinese-big5=AR PL ZenKai Uni
-serif.bolditalic.chinese-gb18030=AR PL ZenKai Uni
-
-
-monospaced.plain.latin-1=DejaVu LGC Sans Mono
-monospaced.plain.japanese-x0208=Sazanami Gothic
-monospaced.plain.korean=Baekmuk Gulim
-monospaced.plain.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-
-monospaced.bold.latin-1=DejaVu LGC Sans Mono Bold
-monospaced.bold.japanese-x0208=Sazanami Gothic
-monospaced.bold.korean=Baekmuk Gulim
-monospaced.bold.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-
-monospaced.italic.latin-1=DejaVu LGC Sans Mono Oblique
-monospaced.italic.japanese-x0208=Sazanami Gothic
-monospaced.italic.korean=Baekmuk Gulim
-monospaced.italic.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-monospaced.bolditalic.latin-1=DejaVu LGC Sans Mono Bold Oblique
-monospaced.bolditalic.japanese-x0208=Sazanami Gothic
-monospaced.bolditalic.korean=Baekmuk Gulim
-monospaced.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-monospaced.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-
-dialoginput.plain.latin-1=DejaVu LGC Sans Mono
-dialoginput.plain.japanese-x0208=Sazanami Gothic
-dialoginput.plain.korean=Baekmuk Gulim
-dialoginput.plain.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.plain.chinese-gb18030=AR PL ShanHeiSun Uni
-
-dialoginput.bold.latin-1=DejaVu LGC Sans Mono Bold
-dialoginput.bold.japanese-x0208=Sazanami Gothic
-dialoginput.bold.korean=Baekmuk Gulim
-dialoginput.bold.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.bold.chinese-gb18030=AR PL ShanHeiSun Uni
-
-dialoginput.italic.latin-1=DejaVu LGC Sans Mono Oblique
-dialoginput.italic.japanese-x0208=Sazanami Gothic
-dialoginput.italic.korean=Baekmuk Gulim
-dialoginput.italic.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.italic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-dialoginput.bolditalic.latin-1=DejaVu LGC Sans Mono Bold Oblique
-dialoginput.bolditalic.japanese-x0208=Sazanami Gothic
-dialoginput.bolditalic.korean=Baekmuk Gulim
-dialoginput.bolditalic.chinese-big5=AR PL ShanHeiSun Uni
-dialoginput.bolditalic.chinese-gb18030=AR PL ShanHeiSun Uni
-
-# Search Sequences
-
-sequence.allfonts=latin-1
-sequence.allfonts.Big5=chinese-big5,latin-1
-sequence.allfonts.x-euc-jp-linux=japanese-x0208,latin-1
-sequence.allfonts.EUC-KR=korean,latin-1
-sequence.allfonts.GB18030=chinese-gb18030,latin-1
-sequence.fallback=chinese-big5,chinese-gb18030,japanese-x0208,korean
-
-# Font File Names
-
-filename.DejaVu_LGC_Sans=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans.ttf
-filename.DejaVu_LGC_Sans_Bold=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans-Bold.ttf
-filename.DejaVu_LGC_Sans_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans-Oblique.ttf
-filename.DejaVu_LGC_Sans_Bold_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSans-BoldOblique.ttf
-
-filename.DejaVu_LGC_Sans_Mono=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono.ttf
-filename.DejaVu_LGC_Sans_Mono_Bold=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono-Bold.ttf
-filename.DejaVu_LGC_Sans_Mono_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono-Oblique.ttf
-filename.DejaVu_LGC_Sans_Mono_Bold_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSansMono-BoldOblique.ttf
-
-filename.DejaVu_LGC_Serif=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif.ttf
-filename.DejaVu_LGC_Serif_Bold=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif-Bold.ttf
-filename.DejaVu_LGC_Serif_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif-Oblique.ttf
-filename.DejaVu_LGC_Serif_Bold_Oblique=/usr/share/fonts/dejavu-lgc/DejaVuLGCSerif-BoldOblique.ttf
-
-filename.Sazanami_Gothic=/usr/share/fonts/japanese/TrueType/sazanami-gothic.ttf
-filename.Sazanami_Mincho=/usr/share/fonts/japanese/TrueType/sazanami-mincho.ttf
-filename.AR_PL_ShanHeiSun_Uni=/usr/share/fonts/chinese/TrueType/uming.ttf
-filename.AR_PL_ZenKai_Uni=/usr/share/fonts/chinese/TrueType/ukai.ttf
-filename.Baekmuk_Gulim=/usr/share/fonts/korean/TrueType/gulim.ttf
-filename.Baekmuk_Batang=/usr/share/fonts/korean/TrueType/batang.ttf
From 7fe48f8a2018f92ebb6e81a021f9596c883fb9cd Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:57:50 -0700
Subject: [PATCH 092/206] Added tag jdk8-b92 for changeset b51d66ab6ffd
---
.hgtags-top-repo | 1 +
1 file changed, 1 insertion(+)
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index dc47bb707b1..729f6cad52d 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -213,3 +213,4 @@ e1a929afcfc492470d50be0b6b0e8dc77d3760b9 jdk8-b88
892a0196d10c67f3a12f0eefb0bb536e423d8868 jdk8-b89
69b773a221b956a3386933ecdbfeccee0edeac47 jdk8-b90
cb51fb4789ac0b8be4056482077ddfb8f3bd3805 jdk8-b91
+3a36c926a7aafa9d4a892a45ef3678e87ad8359b jdk8-b92
From 5eaf3d4ac5f3001bd711124428c5754702eec53c Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:57:52 -0700
Subject: [PATCH 093/206] Added tag jdk8-b92 for changeset 8ada1018118c
---
corba/.hgtags | 1 +
1 file changed, 1 insertion(+)
diff --git a/corba/.hgtags b/corba/.hgtags
index af3629045ae..f928f750ea0 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -213,3 +213,4 @@ f1709874d55a06bc3d5dfa02dbcdfbc59f4cba34 jdk8-b87
fe4150590ee597f4e125fea950aa3b352622cc2d jdk8-b89
c8286839d0df04aba819ec4bef12b86babccf30e jdk8-b90
8f7ffb296385f85a4a6d53f9f2d4a7b13a8fa1ff jdk8-b91
+717aa26f8e0a1c0e768aebb3a763aca56db0c83e jdk8-b92
From e9072745064b0a6b3efc019f5fbb8ee222add6a6 Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:57:57 -0700
Subject: [PATCH 094/206] Added tag jdk8-b92 for changeset b34bf6985a14
---
hotspot/.hgtags | 1 +
1 file changed, 1 insertion(+)
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index f2fb4715f13..8fd9b705d0f 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -345,3 +345,4 @@ c4af77d2045476c56fbf3f914b336bb1b7cd18af hs25-b30
b19517cecc2e91636d7c16ba2f35e3d3dc628099 hs25-b33
7cbdf0e3725c0c56a2ff7540fc70b6d4b5890d04 jdk8-b91
38da9f4f67096745f851318d792d6468aa1f6cf8 hs25-b34
+092018493d3bbeb1c24278fd8c40ff3d76e1fed7 jdk8-b92
From a979b3188ffb717e2fcdab756fb132f169d89da1 Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:58:08 -0700
Subject: [PATCH 095/206] Added tag jdk8-b92 for changeset d2f0e76ff056
---
jaxp/.hgtags | 1 +
1 file changed, 1 insertion(+)
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index e23e9fa8292..5df651317b4 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -213,3 +213,4 @@ eddbc8ad2435a89f64729512337c9f2669e4dd85 jdk8-b87
893d2ba8bbea3a8d090e51d8eaea285b390789ea jdk8-b89
668acc0e1034bc1bec6d02be92e0dd4a63d0667e jdk8-b90
e3065fb07877c7e96e8b93416fe2ab9a4c9eb2a5 jdk8-b91
+1ab5d8d6eab81e65c6c3cf21739474cd67a0e7cf jdk8-b92
From d30d85e939122ca05f983d9db6f2bdada0ba719e Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:58:13 -0700
Subject: [PATCH 096/206] Added tag jdk8-b92 for changeset 3e02d3c20e99
---
jaxws/.hgtags | 1 +
1 file changed, 1 insertion(+)
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 088ec3da462..199677923db 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -213,3 +213,4 @@ a5e7c2f093c9996ab3419db1565094a07b059e9c jdk8-b86
88838e08e4ef6a254867c8126070a1975683108d jdk8-b89
3e5b9ea5ac35ea7096da484e24a863cf4552179f jdk8-b90
0bb1a9fa56b037d072efdaae5f5b73a0f23c966c jdk8-b91
+a0f604766ca14818e2a7b1558cc399499caabf75 jdk8-b92
From f49bd7d3b8ec8565c6322563671137d275f4fc0f Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:58:32 -0700
Subject: [PATCH 097/206] Added tag jdk8-b92 for changeset fe7926936461
---
langtools/.hgtags | 1 +
1 file changed, 1 insertion(+)
diff --git a/langtools/.hgtags b/langtools/.hgtags
index 1c4ad707352..3d445226a63 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -213,3 +213,4 @@ a1e10f3adc47c8602a72e43a41403a642e73e0b1 jdk8-b88
ec434cfd2752a7742c875c2fe7d556d8b81c0f3a jdk8-b89
e19283cd30a43fca94d8f7639c73ef66db493b1e jdk8-b90
997c0fae2b12108959387862be54b78ca0ae3fca jdk8-b91
+149890642a0ed5138a4f16fe08ddbfeb8f8a1cb4 jdk8-b92
From 403f5cc7b32b7df1757b66d830152df2d4dad9f1 Mon Sep 17 00:00:00 2001
From: David Katleman
Date: Thu, 30 May 2013 10:58:35 -0700
Subject: [PATCH 098/206] Added tag jdk8-b92 for changeset 3ed2867af3bf
---
nashorn/.hgtags | 1 +
1 file changed, 1 insertion(+)
diff --git a/nashorn/.hgtags b/nashorn/.hgtags
index 0c80753de1e..b4d15f59f0d 100644
--- a/nashorn/.hgtags
+++ b/nashorn/.hgtags
@@ -201,3 +201,4 @@ e0378f0a50dafdcfb7b04f6401d320f89884baa1 jdk8-b85
45ce27fbe2720d80070095c0db7344ec41e2833d jdk8-b89
67ca019e3713dd71c884d753de02fd0021981969 jdk8-b90
6b9f4120380091b8b1751a825b9f84bf1be224fe jdk8-b91
+dee23cce5235b594a96d3361b65eacc97bd5a583 jdk8-b92
From a246da16d1caab2f524a7aa23cae22511f68364e Mon Sep 17 00:00:00 2001
From: Serguei Spitsyn
Date: Thu, 30 May 2013 11:46:39 -0700
Subject: [PATCH 099/206] 8015436: compiler/ciReplay/TestSA.sh fails with
assert() index is out of bounds
The InstanceKlass _initial_method_idnum value must be adjusted if overpass methods are added.
Reviewed-by: twisti, kvn
---
.../src/share/vm/classfile/defaultMethods.cpp | 1 +
.../test/compiler/8015436/Test8015436.java | 74 +++++++++++++++++++
2 files changed, 75 insertions(+)
create mode 100644 hotspot/test/compiler/8015436/Test8015436.java
diff --git a/hotspot/src/share/vm/classfile/defaultMethods.cpp b/hotspot/src/share/vm/classfile/defaultMethods.cpp
index 1977b07ea10..d6529ca4439 100644
--- a/hotspot/src/share/vm/classfile/defaultMethods.cpp
+++ b/hotspot/src/share/vm/classfile/defaultMethods.cpp
@@ -1349,6 +1349,7 @@ static void merge_in_new_methods(InstanceKlass* klass,
// Replace klass methods with new merged lists
klass->set_methods(merged_methods);
+ klass->set_initial_method_idnum(new_size);
ClassLoaderData* cld = klass->class_loader_data();
MetadataFactory::free_array(cld, original_methods);
diff --git a/hotspot/test/compiler/8015436/Test8015436.java b/hotspot/test/compiler/8015436/Test8015436.java
new file mode 100644
index 00000000000..5037a7a73af
--- /dev/null
+++ b/hotspot/test/compiler/8015436/Test8015436.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
+ * @bug 8015436
+ * @summary the IK _initial_method_idnum value must be adjusted if overpass methods are added
+ * @run main Test8015436
+ *
+ */
+
+/*
+ * The test checks that a MemberName for the defaultMethod() is cached in
+ * the class MemberNameTable without a crash in the VM fastdebug mode.
+ * The original issue was that the InstanceKlass _initial_method_idnum was
+ * not adjusted properly when the overpass methods are added to the class.
+ * The expected/correct behavior: The test does not crash nor throw any exceptions.
+ * All the invocations of the defaultMethod() must be completed successfully.
+ */
+
+import java.lang.invoke.*;
+
+interface InterfaceWithDefaultMethod {
+ public void someMethod();
+
+ default public void defaultMethod(String str){
+ System.out.println("defaultMethod() " + str);
+ }
+}
+
+class Test8015436 implements InterfaceWithDefaultMethod {
+ @Override
+ public void someMethod() {
+ System.out.println("someMethod() invoked");
+ }
+
+ public static void main(String[] args) throws Throwable {
+ Test8015436 testObj = new Test8015436();
+ testObj.someMethod();
+ testObj.defaultMethod("invoked directly");
+
+ MethodHandles.Lookup lookup = MethodHandles.lookup();
+ MethodType mt = MethodType.methodType(void.class, String.class);
+ MethodHandle mh = lookup.findVirtual(Test8015436.class, "defaultMethod", mt);
+ mh.invokeExact(testObj, "invoked via a MethodHandle");
+ }
+}
+
+/*
+ * A successful execution gives the output:
+ * someMethod() invoked
+ * defaultMethod() invoked directly
+ * defaultMethod() invoked via a MethodHandle
+ */
From 06d1d22eb56c0f4f043548409c017d515b75858f Mon Sep 17 00:00:00 2001
From: Vicente Romero
Date: Fri, 31 May 2013 10:04:59 +0100
Subject: [PATCH 100/206] 7179353: try-with-resources fails to compile with
generic exception parameters
Reviewed-by: mcimadamore
---
.../com/sun/tools/javac/comp/Flow.java | 8 ++--
.../com/sun/tools/javac/comp/Resolve.java | 6 +--
.../GenericsAndTWRCompileErrorTest.java | 42 +++++++++++++++++++
3 files changed, 50 insertions(+), 6 deletions(-)
create mode 100644 langtools/test/tools/javac/T7179353/GenericsAndTWRCompileErrorTest.java
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
index 1e6d7da1839..85ce604ff4f 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Flow.java
@@ -808,9 +808,10 @@ public class Flow {
*/
void markThrown(JCTree tree, Type exc) {
if (!chk.isUnchecked(tree.pos(), exc)) {
- if (!chk.isHandled(exc, caught))
+ if (!chk.isHandled(exc, caught)) {
pendingExits.append(new FlowPendingExit(tree, exc));
- thrown = chk.incl(exc, thrown);
+ }
+ thrown = chk.incl(exc, thrown);
}
}
@@ -1066,8 +1067,9 @@ public class Flow {
names.close,
List.nil(),
List.nil());
+ Type mt = types.memberType(resource.type, closeMethod);
if (closeMethod.kind == MTH) {
- for (Type t : ((MethodSymbol)closeMethod).getThrownTypes()) {
+ for (Type t : mt.getThrownTypes()) {
markThrown(resource, t);
}
}
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
index 09b1d4c92f2..9618a00c3bb 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Resolve.java
@@ -349,7 +349,7 @@ public class Resolve {
: isAccessible(env, t.tsym, checkInner);
}
- /** Is symbol accessible as a member of given type in given evironment?
+ /** Is symbol accessible as a member of given type in given environment?
* @param env The current environment.
* @param site The type of which the tested symbol is regarded
* as a member.
@@ -490,11 +490,11 @@ public class Resolve {
};
/** Try to instantiate the type of a method so that it fits
- * given type arguments and argument types. If succesful, return
+ * given type arguments and argument types. If successful, return
* the method's instantiated type, else return null.
* The instantiation will take into account an additional leading
* formal parameter if the method is an instance method seen as a member
- * of un underdetermined site In this case, we treat site as an additional
+ * of an under determined site. In this case, we treat site as an additional
* parameter and the parameters of the class containing the method as
* additional type variables that get instantiated.
*
diff --git a/langtools/test/tools/javac/T7179353/GenericsAndTWRCompileErrorTest.java b/langtools/test/tools/javac/T7179353/GenericsAndTWRCompileErrorTest.java
new file mode 100644
index 00000000000..133bc345ff2
--- /dev/null
+++ b/langtools/test/tools/javac/T7179353/GenericsAndTWRCompileErrorTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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 7179353
+ * @summary try-with-resources fails to compile with generic exception parameters
+ * @compile GenericsAndTWRCompileErrorTest.java
+ */
+
+public class GenericsAndTWRCompileErrorTest {
+
+ public static class Resource implements AutoCloseable {
+ public void close() throws E { }
+ }
+
+ public void test() throws E {
+ try (Resource r = new Resource()) {
+
+ }
+ }
+}
From 912472fd718aa2fb51a203f7a8a3e649b8745e98 Mon Sep 17 00:00:00 2001
From: Anthony Petrov
Date: Fri, 31 May 2013 14:12:53 +0400
Subject: [PATCH 101/206] 8013189: JMenuItems draw behind TextArea
Untie XTextAreaPeer internal components from the TextArea parent to prevent its invalidation. I.e. force the java.awt.smartInvalidate=true locally.
Reviewed-by: art, serb
---
.../classes/sun/awt/X11/XTextAreaPeer.java | 13 +++
.../awt/TextArea/Mixing/TextAreaMixing.java | 99 +++++++++++++++++++
2 files changed, 112 insertions(+)
create mode 100644 jdk/test/java/awt/TextArea/Mixing/TextAreaMixing.java
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java
index fcefc02bbfd..27465df84a5 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java
@@ -1143,6 +1143,19 @@ class XTextAreaPeer extends XComponentPeer implements TextAreaPeer {
addNotify();
}
+ @Override
+ public void invalidate() {
+ synchronized (getTreeLock()) {
+ final Container parent = getParent();
+ AWTAccessor.getComponentAccessor().setParent(this, null);
+ try {
+ super.invalidate();
+ } finally {
+ AWTAccessor.getComponentAccessor().setParent(this, parent);
+ }
+ }
+ }
+
public void focusGained(FocusEvent e) {
Graphics g = getGraphics();
Rectangle r = getViewportBorderBounds();
diff --git a/jdk/test/java/awt/TextArea/Mixing/TextAreaMixing.java b/jdk/test/java/awt/TextArea/Mixing/TextAreaMixing.java
new file mode 100644
index 00000000000..f07ddf3bd99
--- /dev/null
+++ b/jdk/test/java/awt/TextArea/Mixing/TextAreaMixing.java
@@ -0,0 +1,99 @@
+/*
+ * 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 8013189
+ * @run main TextAreaMixing
+ * @summary TextArea should support HW/LW mixing
+ * @author anthony.petrov@oracle.com
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class TextAreaMixing {
+
+ private static volatile boolean menuClicked = false;
+ private static JMenuItem menuItem;
+
+ public static void main(String[] args) throws Exception {
+ // The bug is only reproducible on X11, but there's no reason
+ // for this test to not pass on any platofrm
+
+ final JFrame frame = new JFrame("JFrame");
+ frame.setLayout(new GridLayout(0, 1));
+ frame.setSize(200, 200);
+
+ JMenuBar menuBar = new JMenuBar();
+ JMenu menu = new JMenu("Test Menu");
+
+ for (int i = 0; i < 6; i++) {
+ JMenuItem mi = new JMenuItem(Integer.toString(i));
+ mi.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ menuClicked = true;
+ }
+ });
+ menu.add(mi);
+
+ // Choose a random (OK, the fourth) menu item to click on
+ if (i == 3) {
+ menuItem = mi;
+ }
+ }
+ menuBar.add(menu);
+ frame.setJMenuBar(menuBar);
+
+ frame.getContentPane().add(new TextArea());
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.setVisible(true);
+
+ Thread.sleep(2000);
+
+ Robot robot = new Robot();
+
+ // Open the menu
+ Point loc = menu.getLocationOnScreen();
+ robot.mouseMove(loc.x + menu.getWidth() / 2, loc.y + menu.getHeight() / 2);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+
+ Thread.sleep(500);
+
+ // Click an item
+ loc = menuItem.getLocationOnScreen();
+ robot.mouseMove(loc.x + menuItem.getWidth() / 2, loc.y + menuItem.getHeight() / 2);
+ robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+
+ Thread.sleep(500);
+
+ frame.dispose();
+
+ if (!menuClicked) {
+ throw new RuntimeException("A menu item has never been clicked.");
+ }
+ }
+}
From 3c4b82e2bbe44472434de537566e4081a61c5e2b Mon Sep 17 00:00:00 2001
From: Andrew Brygin
Date: Fri, 31 May 2013 14:30:28 +0400
Subject: [PATCH 102/206] 8015606: Text is not rendered correctly if
destination buffer is custom
Reviewed-by: prr, vadim
---
.../classes/sun/java2d/loops/MaskFill.java | 4 +
.../loops/RenderToCustomBufferTest.java | 115 ++++++++++++++++++
2 files changed, 119 insertions(+)
create mode 100644 jdk/test/sun/java2d/loops/RenderToCustomBufferTest.java
diff --git a/jdk/src/share/classes/sun/java2d/loops/MaskFill.java b/jdk/src/share/classes/sun/java2d/loops/MaskFill.java
index 47c41ee1cd3..601a3fc7eb8 100644
--- a/jdk/src/share/classes/sun/java2d/loops/MaskFill.java
+++ b/jdk/src/share/classes/sun/java2d/loops/MaskFill.java
@@ -36,6 +36,7 @@ import sun.awt.image.BufImgSurfaceData;
import sun.java2d.loops.GraphicsPrimitive;
import sun.java2d.SunGraphics2D;
import sun.java2d.SurfaceData;
+import sun.java2d.pipe.Region;
/**
* MaskFill
@@ -194,10 +195,13 @@ public class MaskFill extends GraphicsPrimitive
// REMIND: This is not pretty. It would be nicer if we
// passed a "FillData" object to the Pixel loops, instead
// of a SunGraphics2D parameter...
+ Region clip = sg2d.clipRegion;
+ sg2d.clipRegion = null;
int pixel = sg2d.pixel;
sg2d.pixel = tmpData.pixelFor(sg2d.getColor());
fillop.FillRect(sg2d, tmpData, 0, 0, w, h);
sg2d.pixel = pixel;
+ sg2d.clipRegion = clip;
maskop.MaskBlit(tmpData, sData, comp, null,
0, 0, x, y, w, h,
diff --git a/jdk/test/sun/java2d/loops/RenderToCustomBufferTest.java b/jdk/test/sun/java2d/loops/RenderToCustomBufferTest.java
new file mode 100644
index 00000000000..37e866f5ba0
--- /dev/null
+++ b/jdk/test/sun/java2d/loops/RenderToCustomBufferTest.java
@@ -0,0 +1,115 @@
+/*
+ * 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 8015606
+ * @summary Test verifies whether a text is rendered correctly to
+ * a custom buffered image.
+ *
+ * @run main RenderToCustomBufferTest
+ */
+
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.WritableRaster;
+
+public class RenderToCustomBufferTest {
+ public static void main(String[] args) {
+ final BufferedImage dst_custom = createCustomBuffer();
+ final BufferedImage dst_dcm = new BufferedImage(width, height,
+ BufferedImage.TYPE_INT_RGB);
+
+ renderTo(dst_custom);
+ renderTo(dst_dcm);
+
+ check(dst_custom, dst_dcm);
+ }
+
+ private static void check(BufferedImage a, BufferedImage b) {
+ for (int y = 0; y < height; y++) {
+ for (int x = 0; x < width; x++) {
+ int pa = a.getRGB(x, y);
+ int pb = b.getRGB(x, y);
+
+ if (pa != pb) {
+ String msg = String.format(
+ "Point [%d, %d] has different colors: %08X and %08X",
+ x, y, pa, pb);
+ throw new RuntimeException("Test failed: " + msg);
+ }
+ }
+ }
+ }
+
+ private static BufferedImage createCustomBuffer() {
+ ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
+ ColorModel cm = new ComponentColorModel(cs, false, false,
+ Transparency.OPAQUE, DataBuffer.TYPE_FLOAT);
+ WritableRaster wr = cm.createCompatibleWritableRaster(width, height);
+
+ return new BufferedImage(cm, wr, false, null);
+ }
+
+ private static void renderTo(BufferedImage dst) {
+ System.out.println("The buffer: " + dst);
+ Graphics2D g = dst.createGraphics();
+
+ final int w = dst.getWidth();
+ final int h = dst.getHeight();
+
+ g.setColor(Color.blue);
+ g.fillRect(0, 0, w, h);
+
+ g.setColor(Color.red);
+ Font f = g.getFont();
+ g.setFont(f.deriveFont(48f));
+
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
+
+ // NB: this clip ctriggers the problem
+ g.setClip(50, 50, 200, 100);
+
+ g.drawString("AA Text", 52, 90);
+
+ g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
+ RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
+
+ // NB: this clip ctriggers the problem
+ g.setClip(50, 100, 100, 100);
+ g.drawString("Text", 52, 148);
+
+ g.dispose();
+ }
+
+ private static final int width = 230;
+ private static final int height = 150;
+}
From 8bcbbe70deb978d2f56eb8d7c52ec52a07b3514a Mon Sep 17 00:00:00 2001
From: Attila Szegedi
Date: Fri, 31 May 2013 12:56:56 +0200
Subject: [PATCH 103/206] 8015693: reduce NodeLiteralNode to NullLiteralNode
Reviewed-by: jlaskey, lagergren
---
.../jdk/nashorn/internal/ir/LiteralNode.java | 62 +++----------------
1 file changed, 9 insertions(+), 53 deletions(-)
diff --git a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
index 7a59c5fe840..c34f9d94c5b 100644
--- a/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
+++ b/nashorn/src/jdk/nashorn/internal/ir/LiteralNode.java
@@ -28,7 +28,6 @@ package jdk.nashorn.internal.ir;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
-
import jdk.nashorn.internal.codegen.CompileUnit;
import jdk.nashorn.internal.codegen.types.Type;
import jdk.nashorn.internal.ir.annotations.Immutable;
@@ -242,8 +241,8 @@ public abstract class LiteralNode