If you set out to write a binary search, you would probably start out with an outline like this:

int binarysearch(int x, int[] xs) { int lo = 0; int hi = xs.length; while (lo < hi) ... return -1; // x not found }

Then you stop to think what should go in the loop. *Well, I need to find the mid point. If the item I'm looking for is less than middle, I go left. If it's greater, I go right. If it's the same, I've found what I'm looking for.* So you write:

int mid = (hi + lo)/2; if (x < xs[mid]) hi = mid; else if (x > xs[mid]) lo = mid; else return mid;

*Yep that looks about right.* You test it and it works. But some time later you find that your program gets stuck in an infinite loop with some inputs. *Bummer, I guess the stop condition should be* `lo < hi-1`

. That solves the infinite loop, but now it returns the wrong answer from time to time...

It's time to deactivate autopilot and practice **mindful programming**: actually thinking about what you're doing. This means thinking carefully about questions like:

- What do the variables actually mean?
- What is the stopping condition?
- What invariants should be maintained in the loop? Is progress towards the stopping condition guaranteed?

Let's apply this approach here. Variables:

- lo: first index in subarray being searched.
- hi: first index after subarray being searched. (Half-open intervals tend to work very well.)
- mid: splits the subarray into two halves. If the size is odd, make the first half smaller; in other words
`mid = (lo+hi)/2`

.

As for the stopping condition, the search can succeed as long as there's at least one element in the subarray. With these definitions of variables, that's `lo < hi`

.

How about the loop invariants? On each iteration, if we get lucky and find the element the loop should exit. If the element is not found, the subarray should become smaller to avoid an infinite loop.

If you now look at the code from before, you'll see it's correct on all accounts except maybe the last: Suppose the subarray has size n. When `x > xs[mid]`

, the new subarray ranges from `mid`

to `hi`

, which makes its size `ceil(n/2)`

. This explains the infinite loop: if n = 1, ceil(n/2) = 1, and the loop makes no progress at all.

When `x > xs[mid]`

, we don't want to look at `xs[mid]`

again, so we can exclude it from the search by setting `lo = mid+1`

. This makes the size of the new subarray `ceil(n/2)-1`

, which *is* guaranteed to be less than n.

The correct* binary search therefore stands:

int binarysearch(int x, int[] xs) { int lo = 0; int hi = xs.length; while (lo < hi) { int mid = (hi + lo)/2; if (x < xs[mid]) hi = mid; else if (x > xs[mid]) lo = mid + 1; else return mid; } return -1; // x not found }

*) Not truly correct if it's possible that computing `hi + lo`

overflows in your programming language. In that case use `lo + (hi - lo)/2`

or something similar.

The usual algorithms for computing variance and standard deviation work on the full data set. What if you have a time series and want the standard deviation for a moving window? You could do the computation from fresh every time the window is advanced, but surely there’s a better way.

Let’s denote the data by \(x_0, x_1, \ldots\) and see how the statistics change when we slide a window of size N by one position, from \((x_0, \ldots, x_{N-1})\) to \((x_1, \ldots, x_N)\).

The mean is easy:

$$

\bar{x}_1 – \bar{x}_0 = \frac{\sum_{i=1}^N x_i – \sum_{i=0}^{N-1} x_i}{N} = \frac{x_n – x_0}{N}

$$

The standard deviation is a little tougher. The variance, which the standard deviation squared, is nicer for algebraic manipulations. Since the variance has an N-1 term in the denominator let’s have a look at what happens when computing \((N-1)s^2\).

$$

\begin{align}

&(N-1)s_1^2 – (N-1)s_0^2 \\

&= \left(\sum_{i=1}^N x_i^2-N \bar{x}_1^2\right)-\left(\sum_{i=0}^{N-1} x_i^2-N\bar{x}_0^2\right) \\

&= x_N^2 – x_0^2 – N (\bar{x}_1^2 – \bar{x}_0^2) \\

&= x_N^2 – x_0^2 – N (\bar{x}_1 – \bar{x}_0) (\bar{x}_1 + \bar{x}_0) \\

&= (x_N – x_0)(x_N + x_0) – (x_N – x_0) (\bar{x}_1 + \bar{x}_0) \\

&= (x_N – x_0)(x_N – \bar{x}_1 + x_0 – \bar{x}_0) \\

\end{align}

$$

The update rule turns out to be remarkably simple. Here’s a possible implementation of these moving window statistics in Python:

class RollingStatistic(object): def __init__(self, window_size, average, variance): self.N = window_size self.average = average self.variance = variance self.stddev = sqrt(variance) def update(new, old): oldavg = self.average newavg = oldavg + (new - old)/self.N self.average = newavg self.variance += (new-old)*(new-newavg+old-oldavg)/(self.N-1) self.stddev = sqrt(variance)

Starting with this equivalent definition of variance, we see that the sum of squares is a part of the formula of variance.

$$

s^2 = \frac{\sum_{i=1}^N x_i^2 – N\bar{x}^2}{N-1}

$$

We could do a rolling update of the sum of squares and of the mean separately. The problem with this approach is that when the variance is small compared to the mean the subtraction suffers of catastrophic cancellation, the same problem that prompts us to use Welford’s method for one-pass variance computation.

]]>You can’t have the same number of positive and negative integers because 255 is odd. The range of representable numbers will not be symmetric around zero; this is the **two’s complement anomaly**. (You could solve the issue by deciding to just not use one, but that brings problems of its own.) In the two’s complement system there’s one negative number that doesn’t have a positive counterpart. This anomaly has a counter-intuitive consequence.

