<commit_before>/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/gpu.hpp"
#include "runtime/deoptimization.hpp"
#include "gpu_hsail.hpp"
#include "utilities/debug.hpp"
#include "utilities/exceptions.hpp"
#include "hsail/vm/gpu_hsail.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
#include "graal/graalEnv.hpp"
#include "graal/graalRuntime.hpp"
#include "graal/graalJavaAccess.hpp"
#include "hsailKernelArguments.hpp"
#include "hsailJavaCallArguments.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
#include "gpu_hsail_Frame.hpp"

// Entry to GPU native method implementation that transitions current thread to '_thread_in_vm'.
#define GPU_VMENTRY(result_type, name, signature) \
  JNIEXPORT result_type JNICALL name signature { \
  GRAAL_VM_ENTRY_MARK; \

// Entry to GPU native method implementation that calls a JNI function
// and hence cannot transition current thread to '_thread_in_vm'.
#define GPU_ENTRY(result_type, name, signature) \
  JNIEXPORT result_type JNICALL name signature { \

#define GPU_END }

#define CC (char*)  /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))

#define OBJECT                "Ljava/lang/Object;"
#define STRING                "Ljava/lang/String;"
#define JLTHREAD              "Ljava/lang/Thread;"
#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
#define HS_COMPILED_NMETHOD   "Lcom/oracle/graal/hotspot/HotSpotCompiledNmethod;"
#define HS_NMETHOD            "Lcom/oracle/graal/hotspot/meta/HotSpotNmethod;"

JNINativeMethod Hsail::HSAIL_methods[] = {
  {CC"initialize",       CC"()Z",                               FN_PTR(Hsail::initialize)},
  {CC"generateKernel",   CC"([B" STRING ")J",                   FN_PTR(Hsail::generate_kernel)},
  {CC"executeKernel0",   CC"("HS_INSTALLED_CODE"I["OBJECT"["JLTHREAD"I[I)Z",  FN_PTR(Hsail::execute_kernel_void_1d)},
};

void* Hsail::_device_context = NULL;
jint  Hsail::_notice_safepoints = false;

Hsail::okra_get_context_func_t     Hsail::_okra_get_context;
Hsail::okra_create_kernel_func_t   Hsail::_okra_create_kernel;
Hsail::okra_push_pointer_func_t    Hsail::_okra_push_pointer;
Hsail::okra_push_boolean_func_t    Hsail::_okra_push_boolean;
Hsail::okra_push_byte_func_t       Hsail::_okra_push_byte;
Hsail::okra_push_double_func_t     Hsail::_okra_push_double;
Hsail::okra_push_float_func_t      Hsail::_okra_push_float;
Hsail::okra_push_int_func_t        Hsail::_okra_push_int;
Hsail::okra_push_long_func_t       Hsail::_okra_push_long;
Hsail::okra_execute_kernel_func_t  Hsail::_okra_execute_kernel;
Hsail::okra_clear_args_func_t      Hsail::_okra_clear_args;
Hsail::okra_dispose_kernel_func_t  Hsail::_okra_dispose_kernel;
Hsail::okra_dispose_context_func_t Hsail::_okra_dispose_context;

//static jint in_kernel = 0;

void Hsail::notice_safepoints() {
  _notice_safepoints = true;
//  if (TraceGPUInteraction) {
//    tty->print_cr("[HSAIL] Notice safepoint in_kernel=%d", in_kernel);
//  }
}

void Hsail::ignore_safepoints() {
  _notice_safepoints = false;
}

GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args,
                                                      jobject donor_threads, jint allocBytesPerWorkitem, jobject oop_map_array))

  ResourceMark rm;
  jlong nmethodValue = InstalledCode::address(kernel_handle);
  if (nmethodValue == 0) {
    SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
  }
  nmethod* nm = (nmethod*) (address) nmethodValue;
  methodHandle mh = nm->method();
  Symbol* signature = mh->signature();

  void* kernel = (void*) HotSpotInstalledCode::codeStart(kernel_handle);
  if (kernel == NULL) {
    SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
  }

return execute_kernel_void_1d_internal((address) kernel, dimX, args, mh, nm, donor_threads, allocBytesPerWorkitem, oop_map_array, CHECK_0);
GPU_END

static void showRanges(jboolean* a, int len) {
  // show ranges
  bool lookFor = true;
  for (int i = 0; i < len; i++) {
    if ((lookFor == true) && (a[i] != 0)) {
      tty->print("%d", i);
      lookFor = false;
    } else if ((lookFor == false) && (a[i] == 0)) {
      tty->print_cr("-%d", i-1);
      lookFor = true;
    }
  }
  if (lookFor == false) {
    tty->print_cr("-%d", len-1);
  }
}

jboolean Hsail::execute_kernel_void_1d_internal(address kernel, int dimX, jobject args, methodHandle& mh, nmethod* nm,
                                                jobject donor_threads, int allocBytesPerWorkitem, jobject oop_map_array, TRAPS) {
  ResourceMark rm(THREAD);
  objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args);
  assert(THREAD->is_Java_thread(), "must be a JavaThread");

  // We avoid HSAILAllocationInfo logic if kernel does not allocate
  // in which case the donor_thread array passed in will be null
  HSAILAllocationInfo* allocInfo = (donor_threads == NULL ? NULL : new HSAILAllocationInfo(donor_threads, dimX, allocBytesPerWorkitem));
  
  // Reset the kernel arguments
  _okra_clear_args(kernel);

  JavaThread* thread = (JavaThread*)THREAD;
  HSAILDeoptimizationInfo* e;
  if (UseHSAILDeoptimization) {
    // get how many bytes per deopt save area are required
    int saveAreaCounts = HSAILOopMapHelper::get_save_area_counts(oop_map_array);
    int numSRegs = saveAreaCounts & 0xff;
    int numDRegs = (saveAreaCounts >> 8) & 0xff;
    int numStackSlots = (saveAreaCounts >> 16);
    int bytesPerSaveArea = numSRegs * 4 + (numDRegs + numStackSlots) * 8;

    e = new (MAX_DEOPT_SLOTS, bytesPerSaveArea) HSAILDeoptimizationInfo(MAX_DEOPT_SLOTS, bytesPerSaveArea, dimX, allocInfo, oop_map_array);
    // copy cur_tlab_infos
    if (allocInfo != NULL) {
      e->set_cur_tlabInfos(allocInfo->getCurTlabInfos());
    }
    // set deopt info in thread so gc oops_do processing can find it
    thread->set_gpu_hsail_deopt_info(e);
  }

  // This object sets up the kernel arguments
  HSAILKernelArguments hka((address) kernel, mh->signature(), argsArray, mh->is_static(), e);
  if (TraceGPUInteraction) {
    tty->print_cr("[HSAIL] range=%d", dimX);
  }

  // If any object passed was null, throw an exception here. Doing this
  // means the kernel code can avoid null checks on the object parameters.
  if (hka.getFirstNullParameterIndex() >= 0) {
    char buf[64];
    sprintf(buf, "Null Kernel Parameter seen, Parameter Index: %d", hka.getFirstNullParameterIndex());
    thread->set_gpu_exception_bci(0);
    thread->set_gpu_exception_method(mh());
    THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), buf);
  }

  // Run the kernel
  bool success = false;
  {
    TraceTime t("execute kernel", TraceGPUInteraction);
    graal_okra_range_t kernel_range = {0};

    //in_kernel = 1;
    // Run the kernel
    kernel_range.dimension = 1;
    kernel_range.global_size[0] = dimX;
    success = _okra_execute_kernel(_device_context, kernel, &kernel_range);
    //in_kernel = 0;
  }

  // avoid HSAILAllocationInfo logic if kernel does not allocate
  if (allocInfo != NULL) {
    allocInfo->postKernelCleanup();
  }

  if (UseHSAILDeoptimization) {
    // check if any workitem requested a deopt
    int deoptcode = e->deopt_occurred();
    if (deoptcode != 1) {
      if (deoptcode == 0) {
        if (TraceGPUInteraction && _notice_safepoints != 0) {
          tty->print_cr("[HSAIL] observed safepoint during kernel");<commit_msg>HSAIL: fix performance warning (treated as error on windows!) due to jint=>bool conversion (in line 197)<commit_after>/*
 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/gpu.hpp"
#include "runtime/deoptimization.hpp"
#include "gpu_hsail.hpp"
#include "utilities/debug.hpp"
#include "utilities/exceptions.hpp"
#include "hsail/vm/gpu_hsail.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/ostream.hpp"
#include "graal/graalEnv.hpp"
#include "graal/graalRuntime.hpp"
#include "graal/graalJavaAccess.hpp"
#include "hsailKernelArguments.hpp"
#include "hsailJavaCallArguments.hpp"
#include "code/pcDesc.hpp"
#include "code/scopeDesc.hpp"
#include "gpu_hsail_Frame.hpp"

// Entry to GPU native method implementation that transitions current thread to '_thread_in_vm'.
#define GPU_VMENTRY(result_type, name, signature) \
  JNIEXPORT result_type JNICALL name signature { \
  GRAAL_VM_ENTRY_MARK; \

// Entry to GPU native method implementation that calls a JNI function
// and hence cannot transition current thread to '_thread_in_vm'.
#define GPU_ENTRY(result_type, name, signature) \
  JNIEXPORT result_type JNICALL name signature { \

#define GPU_END }

#define CC (char*)  /*cast a literal from (const char*)*/
#define FN_PTR(f) CAST_FROM_FN_PTR(void*, &(f))

#define OBJECT                "Ljava/lang/Object;"
#define STRING                "Ljava/lang/String;"
#define JLTHREAD              "Ljava/lang/Thread;"
#define HS_INSTALLED_CODE     "Lcom/oracle/graal/hotspot/meta/HotSpotInstalledCode;"
#define HS_COMPILED_NMETHOD   "Lcom/oracle/graal/hotspot/HotSpotCompiledNmethod;"
#define HS_NMETHOD            "Lcom/oracle/graal/hotspot/meta/HotSpotNmethod;"

JNINativeMethod Hsail::HSAIL_methods[] = {
  {CC"initialize",       CC"()Z",                               FN_PTR(Hsail::initialize)},
  {CC"generateKernel",   CC"([B" STRING ")J",                   FN_PTR(Hsail::generate_kernel)},
  {CC"executeKernel0",   CC"("HS_INSTALLED_CODE"I["OBJECT"["JLTHREAD"I[I)Z",  FN_PTR(Hsail::execute_kernel_void_1d)},
};

void* Hsail::_device_context = NULL;
jint  Hsail::_notice_safepoints = false;

Hsail::okra_get_context_func_t     Hsail::_okra_get_context;
Hsail::okra_create_kernel_func_t   Hsail::_okra_create_kernel;
Hsail::okra_push_pointer_func_t    Hsail::_okra_push_pointer;
Hsail::okra_push_boolean_func_t    Hsail::_okra_push_boolean;
Hsail::okra_push_byte_func_t       Hsail::_okra_push_byte;
Hsail::okra_push_double_func_t     Hsail::_okra_push_double;
Hsail::okra_push_float_func_t      Hsail::_okra_push_float;
Hsail::okra_push_int_func_t        Hsail::_okra_push_int;
Hsail::okra_push_long_func_t       Hsail::_okra_push_long;
Hsail::okra_execute_kernel_func_t  Hsail::_okra_execute_kernel;
Hsail::okra_clear_args_func_t      Hsail::_okra_clear_args;
Hsail::okra_dispose_kernel_func_t  Hsail::_okra_dispose_kernel;
Hsail::okra_dispose_context_func_t Hsail::_okra_dispose_context;

//static jint in_kernel = 0;

void Hsail::notice_safepoints() {
  _notice_safepoints = true;
//  if (TraceGPUInteraction) {
//    tty->print_cr("[HSAIL] Notice safepoint in_kernel=%d", in_kernel);
//  }
}

void Hsail::ignore_safepoints() {
  _notice_safepoints = false;
}

GPU_VMENTRY(jboolean, Hsail::execute_kernel_void_1d, (JNIEnv* env, jclass, jobject kernel_handle, jint dimX, jobject args,
                                                      jobject donor_threads, jint allocBytesPerWorkitem, jobject oop_map_array))

  ResourceMark rm;
  jlong nmethodValue = InstalledCode::address(kernel_handle);
  if (nmethodValue == 0) {
    SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
  }
  nmethod* nm = (nmethod*) (address) nmethodValue;
  methodHandle mh = nm->method();
  Symbol* signature = mh->signature();

  void* kernel = (void*) HotSpotInstalledCode::codeStart(kernel_handle);
  if (kernel == NULL) {
    SharedRuntime::throw_and_post_jvmti_exception(JavaThread::current(), vmSymbols::com_oracle_graal_api_code_InvalidInstalledCodeException(), NULL);
  }

return execute_kernel_void_1d_internal((address) kernel, dimX, args, mh, nm, donor_threads, allocBytesPerWorkitem, oop_map_array, CHECK_0);
GPU_END

static void showRanges(jboolean* a, int len) {
  // show ranges
  bool lookFor = true;
  for (int i = 0; i < len; i++) {
    if ((lookFor == true) && (a[i] != 0)) {
      tty->print("%d", i);
      lookFor = false;
    } else if ((lookFor == false) && (a[i] == 0)) {
      tty->print_cr("-%d", i-1);
      lookFor = true;
    }
  }
  if (lookFor == false) {
    tty->print_cr("-%d", len-1);
  }
}

jboolean Hsail::execute_kernel_void_1d_internal(address kernel, int dimX, jobject args, methodHandle& mh, nmethod* nm,
                                                jobject donor_threads, int allocBytesPerWorkitem, jobject oop_map_array, TRAPS) {
  ResourceMark rm(THREAD);
  objArrayOop argsArray = (objArrayOop) JNIHandles::resolve(args);
  assert(THREAD->is_Java_thread(), "must be a JavaThread");

  // We avoid HSAILAllocationInfo logic if kernel does not allocate
  // in which case the donor_thread array passed in will be null
  HSAILAllocationInfo* allocInfo = (donor_threads == NULL ? NULL : new HSAILAllocationInfo(donor_threads, dimX, allocBytesPerWorkitem));
  
  // Reset the kernel arguments
  _okra_clear_args(kernel);

  JavaThread* thread = (JavaThread*)THREAD;
  HSAILDeoptimizationInfo* e;
  if (UseHSAILDeoptimization) {
    // get how many bytes per deopt save area are required
    int saveAreaCounts = HSAILOopMapHelper::get_save_area_counts(oop_map_array);
    int numSRegs = saveAreaCounts & 0xff;
    int numDRegs = (saveAreaCounts >> 8) & 0xff;
    int numStackSlots = (saveAreaCounts >> 16);
    int bytesPerSaveArea = numSRegs * 4 + (numDRegs + numStackSlots) * 8;

    e = new (MAX_DEOPT_SLOTS, bytesPerSaveArea) HSAILDeoptimizationInfo(MAX_DEOPT_SLOTS, bytesPerSaveArea, dimX, allocInfo, oop_map_array);
    // copy cur_tlab_infos
    if (allocInfo != NULL) {
      e->set_cur_tlabInfos(allocInfo->getCurTlabInfos());
    }
    // set deopt info in thread so gc oops_do processing can find it
    thread->set_gpu_hsail_deopt_info(e);
  }

  // This object sets up the kernel arguments
  HSAILKernelArguments hka((address) kernel, mh->signature(), argsArray, mh->is_static(), e);
  if (TraceGPUInteraction) {
    tty->print_cr("[HSAIL] range=%d", dimX);
  }

  // If any object passed was null, throw an exception here. Doing this
  // means the kernel code can avoid null checks on the object parameters.
  if (hka.getFirstNullParameterIndex() >= 0) {
    char buf[64];
    sprintf(buf, "Null Kernel Parameter seen, Parameter Index: %d", hka.getFirstNullParameterIndex());
    thread->set_gpu_exception_bci(0);
    thread->set_gpu_exception_method(mh());
    THROW_MSG_0(vmSymbols::java_lang_NullPointerException(), buf);
  }

  // Run the kernel
  jboolean success = false;
  {
    TraceTime t("execute kernel", TraceGPUInteraction);
    graal_okra_range_t kernel_range = {0};

    //in_kernel = 1;
    // Run the kernel
    kernel_range.dimension = 1;
    kernel_range.global_size[0] = dimX;
    success = _okra_execute_kernel(_device_context, kernel, &kernel_range);
    //in_kernel = 0;
  }

  // avoid HSAILAllocationInfo logic if kernel does not allocate
  if (allocInfo != NULL) {
    allocInfo->postKernelCleanup();
  }

  if (UseHSAILDeoptimization) {
    // check if any workitem requested a deopt
    int deoptcode = e->deopt_occurred();
    if (deoptcode != 1) {
      if (deoptcode == 0) {
        if (TraceGPUInteraction && _notice_safepoints != 0) {
          tty->print_cr("[HSAIL] observed safepoint during kernel");
{'fraction_non_alphanumeric': 0.10850490336640477, 'fraction_numerical': 0.0069392670757584445, 'mean_word_length': 4.297083839611179, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 50, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4867824', 'n_tokens_mistral': 6061, 'n_tokens_neox': 5797, 'n_words': 1434}