001/* 002 * Copyright (c) 2013, 2014, Oracle and/or its affiliates. All rights reserved. 003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 004 * 005 * This code is free software; you can redistribute it and/or modify it 006 * under the terms of the GNU General Public License version 2 only, as 007 * published by the Free Software Foundation. 008 * 009 * This code is distributed in the hope that it will be useful, but WITHOUT 010 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 011 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 012 * version 2 for more details (a copy is included in the LICENSE file that 013 * accompanied this code). 014 * 015 * You should have received a copy of the GNU General Public License version 016 * 2 along with this work; if not, write to the Free Software Foundation, 017 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 018 * 019 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 020 * or visit www.oracle.com if you need additional information or have any 021 * questions. 022 */ 023package com.oracle.graal.truffle; 024 025import jdk.internal.jvmci.meta.*; 026 027import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; 028import com.oracle.truffle.api.nodes.Node.Child; 029import com.oracle.truffle.api.nodes.Node.Children; 030 031public class TruffleConstantReflectionProvider implements ConstantReflectionProvider { 032 private final ConstantReflectionProvider graalConstantReflection; 033 private final MetaAccessProvider metaAccess; 034 035 public TruffleConstantReflectionProvider(ConstantReflectionProvider graalConstantReflection, MetaAccessProvider metaAccess) { 036 this.graalConstantReflection = graalConstantReflection; 037 this.metaAccess = metaAccess; 038 } 039 040 public Boolean constantEquals(Constant x, Constant y) { 041 return graalConstantReflection.constantEquals(x, y); 042 } 043 044 public Integer readArrayLength(JavaConstant array) { 045 return graalConstantReflection.readArrayLength(array); 046 } 047 048 public JavaConstant readArrayElement(JavaConstant array, int index) { 049 return graalConstantReflection.readArrayElement(array, index); 050 } 051 052 public JavaConstant readConstantArrayElement(JavaConstant array, int index) { 053 return graalConstantReflection.readConstantArrayElement(array, index); 054 } 055 056 public JavaConstant readConstantArrayElementForOffset(JavaConstant array, long offset) { 057 return graalConstantReflection.readConstantArrayElementForOffset(array, offset); 058 } 059 060 public JavaConstant readConstantFieldValue(JavaField field0, JavaConstant receiver) { 061 ResolvedJavaField field = (ResolvedJavaField) field0; 062 if (!field.isStatic() && receiver.isNonNull()) { 063 JavaType fieldType = field.getType(); 064 if (field.isFinal() || field.getAnnotation(CompilationFinal.class) != null || 065 (fieldType.getKind() == Kind.Object && (field.getAnnotation(Child.class) != null || field.getAnnotation(Children.class) != null))) { 066 final JavaConstant constant; 067 if (fieldType.getKind() == Kind.Object && fieldType instanceof ResolvedJavaType && ((ResolvedJavaType) fieldType).isArray() && 068 (field.getAnnotation(CompilationFinal.class) != null || field.getAnnotation(Children.class) != null)) { 069 constant = graalConstantReflection.readStableFieldValue(field, receiver, true); 070 } else { 071 constant = graalConstantReflection.readFieldValue(field, receiver); 072 } 073 assert verifyFieldValue(field, constant); 074 return constant; 075 } 076 } else if (field.isStatic()) { 077 if (field.getAnnotation(CompilationFinal.class) != null) { 078 return graalConstantReflection.readStableFieldValue(field, receiver, true); 079 } 080 } 081 return graalConstantReflection.readConstantFieldValue(field, receiver); 082 } 083 084 private boolean verifyFieldValue(ResolvedJavaField field, JavaConstant constant) { 085 assert field.getAnnotation(Child.class) == null || constant.isNull() || 086 metaAccess.lookupJavaType(com.oracle.truffle.api.nodes.Node.class).isAssignableFrom(metaAccess.lookupJavaType(constant)) : "@Child field value must be a Node: " + field + 087 ", but was: " + constant; 088 assert field.getAnnotation(Children.class) == null || constant.isNull() || metaAccess.lookupJavaType(constant).isArray() : "@Children field value must be an array: " + field + ", but was: " + 089 constant; 090 return true; 091 } 092 093 public JavaConstant readFieldValue(JavaField field, JavaConstant receiver) { 094 return graalConstantReflection.readFieldValue(field, receiver); 095 } 096 097 public JavaConstant readStableFieldValue(JavaField field, JavaConstant receiver, boolean isDefaultStable) { 098 return graalConstantReflection.readStableFieldValue(field, receiver, isDefaultStable); 099 } 100 101 public JavaConstant boxPrimitive(JavaConstant source) { 102 return graalConstantReflection.boxPrimitive(source); 103 } 104 105 public JavaConstant unboxPrimitive(JavaConstant source) { 106 return graalConstantReflection.unboxPrimitive(source); 107 } 108 109 public JavaConstant forString(String value) { 110 return graalConstantReflection.forString(value); 111 } 112 113 public ResolvedJavaType asJavaType(Constant constant) { 114 return graalConstantReflection.asJavaType(constant); 115 } 116 117 public MethodHandleAccessProvider getMethodHandleAccess() { 118 return graalConstantReflection.getMethodHandleAccess(); 119 } 120 121 public MemoryAccessProvider getMemoryAccessProvider() { 122 return graalConstantReflection.getMemoryAccessProvider(); 123 } 124}