Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: jruby/jruby
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 3b2197fab023
Choose a base ref
...
head repository: jruby/jruby
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 4ddb3fd2351c
Choose a head ref
  • 7 commits
  • 1 file changed
  • 1 contributor

Commits on Feb 10, 2016

  1. Copy the full SHA
    df7ebf6 View commit details
  2. Copy the full SHA
    24814b8 View commit details
  3. Copy the full SHA
    5ca98ef View commit details
  4. Copy the full SHA
    c352813 View commit details
  5. Copy the full SHA
    8694c3c View commit details
  6. Copy the full SHA
    bf77c82 View commit details
  7. Copy the full SHA
    4ddb3fd View commit details
Showing with 73 additions and 28 deletions.
  1. +73 −28 tool/jt.rb
101 changes: 73 additions & 28 deletions tool/jt.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#!/usr/bin/env ruby
# Copyright (c) 2015 Oracle and/or its affiliates. All rights reserved. This
# code is released under a tri EPL/GPL/LGPL license. You can use it,
# Copyright (c) 2015, 2016 Oracle and/or its affiliates. All rights reserved.
# This code is released under a tri EPL/GPL/LGPL license. You can use it,
# redistribute it and/or modify it under the terms of the:
#
# Eclipse Public License version 1.0
@@ -21,6 +21,7 @@
JDEBUG_TEST = "-Dmaven.surefire.debug=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=#{JDEBUG_PORT} -Xnoagent -Djava.compiler=NONE"
JEXCEPTION = "-Xtruffle.exceptions.print_java=true"
METRICS_REPS = 10
HIGHER_HEAP = 40

# wait for sub-processes to handle the interrupt
trap(:INT) {}
@@ -254,17 +255,18 @@ def help
puts 'jt tag all spec/ruby/language tag all specs in this file, without running them'
puts 'jt untag spec/ruby/language untag passing specs in this directory'
puts 'jt untag spec/ruby/language/while_spec.rb untag passing specs in this file'
puts 'jt bench debug [options] [vm-args] benchmark run a single benchmark with options for compiler debugging'
puts 'jt bench debug [options] [vm-args] benchmark run a single benchmark with options for compiler debugging'
puts ' --igv make sure IGV is running and dump Graal graphs after partial escape (implies --graal)'
puts ' --full show all phases, not just up to the Truffle partial escape'
puts ' --ruby-backtrace print a Ruby backtrace on any compilation failures'
puts 'jt bench reference [benchmarks] run a set of benchmarks and record a reference point'
puts 'jt bench compare [benchmarks] run a set of benchmarks and compare against a reference point'
puts ' benchmarks can be any benchmarks or group of benchmarks supported'
puts ' by bench9000, eg all, classic, chunky, 3, 5, 10, 15 - default is 5'
puts 'jt metrics alloc ... how much memory is allocated running a program (use -X-T to test normal JRuby on this metric and others)'
puts 'jt metrics minheap ... what is the smallest heap you can use to run an application'
puts 'jt metrics time ... how long does it take to run a command, broken down into different phases'
puts 'jt metrics [--score name] alloc ... how much memory is allocated running a program (use -X-T to test normal JRuby on this metric and others)'
puts ' --score name report results as scores'
puts 'jt metrics ... minheap ... what is the smallest heap you can use to run an application'
puts 'jt metrics ... time ... how long does it take to run a command, broken down into different phases'
puts 'jt install ..../graal/mx/suite.py install a JRuby distribution into an mx suite'
puts
puts 'you can also put build or rebuild in front of any command'
@@ -567,30 +569,43 @@ def bench(command, *args)
end

def metrics(command, *args)
trap(:INT) { puts; exit }
args = args.dup
if args.first == '--score'
args.shift
score_name = args.shift
else
score_name = nil
end
case command
when 'alloc'
metrics_alloc *args
metrics_alloc score_name, *args
when 'minheap'
metrics_minheap *args
metrics_minheap score_name, *args
when 'time'
metrics_time *args
metrics_time score_name, *args
else
raise ArgumentError, command
end
end

