Mercurial > hg > truffle
diff src/share/vm/opto/memnode.cpp @ 2320:41d4973cf100
6942326: x86 code in string_indexof() could read beyond reserved heap space
Summary: copy small (<8) strings on stack if str+16 crosses a page boundary and load from stack into XMM. Back up pointer when loading string's tail.
Reviewed-by: never
author | kvn |
---|---|
date | Sat, 26 Feb 2011 12:10:54 -0800 |
parents | 5a41a201d08c |
children | b099aaf51bf8 |
line wrap: on
line diff
--- a/src/share/vm/opto/memnode.cpp Thu Feb 24 14:49:34 2011 -0800 +++ b/src/share/vm/opto/memnode.cpp Sat Feb 26 12:10:54 2011 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2011, 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 @@ -1559,21 +1559,24 @@ phase->C->has_unsafe_access(), "Field accesses must be precise" ); // For oop loads, we expect the _type to be precise - if (OptimizeStringConcat && klass == phase->C->env()->String_klass() && + if (klass == phase->C->env()->String_klass() && adr->is_AddP() && off != Type::OffsetBot) { - // For constant Strings treat the fields as compile time constants. + // For constant Strings treat the final fields as compile time constants. Node* base = adr->in(AddPNode::Base); const TypeOopPtr* t = phase->type(base)->isa_oopptr(); if (t != NULL && t->singleton()) { - ciObject* string = t->const_oop(); - ciConstant constant = string->as_instance()->field_value_by_offset(off); - if (constant.basic_type() == T_INT) { - return TypeInt::make(constant.as_int()); - } else if (constant.basic_type() == T_ARRAY) { - if (adr->bottom_type()->is_ptr_to_narrowoop()) { - return TypeNarrowOop::make_from_constant(constant.as_object()); - } else { - return TypeOopPtr::make_from_constant(constant.as_object()); + ciField* field = phase->C->env()->String_klass()->get_field_by_offset(off, false); + if (field != NULL && field->is_final()) { + ciObject* string = t->const_oop(); + ciConstant constant = string->as_instance()->field_value(field); + if (constant.basic_type() == T_INT) { + return TypeInt::make(constant.as_int()); + } else if (constant.basic_type() == T_ARRAY) { + if (adr->bottom_type()->is_ptr_to_narrowoop()) { + return TypeNarrowOop::make_from_constant(constant.as_object()); + } else { + return TypeOopPtr::make_from_constant(constant.as_object()); + } } } }