For example, if `x`

is -128 as an 8-bit number, what is `-x`

? If you work this out in binary, you start with `x`

= 1000 0000_{2}, and then you compute `-x`

which is by definition `~x+1`

, you get `-x`

= 0111 1111_{2} + 1 = 1000 0000_{2}. This is exactly what we started with: -x = x = -128, a mathematical impossibility?

Not really. Recall that computer integers are actually defined modulo 2^{M}, and in this case the correct result of -x = 128 is equivalent to -128 modulo 2^{8}. We did get the right result, it just has an unexpected interpretation.

You’ll just have to get used to it: **there are numbers with a negative absolute value** and every time you see a call to `abs()`

you should ask yourself if the argument can be the two’s complement anomaly, and what happens if it is. For example, suppose you want to produce a random stage from the Dreyfus model of skill acquisition, using a function `rnd()`

that produces uniformly random 32-bit signed integers. Here’s a function that does just that:

char *dreyfus_stage() { char *stages[] = {"novice", "advanced beginner", "competent", "proficient", "expert"}; int index = abs(rnd()) % 5; return stages[index]; }

This is the stuff of the Underhanded C Contest: the function looks innocent, but has serious flaws. Not only is it slightly biased; it can also end up computing `index`

as -3 and return random garbage.

IBAN is based on a verification scheme called MOD 97-10. Don’t let the name scare you: what it means is that the codes are numeric, and have two check digits at the end. To verify the code you divide it by 97: if the remainder is 1 the code is valid, otherwise not. When generating the check digits you do the same computation with the check digits set to `00`

. Subtracting the remainder from 98 gives you the check digit. This works because if the code is C and its remainder is R, then the remainder computed for C+(98-R) is the same as for R+98-R = 98. The remainder of 98 when divided by 97 of course is 1. This is really straightforward to implement:

function mod_97_10_check($code) { return bcmod($code, 97) == 1; } function mod_97_10_digit($code) { return 98 - bcmod($code, 97); }

With IBAN you need some preprocessing though. First you have to move the country code and check digits to the right, and replace every letter with digits so that A becomes 10, B becomes 11, C becomes 12, and so on. Here’s a function to generate the IBAN check digits, given the country code and the national account number:

function iban_check_digit1($country, $account_number) { $code = $account_number . $country . '00'; $code = strtr($code, array('A'=>'10','B'=>'11', /* etc */)); return sprintf("%02d", mod_97_10_digit($code)); }

This is great for converting individual account numbers, but what if we have to migrate a whole database? You could write a script that updates every single record one by one, or you could write a single SQL query that does the same thing. In MySQL it’s convenient to first define a function that computes the MOD 97-10 check digits:

create function mod_97_10_check(s text) returns char(2) return lpad(98 - cast(s as decimal(60)) % 97, 2, '0');

For the rest, string manipulation is unfortunately not one of SQL’s strengths, so we’ll simplify a little. For example, in most countries bank account numbers contain only digits, so only the country code needs replacing and we can do that by by hand. For example, `ES`

for Spain is mapped to `1428`

, so this is how you could compute the IBAN check digit for Spanish “CCC” format account numbers:

UPDATE bank_account_numbers SET iban = concat('ES', mod_97_10_check(concat(ccc, '142800')), ccc);

The exact decimal arithmetic implemented in MySQL is really handy here. Without it we would have to create a stored procedure that computes the remainder 9 digits at a time, based on Horner’s rule.

]]>If the two points are near each other, for example in the same city, estimating the great circle with a straight line in the latitude-longitude space will produce minimal error, and be a lot faster to calculate. A minor complication is the fact that the length of a degree of longitude depends on the latitude: a degree of longitude spans 111km on the Equator, but half of that on 60° north. Adjusting for this is easy: multiply the longitude by the cosine of the latitude. Then you can just take the Euclidean distance between the two points, and multiply by the length of a degree:

distance(lat, lng, lat0, lng0): deglen := 110.25 x := lat - lat0 y := (lng - lng0)*cos(lat0) return deglen*sqrt(x*x + y*y)

If you work in SQL, and don’t have spatial geometry primitives, you can apply this snippet to find points that are less than `$d`

km from a given `($lat, $lng)`

pair:

select lat, lng from points where pow(lat-$lat, 2) + pow((lng-$lng)*cos(radians($lat)), 2) < pow($d/110.25, 2)

Can we make it even faster? Sure: you might precompute the cosines when the data first arrives. Also, small errors when computing the cosine don’t matter much, so we can replace it with a table lookup or a polynomial approximation.

When making approximations it’s important to keep in mind how much error you are introducing. If you don’t care about the error, why not just say that the distance between any two points is 5km?

I won’t do a detailed error analysis because the formulas involved in spherical geometry are long, boring, and easy to get wrong. Since the error is worst near the poles, plotting the error made around some points will give us an idea of how bad the error can be. This is a plot of the relative error made over a 5km distance at 89° degrees north, and again at 65° degrees north:

The location for the first plot is completely unrealistic of course: 89° is about 110km from the pole. No permanent human settlements lie that near to a pole, unless you count Antarctic research stations. And yet the relative error is less than 1% for distances less than 5km. The second plot shows relative error is less than 0.04% for distances less than 5km at 65°. That’s not far from the polar circle.

This plot shows that the error at 89° is now a lot bigger: over 10%. This could be expected: the northernmost point of the 50km circle is only about 60km from the pole, so the assumptions made by the approximation are breaking. The circle doesn’t even look like one in the latitude-longitude space. At 65° however the error still stays manageable: less than 0.4%.

The error made by modeling the Earth as a sphere is cited to be larger than 0.5%, so the method for approximate distance derived here is just as good as the Haversine formula, but a lot simpler to compute.

]]>When Java became popular in the late 90s it was said it would not be fast enough for number crunching applications. Java was executed by an interpreter, too separated from the hardware to get top performance. For example, the Mandelbrot set program from my previous post should clearly be faster when written in C.

Let’s test if this is the case. Here is the program from before, ported to C with minimal changes. This is not a “micro benchmark:” the idea is to test two complete programs, that make a computation and write the results to a file. To save the generated image in a file I use the GDK Pixbuf library that supports different file formats, similar to `ImageIO`

in the standard Java library. Notice the difference in the two image libraries: In C the pixel value is written directly to memory through a pointer, but in Java I use the `BufferedImage.setRGB`

method that has to go through several abstraction layers and method calls to actually write the value to a memory.

When I compile the two versions and run them on my laptop, these are the results I get:

$ gcc -std=c99 mandelbrot.c -o mandelb│$ javac MandelbrotBW.java rot $(pkg-config --cflags --libs glib-│$ 2.0 gtk+-2.0) │$ $ for _ in $(seq 5) ; do /usr/bin/time│$ for _ in $(seq 5) ; do /usr/bin/time -f -f %e ./mandelbrot; done │ %e java MandelbrotBW; done 4.81 │4.57 4.79 │4.56 4.79 │4.56 4.79 │4.62 4.79 │4.54

Whoa, even despite the abstraction layers, *the Java version is faster than C!*

This is possible because Java Virtual Machines are not purely interpreters; they compile Java’s platform independent bytecode to native code “just in time,” while it’s being run. In the end the CPU is running native code to do pretty much the same thing, so there’s no reason why Java code should be significantly slower than equivalent C code.

But that’s not the end of the story. When I compiled the C version above I did not enable any compiler optimizations. Let’s see what happens when I do that:

$ gcc -O3 -std=c99 mandelbrot.c -o mandelbrot $(pkg-config --cflags --libs glib -2.0 gtk+-2.0) $ for _ in $(seq 5) ; do /usr/bin/time -f %e ./mandelbrot; done 2.62 2.62 2.62 2.61 2.62

And now the C version is faster by a large margin. Apparently the optimizations made by GCC are really good. Do we conclude that C is faster than Java?

It depends. We’re not really comparing the performance of one *language* to another, but the performance of code generated by different *compilers*. It would be interesting to have a look at the assembler code generated by GCC and by Hotspot, and see how they compare. It may be possible to tune the Java source so that Hotspot will generate code similar to what is produced by GCC, and use a more direct method of setting pixels than the `setRGB`

method. But would it then be a fair comparison?

From experience, programs written in Java tend to feel more sluggish than C programs. There are many things that might cause this: the startup time of the JVM, the time it takes for the JIT to kick in, garbage collector pauses, and the high overhead of native library calls, to name a few. The worst performance killer in my opinion is the general disregard for anything “low level” and the tendency of adding indirections and abstraction layers where none are needed, leading to complicated designs and bloated implementations. In comparison, C programmers tend to pay more attention to optimization, and their programs tend to use simple, flat structures, which is optimal for current CPUs. This doesn’t mean it’s impossible to write Java programs that perform as well as the equivalent C program.

]]>`xprop`

is a program that can list and set X11 window properties. Listing properties is really simple: just run `xprop`

and click on the window that you are interested in, or use the `-root`

or `-id`

command line parameters to choose the “root” window or a window by ID. What’s not so clear is how the properties can be set; the manual does not give any examples.
In order to set a property you have to define the data format. This consists of the bit-width and data type: for example a *string of 8-bit characters* is `8s`

. A *32-bit hexadecimal integer* is `32x`

, these are useful for example for window IDs. The widths and data types that can be used are documented in the manual page.

Here’s a simple example: PulseAudio uses a property called `PULSE_SERVER`

on the root window to know which audio server is used in the desktop session. To redirect the audio to a PulseAudio server on another host over TCP/IP you can use:

xprop -root -f PULSE_SERVER 8s -set PULSE_SERVER tcp:otherhost:4713]]>

When I was 12 or 13 I saw a science program about fractals and chaos theory. I was intrigued by the intricate organic shapes and bright colors, especially of the Mandelbrot set, and decided I wanted to learn how to make them. This is how I got interested in mathematics and programming in the first place. Drawing the Mandelbrot set makes a rewarding exercise for a beginning programmer, covering many important topics like loops and conditional statements.

Mathematically, the Mandelbrot set is defined on the plane of complex numbers by picking a starting point \(c\) and iterating the formula \(z_{k+1} = z_k^2 + c\). The iteration gives you a sequence of numbers that either stays bounded or spirals out of control further and further from the starting point. The complex number \(c\) belongs to the Mandelbrot set if the sequence stays within a radius of 2 from the origin.

Plotting the Mandelbrot set is easy: map each pixel on the screen to a complex number, check if it belongs to the set by iterating the formula, and color the pixel black if it does and white if it doesn’t. Since the iteration may never end we set a maximum

First of all we need a way to represent complex numbers. Some programming languages like Python include a built-in complex number type which we could use to implement the iteration using the above formula directly. Other languages such as Java or JavaScript don’t include complex numbers, but not to worry: we can represent the complex number \(z = x+iy\) as the pair of real numbers \((x,y)\). In this representation the Mandelbrot set iteration becomes:

\[

\begin{align}

x_{k+1} &= x_k^2 – y_k^2 + \mathrm{Re}\ c \\

y_{k+1} &= 2 x_k y_k + \mathrm{Im}\ c

\end{align}

\]

All that’s left now is figuring out how to map pixels to complex numbers. That’s an easy task: we want the center of the image to be mapped to (0,0), so given a pixel we subtract half of the image height from the vertical coordinate, and half of the width from the horizontal coordinate. Next, the scale: we know that the Mandelbrot set lies within a circle of radius 2, so the entire width of the image should have length 4. This gives us the following program for plotting the Mandelbrot set in a C-like language:

for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { double c_re = (col - width/2.0)*4.0/width; double c_im = (row - height/2.0)*4.0/width; double x = 0, y = 0; int iteration = 0; while (x*x+y*y <= 4 && iteration < max) { double x_new = x*x - y*y + c_re; y = 2*x*y + c_im; x = x_new; iteration++; } if (iteration < max) putpixel(col, row, white); else putpixel(col, row, black); } }

(You can find an actual implementation in Java in GitHub.) Here’s the plot produced by it:

That’s not particularly impressive, is it? Where are the pretty colors?

Since the Mandelbrot set has a very fine structure, by plotting only black or white we don’t get any idea of how close a pixel is to the set. The number of iterations gives us some idea of that, so let’s use it to color the pixels that don’t belong to the set. The change needed in the code is trivial: define a color map and use it instead of white:

if (iterations < max) putpixel(col, row, colors[iterations]);

(Implementation in Java.) The image produced by this program is much prettier and gives a better idea of the structure of the set, with fine tendrils springing from the bulbs.

This basic program can be enhanced a lot. Ideally it should be interactive, allowing the user to zoom into different parts of the plot and produce impressive visualization. The aesthetics of the images can be enhanced: in particular the color mapping we have chosen shows discontinuous bands where the iteration count changes. Also, some optimizations can be made to make the program generate the images faster. I’ll treat some of these issues in future posts.

]]>The standard deviation is a measure of how much a dataset differs from its mean; it tells us how dispersed the data are. A dataset that’s pretty much clumped around a single point would have a small standard deviation, while a dataset that’s all over the map would have a large standard deviation.

Given a sample \(x_1, \ldots, x_N\), the standard deviation is defined as the square root of the *variance*:

$$

s^2 = \frac{\sum_{i=1}^N (x_i – \bar{x})^2}{N-1}, s = \sqrt{s^2}

$$

Here \(\bar{x}\) is the mean of the sample: \(\bar{x} = \tfrac{1}{N}\sum_{i=1}^N x_i\). The definition can be converted directly into an algorithm that computes the variance and standard deviation in two passes: compute the mean in one pass over the data, and then do a second pass to compute the squared differences from the mean. Doing two passes is not ideal though, and it can be impractical in some settings. For example, if the samples are generated by a random simulation it may be prohibitively expensive to store samples just so you can do a second pass over them.

A easy computation gives us the following identity that suggests a method for computing the variance in a single pass, by simply accumulating the sums of \(x_i\) and \(x_i^2\):

$$

s^2 = \frac{\sum_{i=1}^N (x_i^2 – 2\bar{x}x_i + \bar{x}^2)}{N-1}

= \frac{\sum x_i^2 – 2 N \bar{x}^2 + N \bar{x}^2}{N-1}

= \frac{\sum x_i^2 – N \bar{x}^2}{N-1}

$$

Pseudocode for a one-pass variance computation could then look like:

variance(samples): sum := 0 sumsq := 0 for x in samples: sum := sum + x sumsq := sumsq + x**2 mean := sum/N return (sumsq - N*mean**2)/(N-1)

Now that you’ve seen it, *do not use this method to compute variance ever*. This is one of those cases where a mathematically simple approach turns out to give wrong results for being numerically unstable. In simple cases the algorithm will seem to work fine, but eventually you will find a dataset that exposes the problem with the algorithm. If the variance is small compared to the square of the mean, and computing the difference leads

**Welford’s method** is a usable single-pass method for computing the variance. It can be derived by looking at the differences between the sums of squared differences for N and N-1 samples. It’s really surprising how simple the difference turns out to be:

$$

\begin{align}

&(N-1)s_N^2 – (N-2)s_{N-1}^2 \\

&= \sum_{i=1}^N (x_i-\bar{x}_N)^2-\sum_{i=1}^{N-1} (x_i-\bar{x}_{N-1})^2 \\

&= (x_N-\bar{x}_N)^2 + \sum_{i=1}^{N-1}\left((x_i-\bar{x}_N)^2-(x_i-\bar{x}_{N-1})^2\right) \\

&= (x_N-\bar{x}_N)^2 + \sum_{i=1}^{N-1}(x_i-\bar{x}_N + x_i-\bar{x}_{N-1})(\bar{x}_{N-1} – \bar{x}_{N}) \\

&= (x_N-\bar{x}_N)^2 + (\bar{x}_N – x_N)(\bar{x}_{N-1} – \bar{x}_{N}) \\

&= (x_N-\bar{x}_N)(x_N-\bar{x}_N – \bar{x}_{N-1} + \bar{x}_{N}) \\

&= (x_N-\bar{x}_N)(x_N – \bar{x}_{N-1}) \\

\end{align}

$$

This means we can compute the variance in a single pass using the following algorithm:

variance(samples): M := 0 S := 0 for k from 1 to N: x := samples[k] oldM := M M := M + (x-M)/k S := S + (x-M)*(x-oldM) return S/(N-1)

To see that this method does work better than the one derived earlier you can make an experiment, or analyze it theoretically. John D. Cook found the accuracy of this method comparable to the accuracy of the two-pass method derived directly from the definition, while the results from the previous one-pass algorithm were found to be useless as expected.

]]>`Thread`

object and call its `start`

method. This raises the question, how is the very first thread of an application started? If it’s created calling the `start`

method, which thread calls it?
The apparent chicken-or-egg problem is easily solved: From a lower level perspective, a `Thread`

object is a mere *representation* of a thread in a program; it is not a thread itself. That is, a `Thread`

object does not maintain the information about call stacks and program counters that a thread should maintain; it only serves as storage for a pointer to lower level mechanisms that implement threads. This means that the JVM is capable of creating threads without using the `Thread`

class, and the `Thread`

object can be created later if needed.

If we study the source code of application startup in OpenJDK 7 we can see how exactly the `Thread`

object is created for the main thread in the Hotspot JVM. In `src/share/vm/runtime/Threads.cpp`

we find a lot of threading related code, the most interesting one being the `Threads::create_vm`

C++ function. This function called directly from the `java`

application launcher (and the CreateJavaVM function in JNI), and it is running in a thread that was created by the operating system when it started the process. It is a very long function, responsible for setting up the JVM so that a Java application can be run. In this function we find this code:

// Attach the main thread to this os thread JavaThread* main_thread = new JavaThread(); main_thread->set_thread_state(_thread_in_vm);

The C++ `JavaThread`

class is used for bookkeeping inside Hotspot; it associates an low level thread with a Java `Thread`

object. The Java object doesn’t exist yet; it is created much later, and at this point the `main_thread`

object will only hold information about the native main thread. The code then goes on to initialize various other things, and later on still in the same function we find this:

// Initialize java_lang.System (needed before creating the thread) if (InitializeJavaLangSystem) { initialize_class(vmSymbols::java_lang_System(), CHECK_0); initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK_0); Handle thread_group = create_initial_thread_group(CHECK_0); Universe::set_main_thread_group(thread_group()); initialize_class(vmSymbols::java_lang_Thread(), CHECK_0); oop thread_object = create_initial_thread(thread_group, main_thread, CHECK_0); main_thread->set_threadObj(thread_object); // Set thread status to running since main thread has // been started and running. java_lang_Thread::set_thread_status(thread_object, java_lang_Thread::RUNNABLE);

In other words, we initialize the `System`

, `ThreadGroup`

, and `Thread`

classes, and call `create_initial_thread`

to create a Java `Thread`

object. Then we sets the `Thread`

object for `main_thread`

.

You may be wondering what `create_initial_thread`

does. It allocates memory for the Java `Thread`

object, storing a pointer to the C++ `JavaThread`

object in its private `eetop`

field. Then it sets the thread priority field to normal, calls the Thread(ThreadGroup group,String name) constructor, and returns the instance. Here it is in all its glory:

// Creates the initial Thread static oop create_initial_thread(Handle thread_group, JavaThread* thread, TRAPS) { klassOop k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_NULL); instanceKlassHandle klass (THREAD, k); instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_NULL); java_lang_Thread::set_thread(thread_oop(), thread); java_lang_Thread::set_priority(thread_oop(), NormPriority); thread->set_threadObj(thread_oop()); Handle string = java_lang_String::create_from_str("main", CHECK_NULL); JavaValue result(T_VOID); JavaCalls::call_special(&result, thread_oop, klass, vmSymbols::object_initializer_name(), vmSymbols::threadgroup_string_void_signature(), thread_group, string, CHECK_NULL); return thread_oop(); }

After `Threads::create_vm`

returns the `Thread`

object for the main thread has been created, and the JVM is now ready to start to execute Java code.