OutOfBoundsExceptionStub.java revision 12651:6ef01bd40ce2
1343171Sdim/*
2343171Sdim * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved.
3353358Sdim * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4353358Sdim *
5353358Sdim * This code is free software; you can redistribute it and/or modify it
6343171Sdim * under the terms of the GNU General Public License version 2 only, as
7343171Sdim * published by the Free Software Foundation.
8343171Sdim *
9343171Sdim * This code is distributed in the hope that it will be useful, but WITHOUT
10343171Sdim * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11343171Sdim * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12343171Sdim * version 2 for more details (a copy is included in the LICENSE file that
13343171Sdim * accompanied this code).
14343171Sdim *
15343171Sdim * You should have received a copy of the GNU General Public License version
16343171Sdim * 2 along with this work; if not, write to the Free Software Foundation,
17343171Sdim * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18343171Sdim *
19343171Sdim * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20343171Sdim * or visit www.oracle.com if you need additional information or have any
21343171Sdim * questions.
22343171Sdim */
23343171Sdimpackage org.graalvm.compiler.hotspot.stubs;
24343171Sdim
25343171Sdimimport org.graalvm.compiler.api.replacements.Snippet;
26343171Sdimimport org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
27343171Sdimimport org.graalvm.compiler.debug.GraalError;
28343171Sdimimport org.graalvm.compiler.hotspot.HotSpotForeignCallLinkage;
29343171Sdimimport org.graalvm.compiler.hotspot.meta.HotSpotProviders;
30343171Sdimimport org.graalvm.compiler.hotspot.nodes.AllocaNode;
31343171Sdimimport org.graalvm.compiler.word.Word;
32343171Sdim
33343171Sdimimport jdk.vm.ci.code.Register;
34343171Sdim
35343171Sdim/**
36343171Sdim * Stub to allocate an {@link ArrayIndexOutOfBoundsException} thrown by a bytecode.
37343171Sdim */
38343171Sdimpublic class OutOfBoundsExceptionStub extends CreateExceptionStub {
39343171Sdim
40343171Sdim    public OutOfBoundsExceptionStub(HotSpotProviders providers, HotSpotForeignCallLinkage linkage) {
41343171Sdim        super("createOutOfBoundsException", providers, linkage);
42343171Sdim    }
43343171Sdim
44343171Sdim    private static final int MAX_INT_STRING_SIZE = Integer.toString(Integer.MIN_VALUE).length();
45343171Sdim
46343171Sdim    @Override
47343171Sdim    protected Object getConstantParameterValue(int index, String name) {
48343171Sdim        switch (index) {
49343171Sdim            case 1:
50343171Sdim                return providers.getRegisters().getThreadRegister();
51343171Sdim            case 2:
52343171Sdim                int wordSize = providers.getWordTypes().getWordKind().getByteCount();
53343171Sdim                // (MAX_INT_STRING_SIZE + 1) / wordSize, rounded up
54343171Sdim                return MAX_INT_STRING_SIZE / wordSize + 1;
55343171Sdim            default:
56343171Sdim                throw GraalError.shouldNotReachHere("unknown parameter " + name + " at index " + index);
57343171Sdim        }
58343171Sdim    }
59343171Sdim
60343171Sdim    @Snippet
61343171Sdim    private static Object createOutOfBoundsException(int idx, @ConstantParameter Register threadRegister, @ConstantParameter int bufferSizeInWords) {
62343171Sdim        Word buffer = AllocaNode.alloca(bufferSizeInWords);
63343171Sdim
64343171Sdim        long number = idx;
65343171Sdim        if (number < 0) {
66343171Sdim            number = -number;
67343171Sdim        }
68343171Sdim
69343171Sdim        Word ptr = buffer.add(MAX_INT_STRING_SIZE);
70343171Sdim        ptr.writeByte(0, (byte) 0);
71343171Sdim        do {
72343171Sdim            long digit = number % 10;
73343171Sdim            number /= 10;
74343171Sdim
75343171Sdim            ptr = ptr.subtract(1);
76343171Sdim            ptr.writeByte(0, (byte) ('0' + digit));
77343171Sdim        } while (number > 0);
78343171Sdim
79343171Sdim        if (idx < 0) {
80343171Sdim            ptr = ptr.subtract(1);
81343171Sdim            ptr.writeByte(0, (byte) '-');
82343171Sdim        }
83343171Sdim
84343171Sdim        return createException(threadRegister, ArrayIndexOutOfBoundsException.class, ptr);
85343171Sdim    }
86343171Sdim}
87343171Sdim