Closed Bug 877893 Opened 11 years ago Closed 11 years ago

PJS: Support basic string operations in parallel

Categories

(Core :: JavaScript Engine, defect)

defect
Not set
normal

Tracking

()

RESOLVED FIXED
mozilla25

People

(Reporter: shu, Assigned: shu)

References

Details

Attachments

(4 files)

Should have at least concatenation and int and double conversion.
Depends on: 877559, 875661
Assignee: general → shu
Attachment #760728 - Flags: review?(wmccloskey)
Attachment #760729 - Flags: review?(kvijayan)
Blocks: 881593
Comment on attachment 760729 [details] [diff] [review]
Part 2: Support string concat in parallel in Ion

Review of attachment 760729 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/ion/MIR.h
@@ +3540,5 @@
> +    }
> +
> +    static MParConcat *New(MDefinition *parSlice, MConcat *concat) {
> +        return New(parSlice, concat->lhs(), concat->rhs());
> +    }

This construction method seems redundant to me, why not just use |ins->lhs()| and |ins->rhs()| at the call site?
Attachment #760729 - Flags: review?(kvijayan) → review+
Comment on attachment 760731 [details] [diff] [review]
Part 4: Support MToString in parallel and add LDoubleToString

Review of attachment 760731 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/ion/CodeGenerator.cpp
@@ +591,5 @@
> +                        StoreRegisterTo(output));
> +        break;
> +      case ParallelExecution:
> +        ool = oolCallVM(ParallelIntToStringInfo, lir, (ArgList(), input),
> +                        StoreValueTo(AnyRegister(output)));

This should be able to be a StoreRegisterTo(output).

A callVM on a function with an output-MutableHandleString will call masm.popRooted(VMFunction::RootString, ReturnReg, JSReturnOperand), and the result will be stored in the ReturnReg.

StoreRegisterTo will perform a store from ReturnReg, whereas StoreValueTo performs a store from ValueOperand.

StoreValueTo's usage here seems incorrect.

@@ +632,5 @@
> +                        StoreRegisterTo(output));
> +        break;
> +      case ParallelExecution:
> +        ool = oolCallVM(ParallelDoubleToStringInfo, lir, (ArgList(), input),
> +                        StoreValueTo(AnyRegister(output)));

Same as above.  This should be StoreRegisterTo.

::: js/src/ion/IonBuilder.cpp
@@ +3253,5 @@
>          (left->type() == MIRType_String || right->type() == MIRType_String) &&
> +        (left->type() == MIRType_String ||
> +         left->type() == MIRType_Int32 || left->type() == MIRType_Double) &&
> +        (right->type() == MIRType_String ||
> +         right->type() == MIRType_Int32 || right->type() == MIRType_Double))

This conditional is super confusing and reflects intent poorly (not due to your changes in particular, but even the old version).

The following would be better:

if (op == JSOP_ADD &&
    ((left->type() == MIRType_String &&
        (right->type() == MIRType_String ||
         right->type() == MIRType_Int32 ||
         right->type() == MIRType_Double)) ||
     (left->type() == MIRType_Int32 &&
      right->type() == MIRType_String) ||
     (left->type() == MIRType_Double &&
      right->type() == MIRType_String)))
{
...
}

This would explain the captured cases a lot more clearly.
Attachment #760731 - Flags: review?(kvijayan) → review+
(In reply to Kannan Vijayan [:djvj] from comment #6)
> Comment on attachment 760731 [details] [diff] [review]
> Part 4: Support MToString in parallel and add LDoubleToString
> 
> Review of attachment 760731 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: js/src/ion/CodeGenerator.cpp
> @@ +591,5 @@
> > +                        StoreRegisterTo(output));
> > +        break;
> > +      case ParallelExecution:
> > +        ool = oolCallVM(ParallelIntToStringInfo, lir, (ArgList(), input),
> > +                        StoreValueTo(AnyRegister(output)));
> 
> This should be able to be a StoreRegisterTo(output).
> 
> A callVM on a function with an output-MutableHandleString will call
> masm.popRooted(VMFunction::RootString, ReturnReg, JSReturnOperand), and the
> result will be stored in the ReturnReg.
> 
> StoreRegisterTo will perform a store from ReturnReg, whereas StoreValueTo
> performs a store from ValueOperand.
> 
> StoreValueTo's usage here seems incorrect.
> 

Good catch, I prepared this patch wrong I think, after I landed the non-Value handle outparam patch on central.

> @@ +632,5 @@
> > +                        StoreRegisterTo(output));
> > +        break;
> > +      case ParallelExecution:
> > +        ool = oolCallVM(ParallelDoubleToStringInfo, lir, (ArgList(), input),
> > +                        StoreValueTo(AnyRegister(output)));
> 
> Same as above.  This should be StoreRegisterTo.
> 
> ::: js/src/ion/IonBuilder.cpp
> @@ +3253,5 @@
> >          (left->type() == MIRType_String || right->type() == MIRType_String) &&
> > +        (left->type() == MIRType_String ||
> > +         left->type() == MIRType_Int32 || left->type() == MIRType_Double) &&
> > +        (right->type() == MIRType_String ||
> > +         right->type() == MIRType_Int32 || right->type() == MIRType_Double))
> 
> This conditional is super confusing and reflects intent poorly (not due to
> your changes in particular, but even the old version).
> 
> The following would be better:
> 
> if (op == JSOP_ADD &&
>     ((left->type() == MIRType_String &&
>         (right->type() == MIRType_String ||
>          right->type() == MIRType_Int32 ||
>          right->type() == MIRType_Double)) ||
>      (left->type() == MIRType_Int32 &&
>       right->type() == MIRType_String) ||
>      (left->type() == MIRType_Double &&
>       right->type() == MIRType_String)))
> {
> ...
> }
> 
> This would explain the captured cases a lot more clearly.

Agreed.
(In reply to Kannan Vijayan [:djvj] from comment #5)
> Comment on attachment 760729 [details] [diff] [review]
> Part 2: Support string concat in parallel in Ion
> 
> Review of attachment 760729 [details] [diff] [review]:
> -----------------------------------------------------------------
> 
> ::: js/src/ion/MIR.h
> @@ +3540,5 @@
> > +    }
> > +
> > +    static MParConcat *New(MDefinition *parSlice, MConcat *concat) {
> > +        return New(parSlice, concat->lhs(), concat->rhs());
> > +    }
> 
> This construction method seems redundant to me, why not just use
> |ins->lhs()| and |ins->rhs()| at the call site?

It's been a convention that all the Par variants have a convenience constructor that takes the sequential variant.
Comment on attachment 760730 [details] [diff] [review]
Part 3: Convert VM functions needed for converting int/double to string to take ThreadSafeContext

Review of attachment 760730 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/jsnum.cpp
@@ +522,1 @@
>      if (JSFlatString *str = c->dtoaCache.lookup(10, si))

This seems a little scary to me. If the main thread were allowed to run at the same time, this would be problematic. Luke pointed out that that doesn't happen, so I guess it's safe. However, I doubt it helps very much, so I'd rather avoid it in the off-thread case, if only for readability. That would happen automatically if we don't have public access to ThreadSafeContext::compartment, which I'd like to see.
Attachment #760730 - Flags: review?(wmccloskey) → review+
Comment on attachment 760728 [details] [diff] [review]
Part 1: Convert various string VM functions to take ThreadSafeContext

Review of attachment 760728 [details] [diff] [review]:
-----------------------------------------------------------------

::: js/src/jsstr.h
@@ +22,5 @@
>  class JSStableString;
>  
>  namespace js {
>  
> +class ThreadSafeContext;

I think this shouldn't be needed with the jspubtd.h change.

::: js/src/vm/String-inl.h
@@ +173,5 @@
>               typename js::MaybeRooted<JSString*, allowGC>::HandleType right,
>               size_t length)
>  {
> +    JSContext *cxIfCanGC = allowGC ? tcx->toJSContext() : NULL;
> +    if (!validateLength(cxIfCanGC, length))

Can you change validateLength to take a ThreadSafeContext and call reportAllocationOverflow on it in the failure case? That seems cleaner.

::: js/src/vm/String.cpp
@@ +162,5 @@
>  }
>  
>  template<JSRope::UsingBarrier b>
>  JSFlatString *
> +JSRope::flattenInternal(ThreadSafeContext *maybetcx)

Can we assert at the top of this function that b == NoBarrier if maybetcx is not a JSContext?

::: js/src/vm/String.h
@@ +32,5 @@
>  namespace js {
>  
>  class StaticStrings;
>  class PropertyName;
> +class ThreadSafeContext;

..same
Attachment #760728 - Flags: review?(wmccloskey) → review+
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: