Title: [195831] trunk
Revision
195831
Author
[email protected]
Date
2016-01-29 11:46:01 -0800 (Fri, 29 Jan 2016)

Log Message

Exits from exceptions shouldn't jettison code
https://bugs.webkit.org/show_bug.cgi?id=153564

Reviewed by Geoffrey Garen.

Source/_javascript_Core:

We create two new exit kinds for exception-handling
OSRExits:
- ExceptionCheck: an exception check after a C call.
- GenericUnwind: an OSR exit executes because it's jumped to from genericUnwind machinery.

Having these two new exit kinds allows us to remove fields from
various OSRExit variants that store booleans indicating
if the exit is an exception handler, and if so, what kind
of exception handler. Most of this patch is just removing
those old fields and adding new equivalent functions.

This patch also implements the policy that we should never consider jettisoning
code from exits that happen from an exception check to an op_catch (it might be worth
considering a similar policy for 'throw'). We're choosing this policy because
it will almost never be more expensive, in total, to execute the OSR exit than
to execute the baseline variant of the code. When an exception is thrown, we do
really expensive work, like call through to genericUnwind, and also create an error
object with a stack trace. The cost of OSR exiting here is small in comparison to
those other operations. And penalizing a CodeBlock for OSR exiting from an exception
is silly because the basis of our implementation of exception handling in the
upper tiers is to OSR exit on a caught exception. So we used to penalize
ourselves for having an implementation that is correct w.r.t our design goals.

I've verified this hypothesis with on v8-raytrace by adding a new 
benchmark that throws with very high frequency. Implementing
this policy on that benchmark results in about a 4-5% speed up.

