< prev index next >

src/hotspot/share/ci/ciField.cpp

Print this page

        

@@ -1,7 +1,7 @@
 /*
- * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2019, 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.

@@ -65,11 +65,11 @@
 // decreases for complex compilation tasks.
 
 // ------------------------------------------------------------------
 // ciField::ciField
 ciField::ciField(ciInstanceKlass* klass, int index) :
-    _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
+  _is_flattened(false), _known_to_link_with_put(NULL), _known_to_link_with_get(NULL) {
   ASSERT_IN_VM;
   CompilerThread *THREAD = CompilerThread::current();
 
   assert(ciObjectFactory::is_initialized(), "not a shared field");
 

@@ -88,21 +88,24 @@
 
   BasicType field_type = FieldType::basic_type(signature);
 
   // If the field is a pointer type, get the klass of the
   // field.
-  if (field_type == T_OBJECT || field_type == T_ARRAY) {
+  if (field_type == T_OBJECT || field_type == T_ARRAY || field_type == T_VALUETYPE) {
     bool ignore;
     // This is not really a class reference; the index always refers to the
     // field's type signature, as a symbol.  Linkage checks do not apply.
     _type = ciEnv::current(THREAD)->get_klass_by_index(cpool, sig_index, ignore, klass);
   } else {
     _type = ciType::make(field_type);
   }
 
   _name = (ciSymbol*)ciEnv::current(THREAD)->get_symbol(name);
 
+  // this is needed if the field class is not yet loaded.
+  _is_flattenable = _signature->is_Q_signature();
+
   // Get the field's declared holder.
   //
   // Note: we actually create a ciInstanceKlass for this klass,
   // even though we may not need to.
   int holder_index = cpool->klass_ref_index_at(index);

@@ -197,11 +200,11 @@
 
   BasicType field_type = fd->field_type();
 
   // If the field is a pointer type, get the klass of the
   // field.
-  if (field_type == T_OBJECT || field_type == T_ARRAY) {
+  if (field_type == T_OBJECT || field_type == T_ARRAY || field_type == T_VALUETYPE) {
     _type = NULL;  // must call compute_type on first access
   } else {
     _type = ciType::make(field_type);
   }
 

@@ -210,10 +213,33 @@
   // Either (a) it is marked shared, or else (b) we are done bootstrapping.
   assert(is_shared() || ciObjectFactory::is_initialized(),
          "bootstrap classes must not create & cache unshared fields");
 }
 
+// Special copy constructor used to flatten value type fields by
+// copying the fields of the value type to a new holder klass.
+ciField::ciField(ciField* field, ciInstanceKlass* holder, int offset, bool is_final) {
+  assert(field->holder()->is_valuetype(), "should only be used for value type field flattening");
+  // Set the is_final flag
+  jint final = is_final ? JVM_ACC_FINAL : ~JVM_ACC_FINAL;
+  AccessFlags flags(field->flags().as_int() & final);
+  _flags = ciFlags(flags);
+  _holder = holder;
+  _offset = offset;
+  // Copy remaining fields
+  _name = field->_name;
+  _signature = field->_signature;
+  _type = field->_type;
+  _is_constant = field->_is_constant;
+  _known_to_link_with_put = field->_known_to_link_with_put;
+  _known_to_link_with_get = field->_known_to_link_with_get;
+  _constant_value = field->_constant_value;
+  assert(!field->is_flattened(), "field must not be flattened");
+  _is_flattened = false;
+  _is_flattenable = field->is_flattenable();
+}
+
 static bool trust_final_non_static_fields(ciInstanceKlass* holder) {
   if (holder == NULL)
     return false;
   if (holder->name() == ciSymbol::java_lang_System())
     // Never trust strangely unstable finals:  System.out, etc.

@@ -247,10 +273,12 @@
   _flags = ciFlags(fd->access_flags());
   _offset = fd->offset();
   Klass* field_holder = fd->field_holder();
   assert(field_holder != NULL, "null field_holder");
   _holder = CURRENT_ENV->get_instance_klass(field_holder);
+  _is_flattened = fd->is_flattened();
+  _is_flattenable = fd->is_flattenable();
 
   // Check to see if the field is constant.
   Klass* k = _holder->get_Klass();
   bool is_stable_field = FoldStableValues && is_stable();
   if ((is_final() && !has_initialized_final_update()) || is_stable_field) {

@@ -359,12 +387,12 @@
 // link errors?
 bool ciField::will_link(ciMethod* accessing_method,
                         Bytecodes::Code bc) {
   VM_ENTRY_MARK;
   assert(bc == Bytecodes::_getstatic || bc == Bytecodes::_putstatic ||
-         bc == Bytecodes::_getfield  || bc == Bytecodes::_putfield,
-         "unexpected bytecode");
+         bc == Bytecodes::_getfield  || bc == Bytecodes::_putfield  ||
+         bc == Bytecodes::_withfield, "unexpected bytecode");
 
   if (_offset == -1) {
     // at creation we couldn't link to our holder so we need to
     // maintain that stance, otherwise there's no safe way to use this
     // ciField.

@@ -425,10 +453,12 @@
   tty->print(" is_constant=%s", bool_to_str(_is_constant));
   if (_is_constant && is_static()) {
     tty->print(" constant_value=");
     _constant_value.print();
   }
+  tty->print(" is_flattenable=%s", bool_to_str(_is_flattenable));
+  tty->print(" is_flattened=%s", bool_to_str(_is_flattened));
   tty->print(">");
 }
 
 // ------------------------------------------------------------------
 // ciField::print_name_on
< prev index next >