for review (XXL): 6655638 method handles for invokedynamic

Tom Rodriguez Thomas.Rodriguez at Sun.COM
Tue Apr 7 15:38:53 PDT 2009


Looks good to me.

tom

On Apr 7, 2009, at 12:37 AM, John Rose wrote:

> Thanks for going over the method handle stuff, Tom.  It needed it.
>
> The updated webrev, hopefully the final one, is here:
>  http://cr.openjdk.java.net/~jrose/6655638/webrev.03/
>
> The difference between webrev.02 and webrev.03 is here; it contains  
> everything described below in this email:
>  http://cr.openjdk.java.net/~jrose/6655638/02-to-03/
>
> My responses are below.  Please me know if you have further  
> comments, or if I missing the point of something you said.
>
> If all is well enough, I hope to push soon and start a round on  
> review on invokedynamic proper.
>
> -- John
>
> On Mar 31, 2009, at 1:08 PM, Tom Rodriguez wrote:
>
>> Most of my comments are below mostly about style and naming and  
>> could be addressed in later putbacks since this obviously isn't done.
>>
>> MethodEntry is too general of a name.  Maybe you can come up with a  
>> better one.
>
> Changed to MethodHandleEntry.  (That was already in webrev.02, did  
> you see it?)
>
>> CHECK_UNHANDLED_OOPS might be worth running at some point.
>
> Good idea; will do.
>
>> methodHandles.hpp:
>>
>> I'm not a big fan of formatting like this:
>>
>> if (mh.is_null() || target.is_null() || ! 
>> java_dyn_MethodHandle::is_instance(target()))
>>   { throw_InternalError(CHECK); }
>
> I'll put the braces in the usual place on those guys.  (The CHECK  
> and THROW macros are a pain sometimes.)
>
>> Could you format this and others normally?  At most it saves one  
>> line.
>
>> Also the throw_* functions seem a bit excessive.  It also defeats  
>> the fact that the THROW macro records the line number of the throw  
>> point which can be handy for debugging.  Do you distrust the THROW  
>> macro?  Actually, with a smart enough compiler they could lead to  
>> unreachable code warnings since you're effectively writing this:
>>
>> { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, NULL); return;  }
>> { report_should_not_reach_here  (__FILE__, __LINE__); BREAKPOINT; }
>
> I'll expand the uses of the local throw functions and remove them.
>
> I think it was mainly a convenience for prototyping; it was a pain  
> matching the THROW_X macro to the enclosing return type.  You are  
> right about the usefulness of the file//line info.  I'll add the  
> missing THROW_NULL and THROW_MSG_NULL to exceptions.hpp; that was  
> the main irritant.
>
> Actually, after refactoring the adapter verification logic (see  
> below), I kept one one for making InternalErrors with formatted  
> message strings.
>
>> A lot of the methods take oop arguments but then immediately  
>> convert them into handles and have extra logic where the oop  
>> argument is nulled out for safety.  Some even take a mix of handles  
>> and oops.  Why not just use handles uniformly?
>
> There are lots of little functions that don't block and  do  
> something small, usually parse a data structure.  The data  
> structures have lots of indirections, so there are lots of temporary  
> oops flying around.  In this case, handles don't add value; they  
> just slow things down.
>
> I'll make a cleaner separation between trapping functions that take  
> handles, and non-trapping ones that don't.  And I'll comment it.
>
> Trapping functions that I'll change to take all handles:  
> verify_method_type.
> Non-trapping ones that I'll change to take all oops:  
> check_method_receiver.
> Trapping ones I changed to not trap:  all the verify_method_type_*  
> functions.
>
> I found a few places with oop-nulling and I made the code there more  
> handle-oriented.
>
>> adapter_conversion could use some asserts validating the encoding.
>
> Yes, I'll DTRT there.
>
>> When writing flags into the MembarName from  
>> access_flags().as_short() shouldn't you be masking them with  
>> JVM_RECOGNIZED_FIELD_MODIFIERS and JVM_RECOGNIZED_METHOD_MODIFIERS  
>> as appropriate?
>
> Good idea.  No sense encouraging bit leakage.
>
>> There are big chunks of VerifyMethodHandles code in the moddle of  
>> other logic and it might be nice if these were broken out so that  
>> main code would be more readable.
>
> OK, I went ahead and factored all three init_XMH guys to call a  
> verify_XMH with at least the main chunk of verification logic  
> contained in it.
>
>> I know in some cases that might be difficult but  
>> init_AdapterMethodHandle in particular has a chunk that might be  
>> movable.
>
> That's very doable, and the code looks better that way.  Thanks.
>
>> Could you make the natives entry points to make it clear that even  
>> though they are JVM_ENTRY they aren't actually JVM_ entry points?
>
> OK.
>
>> methodHandles_x86.cpp:
>>
>> The padding code in MethodEntry::start_compiled_entry could use a  
>> comment explaining that it's reserving space in the beginning for  
>> the Data field.  The space before this trick feels a little too  
>> clever but I'm not totally against it.
>
> Done.
>
>> Don't do the (int32_t)NULL_WORD cast here:
>>    __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
>
> Right.
>
>> In the add_arg_slots code shouldn't there be an assert in the if  
>> (TaggedStackInterpreter) piece that arg_slots is not a register  
>> since constant_arg_slots won't have a valid value in that case?
>
> The relevant assert is against _INSERT_NO_MASK, which says that the  
> caller has explicitly assumed responsibility for inserting the tag  
> bits.
>
> I made this clearer by moving the TSI-related code all into one block.
>
>> In trace_method_handle_stub the format should be:
>>
>> printf("MH %s %p %p "INTX_FORMAT"\n", adaptername, mh, entry_sp,  
>> entry_sp - saved_sp);
>>
>> since entry_sp - saved_sp is an intptr_t.  You might use PTR_FORMAT  
>> instead of %p since %p isn't consistently defined.
>
> Good idea; done.
>
>> Shouldn't these be movptr?
>>
>>     __ movl(rax_klass, Address(rcx_recv,  
>> oopDesc::klass_offset_in_bytes()));
>>     __ movl(rdx_temp, Address(rdx_temp,  
>> oopDesc::klass_offset_in_bytes()));
>
> Yes.  Actually, I'll change them to use load_klass; will make the  
> LP64 port a little easier.
>
>> Are you going to delete any #if 0 pieces still lying around?
>
> Yes, they are gone.
>
>> What controls which values of the switch are valid in  
>> generate_method_handle_stub?  There are quite a few that sum two  
>> values.
>
> Yeah, well.  Having three different places for the adapter sequence  
> stinks, actually.  I changed it to use two enumerations, one for the  
> JVM and one that bridges to the native Java API.  The EntryKind  
> enumeration is now what all the switches key off of, without  
> addition expressions in the cases.  I kept the bridge to Java in  
> impl_java_dyn_AdapterMethodHandle (with some tweaks to make it look  
> even more like the Java defs).  The AdapterKind guy, which was  
> neither one nor the other, is gone.  Is that better?
>
>> Why is  _adapter_opt_f2i commented out?
>
> Because I haven't gotten around to implementing it.
>
>> a2l and a2i are strangely named and freaked me out at first but  
>> then I realized they are actually unbox operations.  maybe unboxi  
>> and unboxl?
>
> Good idea.  It was a weak parallel with l2i, etc., but it's better  
> to emphasize what's going on.
>
> Done.




More information about the hotspot-compiler-dev mailing list