OSDN Git Service

Merge "Allow libcore and JDWP tests to be executed without JIT."
[android-x86/art.git] / runtime / common_throws.cc
1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include "common_throws.h"
18
19 #include <sstream>
20
21 #include "ScopedLocalRef.h"
22
23 #include "art_field-inl.h"
24 #include "art_method-inl.h"
25 #include "base/logging.h"
26 #include "class_linker-inl.h"
27 #include "dex_file-inl.h"
28 #include "dex_instruction-inl.h"
29 #include "invoke_type.h"
30 #include "mirror/class-inl.h"
31 #include "mirror/object-inl.h"
32 #include "mirror/object_array-inl.h"
33 #include "thread.h"
34 #include "verifier/method_verifier.h"
35
36 namespace art {
37
38 static void AddReferrerLocation(std::ostream& os, mirror::Class* referrer)
39     SHARED_REQUIRES(Locks::mutator_lock_) {
40   if (referrer != nullptr) {
41     std::string location(referrer->GetLocation());
42     if (!location.empty()) {
43       os << " (declaration of '" << PrettyDescriptor(referrer)
44             << "' appears in " << location << ")";
45     }
46   }
47 }
48
49 static void ThrowException(const char* exception_descriptor,
50                            mirror::Class* referrer, const char* fmt, va_list* args = nullptr)
51     SHARED_REQUIRES(Locks::mutator_lock_) {
52   std::ostringstream msg;
53   if (args != nullptr) {
54     std::string vmsg;
55     StringAppendV(&vmsg, fmt, *args);
56     msg << vmsg;
57   } else {
58     msg << fmt;
59   }
60   AddReferrerLocation(msg, referrer);
61   Thread* self = Thread::Current();
62   self->ThrowNewException(exception_descriptor, msg.str().c_str());
63 }
64
65 static void ThrowWrappedException(const char* exception_descriptor,
66                                   mirror::Class* referrer, const char* fmt, va_list* args = nullptr)
67     SHARED_REQUIRES(Locks::mutator_lock_) {
68   std::ostringstream msg;
69   if (args != nullptr) {
70     std::string vmsg;
71     StringAppendV(&vmsg, fmt, *args);
72     msg << vmsg;
73   } else {
74     msg << fmt;
75   }
76   AddReferrerLocation(msg, referrer);
77   Thread* self = Thread::Current();
78   self->ThrowNewWrappedException(exception_descriptor, msg.str().c_str());
79 }
80
81 // AbstractMethodError
82
83 void ThrowAbstractMethodError(ArtMethod* method) {
84   ThrowException("Ljava/lang/AbstractMethodError;", nullptr,
85                  StringPrintf("abstract method \"%s\"",
86                               PrettyMethod(method).c_str()).c_str());
87 }
88
89 void ThrowAbstractMethodError(uint32_t method_idx, const DexFile& dex_file) {
90   ThrowException("Ljava/lang/AbstractMethodError;", /* referrer */ nullptr,
91                  StringPrintf("abstract method \"%s\"",
92                               PrettyMethod(method_idx,
93                                            dex_file,
94                                            /* with_signature */ true).c_str()).c_str());
95 }
96
97 // ArithmeticException
98
99 void ThrowArithmeticExceptionDivideByZero() {
100   ThrowException("Ljava/lang/ArithmeticException;", nullptr, "divide by zero");
101 }
102
103 // ArrayIndexOutOfBoundsException
104
105 void ThrowArrayIndexOutOfBoundsException(int index, int length) {
106   ThrowException("Ljava/lang/ArrayIndexOutOfBoundsException;", nullptr,
107                  StringPrintf("length=%d; index=%d", length, index).c_str());
108 }
109
110 // ArrayStoreException
111
112 void ThrowArrayStoreException(mirror::Class* element_class, mirror::Class* array_class) {
113   ThrowException("Ljava/lang/ArrayStoreException;", nullptr,
114                  StringPrintf("%s cannot be stored in an array of type %s",
115                               PrettyDescriptor(element_class).c_str(),
116                               PrettyDescriptor(array_class).c_str()).c_str());
117 }
118
119 // ClassCastException
120
121 void ThrowClassCastException(mirror::Class* dest_type, mirror::Class* src_type) {
122   ThrowException("Ljava/lang/ClassCastException;", nullptr,
123                  StringPrintf("%s cannot be cast to %s",
124                               PrettyDescriptor(src_type).c_str(),
125                               PrettyDescriptor(dest_type).c_str()).c_str());
126 }
127
128 void ThrowClassCastException(const char* msg) {
129   ThrowException("Ljava/lang/ClassCastException;", nullptr, msg);
130 }
131
132 // ClassCircularityError
133
134 void ThrowClassCircularityError(mirror::Class* c) {
135   std::ostringstream msg;
136   msg << PrettyDescriptor(c);
137   ThrowException("Ljava/lang/ClassCircularityError;", c, msg.str().c_str());
138 }
139
140 void ThrowClassCircularityError(mirror::Class* c, const char* fmt, ...) {
141   va_list args;
142   va_start(args, fmt);
143   ThrowException("Ljava/lang/ClassCircularityError;", c, fmt, &args);
144   va_end(args);
145 }
146
147 // ClassFormatError
148
149 void ThrowClassFormatError(mirror::Class* referrer, const char* fmt, ...) {
150   va_list args;
151   va_start(args, fmt);
152   ThrowException("Ljava/lang/ClassFormatError;", referrer, fmt, &args);
153   va_end(args);
154 }
155
156 // IllegalAccessError
157
158 void ThrowIllegalAccessErrorClass(mirror::Class* referrer, mirror::Class* accessed) {
159   std::ostringstream msg;
160   msg << "Illegal class access: '" << PrettyDescriptor(referrer) << "' attempting to access '"
161       << PrettyDescriptor(accessed) << "'";
162   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
163 }
164
165 void ThrowIllegalAccessErrorClassForMethodDispatch(mirror::Class* referrer, mirror::Class* accessed,
166                                                    ArtMethod* called,
167                                                    InvokeType type) {
168   std::ostringstream msg;
169   msg << "Illegal class access ('" << PrettyDescriptor(referrer) << "' attempting to access '"
170       << PrettyDescriptor(accessed) << "') in attempt to invoke " << type
171       << " method " << PrettyMethod(called).c_str();
172   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
173 }
174
175 void ThrowIllegalAccessErrorMethod(mirror::Class* referrer, ArtMethod* accessed) {
176   std::ostringstream msg;
177   msg << "Method '" << PrettyMethod(accessed) << "' is inaccessible to class '"
178       << PrettyDescriptor(referrer) << "'";
179   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
180 }
181
182 void ThrowIllegalAccessErrorField(mirror::Class* referrer, ArtField* accessed) {
183   std::ostringstream msg;
184   msg << "Field '" << PrettyField(accessed, false) << "' is inaccessible to class '"
185       << PrettyDescriptor(referrer) << "'";
186   ThrowException("Ljava/lang/IllegalAccessError;", referrer, msg.str().c_str());
187 }
188
189 void ThrowIllegalAccessErrorFinalField(ArtMethod* referrer, ArtField* accessed) {
190   std::ostringstream msg;
191   msg << "Final field '" << PrettyField(accessed, false) << "' cannot be written to by method '"
192       << PrettyMethod(referrer) << "'";
193   ThrowException("Ljava/lang/IllegalAccessError;",
194                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
195                  msg.str().c_str());
196 }
197
198 void ThrowIllegalAccessError(mirror::Class* referrer, const char* fmt, ...) {
199   va_list args;
200   va_start(args, fmt);
201   ThrowException("Ljava/lang/IllegalAccessError;", referrer, fmt, &args);
202   va_end(args);
203 }
204
205 // IllegalAccessException
206
207 void ThrowIllegalAccessException(const char* msg) {
208   ThrowException("Ljava/lang/IllegalAccessException;", nullptr, msg);
209 }
210
211 // IllegalArgumentException
212
213 void ThrowIllegalArgumentException(const char* msg) {
214   ThrowException("Ljava/lang/IllegalArgumentException;", nullptr, msg);
215 }
216
217
218 // IncompatibleClassChangeError
219
220 void ThrowIncompatibleClassChangeError(InvokeType expected_type, InvokeType found_type,
221                                        ArtMethod* method, ArtMethod* referrer) {
222   std::ostringstream msg;
223   msg << "The method '" << PrettyMethod(method) << "' was expected to be of type "
224       << expected_type << " but instead was found to be of type " << found_type;
225   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
226                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
227                  msg.str().c_str());
228 }
229
230 void ThrowIncompatibleClassChangeErrorClassForInterfaceSuper(ArtMethod* method,
231                                                              mirror::Class* target_class,
232                                                              mirror::Object* this_object,
233                                                              ArtMethod* referrer) {
234   // Referrer is calling interface_method on this_object, however, the interface_method isn't
235   // implemented by this_object.
236   CHECK(this_object != nullptr);
237   std::ostringstream msg;
238   msg << "Class '" << PrettyDescriptor(this_object->GetClass())
239       << "' does not implement interface '" << PrettyDescriptor(target_class) << "' in call to '"
240       << PrettyMethod(method) << "'";
241   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
242                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
243                  msg.str().c_str());
244 }
245
246 void ThrowIncompatibleClassChangeErrorClassForInterfaceDispatch(ArtMethod* interface_method,
247                                                                 mirror::Object* this_object,
248                                                                 ArtMethod* referrer) {
249   // Referrer is calling interface_method on this_object, however, the interface_method isn't
250   // implemented by this_object.
251   CHECK(this_object != nullptr);
252   std::ostringstream msg;
253   msg << "Class '" << PrettyDescriptor(this_object->GetClass())
254       << "' does not implement interface '"
255       << PrettyDescriptor(interface_method->GetDeclaringClass())
256       << "' in call to '" << PrettyMethod(interface_method) << "'";
257   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
258                  referrer != nullptr ? referrer->GetDeclaringClass() : nullptr,
259                  msg.str().c_str());
260 }
261
262 void ThrowIncompatibleClassChangeErrorField(ArtField* resolved_field, bool is_static,
263                                             ArtMethod* referrer) {
264   std::ostringstream msg;
265   msg << "Expected '" << PrettyField(resolved_field) << "' to be a "
266       << (is_static ? "static" : "instance") << " field" << " rather than a "
267       << (is_static ? "instance" : "static") << " field";
268   ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer->GetDeclaringClass(),
269                  msg.str().c_str());
270 }
271
272 void ThrowIncompatibleClassChangeError(mirror::Class* referrer, const char* fmt, ...) {
273   va_list args;
274   va_start(args, fmt);
275   ThrowException("Ljava/lang/IncompatibleClassChangeError;", referrer, fmt, &args);
276   va_end(args);
277 }
278
279 void ThrowIncompatibleClassChangeErrorForMethodConflict(ArtMethod* method) {
280   DCHECK(method != nullptr);
281   ThrowException("Ljava/lang/IncompatibleClassChangeError;",
282                  /*referrer*/nullptr,
283                  StringPrintf("Conflicting default method implementations %s",
284                               PrettyMethod(method).c_str()).c_str());
285 }
286
287
288 // IOException
289
290 void ThrowIOException(const char* fmt, ...) {
291   va_list args;
292   va_start(args, fmt);
293   ThrowException("Ljava/io/IOException;", nullptr, fmt, &args);
294   va_end(args);
295 }
296
297 void ThrowWrappedIOException(const char* fmt, ...) {
298   va_list args;
299   va_start(args, fmt);
300   ThrowWrappedException("Ljava/io/IOException;", nullptr, fmt, &args);
301   va_end(args);
302 }
303
304 // LinkageError
305
306 void ThrowLinkageError(mirror::Class* referrer, const char* fmt, ...) {
307   va_list args;
308   va_start(args, fmt);
309   ThrowException("Ljava/lang/LinkageError;", referrer, fmt, &args);
310   va_end(args);
311 }
312
313 void ThrowWrappedLinkageError(mirror::Class* referrer, const char* fmt, ...) {
314   va_list args;
315   va_start(args, fmt);
316   ThrowWrappedException("Ljava/lang/LinkageError;", referrer, fmt, &args);
317   va_end(args);
318 }
319
320 // NegativeArraySizeException
321
322 void ThrowNegativeArraySizeException(int size) {
323   ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr,
324                  StringPrintf("%d", size).c_str());
325 }
326
327 void ThrowNegativeArraySizeException(const char* msg) {
328   ThrowException("Ljava/lang/NegativeArraySizeException;", nullptr, msg);
329 }
330
331 // NoSuchFieldError
332
333 void ThrowNoSuchFieldError(const StringPiece& scope, mirror::Class* c,
334                            const StringPiece& type, const StringPiece& name) {
335   std::ostringstream msg;
336   std::string temp;
337   msg << "No " << scope << "field " << name << " of type " << type
338       << " in class " << c->GetDescriptor(&temp) << " or its superclasses";
339   ThrowException("Ljava/lang/NoSuchFieldError;", c, msg.str().c_str());
340 }
341
342 void ThrowNoSuchFieldException(mirror::Class* c, const StringPiece& name) {
343   std::ostringstream msg;
344   std::string temp;
345   msg << "No field " << name << " in class " << c->GetDescriptor(&temp);
346   ThrowException("Ljava/lang/NoSuchFieldException;", c, msg.str().c_str());
347 }
348
349 // NoSuchMethodError
350
351 void ThrowNoSuchMethodError(InvokeType type, mirror::Class* c, const StringPiece& name,
352                             const Signature& signature) {
353   std::ostringstream msg;
354   std::string temp;
355   msg << "No " << type << " method " << name << signature
356       << " in class " << c->GetDescriptor(&temp) << " or its super classes";
357   ThrowException("Ljava/lang/NoSuchMethodError;", c, msg.str().c_str());
358 }
359
360 void ThrowNoSuchMethodError(uint32_t method_idx) {
361   ArtMethod* method = Thread::Current()->GetCurrentMethod(nullptr);
362   mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
363   const DexFile& dex_file = *dex_cache->GetDexFile();
364   std::ostringstream msg;
365   msg << "No method '" << PrettyMethod(method_idx, dex_file, true) << "'";
366   ThrowException("Ljava/lang/NoSuchMethodError;",
367                  method->GetDeclaringClass(), msg.str().c_str());
368 }
369
370 // NullPointerException
371
372 void ThrowNullPointerExceptionForFieldAccess(ArtField* field, bool is_read) {
373   std::ostringstream msg;
374   msg << "Attempt to " << (is_read ? "read from" : "write to")
375       << " field '" << PrettyField(field, true) << "' on a null object reference";
376   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
377 }
378
379 static void ThrowNullPointerExceptionForMethodAccessImpl(uint32_t method_idx,
380                                                          const DexFile& dex_file,
381                                                          InvokeType type)
382     SHARED_REQUIRES(Locks::mutator_lock_) {
383   std::ostringstream msg;
384   msg << "Attempt to invoke " << type << " method '"
385       << PrettyMethod(method_idx, dex_file, true) << "' on a null object reference";
386   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg.str().c_str());
387 }
388
389 void ThrowNullPointerExceptionForMethodAccess(uint32_t method_idx,
390                                               InvokeType type) {
391   mirror::DexCache* dex_cache =
392       Thread::Current()->GetCurrentMethod(nullptr)->GetDeclaringClass()->GetDexCache();
393   const DexFile& dex_file = *dex_cache->GetDexFile();
394   ThrowNullPointerExceptionForMethodAccessImpl(method_idx, dex_file, type);
395 }
396
397 void ThrowNullPointerExceptionForMethodAccess(ArtMethod* method,
398                                               InvokeType type) {
399   mirror::DexCache* dex_cache = method->GetDeclaringClass()->GetDexCache();
400   const DexFile& dex_file = *dex_cache->GetDexFile();
401   ThrowNullPointerExceptionForMethodAccessImpl(method->GetDexMethodIndex(),
402                                                dex_file, type);
403 }
404
405 void ThrowNullPointerExceptionFromDexPC() {
406   uint32_t throw_dex_pc;
407   ArtMethod* method = Thread::Current()->GetCurrentMethod(&throw_dex_pc);
408   const DexFile::CodeItem* code = method->GetCodeItem();
409   CHECK_LT(throw_dex_pc, code->insns_size_in_code_units_);
410   const Instruction* instr = Instruction::At(&code->insns_[throw_dex_pc]);
411   switch (instr->Opcode()) {
412     case Instruction::INVOKE_DIRECT:
413       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kDirect);
414       break;
415     case Instruction::INVOKE_DIRECT_RANGE:
416       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kDirect);
417       break;
418     case Instruction::INVOKE_VIRTUAL:
419       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kVirtual);
420       break;
421     case Instruction::INVOKE_VIRTUAL_RANGE:
422       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kVirtual);
423       break;
424     case Instruction::INVOKE_INTERFACE:
425       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_35c(), kInterface);
426       break;
427     case Instruction::INVOKE_INTERFACE_RANGE:
428       ThrowNullPointerExceptionForMethodAccess(instr->VRegB_3rc(), kInterface);
429       break;
430     case Instruction::INVOKE_VIRTUAL_QUICK:
431     case Instruction::INVOKE_VIRTUAL_RANGE_QUICK: {
432       // Since we replaced the method index, we ask the verifier to tell us which
433       // method is invoked at this location.
434       ArtMethod* invoked_method =
435           verifier::MethodVerifier::FindInvokedMethodAtDexPc(method, throw_dex_pc);
436       if (invoked_method != nullptr) {
437         // NPE with precise message.
438         ThrowNullPointerExceptionForMethodAccess(invoked_method, kVirtual);
439       } else {
440         // NPE with imprecise message.
441         ThrowNullPointerException("Attempt to invoke a virtual method on a null object reference");
442       }
443       break;
444     }
445     case Instruction::IGET:
446     case Instruction::IGET_WIDE:
447     case Instruction::IGET_OBJECT:
448     case Instruction::IGET_BOOLEAN:
449     case Instruction::IGET_BYTE:
450     case Instruction::IGET_CHAR:
451     case Instruction::IGET_SHORT: {
452       ArtField* field =
453           Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false);
454       ThrowNullPointerExceptionForFieldAccess(field, true /* read */);
455       break;
456     }
457     case Instruction::IGET_QUICK:
458     case Instruction::IGET_BOOLEAN_QUICK:
459     case Instruction::IGET_BYTE_QUICK:
460     case Instruction::IGET_CHAR_QUICK:
461     case Instruction::IGET_SHORT_QUICK:
462     case Instruction::IGET_WIDE_QUICK:
463     case Instruction::IGET_OBJECT_QUICK: {
464       // Since we replaced the field index, we ask the verifier to tell us which
465       // field is accessed at this location.
466       ArtField* field =
467           verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc);
468       if (field != nullptr) {
469         // NPE with precise message.
470         ThrowNullPointerExceptionForFieldAccess(field, true /* read */);
471       } else {
472         // NPE with imprecise message.
473         ThrowNullPointerException("Attempt to read from a field on a null object reference");
474       }
475       break;
476     }
477     case Instruction::IPUT:
478     case Instruction::IPUT_WIDE:
479     case Instruction::IPUT_OBJECT:
480     case Instruction::IPUT_BOOLEAN:
481     case Instruction::IPUT_BYTE:
482     case Instruction::IPUT_CHAR:
483     case Instruction::IPUT_SHORT: {
484       ArtField* field =
485           Runtime::Current()->GetClassLinker()->ResolveField(instr->VRegC_22c(), method, false);
486       ThrowNullPointerExceptionForFieldAccess(field, false /* write */);
487       break;
488     }
489     case Instruction::IPUT_QUICK:
490     case Instruction::IPUT_BOOLEAN_QUICK:
491     case Instruction::IPUT_BYTE_QUICK:
492     case Instruction::IPUT_CHAR_QUICK:
493     case Instruction::IPUT_SHORT_QUICK:
494     case Instruction::IPUT_WIDE_QUICK:
495     case Instruction::IPUT_OBJECT_QUICK: {
496       // Since we replaced the field index, we ask the verifier to tell us which
497       // field is accessed at this location.
498       ArtField* field =
499           verifier::MethodVerifier::FindAccessedFieldAtDexPc(method, throw_dex_pc);
500       if (field != nullptr) {
501         // NPE with precise message.
502         ThrowNullPointerExceptionForFieldAccess(field, false /* write */);
503       } else {
504         // NPE with imprecise message.
505         ThrowNullPointerException("Attempt to write to a field on a null object reference");
506       }
507       break;
508     }
509     case Instruction::AGET:
510     case Instruction::AGET_WIDE:
511     case Instruction::AGET_OBJECT:
512     case Instruction::AGET_BOOLEAN:
513     case Instruction::AGET_BYTE:
514     case Instruction::AGET_CHAR:
515     case Instruction::AGET_SHORT:
516       ThrowException("Ljava/lang/NullPointerException;", nullptr,
517                      "Attempt to read from null array");
518       break;
519     case Instruction::APUT:
520     case Instruction::APUT_WIDE:
521     case Instruction::APUT_OBJECT:
522     case Instruction::APUT_BOOLEAN:
523     case Instruction::APUT_BYTE:
524     case Instruction::APUT_CHAR:
525     case Instruction::APUT_SHORT:
526       ThrowException("Ljava/lang/NullPointerException;", nullptr,
527                      "Attempt to write to null array");
528       break;
529     case Instruction::ARRAY_LENGTH:
530       ThrowException("Ljava/lang/NullPointerException;", nullptr,
531                      "Attempt to get length of null array");
532       break;
533     default: {
534       // TODO: We should have covered all the cases where we expect a NPE above, this
535       //       message/logging is so we can improve any cases we've missed in the future.
536       const DexFile* dex_file =
537           method->GetDeclaringClass()->GetDexCache()->GetDexFile();
538       ThrowException("Ljava/lang/NullPointerException;", nullptr,
539                      StringPrintf("Null pointer exception during instruction '%s'",
540                                   instr->DumpString(dex_file).c_str()).c_str());
541       break;
542     }
543   }
544 }
545
546 void ThrowNullPointerException(const char* msg) {
547   ThrowException("Ljava/lang/NullPointerException;", nullptr, msg);
548 }
549
550 // RuntimeException
551
552 void ThrowRuntimeException(const char* fmt, ...) {
553   va_list args;
554   va_start(args, fmt);
555   ThrowException("Ljava/lang/RuntimeException;", nullptr, fmt, &args);
556   va_end(args);
557 }
558
559 // Stack overflow.
560
561 void ThrowStackOverflowError(Thread* self) {
562   if (self->IsHandlingStackOverflow()) {
563     LOG(ERROR) << "Recursive stack overflow.";
564     // We don't fail here because SetStackEndForStackOverflow will print better diagnostics.
565   }
566
567   self->SetStackEndForStackOverflow();  // Allow space on the stack for constructor to execute.
568   JNIEnvExt* env = self->GetJniEnv();
569   std::string msg("stack size ");
570   msg += PrettySize(self->GetStackSize());
571
572   // Avoid running Java code for exception initialization.
573   // TODO: Checks to make this a bit less brittle.
574
575   std::string error_msg;
576
577   // Allocate an uninitialized object.
578   ScopedLocalRef<jobject> exc(env,
579                               env->AllocObject(WellKnownClasses::java_lang_StackOverflowError));
580   if (exc.get() != nullptr) {
581     // "Initialize".
582     // StackOverflowError -> VirtualMachineError -> Error -> Throwable -> Object.
583     // Only Throwable has "custom" fields:
584     //   String detailMessage.
585     //   Throwable cause (= this).
586     //   List<Throwable> suppressedExceptions (= Collections.emptyList()).
587     //   Object stackState;
588     //   StackTraceElement[] stackTrace;
589     // Only Throwable has a non-empty constructor:
590     //   this.stackTrace = EmptyArray.STACK_TRACE_ELEMENT;
591     //   fillInStackTrace();
592
593     // detailMessage.
594     // TODO: Use String::FromModifiedUTF...?
595     ScopedLocalRef<jstring> s(env, env->NewStringUTF(msg.c_str()));
596     if (s.get() != nullptr) {
597       env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_detailMessage, s.get());
598
599       // cause.
600       env->SetObjectField(exc.get(), WellKnownClasses::java_lang_Throwable_cause, exc.get());
601
602       // suppressedExceptions.
603       ScopedLocalRef<jobject> emptylist(env, env->GetStaticObjectField(
604           WellKnownClasses::java_util_Collections,
605           WellKnownClasses::java_util_Collections_EMPTY_LIST));
606       CHECK(emptylist.get() != nullptr);
607       env->SetObjectField(exc.get(),
608                           WellKnownClasses::java_lang_Throwable_suppressedExceptions,
609                           emptylist.get());
610
611       // stackState is set as result of fillInStackTrace. fillInStackTrace calls
612       // nativeFillInStackTrace.
613       ScopedLocalRef<jobject> stack_state_val(env, nullptr);
614       {
615         ScopedObjectAccessUnchecked soa(env);
616         stack_state_val.reset(soa.Self()->CreateInternalStackTrace<false>(soa));
617       }
618       if (stack_state_val.get() != nullptr) {
619         env->SetObjectField(exc.get(),
620                             WellKnownClasses::java_lang_Throwable_stackState,
621                             stack_state_val.get());
622
623         // stackTrace.
624         ScopedLocalRef<jobject> stack_trace_elem(env, env->GetStaticObjectField(
625             WellKnownClasses::libcore_util_EmptyArray,
626             WellKnownClasses::libcore_util_EmptyArray_STACK_TRACE_ELEMENT));
627         env->SetObjectField(exc.get(),
628                             WellKnownClasses::java_lang_Throwable_stackTrace,
629                             stack_trace_elem.get());
630       } else {
631         error_msg = "Could not create stack trace.";
632       }
633       // Throw the exception.
634       self->SetException(reinterpret_cast<mirror::Throwable*>(self->DecodeJObject(exc.get())));
635     } else {
636       // Could not allocate a string object.
637       error_msg = "Couldn't throw new StackOverflowError because JNI NewStringUTF failed.";
638     }
639   } else {
640     error_msg = "Could not allocate StackOverflowError object.";
641   }
642
643   if (!error_msg.empty()) {
644     LOG(WARNING) << error_msg;
645     CHECK(self->IsExceptionPending());
646   }
647
648   bool explicit_overflow_check = Runtime::Current()->ExplicitStackOverflowChecks();
649   self->ResetDefaultStackEnd();  // Return to default stack size.
650
651   // And restore protection if implicit checks are on.
652   if (!explicit_overflow_check) {
653     self->ProtectStack();
654   }
655 }
656
657 // VerifyError
658
659 void ThrowVerifyError(mirror::Class* referrer, const char* fmt, ...) {
660   va_list args;
661   va_start(args, fmt);
662   ThrowException("Ljava/lang/VerifyError;", referrer, fmt, &args);
663   va_end(args);
664 }
665
666 }  // namespace art