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;