def metrics_alloc(*args)
def metrics_alloc(score_name, *args)
samples = []
METRICS_REPS.times do
print '.' if STDOUT.tty?
log '.', 'sampling'
r, w = IO.pipe
run '-Xtruffle.metrics.memory_used_on_exit=true', '-J-verbose:gc', *args, {err: w, out: w}, :no_print_cmd
w.close
samples.push memory_allocated(r.read)
r.close
end
puts if STDOUT.tty?
puts "#{human_size(samples.inject(:+)/samples.size)}, max #{human_size(samples.max)}"
log "\n", nil
mean = samples.inject(:+) / samples.size
if score_name
puts "alloc-#{score_name} #{mean}"
else
puts "#{human_size(mean)}, max #{human_size(samples.max)}"
end
end

def memory_allocated(trace)
@@ -608,35 +623,52 @@ def memory_allocated(trace)
end
allocated
end

def metrics_minheap(*args)
def metrics_minheap(score_name, *args)
# Why aren't you doing a binary search? The results seem pretty noisy so
# unless you do reps at each level I'm not sure how to make it work
# reliably.
heap = 1
# reliably. To slightly improve on a basic linear search, we check to see
# if it looks like we can run in 40 MB, and if we can't then we start
# testing there.
log '~', "Trying #{HIGHER_HEAP} MB"
if can_run_in_heap(HIGHER_HEAP, *args)
log '<', "Passed, so starting at 1 MB"
heap = 1
else
log '>', "Failed, so starting at #{HIGHER_HEAP} MB"
heap = HIGHER_HEAP
end
successful = 0
loop do
if successful > 0
print '?' if STDOUT.tty?
log '?', "Verifying #{heap} MB"
else
print '+' if STDOUT.tty?
log '+', "Trying #{heap} MB"
end
if run("-J-Xmx#{heap}M", *args, {err: '/dev/null', out: '/dev/null'}, :continue_on_failure, :no_print_cmd)
if can_run_in_heap(heap, *args)
successful += 1
break if successful == METRICS_REPS
else
heap += 1
successful = 0
end
end
puts if STDOUT.tty?
puts "#{heap} MB"
log "\n", nil
if score_name
puts "minheap-#{score_name} #{heap*1024*1024}"
else
puts "#{heap} MB"
end
end

def metrics_time(*args)

def can_run_in_heap(heap, *command)
run("-J-Xmx#{heap}M", *command, {err: '/dev/null', out: '/dev/null'}, :continue_on_failure, :no_print_cmd)
end

def metrics_time(score_name, *args)
samples = []
METRICS_REPS.times do
print '.' if STDOUT.tty?
log '.', 'sampling'
r, w = IO.pipe
start = Time.now
run '-Xtruffle.metrics.time=true', *args, {err: w, out: w}, :no_print_cmd
@@ -645,10 +677,15 @@ def metrics_time(*args)
samples.push get_times(r.read, finish - start)
r.close
end
puts if STDOUT.tty?
log "\n", nil
samples[0].each_key do |region|
region_samples = samples.map { |s| s[region] }
puts "#{region} #{(region_samples.inject(:+)/samples.size).round(2)} s"
mean = region_samples.inject(:+) / samples.size
if score_name
puts "time-#{region.strip}-#{score_name} #{(mean*1000).round}"
else
puts "#{region} #{mean.round(2)} s"
end
end
end

@@ -693,6 +730,14 @@ def human_size(bytes)
"#{(bytes/1024.0**4).round(2)} TB"
end
end

def log(tty_message, full_message)
if STDOUT.tty?
print(tty_message) unless tty_message.nil?
else
puts full_message unless full_message.nil?
end
end

def check_ambiguous_arguments
ENV.delete "JRUBY_ECLIPSE" # never run from the Eclipse launcher here