Merge
This commit is contained in:
commit
388434f387
@ -93,7 +93,7 @@ JRE_RELEASE_VERSION="\\\"$(JDK_MAJOR_VER).$(JDK_MINOR_VER).$(JDK_MICRO_VER)\\\""
|
||||
!if "$(HOTSPOT_RELEASE_VERSION)" != ""
|
||||
HOTSPOT_RELEASE_VERSION="\\\"$(HOTSPOT_RELEASE_VERSION)\\\""
|
||||
!else
|
||||
HOTSPOT_RELEASE_VERSION="\\\"$(JRE_RELEASE_VERSION)\\\""
|
||||
HOTSPOT_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
|
||||
!endif
|
||||
# Define HOTSPOT_VM_DISTRO if HOTSPOT_VM_DISTRO is set,
|
||||
# and if it is not see if we have the src/closed directory
|
||||
@ -105,9 +105,18 @@ HOTSPOT_VM_DISTRO="\\\"Java HotSpot(TM)\\\""
|
||||
!else
|
||||
HOTSPOT_VM_DISTRO="\\\"OpenJDK\\\""
|
||||
!endif
|
||||
!if "$(JDK_BUILD_NUMBER)" != ""
|
||||
JDK_BUILD_NUMBER="\\\"$(JDK_BUILD_NUMBER)\\\""
|
||||
!else
|
||||
JDK_BUILD_NUMBER="\\\"00\\\""
|
||||
!endif
|
||||
!endif
|
||||
|
||||
ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -define JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -define HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO)
|
||||
JDK_MAJOR_VERSION="\\\"$(JDK_MAJOR_VER)\\\""
|
||||
JDK_MINOR_VERSION="\\\"$(JDK_MINOR_VER)\\\""
|
||||
JDK_MICRO_VERSION="\\\"$(JDK_MICRO_VER)\\\""
|
||||
|
||||
ReleaseOptions = -define HOTSPOT_RELEASE_VERSION=$(HOTSPOT_RELEASE_VERSION) -define JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) -define HOTSPOT_VM_DISTRO=$(HOTSPOT_VM_DISTRO) -define JDK_MAJOR_VERSION=$(JDK_MAJOR_VERSION) -define JDK_MINOR_VERSION=$(JDK_MINOR_VERSION) -define JDK_MICRO_VERSION=$(JDK_MICRO_VERSION) -define JDK_BUILD_NUMBER=$(JDK_BUILD_NUMBER)
|
||||
ProjectCreatorIDEOptions = $(ProjectCreatorIDEOptions) $(ReleaseOptions)
|
||||
|
||||
$(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
|
||||
|
@ -30,12 +30,13 @@
|
||||
//
|
||||
|
||||
// standard library constants
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include <iostream>
|
||||
#include "string.h"
|
||||
#include "ctype.h"
|
||||
#include "stdarg.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <stdarg.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/* Make sure that we have the intptr_t and uintptr_t definitions */
|
||||
|
@ -64,8 +64,6 @@ class PeepMatch;
|
||||
class PeepConstraint;
|
||||
class PeepReplace;
|
||||
|
||||
// class ostream; // ostream is a typedef in some systems
|
||||
|
||||
extern char *toUpper(const char *str);
|
||||
|
||||
//---------------------------ADLParser-----------------------------------------
|
||||
|
@ -25,8 +25,6 @@
|
||||
// FILEBUFF.CPP - Routines for handling a parser file buffer
|
||||
#include "adlc.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
//------------------------------FileBuff---------------------------------------
|
||||
// Create a new parsing buffer
|
||||
FileBuff::FileBuff( BufferedFile *fptr, ArchDesc& archDesc) : _fp(fptr), _AD(archDesc) {
|
||||
|
@ -26,9 +26,6 @@
|
||||
#define SHARE_VM_ADLC_FILEBUFF_HPP
|
||||
|
||||
// FILEBUFF.HPP - Definitions for parser file buffering routines
|
||||
#include <iostream>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES
|
||||
|
||||
|
@ -211,7 +211,7 @@ static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper)
|
||||
const char *type = oper->ideal_type(globals);
|
||||
if (!strcmp(type, "ConI")) {
|
||||
if (i > 0) fprintf(fp,", ");
|
||||
fprintf(fp," int32 _c%d;\n", i);
|
||||
fprintf(fp," int32_t _c%d;\n", i);
|
||||
}
|
||||
else if (!strcmp(type, "ConP")) {
|
||||
if (i > 0) fprintf(fp,", ");
|
||||
@ -307,7 +307,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts,
|
||||
assert(num_consts == 1, "Bad component list detected.\n");
|
||||
switch( constant_type ) {
|
||||
case Form::idealI : {
|
||||
fprintf(fp,is_ideal_bool ? "BoolTest::mask c%d" : "int32 c%d", i);
|
||||
fprintf(fp,is_ideal_bool ? "BoolTest::mask c%d" : "int32_t c%d", i);
|
||||
break;
|
||||
}
|
||||
case Form::idealN : { fprintf(fp,"const TypeNarrowOop *c%d", i); break; }
|
||||
@ -326,7 +326,7 @@ static void defineConstructor(FILE *fp, const char *name, uint num_consts,
|
||||
while((comp = lst.iter()) != NULL) {
|
||||
if (!strcmp(comp->base_type(globals), "ConI")) {
|
||||
if (i > 0) fprintf(fp,", ");
|
||||
fprintf(fp,"int32 c%d", i);
|
||||
fprintf(fp,"int32_t c%d", i);
|
||||
i++;
|
||||
}
|
||||
else if (!strcmp(comp->base_type(globals), "ConP")) {
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/altHashing.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/debugInfo.hpp"
|
||||
#include "code/pcDesc.hpp"
|
||||
|
533
hotspot/src/share/vm/classfile/stringTable.cpp
Normal file
533
hotspot/src/share/vm/classfile/stringTable.cpp
Normal file
@ -0,0 +1,533 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/altHashing.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/gcLocker.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "oops/oop.inline2.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/g1StringDedup.hpp"
|
||||
#endif
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
// the number of buckets a thread claims
|
||||
const int ClaimChunkSize = 32;
|
||||
|
||||
#ifdef ASSERT
|
||||
class StableMemoryChecker : public StackObj {
|
||||
enum { _bufsize = wordSize*4 };
|
||||
|
||||
address _region;
|
||||
jint _size;
|
||||
u1 _save_buf[_bufsize];
|
||||
|
||||
int sample(u1* save_buf) {
|
||||
if (_size <= _bufsize) {
|
||||
memcpy(save_buf, _region, _size);
|
||||
return _size;
|
||||
} else {
|
||||
// copy head and tail
|
||||
memcpy(&save_buf[0], _region, _bufsize/2);
|
||||
memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2);
|
||||
return (_bufsize/2)*2;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
StableMemoryChecker(const void* region, jint size) {
|
||||
_region = (address) region;
|
||||
_size = size;
|
||||
sample(_save_buf);
|
||||
}
|
||||
|
||||
bool verify() {
|
||||
u1 check_buf[sizeof(_save_buf)];
|
||||
int check_size = sample(check_buf);
|
||||
return (0 == memcmp(_save_buf, check_buf, check_size));
|
||||
}
|
||||
|
||||
void set_region(const void* region) { _region = (address) region; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
StringTable* StringTable::_the_table = NULL;
|
||||
|
||||
bool StringTable::_needs_rehashing = false;
|
||||
|
||||
volatile int StringTable::_parallel_claimed_idx = 0;
|
||||
|
||||
// Pick hashing algorithm
|
||||
unsigned int StringTable::hash_string(const jchar* s, int len) {
|
||||
return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
|
||||
java_lang_String::hash_code(s, len);
|
||||
}
|
||||
|
||||
oop StringTable::lookup(int index, jchar* name,
|
||||
int len, unsigned int hash) {
|
||||
int count = 0;
|
||||
for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
|
||||
count++;
|
||||
if (l->hash() == hash) {
|
||||
if (java_lang_String::equals(l->literal(), name, len)) {
|
||||
return l->literal();
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the bucket size is too deep check if this hash code is insufficient.
|
||||
if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
|
||||
_needs_rehashing = check_rehash_table(count);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
|
||||
int len, unsigned int hashValue_arg, TRAPS) {
|
||||
|
||||
assert(java_lang_String::equals(string(), name, len),
|
||||
"string must be properly initialized");
|
||||
// Cannot hit a safepoint in this function because the "this" pointer can move.
|
||||
No_Safepoint_Verifier nsv;
|
||||
|
||||
// Check if the symbol table has been rehashed, if so, need to recalculate
|
||||
// the hash value and index before second lookup.
|
||||
unsigned int hashValue;
|
||||
int index;
|
||||
if (use_alternate_hashcode()) {
|
||||
hashValue = hash_string(name, len);
|
||||
index = hash_to_index(hashValue);
|
||||
} else {
|
||||
hashValue = hashValue_arg;
|
||||
index = index_arg;
|
||||
}
|
||||
|
||||
// Since look-up was done lock-free, we need to check if another
|
||||
// thread beat us in the race to insert the symbol.
|
||||
|
||||
oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
|
||||
if (test != NULL) {
|
||||
// Entry already added
|
||||
return test;
|
||||
}
|
||||
|
||||
HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
|
||||
add_entry(index, entry);
|
||||
return string();
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::lookup(Symbol* symbol) {
|
||||
ResourceMark rm;
|
||||
int length;
|
||||
jchar* chars = symbol->as_unicode(length);
|
||||
return lookup(chars, length);
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::lookup(jchar* name, int len) {
|
||||
unsigned int hash = hash_string(name, len);
|
||||
int index = the_table()->hash_to_index(hash);
|
||||
return the_table()->lookup(index, name, len, hash);
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::intern(Handle string_or_null, jchar* name,
|
||||
int len, TRAPS) {
|
||||
unsigned int hashValue = hash_string(name, len);
|
||||
int index = the_table()->hash_to_index(hashValue);
|
||||
oop found_string = the_table()->lookup(index, name, len, hashValue);
|
||||
|
||||
// Found
|
||||
if (found_string != NULL) return found_string;
|
||||
|
||||
debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
|
||||
assert(!Universe::heap()->is_in_reserved(name),
|
||||
"proposed name of symbol must be stable");
|
||||
|
||||
Handle string;
|
||||
// try to reuse the string if possible
|
||||
if (!string_or_null.is_null()) {
|
||||
string = string_or_null;
|
||||
} else {
|
||||
string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
|
||||
}
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
// Deduplicate the string before it is interned. Note that we should never
|
||||
// deduplicate a string after it has been interned. Doing so will counteract
|
||||
// compiler optimizations done on e.g. interned string literals.
|
||||
G1StringDedup::deduplicate(string());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Grab the StringTable_lock before getting the_table() because it could
|
||||
// change at safepoint.
|
||||
MutexLocker ml(StringTable_lock, THREAD);
|
||||
|
||||
// Otherwise, add to symbol to table
|
||||
return the_table()->basic_add(index, string, name, len,
|
||||
hashValue, CHECK_NULL);
|
||||
}
|
||||
|
||||
oop StringTable::intern(Symbol* symbol, TRAPS) {
|
||||
if (symbol == NULL) return NULL;
|
||||
ResourceMark rm(THREAD);
|
||||
int length;
|
||||
jchar* chars = symbol->as_unicode(length);
|
||||
Handle string;
|
||||
oop result = intern(string, chars, length, CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::intern(oop string, TRAPS)
|
||||
{
|
||||
if (string == NULL) return NULL;
|
||||
ResourceMark rm(THREAD);
|
||||
int length;
|
||||
Handle h_string (THREAD, string);
|
||||
jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);
|
||||
oop result = intern(h_string, chars, length, CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::intern(const char* utf8_string, TRAPS) {
|
||||
if (utf8_string == NULL) return NULL;
|
||||
ResourceMark rm(THREAD);
|
||||
int length = UTF8::unicode_length(utf8_string);
|
||||
jchar* chars = NEW_RESOURCE_ARRAY(jchar, length);
|
||||
UTF8::convert_to_unicode(utf8_string, chars, length);
|
||||
Handle string;
|
||||
oop result = intern(string, chars, length, CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
|
||||
buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed);
|
||||
}
|
||||
|
||||
void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
|
||||
// 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");
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
for (;;) {
|
||||
// Grab next set of buckets to scan
|
||||
int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
|
||||
if (start_idx >= limit) {
|
||||
// End of table
|
||||
break;
|
||||
}
|
||||
|
||||
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
||||
buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed);
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
assert(0 <= start_idx && start_idx <= limit,
|
||||
err_msg("start_idx (%d) is out of bounds", start_idx));
|
||||
assert(0 <= end_idx && end_idx <= limit,
|
||||
err_msg("end_idx (%d) is out of bounds", end_idx));
|
||||
assert(start_idx <= end_idx,
|
||||
err_msg("Index ordering: start_idx=%d, end_idx=%d",
|
||||
start_idx, end_idx));
|
||||
|
||||
for (int i = start_idx; i < end_idx; i += 1) {
|
||||
HashtableEntry<oop, mtSymbol>* 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());
|
||||
|
||||
entry = entry->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
assert(0 <= start_idx && start_idx <= limit,
|
||||
err_msg("start_idx (%d) is out of bounds", start_idx));
|
||||
assert(0 <= end_idx && end_idx <= limit,
|
||||
err_msg("end_idx (%d) is out of bounds", end_idx));
|
||||
assert(start_idx <= end_idx,
|
||||
err_msg("Index ordering: start_idx=%d, end_idx=%d",
|
||||
start_idx, end_idx));
|
||||
|
||||
for (int i = start_idx; i < end_idx; ++i) {
|
||||
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||
while (entry != NULL) {
|
||||
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();
|
||||
the_table()->free_entry(entry);
|
||||
(*removed)++;
|
||||
}
|
||||
(*processed)++;
|
||||
entry = *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::oops_do(OopClosure* f) {
|
||||
buckets_oops_do(f, 0, the_table()->table_size());
|
||||
}
|
||||
|
||||
void StringTable::possibly_parallel_oops_do(OopClosure* f) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
for (;;) {
|
||||
// Grab next set of buckets to scan
|
||||
int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
|
||||
if (start_idx >= limit) {
|
||||
// End of table
|
||||
break;
|
||||
}
|
||||
|
||||
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
||||
buckets_oops_do(f, start_idx, end_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// This verification is part of Universe::verify() and needs to be quick.
|
||||
// See StringTable::verify_and_compare() below for exhaustive verification.
|
||||
void StringTable::verify() {
|
||||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
|
||||
for ( ; p != NULL; p = p->next()) {
|
||||
oop s = p->literal();
|
||||
guarantee(s != NULL, "interned string is NULL");
|
||||
unsigned int h = java_lang_String::hash_string(s);
|
||||
guarantee(p->hash() == h, "broken hash in string table entry");
|
||||
guarantee(the_table()->hash_to_index(h) == i,
|
||||
"wrong index in string table");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::dump(outputStream* st) {
|
||||
the_table()->dump_table(st, "StringTable");
|
||||
}
|
||||
|
||||
StringTable::VerifyRetTypes StringTable::compare_entries(
|
||||
int bkt1, int e_cnt1,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr1,
|
||||
int bkt2, int e_cnt2,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr2) {
|
||||
// These entries are sanity checked by verify_and_compare_entries()
|
||||
// before this function is called.
|
||||
oop str1 = e_ptr1->literal();
|
||||
oop str2 = e_ptr2->literal();
|
||||
|
||||
if (str1 == str2) {
|
||||
tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
|
||||
"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
|
||||
(void *)str1, bkt1, e_cnt1, bkt2, e_cnt2);
|
||||
return _verify_fail_continue;
|
||||
}
|
||||
|
||||
if (java_lang_String::equals(str1, str2)) {
|
||||
tty->print_cr("ERROR: identical String values in entry @ "
|
||||
"bucket[%d][%d] and entry @ bucket[%d][%d]",
|
||||
bkt1, e_cnt1, bkt2, e_cnt2);
|
||||
return _verify_fail_continue;
|
||||
}
|
||||
|
||||
return _verify_pass;
|
||||
}
|
||||
|
||||
StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr,
|
||||
StringTable::VerifyMesgModes mesg_mode) {
|
||||
|
||||
VerifyRetTypes ret = _verify_pass; // be optimistic
|
||||
|
||||
oop str = e_ptr->literal();
|
||||
if (str == NULL) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt,
|
||||
e_cnt);
|
||||
}
|
||||
// NULL oop means no more verifications are possible
|
||||
return _verify_fail_done;
|
||||
}
|
||||
|
||||
if (str->klass() != SystemDictionary::String_klass()) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]",
|
||||
bkt, e_cnt);
|
||||
}
|
||||
// not a String means no more verifications are possible
|
||||
return _verify_fail_done;
|
||||
}
|
||||
|
||||
unsigned int h = java_lang_String::hash_string(str);
|
||||
if (e_ptr->hash() != h) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "
|
||||
"bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h);
|
||||
}
|
||||
ret = _verify_fail_continue;
|
||||
}
|
||||
|
||||
if (the_table()->hash_to_index(h) != bkt) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], "
|
||||
"str_hash=%d, hash_to_index=%d", bkt, e_cnt, h,
|
||||
the_table()->hash_to_index(h));
|
||||
}
|
||||
ret = _verify_fail_continue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// See StringTable::verify() above for the quick verification that is
|
||||
// part of Universe::verify(). This verification is exhaustive and
|
||||
// reports on every issue that is found. StringTable::verify() only
|
||||
// reports on the first issue that is found.
|
||||
//
|
||||
// StringTable::verify_entry() checks:
|
||||
// - oop value != NULL (same as verify())
|
||||
// - oop value is a String
|
||||
// - hash(String) == hash in entry (same as verify())
|
||||
// - index for hash == index of entry (same as verify())
|
||||
//
|
||||
// StringTable::compare_entries() checks:
|
||||
// - oops are unique across all entries
|
||||
// - String values are unique across all entries
|
||||
//
|
||||
int StringTable::verify_and_compare_entries() {
|
||||
assert(StringTable_lock->is_locked(), "sanity check");
|
||||
|
||||
int fail_cnt = 0;
|
||||
|
||||
// first, verify all the entries individually:
|
||||
for (int bkt = 0; bkt < the_table()->table_size(); bkt++) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt);
|
||||
for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) {
|
||||
VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs);
|
||||
if (ret != _verify_pass) {
|
||||
fail_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optimization: if the above check did not find any failures, then
|
||||
// the comparison loop below does not need to call verify_entry()
|
||||
// before calling compare_entries(). If there were failures, then we
|
||||
// have to call verify_entry() to see if the entry can be passed to
|
||||
// compare_entries() safely. When we call verify_entry() in the loop
|
||||
// below, we do so quietly to void duplicate messages and we don't
|
||||
// increment fail_cnt because the failures have already been counted.
|
||||
bool need_entry_verify = (fail_cnt != 0);
|
||||
|
||||
// second, verify all entries relative to each other:
|
||||
for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1);
|
||||
for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) {
|
||||
if (need_entry_verify) {
|
||||
VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1,
|
||||
_verify_quietly);
|
||||
if (ret == _verify_fail_done) {
|
||||
// cannot use the current entry to compare against other entries
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2);
|
||||
int e_cnt2;
|
||||
for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) {
|
||||
if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) {
|
||||
// skip the entries up to and including the one that
|
||||
// we're comparing against
|
||||
continue;
|
||||
}
|
||||
|
||||
if (need_entry_verify) {
|
||||
VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2,
|
||||
_verify_quietly);
|
||||
if (ret == _verify_fail_done) {
|
||||
// cannot compare against this entry
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// compare two entries, report and count any failures:
|
||||
if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2)
|
||||
!= _verify_pass) {
|
||||
fail_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fail_cnt;
|
||||
}
|
||||
|
||||
// Create a new table and using alternate hash code, populate the new table
|
||||
// with the existing strings. Set flag to use the alternate hash code afterwards.
|
||||
void StringTable::rehash_table() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
||||
// This should never happen with -Xshare:dump but it might in testing mode.
|
||||
if (DumpSharedSpaces) return;
|
||||
StringTable* new_table = new StringTable();
|
||||
|
||||
// Rehash the table
|
||||
the_table()->move_to(new_table);
|
||||
|
||||
// Delete the table and buckets (entries are reused in new table).
|
||||
delete _the_table;
|
||||
// Don't check if we need rehashing until the table gets unbalanced again.
|
||||
// Then rehash with a new global seed.
|
||||
_needs_rehashing = false;
|
||||
_the_table = new_table;
|
||||
}
|
162
hotspot/src/share/vm/classfile/stringTable.hpp
Normal file
162
hotspot/src/share/vm/classfile/stringTable.hpp
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_CLASSFILE_STRINGTABLE_HPP
|
||||
#define SHARE_VM_CLASSFILE_STRINGTABLE_HPP
|
||||
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "utilities/hashtable.hpp"
|
||||
|
||||
class StringTable : public Hashtable<oop, mtSymbol> {
|
||||
friend class VMStructs;
|
||||
friend class Symbol;
|
||||
|
||||
private:
|
||||
// The string table
|
||||
static StringTable* _the_table;
|
||||
|
||||
// Set if one bucket is out of balance due to hash algorithm deficiency
|
||||
static bool _needs_rehashing;
|
||||
|
||||
// Claimed high water mark for parallel chunked scanning
|
||||
static volatile int _parallel_claimed_idx;
|
||||
|
||||
static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
|
||||
oop basic_add(int index, Handle string_or_null, jchar* name, int len,
|
||||
unsigned int hashValue, TRAPS);
|
||||
|
||||
oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
|
||||
|
||||
// Apply the give oop closure to the entries to the buckets
|
||||
// in the range [start_idx, end_idx).
|
||||
static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
|
||||
// Unlink or apply the give oop closure to the entries to the buckets
|
||||
// in the range [start_idx, end_idx).
|
||||
static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
|
||||
|
||||
StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
|
||||
sizeof (HashtableEntry<oop, mtSymbol>)) {}
|
||||
|
||||
StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
|
||||
: Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
|
||||
number_of_entries) {}
|
||||
public:
|
||||
// The string table
|
||||
static StringTable* the_table() { return _the_table; }
|
||||
|
||||
// Size of one bucket in the string table. Used when checking for rollover.
|
||||
static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
|
||||
|
||||
static void create_table() {
|
||||
assert(_the_table == NULL, "One string table allowed.");
|
||||
_the_table = new StringTable();
|
||||
}
|
||||
|
||||
// GC support
|
||||
// Delete pointers to otherwise-unreachable objects.
|
||||
static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) {
|
||||
int processed = 0;
|
||||
int removed = 0;
|
||||
unlink_or_oops_do(cl, f, &processed, &removed);
|
||||
}
|
||||
static void unlink(BoolObjectClosure* cl) {
|
||||
int processed = 0;
|
||||
int removed = 0;
|
||||
unlink_or_oops_do(cl, NULL, &processed, &removed);
|
||||
}
|
||||
static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed);
|
||||
static void unlink(BoolObjectClosure* cl, int* processed, int* removed) {
|
||||
unlink_or_oops_do(cl, NULL, processed, removed);
|
||||
}
|
||||
// Serially invoke "f->do_oop" on the locations of all oops in the table.
|
||||
static void oops_do(OopClosure* f);
|
||||
|
||||
// Possibly parallel versions of the above
|
||||
static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed);
|
||||
static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) {
|
||||
possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed);
|
||||
}
|
||||
static void possibly_parallel_oops_do(OopClosure* f);
|
||||
|
||||
// Hashing algorithm, used as the hash value used by the
|
||||
// StringTable for bucket selection and comparison (stored in the
|
||||
// HashtableEntry structures). This is used in the String.intern() method.
|
||||
static unsigned int hash_string(const jchar* s, int len);
|
||||
|
||||
// Internal test.
|
||||
static void test_alt_hash() PRODUCT_RETURN;
|
||||
|
||||
// Probing
|
||||
static oop lookup(Symbol* symbol);
|
||||
static oop lookup(jchar* chars, int length);
|
||||
|
||||
// Interning
|
||||
static oop intern(Symbol* symbol, TRAPS);
|
||||
static oop intern(oop string, TRAPS);
|
||||
static oop intern(const char *utf8_string, TRAPS);
|
||||
|
||||
// Debugging
|
||||
static void verify();
|
||||
static void dump(outputStream* st);
|
||||
|
||||
enum VerifyMesgModes {
|
||||
_verify_quietly = 0,
|
||||
_verify_with_mesgs = 1
|
||||
};
|
||||
|
||||
enum VerifyRetTypes {
|
||||
_verify_pass = 0,
|
||||
_verify_fail_continue = 1,
|
||||
_verify_fail_done = 2
|
||||
};
|
||||
|
||||
static VerifyRetTypes compare_entries(int bkt1, int e_cnt1,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr1,
|
||||
int bkt2, int e_cnt2,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr2);
|
||||
static VerifyRetTypes verify_entry(int bkt, int e_cnt,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr,
|
||||
VerifyMesgModes mesg_mode);
|
||||
static int verify_and_compare_entries();
|
||||
|
||||
// Sharing
|
||||
static void copy_buckets(char** top, char*end) {
|
||||
the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end);
|
||||
}
|
||||
static void copy_table(char** top, char*end) {
|
||||
the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end);
|
||||
}
|
||||
static void reverse() {
|
||||
the_table()->Hashtable<oop, mtSymbol>::reverse();
|
||||
}
|
||||
|
||||
// Rehash the symbol table if it gets out of balance
|
||||
static void rehash_table();
|
||||
static bool needs_rehashing() { return _needs_rehashing; }
|
||||
|
||||
// Parallel chunked scanning
|
||||
static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
|
||||
static int parallel_claimed_index() { return _parallel_claimed_idx; }
|
||||
};
|
||||
#endif // SHARE_VM_CLASSFILE_STRINGTABLE_HPP
|
@ -35,14 +35,10 @@
|
||||
#include "oops/oop.inline2.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "utilities/hashtable.inline.hpp"
|
||||
#if INCLUDE_ALL_GCS
|
||||
#include "gc_implementation/g1/g1StringDedup.hpp"
|
||||
#endif
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
// the number of buckets a thread claims
|
||||
const int ClaimChunkSize = 32;
|
||||
|
||||
@ -589,493 +585,3 @@ void SymbolTable::print() {
|
||||
}
|
||||
}
|
||||
#endif // PRODUCT
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
#ifdef ASSERT
|
||||
class StableMemoryChecker : public StackObj {
|
||||
enum { _bufsize = wordSize*4 };
|
||||
|
||||
address _region;
|
||||
jint _size;
|
||||
u1 _save_buf[_bufsize];
|
||||
|
||||
int sample(u1* save_buf) {
|
||||
if (_size <= _bufsize) {
|
||||
memcpy(save_buf, _region, _size);
|
||||
return _size;
|
||||
} else {
|
||||
// copy head and tail
|
||||
memcpy(&save_buf[0], _region, _bufsize/2);
|
||||
memcpy(&save_buf[_bufsize/2], _region + _size - _bufsize/2, _bufsize/2);
|
||||
return (_bufsize/2)*2;
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
StableMemoryChecker(const void* region, jint size) {
|
||||
_region = (address) region;
|
||||
_size = size;
|
||||
sample(_save_buf);
|
||||
}
|
||||
|
||||
bool verify() {
|
||||
u1 check_buf[sizeof(_save_buf)];
|
||||
int check_size = sample(check_buf);
|
||||
return (0 == memcmp(_save_buf, check_buf, check_size));
|
||||
}
|
||||
|
||||
void set_region(const void* region) { _region = (address) region; }
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
StringTable* StringTable::_the_table = NULL;
|
||||
|
||||
bool StringTable::_needs_rehashing = false;
|
||||
|
||||
volatile int StringTable::_parallel_claimed_idx = 0;
|
||||
|
||||
// Pick hashing algorithm
|
||||
unsigned int StringTable::hash_string(const jchar* s, int len) {
|
||||
return use_alternate_hashcode() ? AltHashing::murmur3_32(seed(), s, len) :
|
||||
java_lang_String::hash_code(s, len);
|
||||
}
|
||||
|
||||
oop StringTable::lookup(int index, jchar* name,
|
||||
int len, unsigned int hash) {
|
||||
int count = 0;
|
||||
for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
|
||||
count++;
|
||||
if (l->hash() == hash) {
|
||||
if (java_lang_String::equals(l->literal(), name, len)) {
|
||||
return l->literal();
|
||||
}
|
||||
}
|
||||
}
|
||||
// If the bucket size is too deep check if this hash code is insufficient.
|
||||
if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
|
||||
_needs_rehashing = check_rehash_table(count);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::basic_add(int index_arg, Handle string, jchar* name,
|
||||
int len, unsigned int hashValue_arg, TRAPS) {
|
||||
|
||||
assert(java_lang_String::equals(string(), name, len),
|
||||
"string must be properly initialized");
|
||||
// Cannot hit a safepoint in this function because the "this" pointer can move.
|
||||
No_Safepoint_Verifier nsv;
|
||||
|
||||
// Check if the symbol table has been rehashed, if so, need to recalculate
|
||||
// the hash value and index before second lookup.
|
||||
unsigned int hashValue;
|
||||
int index;
|
||||
if (use_alternate_hashcode()) {
|
||||
hashValue = hash_string(name, len);
|
||||
index = hash_to_index(hashValue);
|
||||
} else {
|
||||
hashValue = hashValue_arg;
|
||||
index = index_arg;
|
||||
}
|
||||
|
||||
// Since look-up was done lock-free, we need to check if another
|
||||
// thread beat us in the race to insert the symbol.
|
||||
|
||||
oop test = lookup(index, name, len, hashValue); // calls lookup(u1*, int)
|
||||
if (test != NULL) {
|
||||
// Entry already added
|
||||
return test;
|
||||
}
|
||||
|
||||
HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
|
||||
add_entry(index, entry);
|
||||
return string();
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::lookup(Symbol* symbol) {
|
||||
ResourceMark rm;
|
||||
int length;
|
||||
jchar* chars = symbol->as_unicode(length);
|
||||
return lookup(chars, length);
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::lookup(jchar* name, int len) {
|
||||
unsigned int hash = hash_string(name, len);
|
||||
int index = the_table()->hash_to_index(hash);
|
||||
return the_table()->lookup(index, name, len, hash);
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::intern(Handle string_or_null, jchar* name,
|
||||
int len, TRAPS) {
|
||||
unsigned int hashValue = hash_string(name, len);
|
||||
int index = the_table()->hash_to_index(hashValue);
|
||||
oop found_string = the_table()->lookup(index, name, len, hashValue);
|
||||
|
||||
// Found
|
||||
if (found_string != NULL) return found_string;
|
||||
|
||||
debug_only(StableMemoryChecker smc(name, len * sizeof(name[0])));
|
||||
assert(!Universe::heap()->is_in_reserved(name),
|
||||
"proposed name of symbol must be stable");
|
||||
|
||||
Handle string;
|
||||
// try to reuse the string if possible
|
||||
if (!string_or_null.is_null()) {
|
||||
string = string_or_null;
|
||||
} else {
|
||||
string = java_lang_String::create_from_unicode(name, len, CHECK_NULL);
|
||||
}
|
||||
|
||||
#if INCLUDE_ALL_GCS
|
||||
if (G1StringDedup::is_enabled()) {
|
||||
// Deduplicate the string before it is interned. Note that we should never
|
||||
// deduplicate a string after it has been interned. Doing so will counteract
|
||||
// compiler optimizations done on e.g. interned string literals.
|
||||
G1StringDedup::deduplicate(string());
|
||||
}
|
||||
#endif
|
||||
|
||||
// Grab the StringTable_lock before getting the_table() because it could
|
||||
// change at safepoint.
|
||||
MutexLocker ml(StringTable_lock, THREAD);
|
||||
|
||||
// Otherwise, add to symbol to table
|
||||
return the_table()->basic_add(index, string, name, len,
|
||||
hashValue, CHECK_NULL);
|
||||
}
|
||||
|
||||
oop StringTable::intern(Symbol* symbol, TRAPS) {
|
||||
if (symbol == NULL) return NULL;
|
||||
ResourceMark rm(THREAD);
|
||||
int length;
|
||||
jchar* chars = symbol->as_unicode(length);
|
||||
Handle string;
|
||||
oop result = intern(string, chars, length, CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::intern(oop string, TRAPS)
|
||||
{
|
||||
if (string == NULL) return NULL;
|
||||
ResourceMark rm(THREAD);
|
||||
int length;
|
||||
Handle h_string (THREAD, string);
|
||||
jchar* chars = java_lang_String::as_unicode_string(string, length, CHECK_NULL);
|
||||
oop result = intern(h_string, chars, length, CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
oop StringTable::intern(const char* utf8_string, TRAPS) {
|
||||
if (utf8_string == NULL) return NULL;
|
||||
ResourceMark rm(THREAD);
|
||||
int length = UTF8::unicode_length(utf8_string);
|
||||
jchar* chars = NEW_RESOURCE_ARRAY(jchar, length);
|
||||
UTF8::convert_to_unicode(utf8_string, chars, length);
|
||||
Handle string;
|
||||
oop result = intern(string, chars, length, CHECK_NULL);
|
||||
return result;
|
||||
}
|
||||
|
||||
void StringTable::unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
|
||||
buckets_unlink_or_oops_do(is_alive, f, 0, the_table()->table_size(), processed, removed);
|
||||
}
|
||||
|
||||
void StringTable::possibly_parallel_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int* processed, int* removed) {
|
||||
// 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");
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
for (;;) {
|
||||
// Grab next set of buckets to scan
|
||||
int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
|
||||
if (start_idx >= limit) {
|
||||
// End of table
|
||||
break;
|
||||
}
|
||||
|
||||
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
||||
buckets_unlink_or_oops_do(is_alive, f, start_idx, end_idx, processed, removed);
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::buckets_oops_do(OopClosure* f, int start_idx, int end_idx) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
assert(0 <= start_idx && start_idx <= limit,
|
||||
err_msg("start_idx (%d) is out of bounds", start_idx));
|
||||
assert(0 <= end_idx && end_idx <= limit,
|
||||
err_msg("end_idx (%d) is out of bounds", end_idx));
|
||||
assert(start_idx <= end_idx,
|
||||
err_msg("Index ordering: start_idx=%d, end_idx=%d",
|
||||
start_idx, end_idx));
|
||||
|
||||
for (int i = start_idx; i < end_idx; i += 1) {
|
||||
HashtableEntry<oop, mtSymbol>* 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());
|
||||
|
||||
entry = entry->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
assert(0 <= start_idx && start_idx <= limit,
|
||||
err_msg("start_idx (%d) is out of bounds", start_idx));
|
||||
assert(0 <= end_idx && end_idx <= limit,
|
||||
err_msg("end_idx (%d) is out of bounds", end_idx));
|
||||
assert(start_idx <= end_idx,
|
||||
err_msg("Index ordering: start_idx=%d, end_idx=%d",
|
||||
start_idx, end_idx));
|
||||
|
||||
for (int i = start_idx; i < end_idx; ++i) {
|
||||
HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
|
||||
HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
|
||||
while (entry != NULL) {
|
||||
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();
|
||||
the_table()->free_entry(entry);
|
||||
(*removed)++;
|
||||
}
|
||||
(*processed)++;
|
||||
entry = *p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::oops_do(OopClosure* f) {
|
||||
buckets_oops_do(f, 0, the_table()->table_size());
|
||||
}
|
||||
|
||||
void StringTable::possibly_parallel_oops_do(OopClosure* f) {
|
||||
const int limit = the_table()->table_size();
|
||||
|
||||
for (;;) {
|
||||
// Grab next set of buckets to scan
|
||||
int start_idx = Atomic::add(ClaimChunkSize, &_parallel_claimed_idx) - ClaimChunkSize;
|
||||
if (start_idx >= limit) {
|
||||
// End of table
|
||||
break;
|
||||
}
|
||||
|
||||
int end_idx = MIN2(limit, start_idx + ClaimChunkSize);
|
||||
buckets_oops_do(f, start_idx, end_idx);
|
||||
}
|
||||
}
|
||||
|
||||
// This verification is part of Universe::verify() and needs to be quick.
|
||||
// See StringTable::verify_and_compare() below for exhaustive verification.
|
||||
void StringTable::verify() {
|
||||
for (int i = 0; i < the_table()->table_size(); ++i) {
|
||||
HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
|
||||
for ( ; p != NULL; p = p->next()) {
|
||||
oop s = p->literal();
|
||||
guarantee(s != NULL, "interned string is NULL");
|
||||
unsigned int h = java_lang_String::hash_string(s);
|
||||
guarantee(p->hash() == h, "broken hash in string table entry");
|
||||
guarantee(the_table()->hash_to_index(h) == i,
|
||||
"wrong index in string table");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void StringTable::dump(outputStream* st) {
|
||||
the_table()->dump_table(st, "StringTable");
|
||||
}
|
||||
|
||||
StringTable::VerifyRetTypes StringTable::compare_entries(
|
||||
int bkt1, int e_cnt1,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr1,
|
||||
int bkt2, int e_cnt2,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr2) {
|
||||
// These entries are sanity checked by verify_and_compare_entries()
|
||||
// before this function is called.
|
||||
oop str1 = e_ptr1->literal();
|
||||
oop str2 = e_ptr2->literal();
|
||||
|
||||
if (str1 == str2) {
|
||||
tty->print_cr("ERROR: identical oop values (0x" PTR_FORMAT ") "
|
||||
"in entry @ bucket[%d][%d] and entry @ bucket[%d][%d]",
|
||||
(void *)str1, bkt1, e_cnt1, bkt2, e_cnt2);
|
||||
return _verify_fail_continue;
|
||||
}
|
||||
|
||||
if (java_lang_String::equals(str1, str2)) {
|
||||
tty->print_cr("ERROR: identical String values in entry @ "
|
||||
"bucket[%d][%d] and entry @ bucket[%d][%d]",
|
||||
bkt1, e_cnt1, bkt2, e_cnt2);
|
||||
return _verify_fail_continue;
|
||||
}
|
||||
|
||||
return _verify_pass;
|
||||
}
|
||||
|
||||
StringTable::VerifyRetTypes StringTable::verify_entry(int bkt, int e_cnt,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr,
|
||||
StringTable::VerifyMesgModes mesg_mode) {
|
||||
|
||||
VerifyRetTypes ret = _verify_pass; // be optimistic
|
||||
|
||||
oop str = e_ptr->literal();
|
||||
if (str == NULL) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: NULL oop value in entry @ bucket[%d][%d]", bkt,
|
||||
e_cnt);
|
||||
}
|
||||
// NULL oop means no more verifications are possible
|
||||
return _verify_fail_done;
|
||||
}
|
||||
|
||||
if (str->klass() != SystemDictionary::String_klass()) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: oop is not a String in entry @ bucket[%d][%d]",
|
||||
bkt, e_cnt);
|
||||
}
|
||||
// not a String means no more verifications are possible
|
||||
return _verify_fail_done;
|
||||
}
|
||||
|
||||
unsigned int h = java_lang_String::hash_string(str);
|
||||
if (e_ptr->hash() != h) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: broken hash value in entry @ bucket[%d][%d], "
|
||||
"bkt_hash=%d, str_hash=%d", bkt, e_cnt, e_ptr->hash(), h);
|
||||
}
|
||||
ret = _verify_fail_continue;
|
||||
}
|
||||
|
||||
if (the_table()->hash_to_index(h) != bkt) {
|
||||
if (mesg_mode == _verify_with_mesgs) {
|
||||
tty->print_cr("ERROR: wrong index value for entry @ bucket[%d][%d], "
|
||||
"str_hash=%d, hash_to_index=%d", bkt, e_cnt, h,
|
||||
the_table()->hash_to_index(h));
|
||||
}
|
||||
ret = _verify_fail_continue;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// See StringTable::verify() above for the quick verification that is
|
||||
// part of Universe::verify(). This verification is exhaustive and
|
||||
// reports on every issue that is found. StringTable::verify() only
|
||||
// reports on the first issue that is found.
|
||||
//
|
||||
// StringTable::verify_entry() checks:
|
||||
// - oop value != NULL (same as verify())
|
||||
// - oop value is a String
|
||||
// - hash(String) == hash in entry (same as verify())
|
||||
// - index for hash == index of entry (same as verify())
|
||||
//
|
||||
// StringTable::compare_entries() checks:
|
||||
// - oops are unique across all entries
|
||||
// - String values are unique across all entries
|
||||
//
|
||||
int StringTable::verify_and_compare_entries() {
|
||||
assert(StringTable_lock->is_locked(), "sanity check");
|
||||
|
||||
int fail_cnt = 0;
|
||||
|
||||
// first, verify all the entries individually:
|
||||
for (int bkt = 0; bkt < the_table()->table_size(); bkt++) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr = the_table()->bucket(bkt);
|
||||
for (int e_cnt = 0; e_ptr != NULL; e_ptr = e_ptr->next(), e_cnt++) {
|
||||
VerifyRetTypes ret = verify_entry(bkt, e_cnt, e_ptr, _verify_with_mesgs);
|
||||
if (ret != _verify_pass) {
|
||||
fail_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Optimization: if the above check did not find any failures, then
|
||||
// the comparison loop below does not need to call verify_entry()
|
||||
// before calling compare_entries(). If there were failures, then we
|
||||
// have to call verify_entry() to see if the entry can be passed to
|
||||
// compare_entries() safely. When we call verify_entry() in the loop
|
||||
// below, we do so quietly to void duplicate messages and we don't
|
||||
// increment fail_cnt because the failures have already been counted.
|
||||
bool need_entry_verify = (fail_cnt != 0);
|
||||
|
||||
// second, verify all entries relative to each other:
|
||||
for (int bkt1 = 0; bkt1 < the_table()->table_size(); bkt1++) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr1 = the_table()->bucket(bkt1);
|
||||
for (int e_cnt1 = 0; e_ptr1 != NULL; e_ptr1 = e_ptr1->next(), e_cnt1++) {
|
||||
if (need_entry_verify) {
|
||||
VerifyRetTypes ret = verify_entry(bkt1, e_cnt1, e_ptr1,
|
||||
_verify_quietly);
|
||||
if (ret == _verify_fail_done) {
|
||||
// cannot use the current entry to compare against other entries
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
for (int bkt2 = bkt1; bkt2 < the_table()->table_size(); bkt2++) {
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr2 = the_table()->bucket(bkt2);
|
||||
int e_cnt2;
|
||||
for (e_cnt2 = 0; e_ptr2 != NULL; e_ptr2 = e_ptr2->next(), e_cnt2++) {
|
||||
if (bkt1 == bkt2 && e_cnt2 <= e_cnt1) {
|
||||
// skip the entries up to and including the one that
|
||||
// we're comparing against
|
||||
continue;
|
||||
}
|
||||
|
||||
if (need_entry_verify) {
|
||||
VerifyRetTypes ret = verify_entry(bkt2, e_cnt2, e_ptr2,
|
||||
_verify_quietly);
|
||||
if (ret == _verify_fail_done) {
|
||||
// cannot compare against this entry
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// compare two entries, report and count any failures:
|
||||
if (compare_entries(bkt1, e_cnt1, e_ptr1, bkt2, e_cnt2, e_ptr2)
|
||||
!= _verify_pass) {
|
||||
fail_cnt++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fail_cnt;
|
||||
}
|
||||
|
||||
// Create a new table and using alternate hash code, populate the new table
|
||||
// with the existing strings. Set flag to use the alternate hash code afterwards.
|
||||
void StringTable::rehash_table() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
|
||||
// This should never happen with -Xshare:dump but it might in testing mode.
|
||||
if (DumpSharedSpaces) return;
|
||||
StringTable* new_table = new StringTable();
|
||||
|
||||
// Rehash the table
|
||||
the_table()->move_to(new_table);
|
||||
|
||||
// Delete the table and buckets (entries are reused in new table).
|
||||
delete _the_table;
|
||||
// Don't check if we need rehashing until the table gets unbalanced again.
|
||||
// Then rehash with a new global seed.
|
||||
_needs_rehashing = false;
|
||||
_the_table = new_table;
|
||||
}
|
||||
|
@ -42,7 +42,6 @@
|
||||
class BoolObjectClosure;
|
||||
class outputStream;
|
||||
|
||||
|
||||
// Class to hold a newly created or referenced Symbol* temporarily in scope.
|
||||
// new_symbol() and lookup() will create a Symbol* if not already in the
|
||||
// symbol table and add to the symbol's reference count.
|
||||
@ -252,134 +251,4 @@ public:
|
||||
static int parallel_claimed_index() { return _parallel_claimed_idx; }
|
||||
};
|
||||
|
||||
class StringTable : public Hashtable<oop, mtSymbol> {
|
||||
friend class VMStructs;
|
||||
|
||||
private:
|
||||
// The string table
|
||||
static StringTable* _the_table;
|
||||
|
||||
// Set if one bucket is out of balance due to hash algorithm deficiency
|
||||
static bool _needs_rehashing;
|
||||
|
||||
// Claimed high water mark for parallel chunked scanning
|
||||
static volatile int _parallel_claimed_idx;
|
||||
|
||||
static oop intern(Handle string_or_null, jchar* chars, int length, TRAPS);
|
||||
oop basic_add(int index, Handle string_or_null, jchar* name, int len,
|
||||
unsigned int hashValue, TRAPS);
|
||||
|
||||
oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
|
||||
|
||||
// Apply the give oop closure to the entries to the buckets
|
||||
// in the range [start_idx, end_idx).
|
||||
static void buckets_oops_do(OopClosure* f, int start_idx, int end_idx);
|
||||
// Unlink or apply the give oop closure to the entries to the buckets
|
||||
// in the range [start_idx, end_idx).
|
||||
static void buckets_unlink_or_oops_do(BoolObjectClosure* is_alive, OopClosure* f, int start_idx, int end_idx, int* processed, int* removed);
|
||||
|
||||
StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
|
||||
sizeof (HashtableEntry<oop, mtSymbol>)) {}
|
||||
|
||||
StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
|
||||
: Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
|
||||
number_of_entries) {}
|
||||
public:
|
||||
// The string table
|
||||
static StringTable* the_table() { return _the_table; }
|
||||
|
||||
// Size of one bucket in the string table. Used when checking for rollover.
|
||||
static uint bucket_size() { return sizeof(HashtableBucket<mtSymbol>); }
|
||||
|
||||
static void create_table() {
|
||||
assert(_the_table == NULL, "One string table allowed.");
|
||||
_the_table = new StringTable();
|
||||
}
|
||||
|
||||
// GC support
|
||||
// Delete pointers to otherwise-unreachable objects.
|
||||
static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f) {
|
||||
int processed = 0;
|
||||
int removed = 0;
|
||||
unlink_or_oops_do(cl, f, &processed, &removed);
|
||||
}
|
||||
static void unlink(BoolObjectClosure* cl) {
|
||||
int processed = 0;
|
||||
int removed = 0;
|
||||
unlink_or_oops_do(cl, NULL, &processed, &removed);
|
||||
}
|
||||
static void unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed);
|
||||
static void unlink(BoolObjectClosure* cl, int* processed, int* removed) {
|
||||
unlink_or_oops_do(cl, NULL, processed, removed);
|
||||
}
|
||||
// Serially invoke "f->do_oop" on the locations of all oops in the table.
|
||||
static void oops_do(OopClosure* f);
|
||||
|
||||
// Possibly parallel versions of the above
|
||||
static void possibly_parallel_unlink_or_oops_do(BoolObjectClosure* cl, OopClosure* f, int* processed, int* removed);
|
||||
static void possibly_parallel_unlink(BoolObjectClosure* cl, int* processed, int* removed) {
|
||||
possibly_parallel_unlink_or_oops_do(cl, NULL, processed, removed);
|
||||
}
|
||||
static void possibly_parallel_oops_do(OopClosure* f);
|
||||
|
||||
// Hashing algorithm, used as the hash value used by the
|
||||
// StringTable for bucket selection and comparison (stored in the
|
||||
// HashtableEntry structures). This is used in the String.intern() method.
|
||||
static unsigned int hash_string(const jchar* s, int len);
|
||||
|
||||
// Internal test.
|
||||
static void test_alt_hash() PRODUCT_RETURN;
|
||||
|
||||
// Probing
|
||||
static oop lookup(Symbol* symbol);
|
||||
static oop lookup(jchar* chars, int length);
|
||||
|
||||
// Interning
|
||||
static oop intern(Symbol* symbol, TRAPS);
|
||||
static oop intern(oop string, TRAPS);
|
||||
static oop intern(const char *utf8_string, TRAPS);
|
||||
|
||||
// Debugging
|
||||
static void verify();
|
||||
static void dump(outputStream* st);
|
||||
|
||||
enum VerifyMesgModes {
|
||||
_verify_quietly = 0,
|
||||
_verify_with_mesgs = 1
|
||||
};
|
||||
|
||||
enum VerifyRetTypes {
|
||||
_verify_pass = 0,
|
||||
_verify_fail_continue = 1,
|
||||
_verify_fail_done = 2
|
||||
};
|
||||
|
||||
static VerifyRetTypes compare_entries(int bkt1, int e_cnt1,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr1,
|
||||
int bkt2, int e_cnt2,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr2);
|
||||
static VerifyRetTypes verify_entry(int bkt, int e_cnt,
|
||||
HashtableEntry<oop, mtSymbol>* e_ptr,
|
||||
VerifyMesgModes mesg_mode);
|
||||
static int verify_and_compare_entries();
|
||||
|
||||
// Sharing
|
||||
static void copy_buckets(char** top, char*end) {
|
||||
the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end);
|
||||
}
|
||||
static void copy_table(char** top, char*end) {
|
||||
the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end);
|
||||
}
|
||||
static void reverse() {
|
||||
the_table()->Hashtable<oop, mtSymbol>::reverse();
|
||||
}
|
||||
|
||||
// Rehash the symbol table if it gets out of balance
|
||||
static void rehash_table();
|
||||
static bool needs_rehashing() { return _needs_rehashing; }
|
||||
|
||||
// Parallel chunked scanning
|
||||
static void clear_parallel_claimed_index() { _parallel_claimed_idx = 0; }
|
||||
static int parallel_claimed_index() { return _parallel_claimed_idx; }
|
||||
};
|
||||
#endif // SHARE_VM_CLASSFILE_SYMBOLTABLE_HPP
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "classfile/loaderConstraints.hpp"
|
||||
#include "classfile/placeholders.hpp"
|
||||
#include "classfile/resolutionErrors.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "gc_implementation/concurrentMarkSweep/cmsAdaptiveSizePolicy.hpp"
|
||||
|
@ -28,6 +28,7 @@
|
||||
#endif
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "gc_implementation/g1/bufferingOopClosure.hpp"
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -23,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "gc_implementation/parallelScavenge/parallelScavengeHeap.hpp"
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
@ -23,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "gc_implementation/parallelScavenge/cardTableExtension.hpp"
|
||||
#include "gc_implementation/parallelScavenge/gcTaskManager.hpp"
|
||||
|
@ -24,31 +24,19 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "libadt/dict.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
// Dictionaries - An Abstract Data Type
|
||||
|
||||
// %%%%% includes not needed with AVM framework - Ungar
|
||||
|
||||
// #include "port.hpp"
|
||||
//IMPLEMENTATION
|
||||
// #include "dict.hpp"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC
|
||||
|
||||
// The iostream is not needed and it gets confused for gcc by the
|
||||
// define of bool.
|
||||
//
|
||||
// #include <iostream.h>
|
||||
|
||||
//------------------------------data-----------------------------------------
|
||||
// String hash tables
|
||||
#define MAXID 20
|
||||
static byte initflag = 0; // True after 1st initialization
|
||||
static uint8_t initflag = 0; // True after 1st initialization
|
||||
static const char shft[MAXID] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6};
|
||||
static short xsum[MAXID];
|
||||
|
||||
@ -283,7 +271,7 @@ void *Dict::operator [](const void *key) const {
|
||||
// CmpDict compares two dictionaries; they must have the same keys (their
|
||||
// keys must match using CmpKey) and they must have the same values (pointer
|
||||
// comparison). If so 1 is returned, if not 0 is returned.
|
||||
int32 Dict::operator ==(const Dict &d2) const {
|
||||
int32_t Dict::operator ==(const Dict &d2) const {
|
||||
if( _cnt != d2._cnt ) return 0;
|
||||
if( _hash != d2._hash ) return 0;
|
||||
if( _cmp != d2._cmp ) return 0;
|
||||
@ -320,7 +308,7 @@ void Dict::print() {
|
||||
// C text shows excellent spreading of values for any size hash table.
|
||||
int hashstr(const void *t) {
|
||||
register char c, k = 0;
|
||||
register int32 sum = 0;
|
||||
register int32_t sum = 0;
|
||||
register const char *s = (const char *)t;
|
||||
|
||||
while( ((c = *s++) != '\0') && (k < MAXID-1) ) { // Get characters till null or MAXID-1
|
||||
@ -334,11 +322,7 @@ int hashstr(const void *t) {
|
||||
// Slimey cheap hash function; no guaranteed performance. Better than the
|
||||
// default for pointers, especially on MS-DOS machines.
|
||||
int hashptr(const void *key) {
|
||||
#ifdef __TURBOC__
|
||||
return ((intptr_t)key >> 16);
|
||||
#else // __TURBOC__
|
||||
return ((intptr_t)key >> 2);
|
||||
#endif
|
||||
}
|
||||
|
||||
// Slimey cheap hash function; no guaranteed performance.
|
||||
@ -347,12 +331,12 @@ int hashkey(const void *key) {
|
||||
}
|
||||
|
||||
//------------------------------Key Comparator Functions---------------------
|
||||
int32 cmpstr(const void *k1, const void *k2) {
|
||||
int32_t cmpstr(const void *k1, const void *k2) {
|
||||
return strcmp((const char *)k1,(const char *)k2);
|
||||
}
|
||||
|
||||
// Cheap key comparator.
|
||||
int32 cmpkey(const void *key1, const void *key2) {
|
||||
int32_t cmpkey(const void *key1, const void *key2) {
|
||||
if (key1 == key2) return 0;
|
||||
intptr_t delta = (intptr_t)key1 - (intptr_t)key2;
|
||||
if (delta > 0) return 1;
|
||||
|
@ -25,11 +25,12 @@
|
||||
#ifndef SHARE_VM_LIBADT_DICT_HPP
|
||||
#define SHARE_VM_LIBADT_DICT_HPP
|
||||
|
||||
#include "libadt/port.hpp"
|
||||
|
||||
// Dictionaries - An Abstract Data Type
|
||||
//INTERFACE
|
||||
class ostream;
|
||||
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "runtime/thread.hpp"
|
||||
|
||||
class Dict;
|
||||
|
||||
// These dictionaries define a key-value mapping. They can be inserted to,
|
||||
@ -38,7 +39,7 @@ class Dict;
|
||||
// key comparison routine determines if two keys are equal or not. A hash
|
||||
// function can be provided; if it's not provided the key itself is used
|
||||
// instead. A nice string hash function is included.
|
||||
typedef int32 (*CmpKey)(const void *key1, const void *key2);
|
||||
typedef int32_t (*CmpKey)(const void *key1, const void *key2);
|
||||
typedef int (*Hash)(const void *key);
|
||||
typedef void (*FuncDict)(const void *key, const void *val, Dict *d);
|
||||
|
||||
@ -47,7 +48,7 @@ class Dict : public ResourceObj { // Dictionary structure
|
||||
class Arena *_arena; // Where to draw storage from
|
||||
class bucket *_bin; // Hash table is array of buckets
|
||||
uint _size; // Size (# of slots) in hash table
|
||||
uint32 _cnt; // Number of key-value pairs in hash table
|
||||
uint32_t _cnt; // Number of key-value pairs in hash table
|
||||
const Hash _hash; // Hashing function
|
||||
const CmpKey _cmp; // Key comparison function
|
||||
void doubhash( void ); // Double hash table size
|
||||
@ -67,7 +68,7 @@ class Dict : public ResourceObj { // Dictionary structure
|
||||
void Clear();
|
||||
|
||||
// Return # of key-value pairs in dict
|
||||
uint32 Size(void) const { return _cnt; }
|
||||
uint32_t Size(void) const { return _cnt; }
|
||||
|
||||
// Insert inserts the given key-value pair into the dictionary. The prior
|
||||
// value of the key is returned; NULL if the key was not previously defined.
|
||||
@ -81,7 +82,7 @@ class Dict : public ResourceObj { // Dictionary structure
|
||||
// == compares two dictionaries; they must have the same keys (their keys
|
||||
// must match using CmpKey) and they must have the same values (pointer
|
||||
// comparison). If so 1 is returned, if not 0 is returned.
|
||||
int32 operator ==(const Dict &d) const; // Compare dictionaries for equal
|
||||
int32_t operator ==(const Dict &d) const; // Compare dictionaries for equal
|
||||
|
||||
// Print out the dictionary contents as key-value pairs
|
||||
void print();
|
||||
@ -96,9 +97,9 @@ int hashptr(const void *key);
|
||||
int hashkey(const void *key);
|
||||
|
||||
// Key comparators
|
||||
int32 cmpstr(const void *k1, const void *k2);
|
||||
int32_t cmpstr(const void *k1, const void *k2);
|
||||
// Slimey cheap key comparator.
|
||||
int32 cmpkey(const void *key1, const void *key2);
|
||||
int32_t cmpkey(const void *key1, const void *key2);
|
||||
|
||||
//------------------------------Iteration--------------------------------------
|
||||
// The class of dictionary iterators. Fails in the presences of modifications
|
||||
|
@ -1,123 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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.
|
||||
*
|
||||
* 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 "libadt/port.hpp"
|
||||
|
||||
// Code for portable compiling
|
||||
|
||||
#ifdef __GNUC__
|
||||
#pragma implementation
|
||||
#endif
|
||||
|
||||
// %%%%% includes not needed with AVM framework - Ungar
|
||||
// #include "port.hpp"
|
||||
|
||||
// This is only used if turboc is used and it causes problems with
|
||||
// gcc.
|
||||
#ifdef __TURBOC__
|
||||
#include <iostream.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
//------------------------------gcd--------------------------------------------
|
||||
// Greatest common divisor
|
||||
uint32 gcd( register uint32 x, register uint32 y )
|
||||
{
|
||||
register uint32 tmp;
|
||||
while( x ) { // While not zero
|
||||
tmp = x; // Hold onto smaller x value
|
||||
x = y % x; // Compute modulus; since y>=x, 0 <= mod < x
|
||||
y = tmp; // y = old x
|
||||
}
|
||||
return y;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find first 1, or return 32 if empty
|
||||
int ff1( uint32 mask )
|
||||
{
|
||||
unsigned i, n = 0;
|
||||
|
||||
for( i=1, n=0; i; i<<=1, n++)
|
||||
if( mask&i ) return n;
|
||||
return 32;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Find highest 1, or return 32 if empty
|
||||
int fh1( uint32 mask )
|
||||
{
|
||||
unsigned i, n = 0;
|
||||
|
||||
for( i=((uint32)1<<31), n=31; i; i>>=1, n--)
|
||||
if( mask&i ) return n;
|
||||
return 32;
|
||||
}
|
||||
|
||||
//------------------------------rotate32---------------------------------------
|
||||
// Rotate 32bits. Postive rotates left (bits move toward high-order bit),
|
||||
// negative rotates right.
|
||||
uint32 rotate32( register uint32 x, register int32 cnt )
|
||||
{
|
||||
if( cnt >= 0 ) { // Positive rotates left
|
||||
cnt &= 31; // Mask off extra shift bits
|
||||
} else { // Negative rotates right
|
||||
cnt = (-cnt)&31; // Flip sign; mask extra shift bits
|
||||
cnt = 32-cnt; // Rotate right by big left rotation
|
||||
}
|
||||
return (x << cnt) | (x >> (32-cnt));
|
||||
}
|
||||
|
||||
/* Disabled - we have another log2 in the system.
|
||||
This function doesn't work if used as substitute
|
||||
for the existing log2. Keep around until we have
|
||||
verified all uses of log2 do the correct thing!
|
||||
//------------------------------log2-------------------------------------------
|
||||
// Log base 2. Might also be called 'count leading zeros'. Log2(x) returns
|
||||
// an l such that (1L<<l) <= x < (2L<<l). log2(x) returns 32.
|
||||
uint log2( uint32 x )
|
||||
{
|
||||
register uint l = 32; // Log bits
|
||||
register int32 sx = x; // Treat as signed number
|
||||
while( sx >= 0 ) // While high bit is clear
|
||||
sx <<= 1, l--; // Shift bits left, count down log2
|
||||
return l;
|
||||
}
|
||||
*/
|
||||
|
||||
//------------------------------print------------------------------------------
|
||||
// Print a pointer without modifying the contents
|
||||
#ifdef __TURBOC__
|
||||
ostream &ostream::operator << (const void *ptr)
|
||||
{
|
||||
return (*this) << "0x" << hex << (uint)ptr << dec;
|
||||
}
|
||||
#else
|
||||
/*ostream &operator << (ostream &os, const void *ptr)
|
||||
{
|
||||
return os << "0x" << hex << (uint)ptr << dec;
|
||||
}*/
|
||||
#endif
|
@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_VM_LIBADT_PORT_HPP
|
||||
#define SHARE_VM_LIBADT_PORT_HPP
|
||||
|
||||
#include "utilities/top.hpp"
|
||||
|
||||
// Typedefs for portable compiling
|
||||
|
||||
#if defined(__GNUC__)
|
||||
|
||||
#define INTERFACE #pragma interface
|
||||
#define IMPLEMENTATION #pragma implementation
|
||||
//INTERFACE
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
// Access to the C++ class virtual function pointer
|
||||
// Put the class in the macro
|
||||
typedef void *VPTR;
|
||||
// G++ puts it at the end of the base class
|
||||
#define ACCESS_VPTR(class) VPTR&vptr(){return*(VPTR*)((char*)this+sizeof(class)-sizeof(void*));}
|
||||
|
||||
#elif defined(__TURBOC__)
|
||||
|
||||
#include <mem.h>
|
||||
#include <string.h>
|
||||
extern "C" int stricmp(const char *, const char *);
|
||||
inline void bcopy(const void *s, void *d, int l) { memmove(d,s,l); }
|
||||
inline void bzero(void *p, int l) { memset(p,0,l); }
|
||||
inline int bcmp(const void *s, const void *d, int l) { return memcmp(s,d,l); }
|
||||
inline int min( int a, int b) { return a < b ? a : b; }
|
||||
inline int max( int a, int b) { return a > b ? a : b; }
|
||||
//strcasecmp moved to globalDefinitions_visCPP.hpp
|
||||
//inline int strcasecmp(const char *s1, const char *s2) { return stricmp(s1,s2); }
|
||||
inline long abs( long x ) { return x < 0 ? -x : x; }
|
||||
// Access to the C++ class virtual function pointer
|
||||
// Put the class in the macro
|
||||
typedef void near *VPTR;
|
||||
// BorlandC puts it up front
|
||||
#define ACCESS_VPTR(class) VPTR&vptr(){return*(VPTR*)this;}
|
||||
|
||||
#elif defined(__hpux)
|
||||
|
||||
#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
#define signed
|
||||
#include <strings.h>
|
||||
#include <stdlib.h>
|
||||
inline long min( long a, long b) { return a < b ? a : b; }
|
||||
inline long max( long a, long b) { return a > b ? a : b; }
|
||||
inline int min( int a, int b) { return a < b ? a : b; }
|
||||
inline int max( int a, int b) { return a > b ? a : b; }
|
||||
inline long abs( long x ) { return x < 0 ? -x : x; }
|
||||
|
||||
#elif defined(__MOTO__)
|
||||
// Motorola's mcc
|
||||
#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
inline int min( int a, int b) { return a < b ? a : b; }
|
||||
inline int max( int a, int b) { return a > b ? a : b; }
|
||||
|
||||
#elif defined(_AIX)
|
||||
// IBM's xlC compiler
|
||||
#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
// Microsoft Visual C++
|
||||
//#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
#include <stdlib.h>
|
||||
#undef small
|
||||
//strcasecmp moved to globalDefinitions_visCPP.hpp
|
||||
//inline int strcasecmp(const char *s1, const char *s2) { return stricmp(s1,s2); }
|
||||
|
||||
|
||||
#elif defined(SPARC_WORKS)
|
||||
|
||||
#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#elif defined(SOLARIS)
|
||||
|
||||
#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#elif defined(__TANDEM)
|
||||
|
||||
// This case is for the Tandem Business Unit of Compaq Computer Corporation.
|
||||
// The Tandem case must precede the AT&T case,
|
||||
// because the Tandem c89 compiler also defines __cplusplus.
|
||||
|
||||
#include "port_tandem.hpp"
|
||||
|
||||
#elif defined(__cplusplus)
|
||||
// AT&Ts cfront
|
||||
#define INTERFACE
|
||||
#define IMPLEMENTATION
|
||||
#include <unistd.h>
|
||||
#define signed
|
||||
// #include <bstring.h>
|
||||
inline int min( int a, int b) { return a < b ? a : b; }
|
||||
inline int max( int a, int b) { return a > b ? a : b; }
|
||||
|
||||
#else // All other machines
|
||||
|
||||
#define signed
|
||||
extern "C" void bcopy(void *b1, void *b2, int len);
|
||||
inline int min( int a, int b) { return a < b ? a : b; }
|
||||
inline int max( int a, int b) { return a > b ? a : b; }
|
||||
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Safer memory allocations
|
||||
#ifdef SAFE_MEMORY
|
||||
#define malloc(size) safe_malloc(__FILE__,__LINE__,size)
|
||||
#define free(ptr) safe_free(__FILE__,__LINE__,ptr)
|
||||
#define realloc(ptr,size) safe_realloc(__FILE__,__LINE__,ptr,size)
|
||||
#define calloc(nitems,size) safe_calloc(__FILE__,__LINE__,nitems,size)
|
||||
#define strdup(ptr) safe_strdup(__FILE__,__LINE__,ptr)
|
||||
extern void *safe_malloc (const char *file, unsigned line, unsigned size);
|
||||
extern void safe_free (const char *file, unsigned line, void *ptr);
|
||||
extern void *safe_calloc (const char *file, unsigned line, unsigned nitems, unsigned size);
|
||||
extern void *safe_realloc(const char *file, unsigned line, void *ptr, unsigned size);
|
||||
extern char *safe_strdup (const char *file, unsigned line, const char *src);
|
||||
inline void *operator new( size_t size ) throw() { return malloc(size); }
|
||||
inline void operator delete( void *ptr ) { free(ptr); }
|
||||
#endif
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// And now, the bit-size-specified integer sizes
|
||||
typedef signed char int8;
|
||||
typedef unsigned char uint8;
|
||||
typedef unsigned char byte;
|
||||
|
||||
// All uses of *int16 changed to 32-bit to speed up compiler on Intel
|
||||
//typedef signed short int16; // Exactly 16bits signed
|
||||
//typedef unsigned short uint16; // Exactly 16bits unsigned
|
||||
//const unsigned int min_uint16 = 0x0000; // smallest uint16
|
||||
//const unsigned int max_uint16 = 0xFFFF; // largest uint16
|
||||
|
||||
typedef unsigned int uint; // When you need a fast >=16bit unsigned value
|
||||
/*typedef int int; */ // When you need a fast >=16bit value
|
||||
const unsigned int max_uint = (uint)-1;
|
||||
typedef int32_t int32; // Exactly 32bits signed
|
||||
typedef uint32_t uint32; // Exactly 32bits unsigned
|
||||
|
||||
// Bit-sized floating point and long thingies
|
||||
#ifndef __TANDEM
|
||||
// Do not define these for Tandem, because they conflict with typedefs in softieee.h.
|
||||
typedef float float32; // 32-bit float
|
||||
typedef double float64; // 64-bit float
|
||||
#endif // __TANDEM
|
||||
|
||||
typedef jlong int64; // Java long for my 64-bit type
|
||||
typedef julong uint64; // Java long for my 64-bit type
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Nice constants
|
||||
uint32 gcd( uint32 x, uint32 y );
|
||||
int ff1( uint32 mask );
|
||||
int fh1( uint32 mask );
|
||||
uint32 rotate32( uint32 x, int32 cnt );
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
extern uint32 heap_totalmem; // Current total memory allocation
|
||||
extern uint32 heap_highwater; // Highwater mark to date for memory usage
|
||||
|
||||
#endif // SHARE_VM_LIBADT_PORT_HPP
|
@ -28,20 +28,11 @@
|
||||
|
||||
// Sets - An Abstract Data Type
|
||||
|
||||
// %%%%% includes not needed with AVM framework - Ungar
|
||||
// #include "port.hpp"
|
||||
//IMPLEMENTATION
|
||||
// #include "set.hpp"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
// Not needed and it causes terouble for gcc.
|
||||
//
|
||||
// #include <iostream.h>
|
||||
|
||||
//-------------------------Virtual Functions-----------------------------------
|
||||
// These functions MUST be implemented by the inheriting class.
|
||||
class SparseSet;
|
||||
|
@ -25,13 +25,10 @@
|
||||
#ifndef SHARE_VM_LIBADT_SET_HPP
|
||||
#define SHARE_VM_LIBADT_SET_HPP
|
||||
|
||||
#include "libadt/port.hpp"
|
||||
#include "memory/allocation.hpp"
|
||||
|
||||
// Sets - An Abstract Data Type
|
||||
|
||||
//INTERFACE
|
||||
|
||||
class SparseSet;
|
||||
class VectorSet;
|
||||
class ListSet;
|
||||
|
@ -28,15 +28,10 @@
|
||||
|
||||
// Vector Sets - An Abstract Data Type
|
||||
|
||||
// %%%%% includes not needed with AVM framework - Ungar
|
||||
// #include "port.hpp"
|
||||
//IMPLEMENTATION
|
||||
// #include "vectset.hpp"
|
||||
|
||||
// BitsInByte is a lookup table which tells the number of bits that
|
||||
// are in the looked-up number. It is very useful in VectorSet_Size.
|
||||
|
||||
uint8 bitsInByte[256] = {
|
||||
uint8_t bitsInByte[256] = {
|
||||
0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5,
|
||||
@ -59,7 +54,7 @@ uint8 bitsInByte[256] = {
|
||||
// Create a new, empty Set.
|
||||
VectorSet::VectorSet(Arena *arena) : Set(arena) {
|
||||
size = 2; // Small initial size
|
||||
data = (uint32 *)_set_arena->Amalloc(size*sizeof(uint32));
|
||||
data = (uint32_t *)_set_arena->Amalloc(size*sizeof(uint32_t));
|
||||
data[0] = 0; // No elements
|
||||
data[1] = 0;
|
||||
}
|
||||
@ -85,8 +80,8 @@ Set &VectorSet::operator = (const Set &set)
|
||||
void VectorSet::slamin(const VectorSet& s)
|
||||
{
|
||||
size = s.size; // Use new size
|
||||
data = (uint32*)s._set_arena->Amalloc(size*sizeof(uint32)); // Make array of required size
|
||||
memcpy( data, s.data, size*sizeof(uint32) ); // Fill the array
|
||||
data = (uint32_t*)s._set_arena->Amalloc(size*sizeof(uint32_t)); // Make array of required size
|
||||
memcpy( data, s.data, size*sizeof(uint32_t) ); // Fill the array
|
||||
}
|
||||
|
||||
//------------------------------grow-------------------------------------------
|
||||
@ -96,8 +91,8 @@ void VectorSet::grow( uint newsize )
|
||||
newsize = (newsize+31) >> 5; // Convert to longwords
|
||||
uint x = size;
|
||||
while( x < newsize ) x <<= 1;
|
||||
data = (uint32 *)_set_arena->Arealloc(data, size*sizeof(uint32), x*sizeof(uint32));
|
||||
memset((char *)(data + size), 0, (x - size)*sizeof(uint32));
|
||||
data = (uint32_t *)_set_arena->Arealloc(data, size*sizeof(uint32_t), x*sizeof(uint32_t));
|
||||
memset((char *)(data + size), 0, (x - size)*sizeof(uint32_t));
|
||||
size = x;
|
||||
}
|
||||
|
||||
@ -106,7 +101,7 @@ void VectorSet::grow( uint newsize )
|
||||
Set &VectorSet::operator <<= (uint elem)
|
||||
{
|
||||
register uint word = elem >> 5; // Get the longword offset
|
||||
register uint32 mask = 1L << (elem & 31); // Get bit mask
|
||||
register uint32_t mask = 1L << (elem & 31); // Get bit mask
|
||||
|
||||
if( word >= size ) // Need to grow set?
|
||||
grow(elem+1); // Then grow it
|
||||
@ -121,7 +116,7 @@ Set &VectorSet::operator >>= (uint elem)
|
||||
register uint word = elem >> 5; // Get the longword offset
|
||||
if( word >= size ) // Beyond the last?
|
||||
return *this; // Then it's clear & return clear
|
||||
register uint32 mask = 1L << (elem & 31); // Get bit mask
|
||||
register uint32_t mask = 1L << (elem & 31); // Get bit mask
|
||||
data[word] &= ~mask; // Clear bit
|
||||
return *this;
|
||||
}
|
||||
@ -132,8 +127,8 @@ VectorSet &VectorSet::operator &= (const VectorSet &s)
|
||||
{
|
||||
// NOTE: The intersection is never any larger than the smallest set.
|
||||
if( s.size < size ) size = s.size; // Get smaller size
|
||||
register uint32 *u1 = data; // Pointer to the destination data
|
||||
register uint32 *u2 = s.data; // Pointer to the source data
|
||||
register uint32_t *u1 = data; // Pointer to the destination data
|
||||
register uint32_t *u2 = s.data; // Pointer to the source data
|
||||
for( uint i=0; i<size; i++) // For data in set
|
||||
*u1++ &= *u2++; // Copy and AND longwords
|
||||
return *this; // Return set
|
||||
@ -152,14 +147,14 @@ VectorSet &VectorSet::operator |= (const VectorSet &s)
|
||||
{
|
||||
// This many words must be unioned
|
||||
register uint cnt = ((size<s.size)?size:s.size);
|
||||
register uint32 *u1 = data; // Pointer to the destination data
|
||||
register uint32 *u2 = s.data; // Pointer to the source data
|
||||
register uint32_t *u1 = data; // Pointer to the destination data
|
||||
register uint32_t *u2 = s.data; // Pointer to the source data
|
||||
for( uint i=0; i<cnt; i++) // Copy and OR the two sets
|
||||
*u1++ |= *u2++;
|
||||
if( size < s.size ) { // Is set 2 larger than set 1?
|
||||
// Extend result by larger set
|
||||
grow(s.size*sizeof(uint32)*8);
|
||||
memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32));
|
||||
grow(s.size*sizeof(uint32_t)*8);
|
||||
memcpy(&data[cnt], u2, (s.size - cnt)*sizeof(uint32_t));
|
||||
}
|
||||
return *this; // Return result set
|
||||
}
|
||||
@ -177,8 +172,8 @@ VectorSet &VectorSet::operator -= (const VectorSet &s)
|
||||
{
|
||||
// This many words must be unioned
|
||||
register uint cnt = ((size<s.size)?size:s.size);
|
||||
register uint32 *u1 = data; // Pointer to the destination data
|
||||
register uint32 *u2 = s.data; // Pointer to the source data
|
||||
register uint32_t *u1 = data; // Pointer to the destination data
|
||||
register uint32_t *u2 = s.data; // Pointer to the source data
|
||||
for( uint i=0; i<cnt; i++ ) // For data in set
|
||||
*u1++ &= ~(*u2++); // A <-- A & ~B with longwords
|
||||
return *this; // Return new set
|
||||
@ -199,17 +194,17 @@ Set &VectorSet::operator -= (const Set &set)
|
||||
// 1X -- B is a subset of A
|
||||
int VectorSet::compare (const VectorSet &s) const
|
||||
{
|
||||
register uint32 *u1 = data; // Pointer to the destination data
|
||||
register uint32 *u2 = s.data; // Pointer to the source data
|
||||
register uint32 AnotB = 0, BnotA = 0;
|
||||
register uint32_t *u1 = data; // Pointer to the destination data
|
||||
register uint32_t *u2 = s.data; // Pointer to the source data
|
||||
register uint32_t AnotB = 0, BnotA = 0;
|
||||
// This many words must be unioned
|
||||
register uint cnt = ((size<s.size)?size:s.size);
|
||||
|
||||
// Get bits for both sets
|
||||
uint i; // Exit value of loop
|
||||
for( i=0; i<cnt; i++ ) { // For data in BOTH sets
|
||||
register uint32 A = *u1++; // Data from one guy
|
||||
register uint32 B = *u2++; // Data from other guy
|
||||
register uint32_t A = *u1++; // Data from one guy
|
||||
register uint32_t B = *u2++; // Data from other guy
|
||||
AnotB |= (A & ~B); // Compute bits in A not B
|
||||
BnotA |= (B & ~A); // Compute bits in B not A
|
||||
}
|
||||
@ -250,8 +245,8 @@ int VectorSet::disjoint(const Set &set) const
|
||||
|
||||
// NOTE: The intersection is never any larger than the smallest set.
|
||||
register uint small_size = ((size<s.size)?size:s.size);
|
||||
register uint32 *u1 = data; // Pointer to the destination data
|
||||
register uint32 *u2 = s.data; // Pointer to the source data
|
||||
register uint32_t *u1 = data; // Pointer to the destination data
|
||||
register uint32_t *u2 = s.data; // Pointer to the source data
|
||||
for( uint i=0; i<small_size; i++) // For data in set
|
||||
if( *u1++ & *u2++ ) // If any elements in common
|
||||
return 0; // Then not disjoint
|
||||
@ -293,7 +288,7 @@ int VectorSet::operator[](uint elem) const
|
||||
register uint word = elem >> 5; // Get the longword offset
|
||||
if( word >= size ) // Beyond the last?
|
||||
return 0; // Then it's clear
|
||||
register uint32 mask = 1L << (elem & 31); // Get bit mask
|
||||
register uint32_t mask = 1L << (elem & 31); // Get bit mask
|
||||
return ((data[word] & mask))!=0; // Return the sense of the bit
|
||||
}
|
||||
|
||||
@ -305,7 +300,7 @@ uint VectorSet::getelem(void) const
|
||||
for( i=0; i<size; i++ )
|
||||
if( data[i] )
|
||||
break;
|
||||
uint32 word = data[i];
|
||||
uint32_t word = data[i];
|
||||
int j; // Exit value of loop
|
||||
for( j= -1; word; j++, word>>=1 );
|
||||
return (i<<5)+j;
|
||||
@ -316,11 +311,11 @@ uint VectorSet::getelem(void) const
|
||||
void VectorSet::Clear(void)
|
||||
{
|
||||
if( size > 100 ) { // Reclaim storage only if huge
|
||||
FREE_RESOURCE_ARRAY(uint32,data,size);
|
||||
FREE_RESOURCE_ARRAY(uint32_t,data,size);
|
||||
size = 2; // Small initial size
|
||||
data = NEW_RESOURCE_ARRAY(uint32,size);
|
||||
data = NEW_RESOURCE_ARRAY(uint32_t,size);
|
||||
}
|
||||
memset( data, 0, size*sizeof(uint32) );
|
||||
memset( data, 0, size*sizeof(uint32_t) );
|
||||
}
|
||||
|
||||
//------------------------------Size-------------------------------------------
|
||||
@ -328,8 +323,8 @@ void VectorSet::Clear(void)
|
||||
uint VectorSet::Size(void) const
|
||||
{
|
||||
uint sum = 0; // Cumulative size so far.
|
||||
uint8 *currByte = (uint8*)data;
|
||||
for( uint32 i = 0; i < (size<<2); i++) // While have bytes to process
|
||||
uint8_t* currByte = (uint8_t*) data;
|
||||
for( uint32_t i = 0; i < (size<<2); i++) // While have bytes to process
|
||||
sum += bitsInByte[*currByte++]; // Add bits in current byte to size.
|
||||
return sum;
|
||||
}
|
||||
@ -343,7 +338,7 @@ void VectorSet::Sort(void)
|
||||
//------------------------------hash-------------------------------------------
|
||||
int VectorSet::hash() const
|
||||
{
|
||||
uint32 _xor = 0;
|
||||
uint32_t _xor = 0;
|
||||
uint lim = ((size<4)?size:4);
|
||||
for( uint i = 0; i < lim; i++ )
|
||||
_xor ^= data[i];
|
||||
|
@ -47,7 +47,7 @@ class VectorSet : public Set {
|
||||
friend class VectorSetI; // Friendly iterator class
|
||||
protected:
|
||||
uint size; // Size of data IN LONGWORDS (32bits)
|
||||
uint32 *data; // The data, bit packed
|
||||
uint32_t* data; // The data, bit packed
|
||||
|
||||
void slamin( const VectorSet& s ); // Initialize one set with another
|
||||
int compare(const VectorSet &s) const; // Compare set contents
|
||||
@ -99,7 +99,7 @@ public:
|
||||
void Sort(void); // Sort before iterating
|
||||
int hash() const; // Hash function
|
||||
void Reset(void) { // Reset a set
|
||||
memset( data, 0, size*sizeof(uint32) );
|
||||
memset( data, 0, size*sizeof(uint32_t) );
|
||||
}
|
||||
|
||||
/* Removed for MCC BUG
|
||||
@ -108,7 +108,7 @@ public:
|
||||
|
||||
// Expose internals for speed-critical fast iterators
|
||||
uint word_size() const { return size; }
|
||||
uint32 *EXPOSE() const { return data; }
|
||||
uint32_t* EXPOSE() const { return data; }
|
||||
|
||||
// Fast inlined "test and set". Replaces the idiom:
|
||||
// if( visited[idx] ) return;
|
||||
@ -120,8 +120,8 @@ public:
|
||||
uint word = elem >> 5; // Get the longword offset
|
||||
if( word >= size ) // Beyond the last?
|
||||
return test_set_grow(elem); // Then grow; set; return 0;
|
||||
uint32 mask = 1L << (elem & 31); // Get bit mask
|
||||
uint32 datum = data[word] & mask;// Get bit
|
||||
uint32_t mask = 1L << (elem & 31); // Get bit mask
|
||||
uint32_t datum = data[word] & mask;// Get bit
|
||||
data[word] |= mask; // Set bit
|
||||
return datum; // Return bit
|
||||
}
|
||||
@ -134,7 +134,7 @@ public:
|
||||
int test( uint elem ) const {
|
||||
uint word = elem >> 5; // Get the longword offset
|
||||
if( word >= size ) return 0; // Beyond the last?
|
||||
uint32 mask = 1L << (elem & 31); // Get bit mask
|
||||
uint32_t mask = 1L << (elem & 31); // Get bit mask
|
||||
return data[word] & mask; // Get bit
|
||||
}
|
||||
|
||||
@ -144,7 +144,7 @@ public:
|
||||
if( word >= size ) { // Beyond the last?
|
||||
test_set_grow(elem); // Then grow and set
|
||||
} else {
|
||||
uint32 mask = 1L << (elem & 31); // Get bit mask
|
||||
uint32_t mask = 1L << (elem & 31); // Get bit mask
|
||||
data[word] |= mask; // Set bit
|
||||
}
|
||||
}
|
||||
@ -164,7 +164,7 @@ class VectorSetI : public StackObj {
|
||||
friend class VectorSet;
|
||||
const VectorSet *s;
|
||||
uint i, j;
|
||||
uint32 mask;
|
||||
uint32_t mask;
|
||||
uint next(void);
|
||||
|
||||
public:
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/metadataOnStackMark.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "interpreter/linkResolver.hpp"
|
||||
|
@ -1268,7 +1268,6 @@ void UnionFind::extend( uint from_idx, uint to_idx ) {
|
||||
}
|
||||
|
||||
void UnionFind::reset( uint max ) {
|
||||
assert( max <= max_uint, "Must fit within uint" );
|
||||
// Force the Union-Find mapping to be at least this large
|
||||
extend(max,0);
|
||||
// Initialize to be the ID mapping.
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define SHARE_VM_OPTO_CHAITIN_HPP
|
||||
|
||||
#include "code/vmreg.hpp"
|
||||
#include "libadt/port.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "opto/connode.hpp"
|
||||
#include "opto/live.hpp"
|
||||
@ -142,7 +141,7 @@ public:
|
||||
|
||||
// Number of registers this live range uses when it colors
|
||||
private:
|
||||
uint8 _num_regs; // 2 for Longs and Doubles, 1 for all else
|
||||
uint8_t _num_regs; // 2 for Longs and Doubles, 1 for all else
|
||||
// except _num_regs is kill count for fat_proj
|
||||
public:
|
||||
int num_regs() const { return _num_regs; }
|
||||
@ -151,7 +150,7 @@ public:
|
||||
private:
|
||||
// Number of physical registers this live range uses when it colors
|
||||
// Architecture and register-set dependent
|
||||
uint8 _reg_pressure;
|
||||
uint8_t _reg_pressure;
|
||||
public:
|
||||
void set_reg_pressure(int i) { _reg_pressure = i; }
|
||||
int reg_pressure() const { return _reg_pressure; }
|
||||
|
@ -32,7 +32,6 @@
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "libadt/dict.hpp"
|
||||
#include "libadt/port.hpp"
|
||||
#include "libadt/vectset.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
#include "opto/idealGraphPrinter.hpp"
|
||||
|
@ -514,7 +514,7 @@ const Type *DivINode::Value( PhaseTransform *phase ) const {
|
||||
int widen = MAX2(i1->_widen, i2->_widen);
|
||||
|
||||
if( i2->is_con() && i2->get_con() != 0 ) {
|
||||
int32 d = i2->get_con(); // Divisor
|
||||
int32_t d = i2->get_con(); // Divisor
|
||||
jint lo, hi;
|
||||
if( d >= 0 ) {
|
||||
lo = i1->_lo/d;
|
||||
@ -536,7 +536,7 @@ const Type *DivINode::Value( PhaseTransform *phase ) const {
|
||||
|
||||
// If the dividend is a constant
|
||||
if( i1->is_con() ) {
|
||||
int32 d = i1->get_con();
|
||||
int32_t d = i1->get_con();
|
||||
if( d < 0 ) {
|
||||
if( d == min_jint ) {
|
||||
// (-min_jint) == min_jint == (min_jint / -1)
|
||||
|
@ -397,8 +397,9 @@ void PhaseIdealLoop::Dominators() {
|
||||
ntarjan[i]._control = NULL;
|
||||
|
||||
// Store the DFS order for the main loop
|
||||
const uint fill_value = max_juint;
|
||||
uint *dfsorder = NEW_RESOURCE_ARRAY(uint,C->unique()+1);
|
||||
memset(dfsorder, max_uint, (C->unique()+1) * sizeof(uint));
|
||||
memset(dfsorder, fill_value, (C->unique()+1) * sizeof(uint));
|
||||
|
||||
// Tarjan's algorithm, almost verbatim:
|
||||
// Step 1:
|
||||
@ -419,7 +420,7 @@ void PhaseIdealLoop::Dominators() {
|
||||
if( whead->in(j) == NULL || !whead->in(j)->is_CFG() )
|
||||
continue; // Only process control nodes
|
||||
uint b = dfsorder[whead->in(j)->_idx];
|
||||
if(b == max_uint) continue;
|
||||
if(b == fill_value) continue;
|
||||
NTarjan *vx = &ntarjan[b];
|
||||
NTarjan *u = vx->EVAL();
|
||||
if( u->_semi < w->_semi )
|
||||
|
@ -51,7 +51,7 @@ int IndexSet::_serial_count = 1;
|
||||
#endif
|
||||
|
||||
// What is the first set bit in a 5 bit integer?
|
||||
const byte IndexSetIterator::_first_bit[32] = {
|
||||
const uint8_t IndexSetIterator::_first_bit[32] = {
|
||||
0, 0, 1, 0,
|
||||
2, 0, 1, 0,
|
||||
3, 0, 1, 0,
|
||||
@ -63,7 +63,7 @@ const byte IndexSetIterator::_first_bit[32] = {
|
||||
};
|
||||
|
||||
// What is the second set bit in a 5 bit integer?
|
||||
const byte IndexSetIterator::_second_bit[32] = {
|
||||
const uint8_t IndexSetIterator::_second_bit[32] = {
|
||||
5, 5, 5, 1,
|
||||
5, 2, 2, 1,
|
||||
5, 3, 3, 1,
|
||||
@ -298,7 +298,7 @@ IndexSet::IndexSet (IndexSet *set) {
|
||||
set_block(i, &_empty_block);
|
||||
} else {
|
||||
BitBlock *new_block = alloc_block();
|
||||
memcpy(new_block->words(), block->words(), sizeof(uint32) * words_per_block);
|
||||
memcpy(new_block->words(), block->words(), sizeof(uint32_t) * words_per_block);
|
||||
set_block(i, new_block);
|
||||
}
|
||||
}
|
||||
|
@ -106,12 +106,12 @@ class IndexSet : public ResourceObj {
|
||||
// is used by IndexSet to mainting this free list.
|
||||
|
||||
union {
|
||||
uint32 _words[words_per_block];
|
||||
uint32_t _words[words_per_block];
|
||||
BitBlock *_next;
|
||||
} _data;
|
||||
|
||||
// accessors
|
||||
uint32 *words() { return _data._words; }
|
||||
uint32_t* words() { return _data._words; }
|
||||
void set_next(BitBlock *next) { _data._next = next; }
|
||||
BitBlock *next() { return _data._next; }
|
||||
|
||||
@ -120,22 +120,22 @@ class IndexSet : public ResourceObj {
|
||||
// not assume that the block index has been masked out.
|
||||
|
||||
void clear() {
|
||||
memset(words(), 0, sizeof(uint32) * words_per_block);
|
||||
memset(words(), 0, sizeof(uint32_t) * words_per_block);
|
||||
}
|
||||
|
||||
bool member(uint element) {
|
||||
uint word_index = IndexSet::get_word_index(element);
|
||||
uint bit_index = IndexSet::get_bit_index(element);
|
||||
|
||||
return ((words()[word_index] & (uint32)(0x1 << bit_index)) != 0);
|
||||
return ((words()[word_index] & (uint32_t)(0x1 << bit_index)) != 0);
|
||||
}
|
||||
|
||||
bool insert(uint element) {
|
||||
uint word_index = IndexSet::get_word_index(element);
|
||||
uint bit_index = IndexSet::get_bit_index(element);
|
||||
|
||||
uint32 bit = (0x1 << bit_index);
|
||||
uint32 before = words()[word_index];
|
||||
uint32_t bit = (0x1 << bit_index);
|
||||
uint32_t before = words()[word_index];
|
||||
words()[word_index] = before | bit;
|
||||
return ((before & bit) != 0);
|
||||
}
|
||||
@ -144,8 +144,8 @@ class IndexSet : public ResourceObj {
|
||||
uint word_index = IndexSet::get_word_index(element);
|
||||
uint bit_index = IndexSet::get_bit_index(element);
|
||||
|
||||
uint32 bit = (0x1 << bit_index);
|
||||
uint32 before = words()[word_index];
|
||||
uint32_t bit = (0x1 << bit_index);
|
||||
uint32_t before = words()[word_index];
|
||||
words()[word_index] = before & ~bit;
|
||||
return ((before & bit) != 0);
|
||||
}
|
||||
@ -404,14 +404,14 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
|
||||
table_size = (1 << window_size) };
|
||||
|
||||
// For an integer of length window_size, what is the first set bit?
|
||||
static const byte _first_bit[table_size];
|
||||
static const uint8_t _first_bit[table_size];
|
||||
|
||||
// For an integer of length window_size, what is the second set bit?
|
||||
static const byte _second_bit[table_size];
|
||||
static const uint8_t _second_bit[table_size];
|
||||
|
||||
private:
|
||||
// The current word we are inspecting
|
||||
uint32 _current;
|
||||
uint32_t _current;
|
||||
|
||||
// What element number are we currently on?
|
||||
uint _value;
|
||||
@ -420,7 +420,7 @@ class IndexSetIterator VALUE_OBJ_CLASS_SPEC {
|
||||
uint _next_word;
|
||||
|
||||
// A pointer to the contents of the current block
|
||||
uint32 *_words;
|
||||
uint32_t *_words;
|
||||
|
||||
// The index of the next block we will inspect
|
||||
uint _next_block;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef SHARE_VM_OPTO_LIVE_HPP
|
||||
#define SHARE_VM_OPTO_LIVE_HPP
|
||||
|
||||
#include "libadt/port.hpp"
|
||||
#include "libadt/vectset.hpp"
|
||||
#include "opto/block.hpp"
|
||||
#include "opto/indexSet.hpp"
|
||||
|
@ -339,8 +339,8 @@ public:
|
||||
|
||||
Node_List _body; // Loop body for inner loops
|
||||
|
||||
uint8 _nest; // Nesting depth
|
||||
uint8 _irreducible:1, // True if irreducible
|
||||
uint8_t _nest; // Nesting depth
|
||||
uint8_t _irreducible:1, // True if irreducible
|
||||
_has_call:1, // True if has call safepoint
|
||||
_has_sfpt:1, // True if has non-call safepoint
|
||||
_rce_candidate:1; // True if candidate for range check elimination
|
||||
|
@ -235,23 +235,23 @@ const Type *MulINode::mul_ring(const Type *t0, const Type *t1) const {
|
||||
const TypeInt *r1 = t1->is_int();
|
||||
|
||||
// Fetch endpoints of all ranges
|
||||
int32 lo0 = r0->_lo;
|
||||
int32_t lo0 = r0->_lo;
|
||||
double a = (double)lo0;
|
||||
int32 hi0 = r0->_hi;
|
||||
int32_t hi0 = r0->_hi;
|
||||
double b = (double)hi0;
|
||||
int32 lo1 = r1->_lo;
|
||||
int32_t lo1 = r1->_lo;
|
||||
double c = (double)lo1;
|
||||
int32 hi1 = r1->_hi;
|
||||
int32_t hi1 = r1->_hi;
|
||||
double d = (double)hi1;
|
||||
|
||||
// Compute all endpoints & check for overflow
|
||||
int32 A = lo0*lo1;
|
||||
int32_t A = lo0*lo1;
|
||||
if( (double)A != a*c ) return TypeInt::INT; // Overflow?
|
||||
int32 B = lo0*hi1;
|
||||
int32_t B = lo0*hi1;
|
||||
if( (double)B != a*d ) return TypeInt::INT; // Overflow?
|
||||
int32 C = hi0*lo1;
|
||||
int32_t C = hi0*lo1;
|
||||
if( (double)C != b*c ) return TypeInt::INT; // Overflow?
|
||||
int32 D = hi0*hi1;
|
||||
int32_t D = hi0*hi1;
|
||||
if( (double)D != b*d ) return TypeInt::INT; // Overflow?
|
||||
|
||||
if( A < B ) { lo0 = A; hi0 = B; } // Sort range endpoints
|
||||
@ -1228,12 +1228,12 @@ const Type *URShiftINode::Value( PhaseTransform *phase ) const {
|
||||
//
|
||||
// const TypeInstPtr *o = t1->is_instptr();
|
||||
// if( t1->singleton() )
|
||||
// return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift );
|
||||
// return TypeInt::make( ((uint32_t)o->const_oop() + o->_offset) >> shift );
|
||||
// }
|
||||
// else if( t1->base() == Type::KlassPtr ) {
|
||||
// const TypeKlassPtr *o = t1->is_klassptr();
|
||||
// if( t1->singleton() )
|
||||
// return TypeInt::make( ((uint32)o->const_oop() + o->_offset) >> shift );
|
||||
// return TypeInt::make( ((uint32_t)o->const_oop() + o->_offset) >> shift );
|
||||
// }
|
||||
|
||||
return TypeInt::INT;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef SHARE_VM_OPTO_NODE_HPP
|
||||
#define SHARE_VM_OPTO_NODE_HPP
|
||||
|
||||
#include "libadt/port.hpp"
|
||||
#include "libadt/vectset.hpp"
|
||||
#include "opto/compile.hpp"
|
||||
#include "opto/type.hpp"
|
||||
|
@ -366,8 +366,8 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
|
||||
// third inserts nops where needed.
|
||||
|
||||
// Step one, perform a pessimistic sizing pass.
|
||||
uint last_call_adr = max_uint;
|
||||
uint last_avoid_back_to_back_adr = max_uint;
|
||||
uint last_call_adr = max_juint;
|
||||
uint last_avoid_back_to_back_adr = max_juint;
|
||||
uint nop_size = (new (this) MachNopNode())->size(_regalloc);
|
||||
for (uint i = 0; i < nblocks; i++) { // For all blocks
|
||||
Block* block = _cfg->get_block(i);
|
||||
@ -479,7 +479,7 @@ void Compile::shorten_branches(uint* blk_starts, int& code_size, int& reloc_size
|
||||
|
||||
// Step two, replace eligible long jumps.
|
||||
bool progress = true;
|
||||
uint last_may_be_short_branch_adr = max_uint;
|
||||
uint last_may_be_short_branch_adr = max_juint;
|
||||
while (has_short_branch_candidate && progress) {
|
||||
progress = false;
|
||||
has_short_branch_candidate = false;
|
||||
|
@ -405,9 +405,9 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi)
|
||||
|
||||
bool needs_guard = false;
|
||||
int default_dest;
|
||||
int64 total_outlier_size = 0;
|
||||
int64 hi_size = ((int64)hi->hi()) - ((int64)hi->lo()) + 1;
|
||||
int64 lo_size = ((int64)lo->hi()) - ((int64)lo->lo()) + 1;
|
||||
int64_t total_outlier_size = 0;
|
||||
int64_t hi_size = ((int64_t)hi->hi()) - ((int64_t)hi->lo()) + 1;
|
||||
int64_t lo_size = ((int64_t)lo->hi()) - ((int64_t)lo->lo()) + 1;
|
||||
|
||||
if (lo->dest() == hi->dest()) {
|
||||
total_outlier_size = hi_size + lo_size;
|
||||
@ -429,7 +429,7 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi)
|
||||
}
|
||||
|
||||
// Find the total number of cases and ranges
|
||||
int64 num_cases = ((int64)hi->hi()) - ((int64)lo->lo()) + 1;
|
||||
int64_t num_cases = ((int64_t)hi->hi()) - ((int64_t)lo->lo()) + 1;
|
||||
int num_range = hi - lo + 1;
|
||||
|
||||
// Don't create table if: too large, too small, or too sparse.
|
||||
@ -473,7 +473,7 @@ bool Parse::create_jump_tables(Node* key_val, SwitchRange* lo, SwitchRange* hi)
|
||||
// These are the switch destinations hanging off the jumpnode
|
||||
int i = 0;
|
||||
for (SwitchRange* r = lo; r <= hi; r++) {
|
||||
for (int64 j = r->lo(); j <= r->hi(); j++, i++) {
|
||||
for (int64_t j = r->lo(); j <= r->hi(); j++, i++) {
|
||||
Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), (int)(j - lowval)));
|
||||
{
|
||||
PreserveJVMState pjvms(this);
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef SHARE_VM_OPTO_PHASE_HPP
|
||||
#define SHARE_VM_OPTO_PHASE_HPP
|
||||
|
||||
#include "libadt/port.hpp"
|
||||
#include "runtime/timer.hpp"
|
||||
|
||||
class Compile;
|
||||
|
@ -51,7 +51,7 @@
|
||||
|
||||
//-------------Non-zero bit search methods used by RegMask---------------------
|
||||
// Find lowest 1, or return 32 if empty
|
||||
int find_lowest_bit( uint32 mask ) {
|
||||
int find_lowest_bit( uint32_t mask ) {
|
||||
int n = 0;
|
||||
if( (mask & 0xffff) == 0 ) {
|
||||
mask >>= 16;
|
||||
@ -80,7 +80,7 @@ int find_lowest_bit( uint32 mask ) {
|
||||
}
|
||||
|
||||
// Find highest 1, or return 32 if empty
|
||||
int find_hihghest_bit( uint32 mask ) {
|
||||
int find_hihghest_bit( uint32_t mask ) {
|
||||
int n = 0;
|
||||
if( mask > 0xffff ) {
|
||||
mask >>= 16;
|
||||
@ -395,7 +395,7 @@ bool RegMask::is_UP() const {
|
||||
//------------------------------Size-------------------------------------------
|
||||
// Compute size of register mask in bits
|
||||
uint RegMask::Size() const {
|
||||
extern uint8 bitsInByte[256];
|
||||
extern uint8_t bitsInByte[256];
|
||||
uint sum = 0;
|
||||
for( int i = 0; i < RM_SIZE; i++ )
|
||||
sum +=
|
||||
|
@ -26,7 +26,6 @@
|
||||
#define SHARE_VM_OPTO_REGMASK_HPP
|
||||
|
||||
#include "code/vmreg.hpp"
|
||||
#include "libadt/port.hpp"
|
||||
#include "opto/optoreg.hpp"
|
||||
#ifdef TARGET_ARCH_MODEL_x86_32
|
||||
# include "adfiles/adGlobals_x86_32.hpp"
|
||||
@ -68,9 +67,9 @@
|
||||
|
||||
//-------------Non-zero bit search methods used by RegMask---------------------
|
||||
// Find lowest 1, or return 32 if empty
|
||||
int find_lowest_bit( uint32 mask );
|
||||
int find_lowest_bit( uint32_t mask );
|
||||
// Find highest 1, or return 32 if empty
|
||||
int find_hihghest_bit( uint32 mask );
|
||||
int find_hihghest_bit( uint32_t mask );
|
||||
|
||||
//------------------------------RegMask----------------------------------------
|
||||
// The ADL file describes how to print the machine-specific registers, as well
|
||||
|
@ -960,7 +960,7 @@ JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* r
|
||||
} else {
|
||||
// Receiver did not match any saved receiver and there is no empty row for it.
|
||||
// Increment total counter to indicate polymorphic case.
|
||||
intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset()));
|
||||
intptr_t* count_p = (intptr_t*)(((uint8_t*)(data)) + in_bytes(CounterData::count_offset()));
|
||||
*count_p += DataLayout::counter_increment;
|
||||
}
|
||||
JRT_END
|
||||
|
@ -242,8 +242,8 @@ Node *SubINode::Ideal(PhaseGVN *phase, bool can_reshape){
|
||||
const Type *SubINode::sub( const Type *t1, const Type *t2 ) const {
|
||||
const TypeInt *r0 = t1->is_int(); // Handy access
|
||||
const TypeInt *r1 = t2->is_int();
|
||||
int32 lo = r0->_lo - r1->_hi;
|
||||
int32 hi = r0->_hi - r1->_lo;
|
||||
int32_t lo = r0->_lo - r1->_hi;
|
||||
int32_t hi = r0->_hi - r1->_lo;
|
||||
|
||||
// We next check for 32-bit overflow.
|
||||
// If that happens, we just assume all integers are possible.
|
||||
|
@ -25,7 +25,6 @@
|
||||
#ifndef SHARE_VM_OPTO_TYPE_HPP
|
||||
#define SHARE_VM_OPTO_TYPE_HPP
|
||||
|
||||
#include "libadt/port.hpp"
|
||||
#include "opto/adlcVMDeps.hpp"
|
||||
#include "runtime/handles.hpp"
|
||||
|
||||
|
@ -247,7 +247,6 @@
|
||||
# include "utilities/yieldingWorkgroup.hpp"
|
||||
#ifdef COMPILER2
|
||||
# include "libadt/dict.hpp"
|
||||
# include "libadt/port.hpp"
|
||||
# include "libadt/set.hpp"
|
||||
# include "libadt/vectset.hpp"
|
||||
# include "opto/addnode.hpp"
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/javaAssertions.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
#include "gc_interface/collectedHeap.inline.hpp"
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
#include "interpreter/interpreter.hpp"
|
||||
#include "interpreter/oopMapCache.hpp"
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "memory/universe.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/classLoaderData.hpp"
|
||||
|
||||
#include "prims/whitebox.hpp"
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/javaAssertions.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "compiler/compilerOracle.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
#include "gc_interface/collectedHeap.hpp"
|
||||
#include "interpreter/bytecodes.hpp"
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/classLoader.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "compiler/compileBroker.hpp"
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "classfile/verifier.hpp"
|
||||
#include "classfile/vmSymbols.hpp"
|
||||
|
@ -23,7 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/symbolTable.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "code/codeCache.hpp"
|
||||
#include "code/icBuffer.hpp"
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/loaderConstraints.hpp"
|
||||
#include "classfile/placeholders.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "classfile/systemDictionary.hpp"
|
||||
#include "ci/ciField.hpp"
|
||||
#include "ci/ciInstance.hpp"
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "precompiled.hpp"
|
||||
#include "classfile/altHashing.hpp"
|
||||
#include "classfile/javaClasses.hpp"
|
||||
#include "classfile/stringTable.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "memory/filemap.hpp"
|
||||
#include "memory/resourceArea.hpp"
|
||||
|
@ -66,7 +66,6 @@ needs_jdk = \
|
||||
gc/metaspace/TestMetaspacePerfCounters.java \
|
||||
gc/metaspace/TestPerfCountersAndMemoryPools.java \
|
||||
runtime/6819213/TestBootNativeLibraryPath.java \
|
||||
runtime/6925573/SortMethodsTest.java \
|
||||
runtime/7158988/FieldMonitor.java \
|
||||
runtime/7194254/Test7194254.java \
|
||||
runtime/Metaspace/FragmentMetaspace.java \
|
||||
|
Loading…
Reference in New Issue
Block a user