* bytecode/ExitKind.cpp:
(JSC::exitKindToString):
(JSC::exitKindMayJettison):
(JSC::exitKindIsCountable): Deleted.
* bytecode/ExitKind.h:
* dfg/DFGJITCode.cpp:
(JSC::DFG::JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite):
* dfg/DFGJITCompiler.cpp:
(JSC::DFG::JITCompiler::noticeOSREntry):
(JSC::DFG::JITCompiler::appendExceptionHandlingOSRExit):
(JSC::DFG::JITCompiler::exceptionCheck):
(JSC::DFG::JITCompiler::recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded):
* dfg/DFGJITCompiler.h:
* dfg/DFGOSRExit.cpp:
(JSC::DFG::OSRExit::OSRExit):
* dfg/DFGOSRExit.h:
(JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
* dfg/DFGOSRExitBase.h:
(JSC::DFG::OSRExitBase::OSRExitBase):
(JSC::DFG::OSRExitBase::isExceptionHandler):
(JSC::DFG::OSRExitBase::isGenericUnwindHandler):
(JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
* dfg/DFGOSRExitCompiler.cpp:
* dfg/DFGOSRExitCompiler32_64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompiler64.cpp:
(JSC::DFG::OSRExitCompiler::compileExit):
* dfg/DFGOSRExitCompilerCommon.cpp:
(JSC::DFG::handleExitCounts):
(JSC::DFG::osrWriteBarrier):
(JSC::DFG::adjustAndJumpToTarget):
* dfg/DFGOSRExitCompilerCommon.h:
(JSC::DFG::adjustFrameAndStackInOSRExitCompilerThunk):
* ftl/FTLCompile.cpp:
(JSC::FTL::mmAllocateDataSection):
* ftl/FTLExitThunkGenerator.cpp:
(JSC::FTL::ExitThunkGenerator::emitThunk):
* ftl/FTLJITCode.cpp:
(JSC::FTL::JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite):
* ftl/FTLLowerDFGToLLVM.cpp:
(JSC::FTL::DFG::LowerDFGToLLVM::callCheck):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitArgumentsForPatchpointIfWillCatchException):
(JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
(JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
* ftl/FTLOSRExit.cpp:
(JSC::FTL::OSRExitDescriptor::emitOSRExit):
(JSC::FTL::OSRExitDescriptor::emitOSRExitLater):
(JSC::FTL::OSRExitDescriptor::prepareOSRExitHandle):
(JSC::FTL::OSRExit::OSRExit):
(JSC::FTL::OSRExit::spillRegistersToSpillSlot):
(JSC::FTL::OSRExit::recoverRegistersFromSpillSlot):
(JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
(JSC::FTL::OSRExit::willArriveAtOSRExitFromCallOperation):
(JSC::FTL::exceptionTypeWillArriveAtOSRExitFromGenericUnwind): Deleted.
(JSC::FTL::OSRExit::willArriveAtOSRExitFromGenericUnwind): Deleted.
* ftl/FTLOSRExit.h:
* ftl/FTLOSRExitCompiler.cpp:
(JSC::FTL::compileStub):
(JSC::FTL::compileFTLOSRExit):
* ftl/FTLPatchpointExceptionHandle.cpp:
(JSC::FTL::PatchpointExceptionHandle::scheduleExitCreation):
(JSC::FTL::PatchpointExceptionHandle::scheduleExitCreationForUnwind):
(JSC::FTL::PatchpointExceptionHandle::PatchpointExceptionHandle):
(JSC::FTL::PatchpointExceptionHandle::createHandle):
* ftl/FTLPatchpointExceptionHandle.h:

LayoutTests:

* js/regress/script-tests/v8-raytrace-with-try-catch-high-frequency-throws.js: Added.
(randomException):
(Class.create):
(Object.extend):
(Flog.RayTracer.Color.prototype.initialize):
(Flog.RayTracer.Color.prototype.add):
(Flog.RayTracer.Color.prototype.addScalar):
(Flog.RayTracer.Color.prototype.subtract):
(Flog.RayTracer.Color.prototype.multiply):
(Flog.RayTracer.Color.prototype.multiplyScalar):
(Flog.RayTracer.Color.prototype.divideFactor):
(Flog.RayTracer.Color.prototype.limit):
(Flog.RayTracer.Color.prototype.distance):
(Flog.RayTracer.Color.prototype.blend):
(Flog.RayTracer.Color.prototype.brightness):
(Flog.RayTracer.Color.prototype.toString):
(Flog.RayTracer.Light.prototype.initialize):
(Flog.RayTracer.Light.prototype.toString):
(Flog.RayTracer.Vector.prototype.initialize):
(Flog.RayTracer.Vector.prototype.copy):
(Flog.RayTracer.Vector.prototype.normalize):
(Flog.RayTracer.Vector.prototype.magnitude):
(Flog.RayTracer.Vector.prototype.cross):
(Flog.RayTracer.Vector.prototype.dot):
(Flog.RayTracer.Vector.prototype.add):
(Flog.RayTracer.Vector.prototype.subtract):
(Flog.RayTracer.Vector.prototype.multiplyVector):
(Flog.RayTracer.Vector.prototype.multiplyScalar):
(Flog.RayTracer.Vector.prototype.toString):
(Flog.RayTracer.Ray.prototype.initialize):
(Flog.RayTracer.Ray.prototype.toString):
(Flog.RayTracer.Scene.prototype.initialize):
(Flog.RayTracer.Material.BaseMaterial.prototype.initialize):
(Flog.RayTracer.Material.BaseMaterial.prototype.getColor):
(Flog.RayTracer.Material.BaseMaterial.prototype.wrapUp):
(Flog.RayTracer.Material.BaseMaterial.prototype.toString):
(Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.initialize):
(Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.getColor):
(Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.toString):
(Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial):
(Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.initialize):
(Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.getColor):
(Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.toString):
(Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial):
(Flog.RayTracer.Shape.Sphere.prototype.initialize):
(Flog.RayTracer.Shape.Sphere.prototype.intersect):
(Flog.RayTracer.Shape.Sphere.prototype.toString):
(Flog.RayTracer.Shape.Plane.prototype.initialize):
(Flog.RayTracer.Shape.Plane.prototype.intersect):
(Flog.RayTracer.Shape.Plane.prototype.toString):
(Flog.RayTracer.IntersectionInfo.prototype.initialize):
(Flog.RayTracer.IntersectionInfo.prototype.toString):
(Flog.RayTracer.Camera.prototype.initialize):
(Flog.RayTracer.Camera.prototype.getRay):
(Flog.RayTracer.Camera.prototype.toString):
(Flog.RayTracer.Background.prototype.initialize):
(Flog.RayTracer.Engine.prototype.initialize):
(Flog.RayTracer.Engine.prototype.setPixel):
(Flog.RayTracer.Engine.prototype.renderScene):
(Flog.RayTracer.Engine.prototype.getPixelColor):
(Flog.RayTracer.Engine.prototype.testIntersection):
(Flog.RayTracer.Engine.prototype.getReflectionRay):
(Flog.RayTracer.Engine.prototype.rayTrace):
(renderScene):
* js/regress/v8-raytrace-with-try-catch-high-frequency-throws-expected.txt: Added.
* js/regress/v8-raytrace-with-try-catch-high-frequency-throws.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (195830 => 195831)


--- trunk/LayoutTests/ChangeLog	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/LayoutTests/ChangeLog	2016-01-29 19:46:01 UTC (rev 195831)
@@ -1,3 +1,77 @@
+2016-01-29  Saam barati  <[email protected]>
+
+        Exits from exceptions shouldn't jettison code
+        https://bugs.webkit.org/show_bug.cgi?id=153564
+
+        Reviewed by Geoffrey Garen.
+
+        * js/regress/script-tests/v8-raytrace-with-try-catch-high-frequency-throws.js: Added.
+        (randomException):
+        (Class.create):
+        (Object.extend):
+        (Flog.RayTracer.Color.prototype.initialize):
+        (Flog.RayTracer.Color.prototype.add):
+        (Flog.RayTracer.Color.prototype.addScalar):
+        (Flog.RayTracer.Color.prototype.subtract):
+        (Flog.RayTracer.Color.prototype.multiply):
+        (Flog.RayTracer.Color.prototype.multiplyScalar):
+        (Flog.RayTracer.Color.prototype.divideFactor):
+        (Flog.RayTracer.Color.prototype.limit):
+        (Flog.RayTracer.Color.prototype.distance):
+        (Flog.RayTracer.Color.prototype.blend):
+        (Flog.RayTracer.Color.prototype.brightness):
+        (Flog.RayTracer.Color.prototype.toString):
+        (Flog.RayTracer.Light.prototype.initialize):
+        (Flog.RayTracer.Light.prototype.toString):
+        (Flog.RayTracer.Vector.prototype.initialize):
+        (Flog.RayTracer.Vector.prototype.copy):
+        (Flog.RayTracer.Vector.prototype.normalize):
+        (Flog.RayTracer.Vector.prototype.magnitude):
+        (Flog.RayTracer.Vector.prototype.cross):
+        (Flog.RayTracer.Vector.prototype.dot):
+        (Flog.RayTracer.Vector.prototype.add):
+        (Flog.RayTracer.Vector.prototype.subtract):
+        (Flog.RayTracer.Vector.prototype.multiplyVector):
+        (Flog.RayTracer.Vector.prototype.multiplyScalar):
+        (Flog.RayTracer.Vector.prototype.toString):
+        (Flog.RayTracer.Ray.prototype.initialize):
+        (Flog.RayTracer.Ray.prototype.toString):
+        (Flog.RayTracer.Scene.prototype.initialize):
+        (Flog.RayTracer.Material.BaseMaterial.prototype.initialize):
+        (Flog.RayTracer.Material.BaseMaterial.prototype.getColor):
+        (Flog.RayTracer.Material.BaseMaterial.prototype.wrapUp):
+        (Flog.RayTracer.Material.BaseMaterial.prototype.toString):
+        (Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.initialize):
+        (Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.getColor):
+        (Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.toString):
+        (Flog.RayTracer.Material.Solid.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial):
+        (Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.initialize):
+        (Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.getColor):
+        (Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial.toString):
+        (Flog.RayTracer.Material.Chessboard.prototype.Object.extend.new.Flog.RayTracer.Material.BaseMaterial):
+        (Flog.RayTracer.Shape.Sphere.prototype.initialize):
+        (Flog.RayTracer.Shape.Sphere.prototype.intersect):
+        (Flog.RayTracer.Shape.Sphere.prototype.toString):
+        (Flog.RayTracer.Shape.Plane.prototype.initialize):
+        (Flog.RayTracer.Shape.Plane.prototype.intersect):
+        (Flog.RayTracer.Shape.Plane.prototype.toString):
+        (Flog.RayTracer.IntersectionInfo.prototype.initialize):
+        (Flog.RayTracer.IntersectionInfo.prototype.toString):
+        (Flog.RayTracer.Camera.prototype.initialize):
+        (Flog.RayTracer.Camera.prototype.getRay):
+        (Flog.RayTracer.Camera.prototype.toString):
+        (Flog.RayTracer.Background.prototype.initialize):
+        (Flog.RayTracer.Engine.prototype.initialize):
+        (Flog.RayTracer.Engine.prototype.setPixel):
+        (Flog.RayTracer.Engine.prototype.renderScene):
+        (Flog.RayTracer.Engine.prototype.getPixelColor):
+        (Flog.RayTracer.Engine.prototype.testIntersection):
+        (Flog.RayTracer.Engine.prototype.getReflectionRay):
+        (Flog.RayTracer.Engine.prototype.rayTrace):
+        (renderScene):
+        * js/regress/v8-raytrace-with-try-catch-high-frequency-throws-expected.txt: Added.
+        * js/regress/v8-raytrace-with-try-catch-high-frequency-throws.html: Added.
+
 2016-01-29  Carlos Alberto Lopez Perez  <[email protected]>
 
         [GTK] Unreviewed gardening after r195740 (v2).

Added: trunk/LayoutTests/js/regress/script-tests/v8-raytrace-with-try-catch-high-frequency-throws.js (0 => 195831)


--- trunk/LayoutTests/js/regress/script-tests/v8-raytrace-with-try-catch-high-frequency-throws.js	                        (rev 0)
+++ trunk/LayoutTests/js/regress/script-tests/v8-raytrace-with-try-catch-high-frequency-throws.js	2016-01-29 19:46:01 UTC (rev 195831)
@@ -0,0 +1,1101 @@
+// The ray tracer code in this file is written by Adam Burmister. It
+// is available in its original form from:
+//
+//   http://labs.flog.nz.co/raytracer/
+//
+// It has been modified slightly by Google to work as a standalone
+// benchmark, but the all the computational code remains
+// untouched. This file also contains a copy of parts of the Prototype
+// _javascript_ framework which is used by the ray tracer.
+
+// Variable used to hold a number that can be used to verify that
+// the scene was ray traced correctly.
+var checkNumber;
+
+
+// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
+
+// The following is a copy of parts of the Prototype _javascript_ library:
+
+// Prototype _javascript_ framework, version 1.5.0
+// (c) 2005-2007 Sam Stephenson
+//
+// Prototype is freely distributable under the terms of an MIT-style license.
+// For details, see the Prototype web site: http://prototype.conio.net/
+
+let __exceptionCounter = 0;
+function randomException() {
+    __exceptionCounter++;
+    if (__exceptionCounter % 35 === 0) {
+        throw new Error("rando");
+    }
+}
+noInline(randomException);
+
+var Class = {
+    create: function() {
+        return function() {
+            try {
+                this.initialize.apply(this, arguments);
+                randomException();
+            } catch(e) { }
+        }
+    }
+};
+
+
+Object.extend = function(destination, source) {
+    for (var property in source) {
+        try {
+            destination[property] = source[property];
+            randomException();
+        } catch(e) { }
+    }
+    return destination;
+};
+
+
+// ------------------------------------------------------------------------
+// ------------------------------------------------------------------------
+
+// The rest of this file is the actual ray tracer written by Adam
+// Burmister. It's a concatenation of the following files:
+//
+//   flog/color.js
+//   flog/light.js
+//   flog/vector.js
+//   flog/ray.js
+//   flog/scene.js
+//   flog/material/basematerial.js
+//   flog/material/solid.js
+//   flog/material/chessboard.js
+//   flog/shape/baseshape.js
+//   flog/shape/sphere.js
+//   flog/shape/plane.js
+//   flog/intersectioninfo.js
+//   flog/camera.js
+//   flog/background.js
+//   flog/engine.js
+
+
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Color = Class.create();
+
+Flog.RayTracer.Color.prototype = {
+    red : 0.0,
+    green : 0.0,
+    blue : 0.0,
+
+    initialize : function(r, g, b) {
+        try {
+            if(!r) r = 0.0;
+            if(!g) g = 0.0;
+            if(!b) b = 0.0;
+
+            this.red = r;
+            this.green = g;
+            this.blue = b;
+            randomException();
+        } catch(e) { }
+    },
+
+    add : function(c1, c2){
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+
+            result.red = c1.red + c2.red;
+            result.green = c1.green + c2.green;
+            result.blue = c1.blue + c2.blue;
+
+            randomException();
+        } catch(e) { }
+
+        return result;
+    },
+
+    addScalar: function(c1, s){
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+
+            result.red = c1.red + s;
+            result.green = c1.green + s;
+            result.blue = c1.blue + s;
+
+            result.limit();
+
+            randomException();
+        } catch(e) { }
+
+        return result;
+    },
+
+    subtract: function(c1, c2){
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+
+            result.red = c1.red - c2.red;
+            result.green = c1.green - c2.green;
+            result.blue = c1.blue - c2.blue;
+
+            randomException();
+        } catch(e) { }
+
+        return result;
+    },
+
+    multiply : function(c1, c2) {
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+
+            result.red = c1.red * c2.red;
+            result.green = c1.green * c2.green;
+            result.blue = c1.blue * c2.blue;
+
+            randomException();
+        } catch(e) { }
+
+        return result;
+    },
+
+    multiplyScalar : function(c1, f) {
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+
+            result.red = c1.red * f;
+            result.green = c1.green * f;
+            result.blue = c1.blue * f;
+
+            randomException();
+        } catch(e) { }
+
+        return result;
+    },
+
+    divideFactor : function(c1, f) {
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+
+            result.red = c1.red / f;
+            result.green = c1.green / f;
+            result.blue = c1.blue / f;
+
+            randomException();
+        } catch(e) { }
+
+        return result;
+    },
+
+    limit: function(){
+        try { 
+            this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
+            this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
+            this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
+
+            randomException();
+        } catch(e) { }
+    },
+
+    distance : function(color) {
+        try {
+            var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
+            randomException();
+        } catch(e) { }
+        return d;
+    },
+
+    blend: function(c1, c2, w){
+        try {
+            var result = new Flog.RayTracer.Color(0,0,0);
+            result = Flog.RayTracer.Color.prototype.add(
+                    Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
+                    Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
+                    );
+            randomException();
+        } catch(e) { }
+        return result;
+    },
+
+    brightness : function() {
+        try {
+            var r = Math.floor(this.red*255);
+            var g = Math.floor(this.green*255);
+            var b = Math.floor(this.blue*255);
+            randomException();
+        } catch(e) { }
+        return (r * 77 + g * 150 + b * 29) >> 8;
+    },
+
+    toString : function () {
+        try {
+            var r = Math.floor(this.red*255);
+            var g = Math.floor(this.green*255);
+            var b = Math.floor(this.blue*255);
+            randomException();
+        } catch(e) { }
+
+        return "rgb("+ r +","+ g +","+ b +")";
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Light = Class.create();
+
+Flog.RayTracer.Light.prototype = {
+    position: null,
+    color: null,
+    intensity: 10.0,
+
+    initialize : function(pos, color, intensity) {
+        try {
+            this.position = pos;
+            this.color = color;
+            this.intensity = (intensity ? intensity : 10.0);
+
+            randomException();
+        } catch(e) { }
+    },
+
+    toString : function () {
+        try {
+            var result = 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
+            randomException();
+        } catch(e) { }
+        return result;
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Vector = Class.create();
+
+Flog.RayTracer.Vector.prototype = {
+    x : 0.0,
+    y : 0.0,
+    z : 0.0,
+
+    initialize : function(x, y, z) {
+        try {
+            this.x = (x ? x : 0);
+            this.y = (y ? y : 0);
+            this.z = (z ? z : 0);
+            randomException();
+        } catch(e) { }
+    },
+
+    copy: function(vector){
+        try {
+            this.x = vector.x;
+            this.y = vector.y;
+            this.z = vector.z;
+            randomException();
+        } catch(e) { }
+    },
+
+    normalize : function() {
+        try {
+            var m = this.magnitude();
+            var result = new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
+            randomException();
+        } catch(e) { }
+        return result;
+    },
+
+    magnitude : function() {
+        try {
+            return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
+        } catch(e)  { }
+    },
+
+    cross : function(w) {
+        try {
+            return new Flog.RayTracer.Vector(
+                    -this.z * w.y + this.y * w.z,
+                    this.z * w.x - this.x * w.z,
+                    -this.y * w.x + this.x * w.y);
+        } catch(e) { }
+    },
+
+    dot : function(w) {
+        try {
+            return this.x * w.x + this.y * w.y + this.z * w.z;
+        } catch(e) { }
+    },
+
+    add : function(v, w) {
+        try {
+            return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
+        } catch(e) { }
+    },
+
+    subtract : function(v, w) {
+        try {
+            if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
+            return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
+        } catch(e) { }
+    },
+
+    multiplyVector : function(v, w) {
+        try {
+            return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
+        } catch(e) { }
+    },
+
+    multiplyScalar : function(v, w) {
+        try {
+            return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
+        } catch(e) { }
+    },
+
+    toString : function () {
+        try {
+            return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Ray = Class.create();
+
+Flog.RayTracer.Ray.prototype = {
+    position : null,
+    direction : null,
+    initialize : function(pos, dir) {
+        try {
+            this.position = pos;
+            this.direction = dir;
+            randomException();
+        } catch(e) { }
+    },
+
+    toString : function () {
+        try {
+            return 'Ray [' + this.position + ',' + this.direction + ']';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Scene = Class.create();
+
+Flog.RayTracer.Scene.prototype = {
+    camera : null,
+    shapes : [],
+    lights : [],
+    background : null,
+
+    initialize : function() {
+        try {
+            this.camera = new Flog.RayTracer.Camera(
+                    new Flog.RayTracer.Vector(0,0,-5),
+                    new Flog.RayTracer.Vector(0,0,1),
+                    new Flog.RayTracer.Vector(0,1,0)
+                    );
+            this.shapes = new Array();
+            this.lights = new Array();
+            this.background = "" Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);
+
+            randomException();
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+if(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};
+
+Flog.RayTracer.Material.BaseMaterial = Class.create();
+
+Flog.RayTracer.Material.BaseMaterial.prototype = {
+
+    gloss: 2.0,             // [0...infinity] 0 = matt
+    transparency: 0.0,      // 0=opaque
+    reflection: 0.0,        // [0...infinity] 0 = no reflection
+    refraction: 0.50,
+    hasTexture: false,
+
+    initialize : function() {
+
+    },
+
+    getColor: function(u, v){
+
+    },
+
+    wrapUp: function(t){
+        try {
+            t = t % 2.0;
+            if(t < -1) t += 2.0;
+            if(t >= 1) t -= 2.0;
+            randomException();
+        } catch(e) { }
+        return t;
+    },
+
+    toString : function () {
+        try {
+            return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Material.Solid = Class.create();
+
+Flog.RayTracer.Material.Solid.prototype = Object.extend(
+        new Flog.RayTracer.Material.BaseMaterial(), {
+            initialize : function(color, reflection, refraction, transparency, gloss) {
+                try {
+                    this.color = color;
+                    this.reflection = reflection;
+                    this.transparency = transparency;
+                    this.gloss = gloss;
+                    this.hasTexture = false;
+                    randomException();
+                } catch(e) { }
+            },
+
+            getColor: function(u, v){
+                try {
+                    return this.color;
+                } catch(e) { }
+            },
+
+            toString : function () {
+                try {
+                    return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
+                } catch(e) { }
+            }
+        }
+        );
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Material.Chessboard = Class.create();
+
+Flog.RayTracer.Material.Chessboard.prototype = Object.extend(
+        new Flog.RayTracer.Material.BaseMaterial(), {
+            colorEven: null,
+            colorOdd: null,
+            density: 0.5,
+
+            initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
+                try {
+                    this.colorEven = colorEven;
+                    this.colorOdd = colorOdd;
+                    this.reflection = reflection;
+                    this.transparency = transparency;
+                    this.gloss = gloss;
+                    this.density = density;
+                    this.hasTexture = true;
+                    randomException();
+                } catch(e) { }
+            },
+
+            getColor: function(u, v){
+                try {
+                    var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
+                    randomException();
+                } catch(e) { }
+
+                if(t < 0.0)
+                    return this.colorEven;
+                else
+                    return this.colorOdd;
+            },
+
+            toString : function () {
+                try {
+                    return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
+                } catch(e) { }
+            }
+        }
+);
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
+
+Flog.RayTracer.Shape.Sphere = Class.create();
+
+Flog.RayTracer.Shape.Sphere.prototype = {
+    initialize : function(pos, radius, material) {
+        try {
+            this.radius = radius;
+            this.position = pos;
+            this.material = material;
+
+            randomException();
+        } catch(e) { }
+    },
+
+    intersect: function(ray){
+        try {
+            var info = new Flog.RayTracer.IntersectionInfo();
+            info.shape = this;
+
+            var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);
+
+            var B = dst.dot(ray.direction);
+            var C = dst.dot(dst) - (this.radius * this.radius);
+            var D = (B * B) - C;
+
+            if(D > 0){ // intersection!
+                info.isHit = true;
+                info.distance = (-B) - Math.sqrt(D);
+                info.position = Flog.RayTracer.Vector.prototype.add(
+                        ray.position,
+                        Flog.RayTracer.Vector.prototype.multiplyScalar(
+                            ray.direction,
+                            info.distance
+                            )
+                        );
+                info.normal = Flog.RayTracer.Vector.prototype.subtract(
+                        info.position,
+                        this.position
+                        ).normalize();
+
+                info.color = this.material.getColor(0,0);
+            } else {
+                info.isHit = false;
+            }
+
+            randomException();
+        } catch(e) { }
+        return info;
+    },
+
+    toString : function () {
+        try {
+            return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
+
+Flog.RayTracer.Shape.Plane = Class.create();
+
+Flog.RayTracer.Shape.Plane.prototype = {
+    d: 0.0,
+
+    initialize : function(pos, d, material) {
+        try {
+            this.position = pos;
+            this.d = d;
+            this.material = material;
+            randomException();
+        } catch(e) { }
+    },
+
+    intersect: function(ray){
+        try {
+            var info = new Flog.RayTracer.IntersectionInfo();
+
+            var Vd = this.position.dot(ray.direction);
+            if(Vd == 0) return info; // no intersection
+
+            var t = -(this.position.dot(ray.position) + this.d) / Vd;
+            if(t <= 0) return info;
+
+            info.shape = this;
+            info.isHit = true;
+            info.position = Flog.RayTracer.Vector.prototype.add(
+                    ray.position,
+                    Flog.RayTracer.Vector.prototype.multiplyScalar(
+                        ray.direction,
+                        t
+                        )
+                    );
+            info.normal = this.position;
+            info.distance = t;
+
+            if(this.material.hasTexture){
+                var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
+                var vV = vU.cross(this.position);
+                var u = info.position.dot(vU);
+                var v = info.position.dot(vV);
+                info.color = this.material.getColor(u,v);
+            } else {
+                info.color = this.material.getColor(0,0);
+            }
+
+            randomException();
+        } catch(e) { }
+        return info;
+    },
+
+    toString : function () {
+        try {
+            return 'Plane [' + this.position + ', d=' + this.d + ']';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.IntersectionInfo = Class.create();
+
+Flog.RayTracer.IntersectionInfo.prototype = {
+    isHit: false,
+    hitCount: 0,
+    shape: null,
+    position: null,
+    normal: null,
+    color: null,
+    distance: null,
+
+    initialize : function() {
+        try {
+            this.color = new Flog.RayTracer.Color(0,0,0);
+            randomException();
+        } catch(e) { }
+    },
+
+    toString : function () {
+        try {
+            return 'Intersection [' + this.position + ']';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Camera = Class.create();
+
+Flog.RayTracer.Camera.prototype = {
+    position: null,
+    lookAt: null,
+    equator: null,
+    up: null,
+    screen: null,
+
+    initialize : function(pos, lookAt, up) {
+        try {
+            this.position = pos;
+            this.lookAt = lookAt;
+            this.up = up;
+            this.equator = lookAt.normalize().cross(this.up);
+            this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
+            randomException();
+        } catch(e) { }
+    },
+
+    getRay: function(vx, vy){
+        try {
+            var pos = Flog.RayTracer.Vector.prototype.subtract(
+                    this.screen,
+                    Flog.RayTracer.Vector.prototype.subtract(
+                        Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
+                        Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
+                        )
+                    );
+            pos.y = pos.y * -1;
+            var dir = Flog.RayTracer.Vector.prototype.subtract(
+                    pos,
+                    this.position
+                    );
+
+            var ray = new Flog.RayTracer.Ray(pos, dir.normalize());
+
+            randomException();
+        } catch(e) { }
+        return ray;
+    },
+
+    toString : function () {
+        try {
+            return 'Ray []';
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Background = ""
+
+Flog.RayTracer.Background.prototype = {
+    color : null,
+    ambience : 0.0,
+
+    initialize : function(color, ambience) {
+        try {
+            this.color = color;
+            this.ambience = ambience;
+            randomException();
+        } catch(e) { }
+    }
+}
+/* Fake a Flog.* namespace */
+if(typeof(Flog) == 'undefined') var Flog = {};
+if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
+
+Flog.RayTracer.Engine = Class.create();
+
+Flog.RayTracer.Engine.prototype = {
+    canvas: null, /* 2d context we can render to */
+
+    initialize: function(options){
+        try {
+            this.options = Object.extend({
+                canvasHeight: 100,
+                canvasWidth: 100,
+                pixelWidth: 2,
+                pixelHeight: 2,
+                renderDiffuse: false,
+                renderShadows: false,
+                renderHighlights: false,
+                renderReflections: false,
+                rayDepth: 2
+            }, options || {});
+
+            this.options.canvasHeight /= this.options.pixelHeight;
+            this.options.canvasWidth /= this.options.pixelWidth;
+
+            randomException();
+        } catch(e) { }
+
+        /* TODO: dynamically include other scripts */
+    },
+
+    setPixel: function(x, y, color){
+        try {
+            var pxW, pxH;
+            pxW = this.options.pixelWidth;
+            pxH = this.options.pixelHeight;
+
+            if (this.canvas) {
+                this.canvas.fillStyle = color.toString();
+                this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
+            } else {
+                if (x ===  y) {
+                    checkNumber += color.brightness();
+                }
+                // print(x * pxW, y * pxH, pxW, pxH);
+            }
+
+            randomException();
+        } catch(e) { }
+    },
+
+    renderScene: function(scene, canvas){
+        try {
+            checkNumber = 0;
+            /* Get canvas */
+            if (canvas) {
+                this.canvas = canvas.getContext("2d");
+            } else {
+                this.canvas = null;
+            }
+
+            var canvasHeight = this.options.canvasHeight;
+            var canvasWidth = this.options.canvasWidth;
+
+            for(var y=0; y < canvasHeight; y++){
+                for(var x=0; x < canvasWidth; x++){
+                    try {
+                        var yp = y * 1.0 / canvasHeight * 2 - 1;
+                        var xp = x * 1.0 / canvasWidth * 2 - 1;
+
+                        var ray = scene.camera.getRay(xp, yp);
+
+                        var color = this.getPixelColor(ray, scene);
+
+                        this.setPixel(x, y, color);
+
+                        randomException();
+                    } catch(e) { }
+                }
+            }
+        } catch(e) { }
+        if (checkNumber !== 2321) {
+            throw new Error("Scene rendered incorrectly");
+        }
+    },
+
+    getPixelColor: function(ray, scene){
+        try {
+            var info = this.testIntersection(ray, scene, null);
+            if(info.isHit){
+                var color = this.rayTrace(info, ray, scene, 0);
+                return color;
+            }
+            return scene.background.color;
+        } catch(e) { }
+    },
+
+    testIntersection: function(ray, scene, exclude){
+        try {
+            var hits = 0;
+            var best = new Flog.RayTracer.IntersectionInfo();
+            best.distance = 2000;
+
+            for(var i=0; i<scene.shapes.length; i++){
+                try {
+                    var shape = scene.shapes[i];
+
+                    if(shape != exclude){
+                        var info = shape.intersect(ray);
+                        if(info.isHit && info.distance >= 0 && info.distance < best.distance){
+                            best = info;
+                            hits++;
+                        }
+                    }
+
+                    randomException();
+                } catch(e) { }
+            }
+            best.hitCount = hits;
+
+            randomException();
+        } catch(e) { }
+        return best;
+    },
+
+    getReflectionRay: function(P,N,V){
+        try {
+            var c1 = -N.dot(V);
+            var R1 = Flog.RayTracer.Vector.prototype.add(
+                    Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
+                    V
+                    );
+
+            randomException();
+        } catch(e) { }
+        return new Flog.RayTracer.Ray(P, R1);
+    },
+
+    rayTrace: function(info, ray, scene, depth){
+        // Calc ambient
+        try {
+            var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
+            var oldColor = color;
+            var shininess = Math.pow(10, info.shape.material.gloss + 1);
+
+            for(var i=0; i<scene.lights.length; i++){
+                try {
+                    var light = scene.lights[i];
+
+                    // Calc diffuse lighting
+                    var v = Flog.RayTracer.Vector.prototype.subtract(
+                            light.position,
+                            info.position
+                            ).normalize();
+
+                    if(this.options.renderDiffuse){
+                        var L = v.dot(info.normal);
+                        if(L > 0.0){
+                            color = Flog.RayTracer.Color.prototype.add(
+                                    color,
+                                    Flog.RayTracer.Color.prototype.multiply(
+                                        info.color,
+                                        Flog.RayTracer.Color.prototype.multiplyScalar(
+                                            light.color,
+                                            L
+                                            )
+                                        )
+                                    );
+                        }
+                    }
+
+                    randomException();
+                } catch(e) { }
+
+                try {
+                    // The greater the depth the more accurate the colours, but
+                    // this is exponentially (!) expensive
+                    if(depth <= this.options.rayDepth){
+                        // calculate reflection ray
+                        if(this.options.renderReflections && info.shape.material.reflection > 0)
+                        {
+                            var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
+                            var refl = this.testIntersection(reflectionRay, scene, info.shape);
+
+                            if (refl.isHit && refl.distance > 0){
+                                refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
+                            } else {
+                                refl.color = scene.background.color;
+                            }
+
+                            color = Flog.RayTracer.Color.prototype.blend(
+                                    color,
+                                    refl.color,
+                                    info.shape.material.reflection
+                                    );
+                        }
+
+                        // Refraction
+                        /* TODO */
+                    }
+                    randomException();
+                }  catch(e) { }
+
+                /* Render shadows and highlights */
+
+                var shadowInfo = new Flog.RayTracer.IntersectionInfo();
+
+                if(this.options.renderShadows){
+                    var shadowRay = new Flog.RayTracer.Ray(info.position, v);
+
+                    shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
+                    if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
+                        var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
+                        var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
+                        color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
+                    }
+                }
+
+                try {
+                    // Phong specular highlights
+                    if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
+                        var Lv = Flog.RayTracer.Vector.prototype.subtract(
+                                info.shape.position,
+                                light.position
+                                ).normalize();
+
+                        var E = Flog.RayTracer.Vector.prototype.subtract(
+                                scene.camera.position,
+                                info.shape.position
+                                ).normalize();
+
+                        var H = Flog.RayTracer.Vector.prototype.subtract(
+                                E,
+                                Lv
+                                ).normalize();
+
+                        var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
+                        color = Flog.RayTracer.Color.prototype.add(
+                                Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
+                                color
+                                );
+                    }
+                    randomException();
+                } catch(e) { }
+            }
+            color.limit();
+
+            randomException();
+        } catch(e) { }
+        return color;
+    }
+};
+
+
+function renderScene(){
+    try {
+        var scene = new Flog.RayTracer.Scene();
+
+        scene.camera = new Flog.RayTracer.Camera(
+                new Flog.RayTracer.Vector(0, 0, -15),
+                new Flog.RayTracer.Vector(-0.2, 0, 5),
+                new Flog.RayTracer.Vector(0, 1, 0)
+                );
+
+        scene.background = "" Flog.RayTracer.Background(
+                new Flog.RayTracer.Color(0.5, 0.5, 0.5),
+                0.4
+                );
+
+        var sphere = new Flog.RayTracer.Shape.Sphere(
+                new Flog.RayTracer.Vector(-1.5, 1.5, 2),
+                1.5,
+                new Flog.RayTracer.Material.Solid(
+                    new Flog.RayTracer.Color(0,0.5,0.5),
+                    0.3,
+                    0.0,
+                    0.0,
+                    2.0
+                    )
+                );
+
+        var sphere1 = new Flog.RayTracer.Shape.Sphere(
+                new Flog.RayTracer.Vector(1, 0.25, 1),
+                0.5,
+                new Flog.RayTracer.Material.Solid(
+                    new Flog.RayTracer.Color(0.9,0.9,0.9),
+                    0.1,
+                    0.0,
+                    0.0,
+                    1.5
+                    )
+                );
+
+        var plane = new Flog.RayTracer.Shape.Plane(
+                new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
+                1.2,
+                new Flog.RayTracer.Material.Chessboard(
+                    new Flog.RayTracer.Color(1,1,1),
+                    new Flog.RayTracer.Color(0,0,0),
+                    0.2,
+                    0.0,
+                    1.0,
+                    0.7
+                    )
+                );
+
+        scene.shapes.push(plane);
+        scene.shapes.push(sphere);
+        scene.shapes.push(sphere1);
+
+        var light = new Flog.RayTracer.Light(
+                new Flog.RayTracer.Vector(5, 10, -1),
+                new Flog.RayTracer.Color(0.8, 0.8, 0.8)
+                );
+
+        var light1 = new Flog.RayTracer.Light(
+                new Flog.RayTracer.Vector(-3, 5, -15),
+                new Flog.RayTracer.Color(0.8, 0.8, 0.8),
+                100
+                );
+
+        scene.lights.push(light);
+        scene.lights.push(light1);
+
+        var imageWidth = 100; // $F('imageWidth');
+        var imageHeight = 100; // $F('imageHeight');
+        var pixelSize = "5,5".split(','); //  $F('pixelSize').split(',');
+        var renderDiffuse = true; // $F('renderDiffuse');
+        var renderShadows = true; // $F('renderShadows');
+        var renderHighlights = true; // $F('renderHighlights');
+        var renderReflections = true; // $F('renderReflections');
+        var rayDepth = 2;//$F('rayDepth');
+
+        var raytracer = new Flog.RayTracer.Engine(
+                {
+                    canvasWidth: imageWidth,
+                    canvasHeight: imageHeight,
+                    pixelWidth: pixelSize[0],
+                    pixelHeight: pixelSize[1],
+                    "renderDiffuse": renderDiffuse,
+                    "renderHighlights": renderHighlights,
+                    "renderShadows": renderShadows,
+                    "renderReflections": renderReflections,
+                    "rayDepth": rayDepth
+                }
+                );
+
+        raytracer.renderScene(scene, null, 0);
+        randomException();
+    } catch(e) { }
+}
+
+for (var i = 0; i < 6; ++i)
+    renderScene();

Added: trunk/LayoutTests/js/regress/v8-raytrace-with-try-catch-high-frequency-throws-expected.txt (0 => 195831)


--- trunk/LayoutTests/js/regress/v8-raytrace-with-try-catch-high-frequency-throws-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/js/regress/v8-raytrace-with-try-catch-high-frequency-throws-expected.txt	2016-01-29 19:46:01 UTC (rev 195831)
@@ -0,0 +1,10 @@
+JSRegress/v8-raytrace-with-try-catch-high-frequency-throws
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS no exception thrown
+PASS successfullyParsed is true
+
+TEST COMPLETE
+

Added: trunk/LayoutTests/js/regress/v8-raytrace-with-try-catch-high-frequency-throws.html (0 => 195831)


--- trunk/LayoutTests/js/regress/v8-raytrace-with-try-catch-high-frequency-throws.html	                        (rev 0)
+++ trunk/LayoutTests/js/regress/v8-raytrace-with-try-catch-high-frequency-throws.html	2016-01-29 19:46:01 UTC (rev 195831)
@@ -0,0 +1,12 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src=""
+</head>
+<body>
+<script src=""
+<script src=""
+<script src=""
+<script src=""
+</body>
+</html>

Modified: trunk/Source/_javascript_Core/ChangeLog (195830 => 195831)


--- trunk/Source/_javascript_Core/ChangeLog	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ChangeLog	2016-01-29 19:46:01 UTC (rev 195831)
@@ -1,3 +1,103 @@
+2016-01-29  Saam barati  <[email protected]>
+
+        Exits from exceptions shouldn't jettison code
+        https://bugs.webkit.org/show_bug.cgi?id=153564
+
+        Reviewed by Geoffrey Garen.
+
+        We create two new exit kinds for exception-handling
+        OSRExits:
+        - ExceptionCheck: an exception check after a C call.
+        - GenericUnwind: an OSR exit executes because it's jumped to from genericUnwind machinery.
+
+        Having these two new exit kinds allows us to remove fields from
+        various OSRExit variants that store booleans indicating
+        if the exit is an exception handler, and if so, what kind
+        of exception handler. Most of this patch is just removing
+        those old fields and adding new equivalent functions.
+
+        This patch also implements the policy that we should never consider jettisoning
+        code from exits that happen from an exception check to an op_catch (it might be worth
+        considering a similar policy for 'throw'). We're choosing this policy because
+        it will almost never be more expensive, in total, to execute the OSR exit than
+        to execute the baseline variant of the code. When an exception is thrown, we do
+        really expensive work, like call through to genericUnwind, and also create an error
+        object with a stack trace. The cost of OSR exiting here is small in comparison to
+        those other operations. And penalizing a CodeBlock for OSR exiting from an exception
+        is silly because the basis of our implementation of exception handling in the
+        upper tiers is to OSR exit on a caught exception. So we used to penalize
+        ourselves for having an implementation that is correct w.r.t our design goals.
+
+        I've verified this hypothesis with on v8-raytrace by adding a new 
+        benchmark that throws with very high frequency. Implementing
+        this policy on that benchmark results in about a 4-5% speed up.
+
+        * bytecode/ExitKind.cpp:
+        (JSC::exitKindToString):
+        (JSC::exitKindMayJettison):
+        (JSC::exitKindIsCountable): Deleted.
+        * bytecode/ExitKind.h:
+        * dfg/DFGJITCode.cpp:
+        (JSC::DFG::JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite):
+        * dfg/DFGJITCompiler.cpp:
+        (JSC::DFG::JITCompiler::noticeOSREntry):
+        (JSC::DFG::JITCompiler::appendExceptionHandlingOSRExit):
+        (JSC::DFG::JITCompiler::exceptionCheck):
+        (JSC::DFG::JITCompiler::recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded):
+        * dfg/DFGJITCompiler.h:
+        * dfg/DFGOSRExit.cpp:
+        (JSC::DFG::OSRExit::OSRExit):
+        * dfg/DFGOSRExit.h:
+        (JSC::DFG::OSRExit::considerAddingAsFrequentExitSite):
+        * dfg/DFGOSRExitBase.h:
+        (JSC::DFG::OSRExitBase::OSRExitBase):
+        (JSC::DFG::OSRExitBase::isExceptionHandler):
+        (JSC::DFG::OSRExitBase::isGenericUnwindHandler):
+        (JSC::DFG::OSRExitBase::considerAddingAsFrequentExitSite):
+        * dfg/DFGOSRExitCompiler.cpp:
+        * dfg/DFGOSRExitCompiler32_64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompiler64.cpp:
+        (JSC::DFG::OSRExitCompiler::compileExit):
+        * dfg/DFGOSRExitCompilerCommon.cpp:
+        (JSC::DFG::handleExitCounts):
+        (JSC::DFG::osrWriteBarrier):
+        (JSC::DFG::adjustAndJumpToTarget):
+        * dfg/DFGOSRExitCompilerCommon.h:
+        (JSC::DFG::adjustFrameAndStackInOSRExitCompilerThunk):
+        * ftl/FTLCompile.cpp:
+        (JSC::FTL::mmAllocateDataSection):
+        * ftl/FTLExitThunkGenerator.cpp:
+        (JSC::FTL::ExitThunkGenerator::emitThunk):
+        * ftl/FTLJITCode.cpp:
+        (JSC::FTL::JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite):
+        * ftl/FTLLowerDFGToLLVM.cpp:
+        (JSC::FTL::DFG::LowerDFGToLLVM::callCheck):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExitArgumentsForPatchpointIfWillCatchException):
+        (JSC::FTL::DFG::LowerDFGToLLVM::appendOSRExit):
+        (JSC::FTL::DFG::LowerDFGToLLVM::blessSpeculation):
+        * ftl/FTLOSRExit.cpp:
+        (JSC::FTL::OSRExitDescriptor::emitOSRExit):
+        (JSC::FTL::OSRExitDescriptor::emitOSRExitLater):
+        (JSC::FTL::OSRExitDescriptor::prepareOSRExitHandle):
+        (JSC::FTL::OSRExit::OSRExit):
+        (JSC::FTL::OSRExit::spillRegistersToSpillSlot):
+        (JSC::FTL::OSRExit::recoverRegistersFromSpillSlot):
+        (JSC::FTL::OSRExit::willArriveAtExitFromIndirectExceptionCheck):
+        (JSC::FTL::OSRExit::willArriveAtOSRExitFromCallOperation):
+        (JSC::FTL::exceptionTypeWillArriveAtOSRExitFromGenericUnwind): Deleted.
+        (JSC::FTL::OSRExit::willArriveAtOSRExitFromGenericUnwind): Deleted.
+        * ftl/FTLOSRExit.h:
+        * ftl/FTLOSRExitCompiler.cpp:
+        (JSC::FTL::compileStub):
+        (JSC::FTL::compileFTLOSRExit):
+        * ftl/FTLPatchpointExceptionHandle.cpp:
+        (JSC::FTL::PatchpointExceptionHandle::scheduleExitCreation):
+        (JSC::FTL::PatchpointExceptionHandle::scheduleExitCreationForUnwind):
+        (JSC::FTL::PatchpointExceptionHandle::PatchpointExceptionHandle):
+        (JSC::FTL::PatchpointExceptionHandle::createHandle):
+        * ftl/FTLPatchpointExceptionHandle.h:
+
 2016-01-28  Yusuke Suzuki  <[email protected]>
 
         [B3] REGRESSION(r195395): testComplex(64, 128) asserts on Linux with GCC

Modified: trunk/Source/_javascript_Core/bytecode/ExitKind.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/bytecode/ExitKind.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/bytecode/ExitKind.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -84,25 +84,27 @@
         return "WatchdogTimerFired";
     case DebuggerEvent:
         return "DebuggerEvent";
+    case ExceptionCheck:
+        return "ExceptionCheck";
+    case GenericUnwind:
+        return "GenericUnwind";
     }
     RELEASE_ASSERT_NOT_REACHED();
     return "Unknown";
 }
 
-bool exitKindIsCountable(ExitKind kind)
+bool exitKindMayJettison(ExitKind kind)
 {
     switch (kind) {
-    case ExitKindUnset:
-        RELEASE_ASSERT_NOT_REACHED();
-    case BadType:
-    case Uncountable:
-    case LoadFromHole: // Already counted directly by the baseline JIT.
-    case StoreToHole: // Already counted directly by the baseline JIT.
-    case OutOfBounds: // Already counted directly by the baseline JIT.
+    case ExceptionCheck:
+    case GenericUnwind:
         return false;
     default:
         return true;
     }
+
+    RELEASE_ASSERT_NOT_REACHED();
+    return false;
 }
 
 } // namespace JSC

Modified: trunk/Source/_javascript_Core/bytecode/ExitKind.h (195830 => 195831)


--- trunk/Source/_javascript_Core/bytecode/ExitKind.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/bytecode/ExitKind.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -53,11 +53,13 @@
     Uncountable, // We exited for none of the above reasons, and we should not count it. Most uses of this should be viewed as a FIXME.
     UncountableInvalidation, // We exited because the code block was invalidated; this means that we've already counted the reasons why the code block was invalidated.
     WatchdogTimerFired, // We exited because we need to service the watchdog timer.
-    DebuggerEvent // We exited because we need to service the debugger.
+    DebuggerEvent, // We exited because we need to service the debugger.
+    ExceptionCheck, // We exited because a direct exception check showed that we threw an exception from a C call.
+    GenericUnwind, // We exited because a we arrived at this OSR exit from genericUnwind.
 };
 
 const char* exitKindToString(ExitKind);
-bool exitKindIsCountable(ExitKind);
+bool exitKindMayJettison(ExitKind);
 
 } // namespace JSC
 

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCode.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGJITCode.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCode.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -90,7 +90,7 @@
 RegisterSet JITCode::liveRegistersToPreserveAtExceptionHandlingCallSite(CodeBlock* codeBlock, CallSiteIndex callSiteIndex)
 {
     for (OSRExit& exit : osrExit) {
-        if (exit.m_isExceptionHandler && exit.m_exceptionHandlerCallSiteIndex.bits() == callSiteIndex.bits()) {
+        if (exit.isExceptionHandler() && exit.m_exceptionHandlerCallSiteIndex.bits() == callSiteIndex.bits()) {
             Operands<ValueRecovery> valueRecoveries;
             reconstruct(codeBlock, exit.m_codeOrigin, exit.m_streamIndex, valueRecoveries);
             RegisterSet liveAtOSRExit;

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -541,11 +541,9 @@
     entry->m_reshufflings.shrinkToFit();
 }
 
-void JITCompiler::appendExceptionHandlingOSRExit(unsigned eventStreamIndex, CodeOrigin opCatchOrigin, HandlerInfo* exceptionHandler, CallSiteIndex callSite, MacroAssembler::JumpList jumpsToFail)
+void JITCompiler::appendExceptionHandlingOSRExit(ExitKind kind, unsigned eventStreamIndex, CodeOrigin opCatchOrigin, HandlerInfo* exceptionHandler, CallSiteIndex callSite, MacroAssembler::JumpList jumpsToFail)
 {
-    OSRExit exit(Uncountable, JSValueRegs(), graph().methodOfGettingAValueProfileFor(nullptr), m_speculative.get(), eventStreamIndex);
-    exit.m_willArriveAtOSRExitFromGenericUnwind = jumpsToFail.empty(); // If jumps are empty, we're going to jump here from genericUnwind from a child call frame.
-    exit.m_isExceptionHandler = true;
+    OSRExit exit(kind, JSValueRegs(), graph().methodOfGettingAValueProfileFor(nullptr), m_speculative.get(), eventStreamIndex);
     exit.m_codeOrigin = opCatchOrigin;
     exit.m_exceptionHandlerCallSiteIndex = callSite;
     OSRExitCompilationInfo& exitInfo = appendExitInfo(jumpsToFail);
@@ -582,7 +580,7 @@
         unsigned streamIndex = m_speculative->m_outOfLineStreamIndex != UINT_MAX ? m_speculative->m_outOfLineStreamIndex : m_speculative->m_stream->size();
         MacroAssembler::Jump hadException = emitNonPatchableExceptionCheck();
         // We assume here that this is called after callOpeartion()/appendCall() is called.
-        appendExceptionHandlingOSRExit(streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.lastCallSite(), hadException);
+        appendExceptionHandlingOSRExit(ExceptionCheck, streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.lastCallSite(), hadException);
     } else
         m_exceptionChecks.append(emitExceptionCheck());
 }
@@ -594,7 +592,7 @@
     bool willCatchException = m_graph.willCatchExceptionInMachineFrame(callSiteCodeOrigin, opCatchOrigin, exceptionHandler);
     CallSiteIndex callSite = addCallSite(callSiteCodeOrigin);
     if (willCatchException)
-        appendExceptionHandlingOSRExit(eventStreamIndex, opCatchOrigin, exceptionHandler, callSite);
+        appendExceptionHandlingOSRExit(GenericUnwind, eventStreamIndex, opCatchOrigin, exceptionHandler, callSite);
     return callSite;
 }
 

Modified: trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGJITCompiler.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -279,7 +279,7 @@
     void linkOSRExits();
     void disassemble(LinkBuffer&);
 
-    void appendExceptionHandlingOSRExit(unsigned eventStreamIndex, CodeOrigin, HandlerInfo* exceptionHandler, CallSiteIndex, MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList());
+    void appendExceptionHandlingOSRExit(ExitKind, unsigned eventStreamIndex, CodeOrigin, HandlerInfo* exceptionHandler, CallSiteIndex, MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList());
 
     // The dataflow graph currently being generated.
     Graph& m_graph;

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -43,7 +43,6 @@
     , m_patchableCodeOffset(0)
     , m_recoveryIndex(recoveryIndex)
     , m_streamIndex(streamIndex)
-    , m_willArriveAtOSRExitFromGenericUnwind(false)
 {
     bool canExit = jit->m_origin.exitOK;
     if (!canExit && jit->m_currentNode) {

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExit.h (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExit.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExit.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -100,7 +100,6 @@
     void correctJump(LinkBuffer&);
 
     unsigned m_streamIndex;
-    bool m_willArriveAtOSRExitFromGenericUnwind : 1;
     void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
     {
         OSRExitBase::considerAddingAsFrequentExitSite(profiledCodeBlock, ExitFromDFG);

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitBase.h (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitBase.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitBase.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -45,7 +45,6 @@
         , m_count(0)
         , m_codeOrigin(origin)
         , m_codeOriginForExitProfile(originForProfile)
-        , m_isExceptionHandler(false)
     {
         ASSERT(m_codeOrigin.isSet());
         ASSERT(m_codeOriginForExitProfile.isSet());
@@ -58,8 +57,19 @@
     CodeOrigin m_codeOriginForExitProfile;
     CallSiteIndex m_exceptionHandlerCallSiteIndex;
 
-    bool m_isExceptionHandler : 1;
+    ALWAYS_INLINE bool isExceptionHandler() const
+    {
+        return m_kind == ExceptionCheck || m_kind == GenericUnwind;
+    }
 
+    // True if this exit is used as an exception handler for unwinding. This happens to only be set when
+    // isExceptionHandler is true, but all this actually means is that the OSR exit will assume that the
+    // machine state is as it would be coming out of genericUnwind.
+    ALWAYS_INLINE bool isGenericUnwindHandler() const
+    {
+        return m_kind == GenericUnwind;
+    }
+
 protected:
     void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock, ExitingJITType jitType)
     {

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -131,8 +131,8 @@
     OSRExit& exit = codeBlock->jitCode()->dfg()->osrExit[exitIndex];
     
     if (vm->callFrameForCatch)
-        ASSERT(exit.m_willArriveAtOSRExitFromGenericUnwind);
-    if (exit.m_isExceptionHandler)
+        ASSERT(exit.m_kind == GenericUnwind);
+    if (exit.isExceptionHandler())
         ASSERT(!!vm->exception());
         
     
@@ -150,7 +150,7 @@
         CCallHelpers jit(vm, codeBlock);
         OSRExitCompiler exitCompiler(jit);
 
-        if (exit.m_willArriveAtOSRExitFromGenericUnwind) {
+        if (exit.m_kind == GenericUnwind) {
             // We are acting as a defacto op_catch because we arrive here from genericUnwind().
             // So, we must restore our call frame and stack pointer.
             jit.restoreCalleeSavesFromVMCalleeSavesBuffer();

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler32_64.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -248,7 +248,7 @@
     m_jit.emitRestoreCalleeSaves();
     m_jit.emitSaveCalleeSavesFor(m_jit.baselineCodeBlock());
 
-    if (exit.m_isExceptionHandler)
+    if (exit.isExceptionHandler())
         m_jit.copyCalleeSavesToVMCalleeSavesBuffer();
 
     // Do all data format conversions and store the results into the stack.
@@ -397,7 +397,7 @@
     reifyInlinedCallFrames(m_jit, exit);
     
     // And finish.
-    adjustAndJumpToTarget(m_jit, exit, exit.m_isExceptionHandler);
+    adjustAndJumpToTarget(m_jit, exit);
 }
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompiler64.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -261,7 +261,7 @@
     // The tag registers are needed to materialize recoveries below.
     m_jit.emitMaterializeTagCheckRegisters();
 
-    if (exit.m_isExceptionHandler)
+    if (exit.isExceptionHandler())
         m_jit.copyCalleeSavesToVMCalleeSavesBuffer();
 
     // Do all data format conversions and store the results into the stack.
@@ -387,7 +387,7 @@
     reifyInlinedCallFrames(m_jit, exit);
 
     // And finish.
-    adjustAndJumpToTarget(m_jit, exit, exit.m_isExceptionHandler);
+    adjustAndJumpToTarget(m_jit, exit);
 }
 
 } } // namespace JSC::DFG

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -39,6 +39,9 @@
 void handleExitCounts(CCallHelpers& jit, const OSRExitBase& exit)
 {
     jit.add32(AssemblyHelpers::TrustedImm32(1), AssemblyHelpers::AbsoluteAddress(&exit.m_count));
+
+    if (!exitKindMayJettison(exit.m_kind))
+        return;
     
     jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()), GPRInfo::regT0);
     
@@ -264,7 +267,7 @@
     ownerIsRememberedOrInEden.link(&jit);
 }
 
-void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit, bool isExitingToOpCatch)
+void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit)
 {
     jit.move(
         AssemblyHelpers::TrustedImmPtr(
@@ -302,7 +305,7 @@
     void* jumpTarget = codeBlockForExit->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
 
     jit.addPtr(AssemblyHelpers::TrustedImm32(JIT::stackPointerOffsetFor(codeBlockForExit) * sizeof(Register)), GPRInfo::callFrameRegister, AssemblyHelpers::stackPointerRegister);
-    if (isExitingToOpCatch) {
+    if (exit.isExceptionHandler()) {
         // Since we're jumping to op_catch, we need to set callFrameForCatch.
         jit.storePtr(GPRInfo::callFrameRegister, jit.vm()->addressOfCallFrameForCatch());
     }

Modified: trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h (195830 => 195831)


--- trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/dfg/DFGOSRExitCompilerCommon.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -39,7 +39,7 @@
 
 void handleExitCounts(CCallHelpers&, const OSRExitBase&);
 void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
-void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&, bool isExitingToOpCatch);
+void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
 
 template <typename JITCodeType>
 void adjustFrameAndStackInOSRExitCompilerThunk(MacroAssembler& jit, VM* vm, JITCode::JITType jitType)

Modified: trunk/Source/_javascript_Core/ftl/FTLCompile.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLCompile.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -492,7 +492,7 @@
         }
 
         OSRExitDescriptorImpl& exitDescriptorImpl = state.osrExitDescriptorImpls[i];
-        if (exceptionTypeWillArriveAtOSRExitFromGenericUnwind(exitDescriptorImpl.m_exceptionType))
+        if (exitDescriptorImpl.m_kind == GenericUnwind)
             genericUnwindOSRExitDescriptors.add(exitDescriptor, &exitDescriptorImpl);
 
         for (unsigned j = exitDescriptor->m_values.size(); j--;)
@@ -503,7 +503,7 @@
         for (unsigned j = 0; j < iter->value.size(); j++) {
             {
                 uint32_t stackmapRecordIndex = iter->value[j].index;
-                OSRExit exit(exitDescriptor, exitDescriptorImpl, stackmapRecordIndex);
+                OSRExit exit(exitDescriptor, exitDescriptorImpl.m_kind, exitDescriptorImpl, stackmapRecordIndex);
                 state.jitCode->osrExit.append(exit);
                 state.finalizer->osrExit.append(OSRExitCompilationInfo());
             }
@@ -528,7 +528,7 @@
                     // and the other that will be arrived at from the callOperation exception handler path.
                     // This code here generates the second callOperation variant.
                     uint32_t stackmapRecordIndex = iter->value[j].index;
-                    OSRExit exit(exitDescriptor, exitDescriptorImpl, stackmapRecordIndex);
+                    OSRExit exit(exitDescriptor, ExceptionCheck, exitDescriptorImpl, stackmapRecordIndex);
                     if (exitDescriptorImpl.m_exceptionType == ExceptionType::GetById)
                         exit.m_exceptionType = ExceptionType::GetByIdCallOperation;
                     else
@@ -590,7 +590,7 @@
             info.m_thunkAddress = linkBuffer->locationOf(info.m_thunkLabel);
             exit.m_patchableCodeOffset = linkBuffer->offsetOf(info.m_thunkJump);
 
-            if (exit.willArriveAtOSRExitFromGenericUnwind()) {
+            if (exit.isGenericUnwindHandler()) {
                 HandlerInfo newHandler = genericUnwindOSRExitDescriptors.get(exit.m_descriptor)->m_baselineExceptionHandler;
                 newHandler.start = exit.m_exceptionHandlerCallSiteIndex.bits();
                 newHandler.end = exit.m_exceptionHandlerCallSiteIndex.bits() + 1;

Modified: trunk/Source/_javascript_Core/ftl/FTLExitThunkGenerator.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLExitThunkGenerator.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLExitThunkGenerator.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -49,7 +49,7 @@
 void ExitThunkGenerator::emitThunk(unsigned index)
 {
     OSRExit& exit = m_state.jitCode->osrExit[index];
-    ASSERT_UNUSED(exit, !(exit.willArriveAtOSRExitFromGenericUnwind() && exit.willArriveAtOSRExitFromCallOperation()));
+    ASSERT_UNUSED(exit, !(exit.isGenericUnwindHandler() && exit.willArriveAtOSRExitFromCallOperation()));
     
     OSRExitCompilationInfo& info = m_state.finalizer->osrExit[index];
     info.m_thunkLabel = label();

Modified: trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLJITCode.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -170,15 +170,15 @@
 #if FTL_USES_B3
     for (OSRExit& exit : osrExit) {
         if (exit.m_exceptionHandlerCallSiteIndex.bits() == callSiteIndex.bits()) {
-            RELEASE_ASSERT(exit.m_isExceptionHandler);
-            RELEASE_ASSERT(exit.m_isUnwindHandler);
+            RELEASE_ASSERT(exit.isExceptionHandler());
+            RELEASE_ASSERT(exit.isGenericUnwindHandler());
             return ValueRep::usedRegisters(exit.m_valueReps);
         }
     }
 #else // FTL_USES_B3
     for (OSRExit& exit : osrExit) {
         if (exit.m_exceptionHandlerCallSiteIndex.bits() == callSiteIndex.bits()) {
-            RELEASE_ASSERT(exit.m_isExceptionHandler);
+            RELEASE_ASSERT(exit.isExceptionHandler());
             return stackmaps.records[exit.m_stackmapRecordIndex].usedRegisterSet();
         }
     }

Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToLLVM.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -10186,7 +10186,7 @@
             bool exitOK = true;
             bool isExceptionHandler = true;
             appendOSRExit(
-                Uncountable, noValue(), nullptr, hadException,
+                ExceptionCheck, noValue(), nullptr, hadException,
                 m_origin.withForExitAndExitOK(opCatchOrigin, exitOK), isExceptionHandler);
             return;
         }
@@ -10244,7 +10244,22 @@
         if (!willCatchException)
             return;
 
-        appendOSRExitDescriptor(Uncountable, exceptionType, noValue(), nullptr, m_origin.withForExitAndExitOK(opCatchOrigin, true));
+        ExitKind exitKind;
+        switch (exceptionType) {
+        case ExceptionType::JSCall:
+        case ExceptionType::GetById:
+        case ExceptionType::PutById:
+            exitKind = GenericUnwind;
+            break;
+        case ExceptionType::LazySlowPath:
+        case ExceptionType::BinaryOpGenerator:
+            exitKind = ExceptionCheck;
+            break;
+        default:
+            RELEASE_ASSERT_NOT_REACHED();
+        }
+
+        appendOSRExitDescriptor(exitKind, exceptionType, noValue(), nullptr, m_origin.withForExitAndExitOK(opCatchOrigin, true));
         OSRExitDescriptor* exitDescriptor = &m_ftlState.jitCode->osrExitDescriptors.last();
         exitDescriptor->m_stackmapID = m_stackmapIDs - 1;
 
@@ -10320,7 +10335,7 @@
 
 #if FTL_USES_B3
         blessSpeculation(
-            m_out.speculate(failCondition), kind, lowValue, highValue, origin, isExceptionHandler);
+            m_out.speculate(failCondition), kind, lowValue, highValue, origin);
 #else // FTL_USES_B3
         OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(kind, isExceptionHandler ? ExceptionType::CCallException : ExceptionType::None, lowValue, highValue, origin);
 
@@ -10348,7 +10363,7 @@
     }
 
 #if FTL_USES_B3
-    void blessSpeculation(CheckValue* value, ExitKind kind, FormattedValue lowValue, Node* highValue, NodeOrigin origin, bool isExceptionHandler = false)
+    void blessSpeculation(CheckValue* value, ExitKind kind, FormattedValue lowValue, Node* highValue, NodeOrigin origin)
     {
         OSRExitDescriptor* exitDescriptor = appendOSRExitDescriptor(lowValue, highValue);
         
@@ -10358,7 +10373,7 @@
         value->setGenerator(
             [=] (CCallHelpers& jit, const B3::StackmapGenerationParams& params) {
                 exitDescriptor->emitOSRExit(
-                    *state, kind, origin, jit, params, 0, isExceptionHandler);
+                    *state, kind, origin, jit, params, 0);
             });
     }
 #endif

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExit.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -69,20 +69,20 @@
 #if FTL_USES_B3
 RefPtr<OSRExitHandle> OSRExitDescriptor::emitOSRExit(
     State& state, ExitKind exitKind, const NodeOrigin& nodeOrigin, CCallHelpers& jit,
-    const StackmapGenerationParams& params, unsigned offset, bool isExceptionHandler)
+    const StackmapGenerationParams& params, unsigned offset)
 {
     RefPtr<OSRExitHandle> handle =
-        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
+        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset);
     handle->emitExitThunk(state, jit);
     return handle;
 }
 
 RefPtr<OSRExitHandle> OSRExitDescriptor::emitOSRExitLater(
     State& state, ExitKind exitKind, const NodeOrigin& nodeOrigin,
-    const StackmapGenerationParams& params, unsigned offset, bool isExceptionHandler)
+    const StackmapGenerationParams& params, unsigned offset)
 {
     RefPtr<OSRExitHandle> handle =
-        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset, isExceptionHandler);
+        prepareOSRExitHandle(state, exitKind, nodeOrigin, params, offset);
     params.addLatePath(
         [handle, &state] (CCallHelpers& jit) {
             handle->emitExitThunk(state, jit);
@@ -92,11 +92,11 @@
 
 RefPtr<OSRExitHandle> OSRExitDescriptor::prepareOSRExitHandle(
     State& state, ExitKind exitKind, const NodeOrigin& nodeOrigin,
-    const StackmapGenerationParams& params, unsigned offset, bool isExceptionHandler)
+    const StackmapGenerationParams& params, unsigned offset)
 {
     unsigned index = state.jitCode->osrExit.size();
     OSRExit& exit = state.jitCode->osrExit.alloc(
-        this, exitKind, nodeOrigin.forExit, nodeOrigin.semantic, isExceptionHandler);
+        this, exitKind, nodeOrigin.forExit, nodeOrigin.semantic);
     RefPtr<OSRExitHandle> handle = adoptRef(new OSRExitHandle(index, exit));
     for (unsigned i = offset; i < params.size(); ++i)
         exit.m_valueReps.append(params[i]);
@@ -108,23 +108,20 @@
 #if FTL_USES_B3
 OSRExit::OSRExit(
     OSRExitDescriptor* descriptor,
-    ExitKind exitKind, CodeOrigin codeOrigin, CodeOrigin codeOriginForExitProfile,
-    bool isExceptionHandler)
+    ExitKind exitKind, CodeOrigin codeOrigin, CodeOrigin codeOriginForExitProfile)
     : OSRExitBase(exitKind, codeOrigin, codeOriginForExitProfile)
     , m_descriptor(descriptor)
 {
-    m_isExceptionHandler = isExceptionHandler;
 }
 #else // FTL_USES_B3
 OSRExit::OSRExit(
-    OSRExitDescriptor* descriptor, OSRExitDescriptorImpl& exitDescriptorImpl,
+    OSRExitDescriptor* descriptor, ExitKind exitKind, OSRExitDescriptorImpl& exitDescriptorImpl,
     uint32_t stackmapRecordIndex)
-    : OSRExitBase(exitDescriptorImpl.m_kind, exitDescriptorImpl.m_codeOrigin, exitDescriptorImpl.m_codeOriginForExitProfile)
+    : OSRExitBase(exitKind, exitDescriptorImpl.m_codeOrigin, exitDescriptorImpl.m_codeOriginForExitProfile)
     , m_descriptor(descriptor)
     , m_stackmapRecordIndex(stackmapRecordIndex)
     , m_exceptionType(exitDescriptorImpl.m_exceptionType)
 {
-    m_isExceptionHandler = exitDescriptorImpl.m_exceptionType != ExceptionType::None;
 }
 #endif // FTL_USES_B3
 
@@ -178,7 +175,7 @@
 
 void OSRExit::spillRegistersToSpillSlot(CCallHelpers& jit, int32_t stackSpillSlot)
 {
-    RELEASE_ASSERT(willArriveAtOSRExitFromGenericUnwind() || willArriveAtOSRExitFromCallOperation());
+    RELEASE_ASSERT(isGenericUnwindHandler() || willArriveAtOSRExitFromCallOperation());
     unsigned count = 0;
     for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
         if (registersToPreserveForCallThatMightThrow.get(reg)) {
@@ -196,7 +193,7 @@
 
 void OSRExit::recoverRegistersFromSpillSlot(CCallHelpers& jit, int32_t stackSpillSlot)
 {
-    RELEASE_ASSERT(willArriveAtOSRExitFromGenericUnwind() || willArriveAtOSRExitFromCallOperation());
+    RELEASE_ASSERT(isGenericUnwindHandler() || willArriveAtOSRExitFromCallOperation());
     unsigned count = 0;
     for (GPRReg reg = MacroAssembler::firstRegister(); reg <= MacroAssembler::lastRegister(); reg = MacroAssembler::nextRegister(reg)) {
         if (registersToPreserveForCallThatMightThrow.get(reg)) {
@@ -229,24 +226,6 @@
     RELEASE_ASSERT_NOT_REACHED();
 }
 
-bool exceptionTypeWillArriveAtOSRExitFromGenericUnwind(ExceptionType exceptionType)
-{
-    switch (exceptionType) {
-    case ExceptionType::JSCall:
-    case ExceptionType::GetById:
-    case ExceptionType::PutById:
-        return true;
-    default:
-        return false;
-    }
-    RELEASE_ASSERT_NOT_REACHED();
-}
-
-bool OSRExit::willArriveAtOSRExitFromGenericUnwind() const
-{
-    return exceptionTypeWillArriveAtOSRExitFromGenericUnwind(m_exceptionType);
-}
-
 bool OSRExit::willArriveAtOSRExitFromCallOperation() const
 {
     switch (m_exceptionType) {

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExit.h (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExit.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExit.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -80,8 +80,6 @@
     LazySlowPath,
     BinaryOpGenerator,
 };
-
-bool exceptionTypeWillArriveAtOSRExitFromGenericUnwind(ExceptionType);
 #endif // !FTL_USES_B3
 
 struct OSRExitDescriptor {
@@ -116,7 +114,7 @@
     // this call, the OSRExit is simply ready to go.
     RefPtr<OSRExitHandle> emitOSRExit(
         State&, ExitKind, const DFG::NodeOrigin&, CCallHelpers&, const B3::StackmapGenerationParams&,
-        unsigned offset = 0, bool isExceptionHandler = false);
+        unsigned offset = 0);
 
     // In some cases you want an OSRExit to come into existence, but you don't want to emit it right now.
     // This will emit the OSR exit in a late path. You can't be sure exactly when that will happen, but
@@ -128,14 +126,15 @@
     // eventually gets access to its label.
     RefPtr<OSRExitHandle> emitOSRExitLater(
         State&, ExitKind, const DFG::NodeOrigin&, const B3::StackmapGenerationParams&,
-        unsigned offset = 0, bool isExceptionHandler = false);
+        unsigned offset = 0);
 
+private:
     // This is the low-level interface. It will create a handle representing the desire to emit code for
     // an OSR exit. You can call OSRExitHandle::emitExitThunk() once you have a place to emit it. Note
     // that the above two APIs are written in terms of this and OSRExitHandle::emitExitThunk().
     RefPtr<OSRExitHandle> prepareOSRExitHandle(
         State&, ExitKind, const DFG::NodeOrigin&, const B3::StackmapGenerationParams&,
-        unsigned offset = 0, bool isExceptionHandler = false);
+        unsigned offset = 0);
 #endif // FTL_USES_B3
 };
 
@@ -160,9 +159,9 @@
 
 struct OSRExit : public DFG::OSRExitBase {
     OSRExit(
-        OSRExitDescriptor*,
+        OSRExitDescriptor*, ExitKind,
 #if FTL_USES_B3
-        ExitKind, CodeOrigin, CodeOrigin codeOriginForExitProfile, bool isExceptionHandler
+        CodeOrigin, CodeOrigin codeOriginForExitProfile
 #else // FTL_USES_B3
         OSRExitDescriptorImpl&, uint32_t stackmapRecordIndex
 #endif // FTL_USES_B3
@@ -174,10 +173,6 @@
     // This tells us where to place a jump.
     CodeLocationJump m_patchableJump;
     Vector<B3::ValueRep> m_valueReps;
-    // True if this exit is used as an exception handler for unwinding. This happens to only be set when
-    // isExceptionHandler is true, but all this actually means is that the OSR exit will assume that the
-    // machine state is as it would be coming out of genericUnwind.
-    bool m_isUnwindHandler { false };
 #else // FTL_USES_B3
     // Offset within the exit stubs of the stub for this exit.
     unsigned m_patchableCodeOffset;
@@ -198,7 +193,6 @@
     void spillRegistersToSpillSlot(CCallHelpers&, int32_t stackSpillSlot);
     void recoverRegistersFromSpillSlot(CCallHelpers& jit, int32_t stackSpillSlot);
 
-    bool willArriveAtOSRExitFromGenericUnwind() const;
     bool willArriveAtExitFromIndirectExceptionCheck() const;
     bool willArriveAtOSRExitFromCallOperation() const;
     bool needsRegisterRecoveryOnGenericUnwindOSRExitPath() const;

Modified: trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLOSRExitCompiler.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -207,13 +207,7 @@
     CCallHelpers jit(vm, codeBlock);
 
     // The first thing we need to do is restablish our frame in the case of an exception.
-    if (
-#if FTL_USES_B3
-        exit.m_isUnwindHandler
-#else // FTL_USES_B3
-        exit.willArriveAtOSRExitFromGenericUnwind()
-#endif // FTL_USES_B3
-        ) {
+    if (exit.isGenericUnwindHandler()) {
         RELEASE_ASSERT(vm->callFrameForCatch); // The first time we hit this exit, like at all other times, this field should be non-null.
         jit.restoreCalleeSavesFromVMCalleeSavesBuffer();
         jit.loadPtr(vm->addressOfCallFrameForCatch(), MacroAssembler::framePointerRegister);
@@ -488,19 +482,19 @@
     RegisterAtOffsetList* baselineCalleeSaves = baselineCodeBlock->calleeSaveRegisters();
     RegisterAtOffsetList* vmCalleeSaves = vm->getAllCalleeSaveRegisterOffsets();
     RegisterSet vmCalleeSavesToSkip = RegisterSet::stackRegisters();
-    if (exit.m_isExceptionHandler)
+    if (exit.isExceptionHandler())
         jit.move(CCallHelpers::TrustedImmPtr(vm->calleeSaveRegistersBuffer), GPRInfo::regT1);
 
     for (Reg reg = Reg::first(); reg <= Reg::last(); reg = reg.next()) {
         if (!allFTLCalleeSaves.get(reg)) {
-            if (exit.m_isExceptionHandler)
+            if (exit.isExceptionHandler())
                 RELEASE_ASSERT(!vmCalleeSaves->find(reg));
             continue;
         }
         unsigned unwindIndex = codeBlock->calleeSaveRegisters()->indexOf(reg);
         RegisterAtOffset* baselineRegisterOffset = baselineCalleeSaves->find(reg);
         RegisterAtOffset* vmCalleeSave = nullptr; 
-        if (exit.m_isExceptionHandler)
+        if (exit.isExceptionHandler())
             vmCalleeSave = vmCalleeSaves->find(reg);
 
         if (reg.isGPR()) {
@@ -540,7 +534,7 @@
         }
     }
 
-    if (exit.m_isExceptionHandler) {
+    if (exit.isExceptionHandler()) {
         RegisterAtOffset* vmCalleeSave = vmCalleeSaves->find(GPRInfo::tagTypeNumberRegister);
         jit.store64(GPRInfo::tagTypeNumberRegister, MacroAssembler::Address(GPRInfo::regT1, vmCalleeSave->offset()));
 
@@ -564,7 +558,7 @@
     
     handleExitCounts(jit, exit);
     reifyInlinedCallFrames(jit, exit);
-    adjustAndJumpToTarget(jit, exit, exit.m_isExceptionHandler);
+    adjustAndJumpToTarget(jit, exit);
     
     LinkBuffer patchBuffer(*vm, jit, codeBlock);
 #if FTL_USES_B3
@@ -622,13 +616,11 @@
         dataLog("    Exit stackmap ID: ", exit.m_descriptor->m_stackmapID, "\n");
 #endif // !FTL_USES_B3
         dataLog("    Current call site index: ", exec->callSiteIndex().bits(), "\n");
-        dataLog("    Exit is exception handler: ", exit.m_isExceptionHandler, "\n");
-#if FTL_USES_B3
-        dataLog("    Is unwind handler: ", exit.m_isUnwindHandler, "\n");
-#else // FTL_USES_B3
-        dataLog("    Will arrive at exit from genericUnwind(): ", exit.willArriveAtOSRExitFromGenericUnwind(), "\n");
+        dataLog("    Exit is exception handler: ", exit.isExceptionHandler(), "\n");
+        dataLog("    Is unwind handler: ", exit.isGenericUnwindHandler(), "\n");
+#if !FTL_USES_B3
         dataLog("    Will arrive at exit from lazy slow path: ", exit.m_exceptionType == ExceptionType::LazySlowPath, "\n");
-#endif // FTL_USES_B3
+#endif // !FTL_USES_B3
         dataLog("    Exit values: ", exit.m_descriptor->m_values, "\n");
 #if FTL_USES_B3
         dataLog("    Value reps: ", listDump(exit.m_valueReps), "\n");

Modified: trunk/Source/_javascript_Core/ftl/FTLPatchpointExceptionHandle.cpp (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLPatchpointExceptionHandle.cpp	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLPatchpointExceptionHandle.cpp	2016-01-29 19:46:01 UTC (rev 195831)
@@ -69,7 +69,7 @@
             new ExceptionTarget(isDefaultHandler, m_state.exceptionHandler, nullptr));
     }
     bool isDefaultHandler = false;
-    return adoptRef(new ExceptionTarget(isDefaultHandler, { }, createHandle(params)));
+    return adoptRef(new ExceptionTarget(isDefaultHandler, { }, createHandle(ExceptionCheck, params)));
 }
 
 void PatchpointExceptionHandle::scheduleExitCreationForUnwind(
@@ -78,9 +78,8 @@
     if (!m_descriptor)
         return;
     
-    RefPtr<OSRExitHandle> handle = createHandle(params);
+    RefPtr<OSRExitHandle> handle = createHandle(GenericUnwind, params);
 
-    handle->exit.m_isUnwindHandler = true;
     handle->exit.m_exceptionHandlerCallSiteIndex = callSiteIndex;
 
     HandlerInfo handler = m_handler;
@@ -110,11 +109,10 @@
 }
 
 RefPtr<OSRExitHandle> PatchpointExceptionHandle::createHandle(
-    const B3::StackmapGenerationParams& params)
+    ExitKind kind, const B3::StackmapGenerationParams& params)
 {
-    bool isExceptionHandler = true;
     return m_descriptor->emitOSRExitLater(
-        m_state, Uncountable, m_origin, params, m_offset, isExceptionHandler);
+        m_state, kind, m_origin, params, m_offset);
 }
 
 } } // namespace JSC::FTL

Modified: trunk/Source/_javascript_Core/ftl/FTLPatchpointExceptionHandle.h (195830 => 195831)


--- trunk/Source/_javascript_Core/ftl/FTLPatchpointExceptionHandle.h	2016-01-29 19:19:42 UTC (rev 195830)
+++ trunk/Source/_javascript_Core/ftl/FTLPatchpointExceptionHandle.h	2016-01-29 19:46:01 UTC (rev 195831)
@@ -31,6 +31,7 @@
 #if ENABLE(FTL_JIT) && FTL_USES_B3
 
 #include "DFGNodeOrigin.h"
+#include "ExitKind.h"
 #include "HandlerInfo.h"
 #include <wtf/Ref.h>
 #include <wtf/ThreadSafeRefCounted.h>
@@ -88,7 +89,7 @@
     PatchpointExceptionHandle(
         State&, OSRExitDescriptor*, DFG::NodeOrigin, unsigned offset, const HandlerInfo&);
 
-    RefPtr<OSRExitHandle> createHandle(const B3::StackmapGenerationParams&);
+    RefPtr<OSRExitHandle> createHandle(ExitKind, const B3::StackmapGenerationParams&);
 
     State& m_state;
     OSRExitDescriptor* m_descriptor;
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to