Closed Bug 521447 Opened 15 years ago Closed 15 years ago

Int/double confusion when computing sum with recursion

Categories

(Core :: JavaScript Engine, defect)

x86
macOS
defect
Not set
normal

Tracking

()

RESOLVED FIXED

People

(Reporter: jruderman, Assigned: dvander)

References

Details

(Keywords: regression, testcase, Whiteboard: fixed-in-tracemonkey)

Attachments

(1 file, 2 obsolete files)

print("hello");
function sum_slicing(array) {
  return array.length==0?0:array[0]+sum_slicing(array.slice(1));
}
for (var j = 0; j < 40; ++j) {
  if (j % 2 == 1) {
    print(sum_slicing([1,2,4,.1,.2]));
  }
}


Should say "7.3" consistently, but on some iterations it says "-6.277435978499887e+66".
Assignee: general → dvander
The bug is that RecursiveSlotMap::adjustTypes() doesn't fix-up the specialization of the return value in case of int/double confusion.

This is not a trivial fix, I have to rework the SlotMap design a little and verify that both consumers of RecursiveSlotMap will be compatible.

I have a patch almost ready but it asserts with the test case in bug 521476, so it needs a little more work.
Attached patch fix (obsolete) — Splinter Review
When closing a loop, |SlotMap::adjustTypes()| invokes the tracker one last time to deal with promotion fixups. This is crucial because if slot X is INT32, and is compatible with a peer tree where slot X is DOUBLE, adjustTypes() will correctly link them together.

What this means: An exit typemap can have INT32 in a slot, but actually contain a double, if it is directly connected to a compatible peer.

Unfortunately the tracker doesn't work for propagating the return value with recursion, because the |sp| offset has a whacky computation. I tried to avoid that by manually and aggressively demoting the return value, but I didn't account for this in adjustTypes(), and trees got stitched together with incorrect types.

This patch puts return value propagation in the intended order, emulating what the tracker would do. There are two cases: 1) normal up recursion, where the return value must be written to the prior frame, and the current frame popped, and 2) "slurp" recursion, where the return value can be placed in the current frame.

While going over this code it seems like the entire TypeCheck_Promote path, recursive or not, is either unnecessary or poorly understood. Follow-up bug coming to address this.
Attached patch more context (obsolete) — Splinter Review
Attachment #405953 - Attachment is obsolete: true
Attachment #405954 - Flags: review?(gal)
Comment on attachment 405954 [details] [diff] [review]
more context

I think this patch can be simplified if I just address the TypeCheck_Promote oddities now - will post another shortly.
Attached patch better fixSplinter Review
Attachment #405954 - Attachment is obsolete: true
Attachment #406105 - Flags: review?(gal) → review+
Comment on attachment 406105 [details] [diff] [review]
better fix


We should create some common code for this (in a follow-up patch):

>+        switch (returnType)
>+        {
>+          case TT_PSEUDOBOOLEAN:
>+          case TT_INT32:
>+            rval_ins = lir->insLoad(LIR_ld, lirbuf->sp, exit->sp_adj - sizeof(double));
>+            break;
>+          case TT_DOUBLE:
>+            rval_ins = lir->insLoad(LIR_ldq, lirbuf->sp, exit->sp_adj - sizeof(double));
>+            break;
>+          case TT_FUNCTION:
>+          case TT_OBJECT:
>+          case TT_STRING:
>+          case TT_NULL:
>+            rval_ins = lir->insLoad(LIR_ldp, lirbuf->sp, exit->sp_adj - sizeof(double));
>+            break;
>+          default:
>+            JS_NOT_REACHED("unknown type");
>+        }
>     }
Whiteboard: fixed-in-tracemonkey
http://hg.mozilla.org/mozilla-central/rev/31a4c08387f1
Status: NEW → RESOLVED
Closed: 15 years ago
Resolution: --- → FIXED
Group: core-security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: