Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/hotspot/share/c1/c1_Instruction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,14 +137,16 @@ bool Instruction::maybe_flat_array() {
if (UseArrayFlattening) {
ciType* type = declared_type();
if (type != nullptr) {
if (type->is_obj_array_klass()) {
// Due to array covariance, the runtime type might be a flat array.
if (type->is_ref_array_klass()) {
return false;
} else if (type->is_flat_array_klass()) {
return true;
} else if (type->is_obj_array_klass()) {
// This is the unrefined array type
ciKlass* element_klass = type->as_obj_array_klass()->element_klass();
if (element_klass->can_be_inline_klass() && (!element_klass->is_inlinetype() || element_klass->as_inline_klass()->maybe_flat_in_array())) {
return true;
}
} else if (type->is_flat_array_klass()) {
return true;
} else if (type->is_klass() && type->as_klass()->is_java_lang_Object()) {
// This can happen as a parameter to System.arraycopy()
return true;
Expand Down
4 changes: 1 addition & 3 deletions src/hotspot/share/ci/ciArrayKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,12 @@ ciType* ciArrayKlass::element_type() {
ciType* ciArrayKlass::base_element_type() {
if (is_type_array_klass()) {
return ciType::make(as_type_array_klass()->element_type());
} else if (is_obj_array_klass()) {
} else {
ciKlass* ek = as_obj_array_klass()->base_element_klass();
if (ek->is_type_array_klass()) {
return ciType::make(ek->as_type_array_klass()->element_type());
}
return ek;
} else {
return as_flat_array_klass()->base_element_klass();
}
}

Expand Down
3 changes: 2 additions & 1 deletion src/hotspot/share/ci/ciClassList.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,9 @@ class ciKlass;
class ciInstanceKlass;
class ciInlineKlass;
class ciArrayKlass;
class ciFlatArrayKlass;
class ciObjArrayKlass;
class ciFlatArrayKlass;
class ciRefArrayKlass;
class ciTypeArrayKlass;

// Simulate Java Language style package-private access with
Expand Down
9 changes: 7 additions & 2 deletions src/hotspot/share/ci/ciEnv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,13 +199,18 @@ class ciEnv : StackObj {
if (o == nullptr) return nullptr;
return get_object(o)->as_instance();
}
ciObjArrayKlass* get_obj_array_klass(Klass* o) {
if (o == nullptr) return nullptr;
assert(o->is_objArray_klass() && !o->is_flatArray_klass() && !o->is_refArray_klass(), "must be exact");
return get_metadata(o)->as_obj_array_klass();
}
ciFlatArrayKlass* get_flat_array_klass(Klass* o) {
if (o == nullptr) return nullptr;
return get_metadata(o)->as_flat_array_klass();
}
ciObjArrayKlass* get_obj_array_klass(Klass* o) {
ciRefArrayKlass* get_ref_array_klass(Klass* o) {
if (o == nullptr) return nullptr;
return get_metadata(o)->as_obj_array_klass();
return get_metadata(o)->as_ref_array_klass();
}
ciTypeArrayKlass* get_type_array_klass(Klass* o) {
if (o == nullptr) return nullptr;
Expand Down
78 changes: 0 additions & 78 deletions src/hotspot/share/ci/ciFlatArrayKlass.cpp

This file was deleted.

37 changes: 13 additions & 24 deletions src/hotspot/share/ci/ciFlatArrayKlass.hpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2025, 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
Expand All @@ -25,56 +25,45 @@
#ifndef SHARE_VM_CI_CIFLATARRAYKLASS_HPP
#define SHARE_VM_CI_CIFLATARRAYKLASS_HPP

#include "ci/ciArrayKlass.hpp"
#include "ci/ciInlineKlass.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "oops/flatArrayKlass.hpp"

// ciFlatArrayKlass
//
// This class represents a Klass* in the HotSpot virtual machine
// whose Klass part is a FlatArrayKlass.
class ciFlatArrayKlass : public ciArrayKlass {
class ciFlatArrayKlass : public ciObjArrayKlass {
CI_PACKAGE_ACCESS
friend class ciEnv;

private:
ciKlass* _element_klass;
ciKlass* _base_element_klass;

protected:
ciFlatArrayKlass(Klass* h_k);
ciFlatArrayKlass(Klass* k) : ciObjArrayKlass(k) {
assert(k->is_flatArray_klass(), "wrong type");
}

const FlatArrayKlass* get_FlatArrayKlass() const {
return FlatArrayKlass::cast(get_Klass());
}

const char* type_string() { return "ciFlatArrayKlass"; }

oop loader() { return _base_element_klass->loader(); }
jobject loader_handle() { return _base_element_klass->loader_handle(); }
virtual const char* type_string() override { return "ciFlatArrayKlass"; }

public:
LayoutKind layout_kind() const { return get_FlatArrayKlass()->layout_kind(); }

// The one-level type of the array elements.
ciKlass* element_klass();

int log2_element_size() {
return Klass::layout_helper_log2_element_size(layout_helper());
}
int element_byte_size() { return 1 << log2_element_size(); }

// The innermost type of the array elements.
ciKlass* base_element_klass() { return _base_element_klass; }
int element_byte_size() { return 1 << log2_element_size(); }

// What kind of ciObject is this?
bool is_flat_array_klass() const { return true; }
virtual bool is_flat_array_klass() const override { return true; }

virtual ciKlass* exact_klass();

virtual bool can_be_inline_array_klass() {
return true;
virtual ciKlass* exact_klass() override {
assert(element_klass()->as_inline_klass()->exact_klass() != nullptr, "must have exact klass");
return this;
}
};


#endif // SHARE_VM_CI_CIFLATARRAYKLASS_HPP
13 changes: 9 additions & 4 deletions src/hotspot/share/ci/ciMetadata.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ class ciMetadata: public ciBaseObject {
virtual bool is_instance_klass() const { return false; }
virtual bool is_inlinetype() const { return false; }
virtual bool is_array_klass() const { return false; }
virtual bool is_flat_array_klass() const { return false; }
virtual bool is_obj_array_klass() const { return false; }
virtual bool is_flat_array_klass() const { return false; }
virtual bool is_ref_array_klass() const { return false; }
virtual bool is_type_array_klass() const { return false; }
virtual bool is_early_larval() const { return false; }
virtual bool maybe_flat_in_array() const { return false; }
Expand Down Expand Up @@ -96,13 +97,17 @@ class ciMetadata: public ciBaseObject {
assert(is_array_klass(), "bad cast");
return (ciArrayKlass*)this;
}
ciObjArrayKlass* as_obj_array_klass() {
assert(is_obj_array_klass(), "bad cast");
return (ciObjArrayKlass*)this;
}
ciFlatArrayKlass* as_flat_array_klass() {
assert(is_flat_array_klass(), "bad cast");
return (ciFlatArrayKlass*)this;
}
ciObjArrayKlass* as_obj_array_klass() {
assert(is_obj_array_klass(), "bad cast");
return (ciObjArrayKlass*)this;
ciRefArrayKlass* as_ref_array_klass() {
assert(is_ref_array_klass(), "bad cast");
return (ciRefArrayKlass*)this;
}
ciTypeArrayKlass* as_type_array_klass() {
assert(is_type_array_klass(), "bad cast");
Expand Down
54 changes: 21 additions & 33 deletions src/hotspot/share/ci/ciObjArrayKlass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,10 @@
#include "ci/ciFlatArrayKlass.hpp"
#include "ci/ciInstanceKlass.hpp"
#include "ci/ciObjArrayKlass.hpp"
#include "ci/ciRefArrayKlass.hpp"
#include "ci/ciSymbol.hpp"
#include "ci/ciUtilities.hpp"
#include "ci/ciUtilities.inline.hpp"
#include "oops/inlineKlass.inline.hpp"
#include "oops/objArrayKlass.hpp"
#include "runtime/signature.hpp"

Expand Down Expand Up @@ -68,7 +69,8 @@ ciObjArrayKlass::ciObjArrayKlass(ciSymbol* array_name,
_base_element_klass = base_element_klass;
assert(_base_element_klass->is_instance_klass() ||
_base_element_klass->is_type_array_klass() ||
_base_element_klass->is_flat_array_klass(), "bad base klass");
_base_element_klass->is_flat_array_klass() ||
_base_element_klass->is_ref_array_klass(), "bad base klass");
if (dimension == 1) {
_element_klass = base_element_klass;
} else {
Expand Down Expand Up @@ -135,7 +137,7 @@ ciSymbol* ciObjArrayKlass::construct_array_name(ciSymbol* element_name,
// ciObjArrayKlass::make_impl
//
// Implementation of make.
ciArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass, bool refined_type, bool null_free, bool atomic) {
ciObjArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass, bool refined_type, bool null_free, bool atomic) {
if (element_klass->is_loaded()) {
EXCEPTION_CONTEXT;
// The element klass is loaded
Expand All @@ -145,22 +147,24 @@ ciArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass, bool refined_ty
CURRENT_THREAD_ENV->record_out_of_memory_failure();
return ciEnv::unloaded_ciobjarrayklass();
}
if (refined_type) {
ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT;
if (null_free) {
assert(element_klass->is_inlinetype(), "Only value class arrays can be null free");
props = (ArrayKlass::ArrayProperties)(props | ArrayKlass::ArrayProperties::NULL_RESTRICTED);
}
if (!atomic) {
assert(element_klass->is_inlinetype(), "Only value class arrays can be non-atomic");
props = (ArrayKlass::ArrayProperties)(props | ArrayKlass::ArrayProperties::NON_ATOMIC);
}
array = ObjArrayKlass::cast(array)->klass_with_properties(props, THREAD);
if (!refined_type) {
return CURRENT_THREAD_ENV->get_obj_array_klass(array);
}

ArrayKlass::ArrayProperties props = ArrayKlass::ArrayProperties::DEFAULT;
if (null_free) {
assert(element_klass->is_inlinetype(), "Only value class arrays can be null free");
props = (ArrayKlass::ArrayProperties)(props | ArrayKlass::ArrayProperties::NULL_RESTRICTED);
}
if (!atomic) {
assert(element_klass->is_inlinetype(), "Only value class arrays can be non-atomic");
props = (ArrayKlass::ArrayProperties)(props | ArrayKlass::ArrayProperties::NON_ATOMIC);
}
array = ObjArrayKlass::cast(array)->klass_with_properties(props, THREAD);
if (array->is_flatArray_klass()) {
return CURRENT_THREAD_ENV->get_flat_array_klass(array);
} else {
return CURRENT_THREAD_ENV->get_obj_array_klass(array);
return CURRENT_THREAD_ENV->get_ref_array_klass(array);
}
}

Expand All @@ -178,7 +182,7 @@ ciArrayKlass* ciObjArrayKlass::make_impl(ciKlass* element_klass, bool refined_ty
// ciObjArrayKlass::make
//
// Make an array klass corresponding to the specified primitive type.
ciArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass, bool refined_type, bool null_free, bool atomic) {
ciObjArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass, bool refined_type, bool null_free, bool atomic) {
GUARDED_VM_ENTRY(return make_impl(element_klass, refined_type, null_free, atomic);)
}

Expand All @@ -191,22 +195,6 @@ ciArrayKlass* ciObjArrayKlass::make(ciKlass* element_klass, int dims) {
}

ciKlass* ciObjArrayKlass::exact_klass() {
if (!is_loaded()) {
return nullptr;
}
ciType* base = base_element_type();
if (base->is_instance_klass()) {
ciInstanceKlass* ik = base->as_instance_klass();
// Even though MyValue is final, [LMyValue is only exact if the array
// is null-free due to null-free [LMyValue <: null-able [LMyValue.
if (ik->is_inlinetype() && !is_elem_null_free()) {
return nullptr;
}
if (ik->exact_klass() != nullptr) {
return this;
}
} else if (base->is_primitive_type()) {
return this;
}
// This cannot be an exact klass because the refined types subtype it
return nullptr;
}
7 changes: 4 additions & 3 deletions src/hotspot/share/ci/ciObjArrayKlass.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#define SHARE_CI_CIOBJARRAYKLASS_HPP

#include "ci/ciArrayKlass.hpp"
#include "oops/objArrayKlass.hpp"

// ciObjArrayKlass
//
Expand All @@ -46,10 +47,10 @@ class ciObjArrayKlass : public ciArrayKlass {
int dimension);

ObjArrayKlass* get_ObjArrayKlass() {
return (ObjArrayKlass*)get_Klass();
return ObjArrayKlass::cast(get_Klass());
}

static ciArrayKlass* make_impl(ciKlass* element_klass, bool refined_type = false, bool null_free = false, bool atomic = true);
static ciObjArrayKlass* make_impl(ciKlass* element_klass, bool refined_type = false, bool null_free = false, bool atomic = true);
static ciSymbol* construct_array_name(ciSymbol* element_name,
int dimension);

Expand All @@ -68,7 +69,7 @@ class ciObjArrayKlass : public ciArrayKlass {
// What kind of ciObject is this?
bool is_obj_array_klass() const { return true; }

static ciArrayKlass* make(ciKlass* element_klass, bool refined_type = true, bool null_free = false, bool atomic = true);
static ciObjArrayKlass* make(ciKlass* element_klass, bool refined_type = true, bool null_free = false, bool atomic = true);
static ciArrayKlass* make(ciKlass* element_klass, int dims);

virtual ciKlass* exact_klass();
Expand Down
Loading