diff --git a/snapi-client/src/test/scala/raw/compiler/rql2/tests/benchmark/BenchmarkTests.scala b/snapi-client/src/test/scala/raw/compiler/rql2/tests/benchmark/BenchmarkTests.scala index bc3f1277b..914dbfdca 100644 --- a/snapi-client/src/test/scala/raw/compiler/rql2/tests/benchmark/BenchmarkTests.scala +++ b/snapi-client/src/test/scala/raw/compiler/rql2/tests/benchmark/BenchmarkTests.scala @@ -16,410 +16,154 @@ import raw.compiler.rql2.tests.CompilerTestContext trait BenchmarkTests extends CompilerTestContext { - val shouldBeExecuted = false - - val numberOfRuns = 10 - - test("Range Count test") { _ => - assume(shouldBeExecuted, "This test is disabled by default") + property("raw.training-wheels", "false") + + //testing if the code is running + // test( + // """let + // | lineitemsType = type collection(record(l_orderkey: int, l_payedammount: double)), + // | customerType = type record(customer: collection(record(c_custkey: string))), + // | ordersType = type collection(record(o_orderkey: int, o_custkey: int)), + // | lineitems = PostgreSQL.Query( + // | "postgres", + // | "select l_orderkey, (l_extendedprice * (1 - l_discount)) as l_payedammount from tpch1.lineitem", + // | lineitemsType, + // | host = "localhost", + // | username = "postgres", + // | password = "1234" + // | ), + // | customers = Json.Read("file:///home/ld/workspace/TPCH/1GB/customer.json", customerType), // an object with an array inside + // | orders = Csv.Read("file:///home/ld/workspace/TPCH/1GB/orders.csv", ordersType, delimiter = "\t"), + // | customersOrders = Collection.EquiJoin(customers.customer, orders, (c) -> Int.From(c.c_custkey), (o) -> o.o_custkey), + // | customerOrdersItems = Collection.EquiJoin( + // | customersOrders, + // | lineitems, + // | (co) -> Int.From(co.o_orderkey), + // | (oi) -> oi.l_orderkey + // | ), + // | grouped = Collection.GroupBy(customerOrdersItems, (c) -> c.c_custkey), + // | result = Collection.Transform(grouped, (g) -> {id: g, total_payed: Collection.Sum(g.group.l_payedammount)}), + // | finalResult = Collection.Filter(result, (r) -> r.total_payed > 6000000) + // |in + // | Collection.Count(finalResult)""".stripMargin + // )(_ should evaluateTo("[]")) + + test("Range Join File with db test") { _ => + assume(false, "This test is disabled by default") + val prog = """let + | lineitemsType = type collection(record(l_orderkey: int, l_payedammount: double)), + | customerType = type record(customer: collection(record(c_custkey: string))), + | ordersType = type collection(record(o_orderkey: int, o_custkey: int)), + | lineitems = PostgreSQL.Query( + | "postgres", + | "select l_orderkey, (l_extendedprice * (1 - l_discount)) as l_payedammount from tpch1.lineitem", + | lineitemsType, + | host = "localhost:44444", + | username = "postgres", + | password = "1234" + | ), + | customers = Json.Read("file:///home/ld/workspace/TPCH/1GB/customer.json", customerType), // an object with an array inside + | orders = Csv.Read("file:///home/ld/workspace/TPCH/1GB/orders.csv", ordersType, delimiter = "\t"), + | customersOrders = Collection.EquiJoin(customers.customer, orders, (c) -> Int.From(c.c_custkey), (o) -> o.o_custkey), + | customerOrdersItems = Collection.EquiJoin( + | customersOrders, + | lineitems, + | (co) -> Int.From(co.o_orderkey), + | (oi) -> oi.l_orderkey + | ), + | grouped = Collection.GroupBy(customerOrdersItems, (c) -> c.c_custkey), + | result = Collection.Transform(grouped, (g) -> {id: g, total_payed: Collection.Sum(g.group.l_payedammount)}), + | finalResult = Collection.Filter(result, (r) -> r.total_payed > 6000000) + |in + | Collection.Count(finalResult)""".stripMargin - fastExecute("""let a = "hello" in a """) // some random query - fastExecute("""let a = 2 + 2 in a """) // some random query - fastExecute("""let a = 2/2 in a """) // some random query + val numberOfRuns = 5 - val prog = """// Utility functions - |min(a: double, b: double) = if(a<=b) then a else b - |max(a: double, b: double) = if(a>=b) then a else b - |//dayOfYear(d: date):int = Int.From(Interval.ToMillis(Date.Subtract(d, Date.Build(Date.Year(d), 1, 1))) / 8.64e+7) + 1 - |dayOfYear(d: date) = - |let - | getDaysOfMonth(year:int, month:int)= - | let - | start=Date.Build(year,month,1), - | end=Date.FromTimestamp(Date.SubtractInterval(Date.Build(year, month+1, 1), Interval.Build(days=1))) - | in - | Interval.Days(Date.Subtract(end, start))+1 - | , - | - | rec m2(d:date, month:int):int = - | let - | year=Date.Year(d), - | i1=Date.Subtract(d, Date.Build(year, month, 1)), - | mondiff=Interval.Months(i1), - | daysDiff=Interval.Days(i1), - | output = - | if(mondiff<0) then 0 - | else if(mondiff==0) then daysDiff - | else getDaysOfMonth(year, month)+m2(d, month+1) - | in - | output - | , - | output=m2(d,1)+1 - |in - | output - | - |isLeapYear(year: int) = - | if (year % 4 == 0 and year % 100 != 0 ) or (year % 400 == 0) then true - | else false - | - |// Normalization functions - |// we saw that some watt numbers where actually kilowatts, so we simply divided by 1000 - also negative watts numbers become zeros - |normalizeWatt(a: double) = if(a>=1000) then a/1000.0 else max(0,a) - |normalizeTemperature(a: double) = a - | - |// Calculate PDC for a given time slot - |find_I_panel_pdc(r: record(timestamp: timestamp, watt: int, temperature: double), angle: double, method: string) = - | let - | std=1367.00, - | year=Timestamp.Year(r.timestamp), - | days_of_year=if(isLeapYear(year)) then 366.0 else 365.0, - | day_of_year=dayOfYear(Date.FromTimestamp(r.timestamp)), - | cur_time=Time.Build(Timestamp.Hour(r.timestamp), Timestamp.Minute(r.timestamp)), - | latitude=37.97385, - | time_math=Time.Hour(cur_time)+Time.Minute(cur_time)/Double.From(60.00), - | beta=(360.00*(day_of_year-1.00))/days_of_year, - | delta=23.45*Math.Sin(Math.Radians(360.00*(284.00+day_of_year)/days_of_year)), - | e_min=229.2*(0.000075+(0.001868*Math.Cos(Math.Radians(beta)))-(0.032077*Math.Sin(Math.Radians(beta)))-(0.014615*Math.Cos(Math.Radians(2.00*beta)))-(0.04089*Math.Sin(Math.Radians(2.00*beta)))), - | t_solar=time_math+e_min/60.00+4.00*(30.00-23.78743)/60.00, - | omega=15.00*(t_solar-12.00), - | sin_beta=(Math.Sin(Math.Radians(delta)))*Math.Sin(Math.Radians(latitude))+(Math.Cos(Math.Radians(delta)))*Math.Cos(Math.Radians(latitude))*Math.Cos(Math.Radians(omega)), - | b_m=Math.Asin(sin_beta)*180.00/Math.Pi(), - | e_o=1.0001+(0.034221*Math.Cos(Math.Radians(beta)))+(0.00128*Math.Sin(Math.Radians(beta)))+(0.000719*Math.Cos(Math.Radians(2.0*beta)))+(0.000077*Math.Sin(Math.Radians(2.0*beta))), - | g_extraterrestrial=e_o*std, - | g_global_h_oa_na=e_o*std*sin_beta, - | g_global_h_oa=max(0,g_global_h_oa_na), - | k_t_base=r.watt/g_global_h_oa, - | k_t= - | if(g_global_h_oa<=0) - | then 0 - | else - | if(k_t_base>1) - | then 1 - | else k_t_base, - | kappa=k_t, - | kappa_d= - | if(method=="erbs") - | then - | if(kappa<=0.22) - | then 1.0-0.09*kappa - | else if(kappa>=0.8) - | then 0.165 - | else 0.9511-0.1604*kappa+4.388*Math.Power(kappa,2)-16.638*Math.Power(kappa,3)+12.336*Math.Power(kappa,4) - | else if(method=="karatasou") - | then - | (if(kappa<=0.78) - | then 0.9995-0.05*kappa-2.4156*Math.Power(kappa,2) +1.4926*Math.Power(kappa,3) - | else 0.20) - | else Error.Build("Illegal method. Valid methods are 'erbs' and 'karatasou'") - | , - | g_beam_h_10min=(if(sin_beta>0) then (r.watt*(1-kappa_d)) else 0), - | g_diff_10min=r.watt-g_beam_h_10min, - | g_beam_i_10min=(if(g_beam_h_10min*Math.Sin(Math.Radians(angle+b_m))/Math.Sin(Math.Radians(b_m))>g_extraterrestrial) then 0 else (g_beam_h_10min*Math.Sin(Math.Radians((angle+b_m)))/Math.Sin(Math.Radians(b_m)))), - | g_diff_i_10min=g_diff_10min*(1+Math.Cos(Math.Radians(angle)))/2.00, - | g_albedo_i_10min=r.watt*0.2*(1-Math.Cos(Math.Radians(angle)))/2.00, - | g_glogal_i_10min=g_beam_i_10min+g_diff_i_10min+g_albedo_i_10min, - | output=g_glogal_i_10min/6000 - | in - | output - | //Debugging: {timestamp:r.timestamp,sin_beta:sin_beta, e_o: e_o, g_global_h_oa: g_global_h_oa, k_t: k_t, kappa_d:kappa_d, g_diff_10min:g_diff_10min, g_beam_i_10min: g_beam_i_10min, g_diff_i_10min: g_diff_i_10min, g_albedo_i_10min: g_albedo_i_10min, t_cell: t_cell, p_dc: p_dc} - | - | - |// Main method - |main(min_date_inclusive: date = Date.Build(1998,12,11), max_date_inclusive: date = Date.Build(2009,09,01), method: string = "erbs") = - | let - | // Iterate through angles [0..89] - | min_angle=0, - | max_angle=90, - | - | output= - | // Valid time period is [1998-12-11 .. 2009-09-01) - | if(Date.Build(1998,12,11)>min_date_inclusive or max_date_inclusive>Date.Build(2009,09,01)) then Error.Build("Illegal period. Permissible period is [1999/01/01 .. 2009/09/01]") - | else - | let - | angles=List.From(Int.Range(min_angle, max_angle)), - | - | // Get temperatures from meteo (uploaded to a public site) - | temperature_raw=Csv.InferAndRead("file:/home/ld/Downloads/truffle_data/dataset_temperature_athens.csv"), - | // Consider only temperature measurements that are within the valid time period and normalize them - | temperature_data= - | List.From(Collection.Transform( - | Collection.Filter( - | temperature_raw, - | c -> Date.FromTimestamp(c._1)>=min_date_inclusive and Date.FromTimestamp(c._1)<=max_date_inclusive - | ), - | c -> {timestamp: c._1, temperature: normalizeTemperature(c._2)} - | )), - | - | // Get solar radiation from meteo (uploaded to a public site) - | solar_radiation_raw=Csv.InferAndRead("file:/home/ld/Downloads/truffle_data/dataset_solar_radiation_athens_v2.csv"), - | // Consider only solar radiation measurements that are within the valid time period and normalize them - | solar_radiation_data= - | Collection.Transform( - | Collection.Filter( - | solar_radiation_raw, - | c -> Date.FromTimestamp(c._1)>=min_date_inclusive and Date.FromTimestamp(c._1)<=max_date_inclusive - | ), - | c -> {timestamp: c._1, watt: Int.From(normalizeWatt(c._2)*1000)} - | ), - | solar_radiation_list=List.From(solar_radiation_data), - | - | // Join solar radiation and temperature lists, based on their timestamps - | combined_data= - | List.Transform(List.EquiJoin(temperature_data, solar_radiation_list, a -> a.timestamp, b -> b.timestamp), - | r -> {timestamp: Record.GetFieldByIndex(r, 1), watt:r.watt, temperature: r.temperature} - | ), - | - | // For each angle [0..89] calculate the total output - | output=List.Transform(angles, angle -> - | { - | angle: Double.From(angle), - | H: - | List.Sum(List.Transform(combined_data, r -> find_I_panel_pdc(r, Double.From(angle), method))) - | } - | ) - | in - | output - | in - | // Sort angles by higher output - | //List.OrderBy(output, r -> r.H, "DESC") - | output - | - | - |// Test run: entire 2006 - |main(min_date_inclusive=Date.Build(2008,2,1), max_date_inclusive=Date.Build(2008,2,1)) - |//dayOfYear(Date.Build(2006,3,1)) - |//isLeapYear(2008)""".stripMargin + val values = Array.fill(numberOfRuns + 1)(0L) - //Warmup - fastExecute(prog) - fastExecute(prog) - fastExecute(prog) val started = System.currentTimeMillis() for (i <- 0 to numberOfRuns) { + val startedIn = System.currentTimeMillis() fastExecute(prog) + val elapsedIn = System.currentTimeMillis() + values(i) = elapsedIn - startedIn } val elapsed = System.currentTimeMillis() - logger.info("++++++++++ Average execution time time: " + ((elapsed - started) / numberOfRuns)) + val mean = (elapsed - started) / numberOfRuns + + var standardDeviation = 0.0 + for (num <- values) { + standardDeviation += Math.pow(num - mean, 2) + } + + logger.info("++++++++++ Average execution time: " + mean) + logger.info("++++++++++ Standard deviation is: " + Math.sqrt(standardDeviation / numberOfRuns)) } - // A.Z. this one I use for the _experimental package test just to see how it works - // test("""Math.Power(1,1)""")(it => it should run) - // test("""{a: {a: {a: {a: {a: {a: {a: {a: {a: {a: {a: {a: 1, b: 2}, b: 2}, b: 2}, b: 2}, b: 2}}}}}}}}""")(it => it should run) + test("Range Count test") { _ => + assume(false, "This test is disabled by default") + + for (i <- 0 to 20) { + fastExecute( + """let + | range = 1000L + |in + | Collection.Count(Collection.Transform(Collection.Filter(Long.Range(0, range), (x) -> x % 2 == 0), (y) -> y + 1))""".stripMargin + ) + } + + val values = Array.fill(7)(0L) + + for (i <- 0 to 6) { + logger.info("++++++++++ 10^" + (i + 3)) + val startedIn = System.currentTimeMillis() + fastExecute( + s"""let + | range = ${Math.pow(10, i + 3).toLong}L + |in + | Collection.Count(Collection.Transform(Collection.Filter(Long.Range(0, range), (x) -> x % 2 == 0), (y) -> y + 1))""".stripMargin + ) + val elapsedIn = System.currentTimeMillis() + values(i) = elapsedIn - startedIn + } + logger.info("++++++++++ Values: " + values.mkString(", ")) -// test("Json Writer range test") { _ => + // Execution with STD + // val numberOfRuns = 100 + // fastExecute("""let a = "hello" in a """) // some random query + // fastExecute("""let a = 2 + 2 in a """) // some random query + // fastExecute("""let a = 2/2 in a """) // some random query + // + // val prog = """let + // | range = 100000000L + // |in + // | Collection.Count(Collection.Transform(Collection.Filter(Long.Range(0, range), (x) -> x % 2 == 0), (y) -> y + 1))""".stripMargin + // + // //Warmup + // for (i <- 0 to 20) { + // fastExecute(prog) + // } + // logger.info("++++++++++ Warmup finished") + // val values = Array.fill(numberOfRuns + 1)(0L) + // // val started = System.currentTimeMillis() - // fastExecute( - // """let a = Int.Range(0,21474836,step=1), b = Collection.Transform(a, x -> x + 1) in b""" - // ) + // for (i <- 0 to numberOfRuns) { + // val startedIn = System.currentTimeMillis() + // fastExecute(prog) + // val elapsedIn = System.currentTimeMillis() + // values(i) = elapsedIn - startedIn + // } // val elapsed = System.currentTimeMillis() // - // logger.info("++++++++++ Average execution time time: " + (elapsed - started)) - // } - -// test("bug-test") { _ => -// executeQuery("""main(url: string) = -// | let gpxType = type record( -// | trk: record( -// | trkseg: record( -// | trkpt: collection(record(`@lat`: double, `@lon`: double))))), -// | gpx = Xml.Read(url, type gpxType) -// | in gpx -// | -// |main("file:/home/ld/Downloads/Route Touristique du Champagne Montagne de Reims.gpx")""".stripMargin) -// } - -// test("bug-test") { _ => -// executeQuery("""main(url: string) = -// | let gpxType = type record( -// | trk: record( -// | trkseg: record( -// | trkpt: collection(record(`@lat`: double, `@lon`: double))))), -// | gpx = Xml.Read(url, type gpxType), -// | size = 100, -// | wpt = gpx.trk.trkseg.trkpt, -// | minLat = Collection.Min(wpt.`@lat`), -// | maxLat = Collection.Max(wpt.`@lat`), -// | minLon = Collection.Min(wpt.`@lon`), -// | maxLon = Collection.Max(wpt.`@lon`), -// | maxBoth = List.Max([maxLon - minLon, maxLat - minLat]), -// | normalizedCoordinates = Collection.Transform(wpt, -// | r -> { -// | x: (r.`@lon` - minLon) / maxBoth * size, -// | y: (r.`@lat` - minLat) / maxBoth * size -// | } -// | ), -// | intCoordinates = Collection.Transform(normalizedCoordinates, r -> { -// | x: Int.From(r.x), -// | y: Int.From(r.y) -// | }), -// | // dim100 = Collection.Range(0, 100), -// | dim10 = Collection.Build(0, 1, 2, 3, 4, 5, 6, 7, 8, 9), -// | dim100 = Collection.Unnest(dim10, n1 -> Collection.Transform(dim10, n2 -> n1*10 + n2)), -// | map = Collection.Transform(dim100, -// | y -> Collection.Transform(dim100, -// | x -> -// | // check 100 - y to make the map upside down -// | if Nullable.IsNull(Collection.First(Collection.Filter(intCoordinates, r -> r.x == x and r.y == 100 - y))) -// | then "-" -// | else "+" -// | ) -// | ) -// | in map -// | -// |main("file:/home/ld/Downloads/Route Touristique du Champagne Montagne de Reims.gpx")""".stripMargin) -// } - -// test("bug-test") { _ => -// val started = System.currentTimeMillis() -// fastExecute("""getAuth0Users( -// | email: string = null, -// | start_date: date = Date.FromTimestamp(Date.SubtractInterval(Date.Now(), Interval.Build(months = 1))), -// | last_login_since: date = Date.FromTimestamp(Date.SubtractInterval(Date.Now(), Interval.Build(years = 1))), -// | end_date: date = Date.FromTimestamp(Date.AddInterval(Date.Now(), Interval.Build(days = 1))), -// | organization: string = null) = -// | let -// | auth0_user_type = type record( -// | created_at: string, -// | email: string, -// | email_verified: bool, -// | user_id: string, -// | last_login: string, -// | last_ip: string, -// | logins_count: int, -// | app_metadata: record( -// | rawOrg: collection(string), -// | raw_clients: collection(undefined) -// | ) -// | ), -// | auth0_users_type = type collection(record( -// | created_at: string, -// | email: string, -// | email_verified: bool, -// | user_id: string, -// | last_login: string, -// | last_ip: string, -// | logins_count: int, -// | app_metadata: record( -// | rawOrg: collection(string), -// | raw_clients: collection(undefined) -// | ) -// | )), -// | -// | rec getUserPage(page: int = 1): auth0_users_type = -// | let -// | payload = -// | if(page>10 or page<0) -// | then -// | Error.Build("Illegal page number. Valid pages are [1..10]") -// | else if(page==10) -// | then -// | Collection.Empty(auth0_user_type) -// | else -// | Collection.Union( -// | Json.Read( -// | Http.Get( -// | "https://raw.eu.auth0.com/api/v2/users", -// | token="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlFUaERPVGc1TXpkQ1FUbENRVGd6TVRsRU1URTFOVFl3TVRrM1JUTkdRall6TWtNME1qSkZPUSJ9.eyJpc3MiOiJodHRwczovL3Jhdy5ldS5hdXRoMC5jb20vIiwic3ViIjoiZ2ttZGxnYTRqeEt4cmFoYVVwT3Q0YkJaTElBeXk0ZDZAY2xpZW50cyIsImF1ZCI6Imh0dHBzOi8vcmF3LmV1LmF1dGgwLmNvbS9hcGkvdjIvIiwiaWF0IjoxNjkzODMxNzkwLCJleHAiOjExNjkzODMxNzg5LCJhenAiOiJna21kbGdhNGp4S3hyYWhhVXBPdDRiQlpMSUF5eTRkNiIsInNjb3BlIjoicmVhZDpjbGllbnRfZ3JhbnRzIGNyZWF0ZTpjbGllbnRfZ3JhbnRzIGRlbGV0ZTpjbGllbnRfZ3JhbnRzIHVwZGF0ZTpjbGllbnRfZ3JhbnRzIHJlYWQ6dXNlcnMgdXBkYXRlOnVzZXJzIGRlbGV0ZTp1c2VycyBjcmVhdGU6dXNlcnMgcmVhZDp1c2Vyc19hcHBfbWV0YWRhdGEgdXBkYXRlOnVzZXJzX2FwcF9tZXRhZGF0YSBkZWxldGU6dXNlcnNfYXBwX21ldGFkYXRhIGNyZWF0ZTp1c2Vyc19hcHBfbWV0YWRhdGEgY3JlYXRlOnVzZXJfdGlja2V0cyByZWFkOmNsaWVudHMgdXBkYXRlOmNsaWVudHMgZGVsZXRlOmNsaWVudHMgY3JlYXRlOmNsaWVudHMgcmVhZDpjbGllbnRfa2V5cyB1cGRhdGU6Y2xpZW50X2tleXMgZGVsZXRlOmNsaWVudF9rZXlzIGNyZWF0ZTpjbGllbnRfa2V5cyByZWFkOmNvbm5lY3Rpb25zIHVwZGF0ZTpjb25uZWN0aW9ucyBkZWxldGU6Y29ubmVjdGlvbnMgY3JlYXRlOmNvbm5lY3Rpb25zIHJlYWQ6cmVzb3VyY2Vfc2VydmVycyB1cGRhdGU6cmVzb3VyY2Vfc2VydmVycyBkZWxldGU6cmVzb3VyY2Vfc2VydmVycyBjcmVhdGU6cmVzb3VyY2Vfc2VydmVycyByZWFkOmRldmljZV9jcmVkZW50aWFscyB1cGRhdGU6ZGV2aWNlX2NyZWRlbnRpYWxzIGRlbGV0ZTpkZXZpY2VfY3JlZGVudGlhbHMgY3JlYXRlOmRldmljZV9jcmVkZW50aWFscyByZWFkOnJ1bGVzIHVwZGF0ZTpydWxlcyBkZWxldGU6cnVsZXMgY3JlYXRlOnJ1bGVzIHJlYWQ6cnVsZXNfY29uZmlncyB1cGRhdGU6cnVsZXNfY29uZmlncyBkZWxldGU6cnVsZXNfY29uZmlncyByZWFkOmVtYWlsX3Byb3ZpZGVyIHVwZGF0ZTplbWFpbF9wcm92aWRlciBkZWxldGU6ZW1haWxfcHJvdmlkZXIgY3JlYXRlOmVtYWlsX3Byb3ZpZGVyIGJsYWNrbGlzdDp0b2tlbnMgcmVhZDpzdGF0cyByZWFkOnRlbmFudF9zZXR0aW5ncyB1cGRhdGU6dGVuYW50X3NldHRpbmdzIHJlYWQ6bG9ncyByZWFkOnNoaWVsZHMgY3JlYXRlOnNoaWVsZHMgZGVsZXRlOnNoaWVsZHMgdXBkYXRlOnRyaWdnZXJzIHJlYWQ6dHJpZ2dlcnMgcmVhZDpncmFudHMgZGVsZXRlOmdyYW50cyByZWFkOmd1YXJkaWFuX2ZhY3RvcnMgdXBkYXRlOmd1YXJkaWFuX2ZhY3RvcnMgcmVhZDpndWFyZGlhbl9lbnJvbGxtZW50cyBkZWxldGU6Z3VhcmRpYW5fZW5yb2xsbWVudHMgY3JlYXRlOmd1YXJkaWFuX2Vucm9sbG1lbnRfdGlja2V0cyByZWFkOnVzZXJfaWRwX3Rva2VucyBjcmVhdGU6cGFzc3dvcmRzX2NoZWNraW5nX2pvYiBkZWxldGU6cGFzc3dvcmRzX2NoZWNraW5nX2pvYiByZWFkOmN1c3RvbV9kb21haW5zIGRlbGV0ZTpjdXN0b21fZG9tYWlucyBjcmVhdGU6Y3VzdG9tX2RvbWFpbnMiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.BWM8qNG7hWx95e5TIsZDd7wyPLrSt06BYUsDGtTzYbEJMiWmJJlcUv-J1oZMJfrO4OLfFIqNAYeu5SpK--2nC-rRDFRE9Nw9pBWRfx08L3jeODTSQ3NlfmKP0jKSLCs3af6Q4c-dZFPxRXHyk1Kh9QUlk7-wUJDdnB4WCcw64dilfe_tt2HNFMYvFSNSbfzcAdMEfBRRHnjjYUBGrkY2zE8adoc-QRQKi0a7MkRoXJsDi-LRNwr0Nvy1AceLuAkxjPgN6R47vdBTziRBxTIBCgmUWbXcrXXGwGPtnXIq3KsaDlI7jq2ZoUvvSWu4XzD0HQSNwYo2oR-Mh2hJ-CiBMw", -// | args=List.Build( -// | Record.Build(_1="per_page",_2="100"), -// | Record.Build(_1="fields", _2="email,app_metadata,email_verified,user_id,last_login,last_ip,logins_count,created_at"), -// | Record.Build(_1="page",_2=String.From(page))) -// | ), -// | auth0_users_type -// | ), -// | getUserPage(page+1) -// | ), -// | filterByEmail = -// | if(Nullable.IsNull(email)) -// | then -// | payload -// | else -// | Collection.Filter(payload, p -> p.email==email), -// | filterStartDate = -// | Collection.Filter(filterByEmail, t -> start_date<=Date.FromTimestamp(Timestamp.Parse(t.created_at, "yyyy-M-d'T'H:m:s.SSS'Z'"))), -// | filterEndDate = -// | Collection.Filter(filterStartDate, t -> end_date>=Date.FromTimestamp(Timestamp.Parse(t.created_at, "yyyy-M-d'T'H:m:s.SSS'Z'"))), -// | filterLastLogin = -// | Collection.Filter(filterEndDate, t -> last_login_since<=Date.FromTimestamp(Timestamp.Parse(t.last_login, "yyyy-M-d'T'H:m:s.SSS'Z'"))), -// | filterOrg = -// | if(Nullable.IsNull(organization)) -// | then -// | filterLastLogin -// | else -// | Collection.Filter(filterLastLogin, t -> Collection.Contains(t.app_metadata.rawOrg, organization)), -// | output = filterOrg -// | in -// | output -// | -// | in -// | Collection.Transform(getUserPage(0), c -> Record.AddField(c, reg=Date.FromTimestamp(Timestamp.Parse(c.created_at, "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")))) -// | -// |getAuth0Users()""".stripMargin) // some random query -// -// val elapsed = System.currentTimeMillis() -// -// logger.info("\n++++++++++ Execution time: " + (elapsed - started)) -// println("\n++++++++++ Execution time: " + (elapsed - started)) -// } - -// test("Json Writer range test") { _ => -// assume(shouldBeExecuted, "This test is disabled by default") -// -// fastExecute("""let a = "hello" in a """) // some random query -// fastExecute("""let a = 2 + 2 in a """) // some random query -// fastExecute("""let a = 2/2 in a """) // some random query -// -// //Warmup -// fastExecute( -// """Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))} , {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}, {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}, {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}, {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}))""" -// ) -// -// val started = System.currentTimeMillis() -// for (i <- 0 to numberOfRuns) { -// fastExecute( -// """Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))} , {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}, {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}, {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}, {a: x, b: Collection.Transform(Int.Range(0,100,step=1), x -> List.Build({a: x, b: "hello"} , {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}, {a: x, b: "hello"}))}))""" -// ) -// } -// val elapsed = System.currentTimeMillis() -// -// logger.info("++++++++++ Average execution time time: " + ((elapsed - started) / numberOfRuns)) -// } -// -// test("Range Count test") { _ => -// assume(shouldBeExecuted, "This test is disabled by default") -// -// fastExecute("""let a = "hello" in a """) // some random query -// fastExecute("""let a = 2 + 2 in a """) // some random query -// fastExecute("""let a = 2/2 in a """) // some random query -// -// //Warmup -// fastExecute(s"Collection.Count(Int.Range(0,${Int.MaxValue},step=1))") -// val started = System.currentTimeMillis() -// for (i <- 0 to numberOfRuns) { -// fastExecute(s"Collection.Count(Int.Range(0,${Int.MaxValue},step=1))") -// } -// val elapsed = System.currentTimeMillis() -// -// logger.info("++++++++++ Average execution time time: " + ((elapsed - started) / numberOfRuns)) -// } -// -// test("Filter Test") { _ => -// assume(shouldBeExecuted, "This test is disabled by default") -// -// fastExecute("""let a = "hello" in a """) // some random query -// fastExecute("""let a = 2 + 2 in a """) // some random query -// fastExecute("""let a = 2/2 in a """) // some random query -// -// //Warmup -// fastExecute(s"Collection.Filter(Int.Range(0,${Int.MaxValue},step=1), x -> x > ${Int.MaxValue - 2})") -// val started = System.currentTimeMillis() -// for (i <- 0 to numberOfRuns) { -// fastExecute(s"Collection.Filter(Int.Range(0,${Int.MaxValue},step=1), x -> x > ${Int.MaxValue - 2})") -// } -// val elapsed = System.currentTimeMillis() -// -// logger.info("++++++++++ Average execution time time: " + ((elapsed - started) / numberOfRuns)) -// } - + // val mean = (elapsed - started) / numberOfRuns + // + // var standardDeviation = 0.0 + // for (num <- values) { + // standardDeviation += Math.pow(num - mean, 2) + // } + // + // logger.info("++++++++++ Average execution time: " + mean) + // logger.info("++++++++++ Standard deviation is: " + Math.sqrt(standardDeviation / numberOfRuns)) + } } diff --git a/snapi-client/src/test/scala/raw/compiler/rql2/tests/builtin/collection/CollectionRangeTest.scala b/snapi-client/src/test/scala/raw/compiler/rql2/tests/builtin/collection/CollectionRangeTest.scala index fc201ea80..53c2512db 100644 --- a/snapi-client/src/test/scala/raw/compiler/rql2/tests/builtin/collection/CollectionRangeTest.scala +++ b/snapi-client/src/test/scala/raw/compiler/rql2/tests/builtin/collection/CollectionRangeTest.scala @@ -21,6 +21,10 @@ trait CollectionRangeTest extends CompilerTestContext { test("""Long.Range(0, 10)""")(_ should evaluateTo("[0L,1L,2L,3L,4L,5L,6L,7L,8L,9L]")) test("""Long.Range(0, 1)""")(_ should evaluateTo("[0L]")) + test("""Collection.Filter(Long.Range(0, 1000000), x -> x == 999999)""")( + _ should evaluateTo("Collection.Build(999999L)") + ) + // end = start test("""Long.Range(0, 0)""")(_ should evaluateTo("[]")) test("""Long.Range(12, 12)""")(_ should evaluateTo("[]")) diff --git a/snapi-truffle/src/main/java/module-info.java b/snapi-truffle/src/main/java/module-info.java index 73a1890f3..a8feba773 100644 --- a/snapi-truffle/src/main/java/module-info.java +++ b/snapi-truffle/src/main/java/module-info.java @@ -303,8 +303,6 @@ exports raw.runtime.truffle; exports raw.runtime.truffle.boundary; - exports raw.runtime.truffle.runtime.aggregation; - exports raw.runtime.truffle.runtime.aggregation.aggregator; exports raw.runtime.truffle.runtime.record; exports raw.runtime.truffle.runtime.operators; exports raw.runtime.truffle.runtime.function; @@ -357,6 +355,7 @@ exports raw.runtime.truffle.ast.io.binary; exports raw.runtime.truffle.ast.local; exports raw.runtime.truffle.ast.expressions.unary; + exports raw.runtime.truffle.ast.expressions.iterable; exports raw.runtime.truffle.ast.expressions.iterable.collection; exports raw.runtime.truffle.ast.expressions.iterable.list; exports raw.runtime.truffle.ast.expressions.record; @@ -387,7 +386,11 @@ exports raw.runtime.truffle.ast.expressions.builtin.string_package; exports raw.runtime.truffle.ast.expressions.builtin.location_package; exports raw.runtime.truffle.ast.expressions.builtin.binary_package; + exports raw.runtime.truffle.ast.expressions.aggregation; exports raw.runtime.truffle.ast.controlflow; + exports raw.runtime.truffle.ast.osr; + exports raw.runtime.truffle.ast.osr.bodies; + exports raw.runtime.truffle.ast.osr.conditions; exports raw.runtime.truffle.runtime.exceptions.validation; exports raw.compiler.snapi.truffle.compiler; exports raw.compiler.rql2output.truffle.builtin; diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEmitter.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEmitter.java index 2f3f43cc9..bb9ce7a36 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEmitter.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEmitter.java @@ -30,7 +30,9 @@ public abstract class TruffleEmitter { public abstract ClosureNode recurseLambda(TruffleBuildBody truffleBuildBody); - protected abstract RawLanguage getLanguage(); + public abstract FrameDescriptor.Builder getFrameDescriptorBuilder(); + + public abstract RawLanguage getLanguage(); protected abstract StatementNode emitMethod(Rql2Method m); } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEntryExtension.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEntryExtension.java index e46e1337d..a11ddb46b 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEntryExtension.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/TruffleEntryExtension.java @@ -25,16 +25,15 @@ default ExpressionNode toTruffle(Type type, List args, RawLanguage r } default ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { - return toTruffle( - type, - args.stream() - .map( - a -> - new TruffleArg( - emitter.recurseExp(a.e()), - a.t(), - a.idn().isDefined() ? a.idn().get() : null)) - .collect(Collectors.toList()), - emitter.getLanguage()); + return toTruffle(type, rql2argsToTruffleArgs(args, emitter), emitter.getLanguage()); + } + + default List rql2argsToTruffleArgs(List args, TruffleEmitter emitter) { + return args.stream() + .map( + a -> + new TruffleArg( + emitter.recurseExp(a.e()), a.t(), a.idn().isDefined() ? a.idn().get() : null)) + .collect(Collectors.toList()); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleCountCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleCountCollectionEntry.java index f2f4e6608..394a1640b 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleCountCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleCountCollectionEntry.java @@ -12,19 +12,30 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.CountCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionCountNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; public class TruffleCountCollectionEntry extends CountCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionCountNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + truffleArgs.get(0).exprNode(), Aggregations.COUNT, generatorSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleExistsCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleExistsCollectionEntry.java index 1961dc154..5cf9c6658 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleExistsCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleExistsCollectionEntry.java @@ -12,22 +12,38 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.ExistsCollectionEntry; -import raw.compiler.rql2.source.FunType; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionExistsNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionExistsNode; public class TruffleExistsCollectionEntry extends ExistsCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - FunType funType = (FunType) args.get(1).type(); - - return CollectionExistsNodeGen.create(args.get(0).exprNode(), args.get(1).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int functionSlot = + builder.addSlot(FrameSlotKind.Object, "function", "a slot to store the function of osr"); + int predicateResultSlot = + builder.addSlot( + FrameSlotKind.Boolean, + "predicateResult", + "a slot to store the result of applying the function"); + return new CollectionExistsNode( + truffleArgs.get(0).exprNode(), + truffleArgs.get(1).exprNode(), + generatorSlot, + functionSlot, + predicateResultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleFilterCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleFilterCollectionEntry.java index b7df47632..bc29b9c09 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleFilterCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleFilterCollectionEntry.java @@ -19,12 +19,12 @@ import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionFilterNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionFilterNode; public class TruffleFilterCollectionEntry extends FilterCollectionEntry implements TruffleEntryExtension { @Override public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionFilterNodeGen.create(args.get(0).exprNode(), args.get(1).exprNode()); + return new CollectionFilterNode(args.get(0).exprNode(), args.get(1).exprNode()); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleLastCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleLastCollectionEntry.java index 844a2103e..ec7a6130f 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleLastCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleLastCollectionEntry.java @@ -12,19 +12,30 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.LastCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionLastNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; public class TruffleLastCollectionEntry extends LastCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionLastNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + truffleArgs.get(0).exprNode(), Aggregations.LAST, generatorSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMaxCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMaxCollectionEntry.java index 572ae8abc..73e4a9831 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMaxCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMaxCollectionEntry.java @@ -12,18 +12,29 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.MaxCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionMaxNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; public class TruffleMaxCollectionEntry extends MaxCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionMaxNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + truffleArgs.get(0).exprNode(), Aggregations.MAX, generatorSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMinCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMinCollectionEntry.java index 54ddcd64e..89376aab7 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMinCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMinCollectionEntry.java @@ -12,18 +12,29 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.MinCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionMinNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; public class TruffleMinCollectionEntry extends MinCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionMinNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + truffleArgs.get(0).exprNode(), Aggregations.MIN, generatorSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMkStringCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMkStringCollectionEntry.java index c6572542a..b3a851189 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMkStringCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleMkStringCollectionEntry.java @@ -12,41 +12,54 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.MkStringCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionMkStringNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionMkStringNode; import raw.runtime.truffle.ast.expressions.literals.StringNode; public class TruffleMkStringCollectionEntry extends MkStringCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int sepSlot = + builder.addSlot(FrameSlotKind.Object, "separator", "a slot to store the separator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Boolean, "result", "a slot to store the result of osr"); + ExpressionNode start = - args.stream() + truffleArgs.stream() .filter(a -> a.identifier() != null && a.identifier().contains("start")) .map(TruffleArg::exprNode) .findFirst() .orElse(new StringNode("")); ExpressionNode sep = - args.stream() + truffleArgs.stream() .filter(a -> a.identifier() != null && a.identifier().contains("sep")) .map(TruffleArg::exprNode) .findFirst() .orElse(new StringNode("")); ExpressionNode end = - args.stream() + truffleArgs.stream() .filter(a -> a.identifier() != null && a.identifier().contains("end")) .map(TruffleArg::exprNode) .findFirst() .orElse(new StringNode("")); - return CollectionMkStringNodeGen.create(args.get(0).exprNode(), start, sep, end); + return new CollectionMkStringNode( + truffleArgs.get(0).exprNode(), start, sep, end, generatorSlot, sepSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleSumCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleSumCollectionEntry.java index 7c09c2f38..84c3e3374 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleSumCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleSumCollectionEntry.java @@ -12,18 +12,29 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.SumCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionSumNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; public class TruffleSumCollectionEntry extends SumCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionSumNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + truffleArgs.get(0).exprNode(), Aggregations.SUM, generatorSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleTupleAvgCollectionEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleTupleAvgCollectionEntry.java index 57504d460..5b59fcaa5 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleTupleAvgCollectionEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/collection_extension/TruffleTupleAvgCollectionEntry.java @@ -12,19 +12,28 @@ package raw.compiler.snapi.truffle.builtin.collection_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.TupleAvgCollectionEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionTupleAvgNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionTupleAvgNode; public class TruffleTupleAvgCollectionEntry extends TupleAvgCollectionEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return CollectionTupleAvgNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new CollectionTupleAvgNode(truffleArgs.get(0).exprNode(), generatorSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/json_extension/JsonParser.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/json_extension/JsonParser.java index 2ffb0dc22..da4becb24 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/json_extension/JsonParser.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/json_extension/JsonParser.java @@ -13,6 +13,7 @@ package raw.compiler.snapi.truffle.builtin.json_extension; import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import raw.compiler.rql2.source.*; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawLanguage; @@ -27,7 +28,6 @@ import raw.runtime.truffle.ast.io.json.reader.parser.FloatParseJsonNodeGen; import raw.runtime.truffle.ast.io.json.reader.parser.IntParseJsonNodeGen; import raw.runtime.truffle.ast.io.json.reader.parser.IntervalParseJsonNodeGen; -import raw.runtime.truffle.ast.io.json.reader.parser.ListParseJsonNodeGen; import raw.runtime.truffle.ast.io.json.reader.parser.LongParseJsonNodeGen; import raw.runtime.truffle.ast.io.json.reader.parser.ShortParseJsonNodeGen; import raw.runtime.truffle.ast.io.json.reader.parser.StringParseJsonNodeGen; @@ -57,7 +57,21 @@ public ProgramExpressionNode recurse(Rql2TypeWithProperties tipe, RawLanguage la } private ProgramExpressionNode recurse(Rql2TypeWithProperties tipe, boolean appendNullCheck, RawLanguage lang) { - return program(switch (tipe){ + FrameDescriptor.Builder builder = FrameDescriptor.newBuilder(); + int parserSlot = + builder.addSlot( + FrameSlotKind.Object, "parser", "a slot to store the parser of osr"); + int llistSlot = + builder.addSlot( + FrameSlotKind.Object, "list", "a slot to store the ArrayList of osr"); + int currentIdxSlot = + builder.addSlot(FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list for osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "list", "a slot to store the result internal array for osr"); + ExpressionNode e = switch (tipe){ case Rql2TypeWithProperties nt when nt.props().contains(tryable) -> { Rql2TypeWithProperties nextType = (Rql2TypeWithProperties) nt.cloneAndRemoveProp(tryable); ProgramExpressionNode child = recurse(nextType, !(nt instanceof Rql2UndefinedType), lang); @@ -70,15 +84,25 @@ private ProgramExpressionNode recurse(Rql2TypeWithProperties tipe, boolean appen } case Rql2TypeWithProperties v when v.props().isEmpty() -> { ExpressionNode result = switch (v){ - case Rql2ListType r ->{ + case Rql2ListType r -> { ProgramExpressionNode child = recurse((Rql2TypeWithProperties)r.innerType(), lang); - yield ListParseJsonNodeGen.create( - (Rql2TypeWithProperties)r.innerType(), child.getCallTarget() - ); + yield new ListParseJsonNode( + (Rql2TypeWithProperties)r.innerType(), + child.getCallTarget(), + parserSlot, + llistSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } case Rql2IterableType r ->{ ProgramExpressionNode child = recurse((Rql2TypeWithProperties)r.innerType(), lang); - yield new IterableParseJsonNode(program(ListParseJsonNodeGen.create((Rql2TypeWithProperties)r.innerType(), child.getCallTarget()),lang)); + yield new IterableParseJsonNode( + program(new ListParseJsonNode( + (Rql2TypeWithProperties)r.innerType(), + child.getCallTarget(), + parserSlot, llistSlot, currentIdxSlot, listSizeSlot, resultSlot), + builder.build(), lang)); } case Rql2RecordType r ->{ LinkedHashMap hashMap = new LinkedHashMap<>(); @@ -118,15 +142,17 @@ yield new RecordParseJsonNode( case Rql2UndefinedType ignored -> new UndefinedParseJsonNode(); default -> throw new RawTruffleInternalErrorException(); }; - if (appendNullCheck) yield new CheckNonNullJsonNode(program(result,lang)); + if (appendNullCheck) { + yield new CheckNonNullJsonNode(program(result, builder.build(), lang)); + } else yield result; } default -> throw new RawTruffleInternalErrorException(); - }, lang); + }; + return program(e, builder.build(), lang); } - private ProgramExpressionNode program(ExpressionNode e, RawLanguage lang){ - FrameDescriptor frameDescriptor = new FrameDescriptor(); + private ProgramExpressionNode program(ExpressionNode e, FrameDescriptor frameDescriptor, RawLanguage lang){ return new ProgramExpressionNode(lang, frameDescriptor, e); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleExistsListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleExistsListEntry.java index ab38ea412..ad8edf460 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleExistsListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleExistsListEntry.java @@ -12,18 +12,37 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.ExistsListEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListExistsNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListExistsNode; public class TruffleExistsListEntry extends ExistsListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return ListExistsNodeGen.create(args.get(0).exprNode(), args.get(1).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int functionSlot = + builder.addSlot(FrameSlotKind.Object, "function", "a slot to store the function of osr"); + int predicateResultSlot = + builder.addSlot( + FrameSlotKind.Boolean, + "predicateResult", + "a slot to store the result of applying the function"); + return new ListExistsNode( + truffleArgs.get(0).exprNode(), + truffleArgs.get(1).exprNode(), + generatorSlot, + functionSlot, + predicateResultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFilterListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFilterListEntry.java index 3fab5d791..93be6ea02 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFilterListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFilterListEntry.java @@ -12,18 +12,50 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.FilterListEntry; +import raw.compiler.rql2.source.Rql2ListType; +import raw.compiler.rql2.source.Rql2Type; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFilterNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFilterNode; public class TruffleFilterListEntry extends FilterListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return ListFilterNodeGen.create(args.get(0).exprNode(), args.get(1).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + Rql2ListType listType = (Rql2ListType) type; + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int functionSlot = + builder.addSlot(FrameSlotKind.Object, "function", "a slot to store the function of osr"); + int listSlot = + builder.addSlot(FrameSlotKind.Object, "filterList", "a slot to store the ArrayList of osr"); + int currentIdxSlot = + builder.addSlot( + FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list for osr"); + int resultSlot = + builder.addSlot( + FrameSlotKind.Object, "result", "a slot to store the result internal array for osr"); + return new ListFilterNode( + truffleArgs.get(0).exprNode(), + truffleArgs.get(1).exprNode(), + (Rql2Type) listType.innerType(), + generatorSlot, + functionSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFromListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFromListEntry.java index 2171cc6b9..7a66853b2 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFromListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleFromListEntry.java @@ -12,21 +12,45 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.FromListEntry; import raw.compiler.rql2.source.Rql2ListType; import raw.compiler.rql2.source.Rql2Type; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFromNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFromNode; public class TruffleFromListEntry extends FromListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { Rql2ListType rql2ListType = (Rql2ListType) type; - return ListFromNodeGen.create(args.get(0).exprNode(), (Rql2Type) rql2ListType.innerType()); + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int listSlot = + builder.addSlot(FrameSlotKind.Object, "filterList", "a slot to store the ArrayList of osr"); + int currentIdxSlot = + builder.addSlot( + FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "list", "a slot to store the result array of osr"); + return new ListFromNode( + truffleArgs.get(0).exprNode(), + (Rql2Type) rql2ListType.innerType(), + generatorSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleGroupListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleGroupListEntry.java index 77835eb03..e602e96c0 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleGroupListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleGroupListEntry.java @@ -12,22 +12,28 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.Arrays; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.GroupListEntry; import raw.compiler.rql2.source.*; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListGroupByNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListGroupByNode; import scala.collection.JavaConverters; import scala.collection.immutable.HashSet; public class TruffleGroupListEntry extends GroupListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + Rql2ListType listType = (Rql2ListType) type; Rql2RecordType record = (Rql2RecordType) listType.innerType(); Rql2AttrType[] atts = @@ -48,10 +54,26 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra .findFirst() .orElse(Rql2AttrType.apply("key", new Rql2UndefinedType(new HashSet<>()))) .tipe(); - return ListGroupByNodeGen.create( - args.get(0).exprNode(), - args.get(1).exprNode(), + + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int keyFuncSlot = + builder.addSlot( + FrameSlotKind.Object, "keyFunction", "a slot to store the key function of osr"); + int mapSlot = + builder.addSlot(FrameSlotKind.Object, "mapSlot", "a slot to store the map of osr"); + int listSlot = + builder.addSlot(FrameSlotKind.Object, "listSize", "a slot to store the list of osr"); + + return new ListGroupByNode( + truffleArgs.get(0).exprNode(), + truffleArgs.get(1).exprNode(), keyType, - (Rql2TypeWithProperties) groupType.innerType()); + (Rql2TypeWithProperties) groupType.innerType(), + generatorSlot, + keyFuncSlot, + mapSlot, + listSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMaxListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMaxListEntry.java index a0207c2bb..59492358c 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMaxListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMaxListEntry.java @@ -12,18 +12,33 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.MaxListEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListMaxNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionFromNodeGen; public class TruffleMaxListEntry extends MaxListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return ListMaxNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + CollectionFromNodeGen.create(truffleArgs.get(0).exprNode()), + Aggregations.MAX, + generatorSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMinListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMinListEntry.java index c293dd22d..856b5bea7 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMinListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleMinListEntry.java @@ -12,18 +12,33 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.MinListEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListMinNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionFromNodeGen; public class TruffleMinListEntry extends MinListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return ListMinNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + CollectionFromNodeGen.create(truffleArgs.get(0).exprNode()), + Aggregations.MIN, + generatorSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleSumListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleSumListEntry.java index 37ff7e9e7..a6363b0ca 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleSumListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleSumListEntry.java @@ -12,18 +12,33 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.SumListEntry; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListSumNodeGen; +import raw.runtime.truffle.ast.expressions.aggregation.AggregateSingleNode; +import raw.runtime.truffle.ast.expressions.aggregation.Aggregations; +import raw.runtime.truffle.ast.expressions.iterable.collection.CollectionFromNodeGen; public class TruffleSumListEntry extends SumListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - return ListSumNodeGen.create(args.get(0).exprNode()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "result", "a slot to store the result of osr"); + return new AggregateSingleNode( + CollectionFromNodeGen.create(truffleArgs.get(0).exprNode()), + Aggregations.SUM, + generatorSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleTransformListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleTransformListEntry.java index c5f41bd8c..d25eac83a 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleTransformListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleTransformListEntry.java @@ -12,22 +12,47 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.TransformListEntry; import raw.compiler.rql2.source.FunType; import raw.compiler.rql2.source.Rql2Type; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListTransformNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListTransformNode; public class TruffleTransformListEntry extends TransformListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - FunType funType = (FunType) args.get(1).type(); - return ListTransformNodeGen.create( - args.get(0).exprNode(), args.get(1).exprNode(), (Rql2Type) funType.r()); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FunType funType = (FunType) truffleArgs.get(1).type(); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int listSlot = builder.addSlot(FrameSlotKind.Object, "list", "a slot to store the list of osr"); + int functionSlot = + builder.addSlot(FrameSlotKind.Object, "function", "a slot to store the function of osr"); + int currentIdxSlot = + builder.addSlot( + FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list of osr"); + int resultSlot = + builder.addSlot( + FrameSlotKind.Object, "list", "a slot to store the result list internal array of osr"); + + return new ListTransformNode( + truffleArgs.get(0).exprNode(), + truffleArgs.get(1).exprNode(), + (Rql2Type) funType.r(), + listSlot, + functionSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleUnsafeFromListEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleUnsafeFromListEntry.java index 434fa5fc6..912b329a3 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleUnsafeFromListEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/list_extension/TruffleUnsafeFromListEntry.java @@ -12,23 +12,46 @@ package raw.compiler.snapi.truffle.builtin.list_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.UnsafeFromListEntry; import raw.compiler.rql2.source.Rql2ListType; import raw.compiler.rql2.source.Rql2Type; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFromUnsafeNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFromUnsafe; public class TruffleUnsafeFromListEntry extends UnsafeFromListEntry implements TruffleEntryExtension { @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); Rql2ListType rql2ListType = (Rql2ListType) type; - return ListFromUnsafeNodeGen.create( - args.get(0).exprNode(), (Rql2Type) rql2ListType.innerType()); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + int generatorSlot = + builder.addSlot(FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int listSlot = + builder.addSlot(FrameSlotKind.Object, "filterList", "a slot to store the ArrayList of osr"); + int currentIdxSlot = + builder.addSlot( + FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list of osr"); + int resultSlot = + builder.addSlot(FrameSlotKind.Object, "list", "a slot to store the result array of osr"); + return new ListFromUnsafe( + truffleArgs.get(0).exprNode(), + (Rql2Type) rql2ListType.innerType(), + generatorSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleParseXmlEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleParseXmlEntry.java index a1d881776..1c73a82d7 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleParseXmlEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleParseXmlEntry.java @@ -12,25 +12,27 @@ package raw.compiler.snapi.truffle.builtin.xml_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; +import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.ParseXmlEntry; import raw.compiler.rql2.source.Rql2IterableType; import raw.compiler.rql2.source.Rql2ListType; import raw.compiler.rql2.source.Rql2Type; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFromNodeGen; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFromUnsafeNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFromNode; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFromUnsafe; import raw.runtime.truffle.ast.expressions.literals.StringNode; import raw.runtime.truffle.ast.io.json.reader.TryableTopLevelWrapper; import raw.runtime.truffle.ast.io.xml.parser.XmlParseCollectionNode; import raw.runtime.truffle.ast.io.xml.parser.XmlParseValueNode; -import java.util.List; - public class TruffleParseXmlEntry extends ParseXmlEntry implements TruffleEntryExtension { private static ExpressionNode getArg( @@ -48,10 +50,14 @@ private static ExpressionNode getArg( private static final ExpressionNode defaultDateFormat = new StringNode("yyyy-M-d"); private static final ExpressionNode defaultTimeFormat = new StringNode("HH:mm[:ss[.SSS]]"); - @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - List unnamedArgs = args.stream().filter(arg -> arg.identifier() == null).toList(); - List namedArgs = args.stream().filter(arg -> arg.identifier() != null).toList(); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + + List unnamedArgs = + truffleArgs.stream().filter(arg -> arg.identifier() == null).toList(); + List namedArgs = + truffleArgs.stream().filter(arg -> arg.identifier() != null).toList(); ExpressionNode encoding = getArg(namedArgs, "encoding", defaultEncoding); ExpressionNode timeFormatExp = getArg(namedArgs, "timeFormat", defaultTimeFormat); ExpressionNode dateFormatExp = getArg(namedArgs, "dateFormat", defaultDateFormat); @@ -67,7 +73,7 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra timeFormatExp, timestampFormatExp, XmlRecurse.recurseXmlParser( - (Rql2TypeWithProperties) iterableType.innerType(), rawLanguage)); + (Rql2TypeWithProperties) iterableType.innerType(), emitter.getLanguage())); if (XmlRecurse.isTryable(iterableType)) { // Probably will need to be either reused in json and xml or create a copy yield new TryableTopLevelWrapper(parseNode); @@ -83,12 +89,43 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra timeFormatExp, timestampFormatExp, XmlRecurse.recurseXmlParser( - (Rql2TypeWithProperties) listType.innerType(), rawLanguage)); + (Rql2TypeWithProperties) listType.innerType(), emitter.getLanguage())); + + int generatorSlot = + builder.addSlot( + FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int listSlot = + builder.addSlot( + FrameSlotKind.Object, "filterList", "a slot to store the ArrayList of osr"); + int currentIdxSlot = + builder.addSlot( + FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list of osr"); + int resultSlot = + builder.addSlot( + FrameSlotKind.Object, "list", "a slot to store the result array of osr"); + if (XmlRecurse.isTryable(listType)) { // Probably will need to be either reused in json and xml or create a copy - yield ListFromNodeGen.create(parseNode, (Rql2Type) listType.innerType()); + yield new ListFromNode( + parseNode, + (Rql2Type) listType.innerType(), + generatorSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } else { - yield ListFromUnsafeNodeGen.create(parseNode, (Rql2Type) listType.innerType()); + yield new ListFromUnsafe( + parseNode, + (Rql2Type) listType.innerType(), + generatorSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } } case Rql2TypeWithProperties t -> { @@ -98,7 +135,7 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra dateFormatExp, timeFormatExp, timestampFormatExp, - XmlRecurse.recurseXmlParser(t, rawLanguage).getCallTarget()); + XmlRecurse.recurseXmlParser(t, emitter.getLanguage()).getCallTarget()); if (XmlRecurse.isTryable(t)) { yield new TryableTopLevelWrapper(parseNode); } else { diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleReadXmlEntry.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleReadXmlEntry.java index 4d5db6490..9352106f0 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleReadXmlEntry.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/builtin/xml_extension/TruffleReadXmlEntry.java @@ -12,25 +12,27 @@ package raw.compiler.snapi.truffle.builtin.xml_extension; +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.FrameSlotKind; +import java.util.List; import raw.compiler.base.source.Type; +import raw.compiler.rql2.api.Rql2Arg; import raw.compiler.rql2.builtin.ReadXmlEntry; import raw.compiler.rql2.source.Rql2IterableType; import raw.compiler.rql2.source.Rql2ListType; import raw.compiler.rql2.source.Rql2Type; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.compiler.snapi.truffle.TruffleArg; +import raw.compiler.snapi.truffle.TruffleEmitter; import raw.compiler.snapi.truffle.TruffleEntryExtension; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFromNodeGen; -import raw.runtime.truffle.ast.expressions.iterable.list.ListFromUnsafeNodeGen; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFromNode; +import raw.runtime.truffle.ast.expressions.iterable.list.ListFromUnsafe; import raw.runtime.truffle.ast.expressions.literals.StringNode; import raw.runtime.truffle.ast.io.json.reader.TryableTopLevelWrapper; import raw.runtime.truffle.ast.io.xml.parser.XmlReadCollectionNode; import raw.runtime.truffle.ast.io.xml.parser.XmlReadValueNode; -import java.util.List; - public class TruffleReadXmlEntry extends ReadXmlEntry implements TruffleEntryExtension { private static ExpressionNode getArg( @@ -49,9 +51,14 @@ private static ExpressionNode getArg( private static final ExpressionNode defaultTimeFormat = new StringNode("HH:mm[:ss[.SSS]]"); @Override - public ExpressionNode toTruffle(Type type, List args, RawLanguage rawLanguage) { - List unnamedArgs = args.stream().filter(arg -> arg.identifier() == null).toList(); - List namedArgs = args.stream().filter(arg -> arg.identifier() != null).toList(); + public ExpressionNode toTruffle(Type type, List args, TruffleEmitter emitter) { + List truffleArgs = rql2argsToTruffleArgs(args, emitter); + FrameDescriptor.Builder builder = emitter.getFrameDescriptorBuilder(); + + List unnamedArgs = + truffleArgs.stream().filter(arg -> arg.identifier() == null).toList(); + List namedArgs = + truffleArgs.stream().filter(arg -> arg.identifier() != null).toList(); ExpressionNode encoding = getArg(namedArgs, "encoding", defaultEncoding); ExpressionNode timeFormatExp = getArg(namedArgs, "timeFormat", defaultTimeFormat); ExpressionNode dateFormatExp = getArg(namedArgs, "dateFormat", defaultDateFormat); @@ -68,7 +75,7 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra timeFormatExp, timestampFormatExp, XmlRecurse.recurseXmlParser( - (Rql2TypeWithProperties) iterableType.innerType(), rawLanguage)); + (Rql2TypeWithProperties) iterableType.innerType(), emitter.getLanguage())); if (XmlRecurse.isTryable(iterableType)) { // Probably will need to be either reused in json and xml or create a copy yield new TryableTopLevelWrapper(parseNode); @@ -85,12 +92,43 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra timeFormatExp, timestampFormatExp, XmlRecurse.recurseXmlParser( - (Rql2TypeWithProperties) listType.innerType(), rawLanguage)); + (Rql2TypeWithProperties) listType.innerType(), emitter.getLanguage())); + + int generatorSlot = + builder.addSlot( + FrameSlotKind.Object, "generator", "a slot to store the generator of osr"); + int listSlot = + builder.addSlot( + FrameSlotKind.Object, "filterList", "a slot to store the ArrayList of osr"); + int currentIdxSlot = + builder.addSlot( + FrameSlotKind.Int, "currentIdxSlot", "a slot to store the current index of osr"); + int listSizeSlot = + builder.addSlot( + FrameSlotKind.Int, "listSize", "a slot to store the size of the list of osr"); + int resultSlot = + builder.addSlot( + FrameSlotKind.Object, "list", "a slot to store the result array of osr"); + if (XmlRecurse.isTryable(listType)) { // Probably will need to be either reused in json and xml or create a copy - yield ListFromNodeGen.create(parseNode, (Rql2Type) listType.innerType()); + yield new ListFromNode( + parseNode, + (Rql2Type) listType.innerType(), + generatorSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } else { - yield ListFromUnsafeNodeGen.create(parseNode, (Rql2Type) listType.innerType()); + yield new ListFromUnsafe( + parseNode, + (Rql2Type) listType.innerType(), + generatorSlot, + listSlot, + currentIdxSlot, + listSizeSlot, + resultSlot); } } case Rql2TypeWithProperties t -> { @@ -101,7 +139,7 @@ public ExpressionNode toTruffle(Type type, List args, RawLanguage ra dateFormatExp, timeFormatExp, timestampFormatExp, - XmlRecurse.recurseXmlParser(t, rawLanguage).getCallTarget()); + XmlRecurse.recurseXmlParser(t, emitter.getLanguage()).getCallTarget()); if (XmlRecurse.isTryable(t)) { yield new TryableTopLevelWrapper(parseNode); } else { diff --git a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/compiler/SnapiTruffleEmitter.java b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/compiler/SnapiTruffleEmitter.java index b0efc8396..10bc4c4e2 100644 --- a/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/compiler/SnapiTruffleEmitter.java +++ b/snapi-truffle/src/main/java/raw/compiler/snapi/truffle/compiler/SnapiTruffleEmitter.java @@ -81,7 +81,7 @@ private Type tipe(Exp e) { return analyzer.tipe(e); } - protected RawLanguage getLanguage() { + public RawLanguage getLanguage() { return this.rawLanguage; } @@ -112,7 +112,7 @@ protected FrameDescriptor dropScope() { return frameDescriptorBuilder.build(); } - private FrameDescriptor.Builder getFrameDescriptorBuilder() { + public FrameDescriptor.Builder getFrameDescriptorBuilder() { return frameDescriptorBuilderScope.get(0); } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregateMultipleNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregateMultipleNode.java new file mode 100644 index 000000000..bf5bfa53d --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregateMultipleNode.java @@ -0,0 +1,93 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.expressions.aggregation; + +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRMultiAggregationBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; +import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; +import raw.runtime.truffle.runtime.primitives.ErrorObject; + +public class AggregateMultipleNode extends ExpressionNode { + + @Child ExpressionNode iterableNode; + + @Child private LoopNode loop; + + @Child + GeneratorNodes.GeneratorInitNode initNode = GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + GeneratorNodes.GeneratorCloseNode closeNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + @Child + IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child AggregatorNodes.Zero zeroNode = AggregatorNodesFactory.ZeroNodeGen.create(); + + private final byte[] aggregationTypes; + + private final int generatorSlot; + private final int resultSlot; + + public AggregateMultipleNode( + ExpressionNode iterableNode, byte[] aggregationTypes, int generatorSlot, int resultSlot) { + this.iterableNode = iterableNode; + loop = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(generatorSlot), + new OSRMultiAggregationBodyNode(aggregationTypes, generatorSlot, resultSlot))); + this.aggregationTypes = aggregationTypes; + this.generatorSlot = generatorSlot; + this.resultSlot = resultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame virtualFrame) { + Object generator = getGeneratorNode.execute(this, iterableNode.executeGeneric(virtualFrame)); + try { + initNode.execute(this, generator); + Object[] results = new Object[aggregationTypes.length]; + for (int i = 0; i < aggregationTypes.length; i++) { + results[i] = zeroNode.execute(this, aggregationTypes[i]); + } + if (!hasNextNode.execute(this, generator)) { + return results; + } + virtualFrame.setObject(generatorSlot, generator); + virtualFrame.setObject(resultSlot, results); + loop.execute(virtualFrame); + return virtualFrame.getObject(resultSlot); + } catch (RawTruffleRuntimeException e) { + return new ErrorObject(e.getMessage()); + } finally { + closeNode.execute(this, generator); + } + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregateSingleNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregateSingleNode.java new file mode 100644 index 000000000..523385764 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregateSingleNode.java @@ -0,0 +1,91 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.expressions.aggregation; + +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRSingleAggregationBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; +import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; +import raw.runtime.truffle.runtime.primitives.ErrorObject; + +public class AggregateSingleNode extends ExpressionNode { + + @Child ExpressionNode iterableNode; + + @Child private LoopNode loop; + + @Child + GeneratorNodes.GeneratorInitNode initNode = GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + GeneratorNodes.GeneratorCloseNode closeNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + @Child + IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child AggregatorNodes.Zero zeroNode = AggregatorNodesFactory.ZeroNodeGen.create(); + + private final byte aggregationType; + + private final int generatorSlot; + private final int resultSlot; + + public AggregateSingleNode( + ExpressionNode iterableNode, byte aggregationType, int generatorSlot, int resultSlot) { + this.iterableNode = iterableNode; + loop = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(generatorSlot), + new OSRSingleAggregationBodyNode(aggregationType, generatorSlot, resultSlot))); + this.aggregationType = aggregationType; + this.generatorSlot = generatorSlot; + this.resultSlot = resultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame virtualFrame) { + Object generator = getGeneratorNode.execute(this, iterableNode.executeGeneric(virtualFrame)); + try { + initNode.execute(this, generator); + if (!hasNextNode.execute(this, generator)) { + return zeroNode.execute(this, aggregationType); + } + Object result = zeroNode.execute(this, aggregationType); + + virtualFrame.setObject(generatorSlot, generator); + virtualFrame.setObject(resultSlot, result); + loop.execute(virtualFrame); + return virtualFrame.getObject(resultSlot); + } catch (RawTruffleRuntimeException e) { + return new ErrorObject(e.getMessage()); + } finally { + closeNode.execute(this, generator); + } + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/aggregator/Aggregators.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/Aggregations.java similarity index 81% rename from snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/aggregator/Aggregators.java rename to snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/Aggregations.java index 5cc577731..816988a45 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/aggregator/Aggregators.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/Aggregations.java @@ -10,11 +10,12 @@ * licenses/APL.txt. */ -package raw.runtime.truffle.runtime.aggregation.aggregator; +package raw.runtime.truffle.ast.expressions.aggregation; -public class Aggregators { +public class Aggregations { public static final byte COUNT = 0; public static final byte MAX = 1; public static final byte MIN = 2; public static final byte SUM = 3; + public static final byte LAST = 4; } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/aggregator/AggregatorNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregatorNodes.java similarity index 89% rename from snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/aggregator/AggregatorNodes.java rename to snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregatorNodes.java index 43c0b3dd9..198678c33 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/aggregator/AggregatorNodes.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/aggregation/AggregatorNodes.java @@ -10,7 +10,7 @@ * licenses/APL.txt. */ -package raw.runtime.truffle.runtime.aggregation.aggregator; +package raw.runtime.truffle.ast.expressions.aggregation; import com.oracle.truffle.api.dsl.*; import com.oracle.truffle.api.nodes.Node; @@ -23,7 +23,7 @@ public class AggregatorNodes { @NodeInfo(shortName = "Aggregator.Zero") @GenerateUncached @GenerateInline - @ImportStatic(Aggregators.class) + @ImportStatic(Aggregations.class) public abstract static class Zero extends Node { public abstract Object execute(Node node, byte aggregatorType); @@ -47,12 +47,17 @@ static Object minZero(Node node, byte aggregatorType) { static Object sumZero(Node node, byte aggregatorType) { return NullObject.INSTANCE; } + + @Specialization(guards = "aggregatorType == LAST") + static Object sumLast(Node node, byte aggregatorType) { + return NullObject.INSTANCE; + } } @NodeInfo(shortName = "Aggregator.Merge") @GenerateUncached @GenerateInline - @ImportStatic(Aggregators.class) + @ImportStatic(Aggregations.class) public abstract static class Merge extends Node { public abstract Object execute(Node node, byte aggregatorType, Object current, Object next); @@ -124,5 +129,10 @@ static Object mergeSum( @Cached OperatorNodes.AddNode add) { return add.execute(thisNode, current, next); } + + @Specialization(guards = "aggregatorType == LAST") + static Object mergeLast(Node node, byte aggregatorType, Object current, Object next) { + return next; + } } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/ArrayOperationNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/ArrayOperationNodes.java new file mode 100644 index 000000000..5cd10b0f8 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/ArrayOperationNodes.java @@ -0,0 +1,201 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.expressions.iterable; + +import com.oracle.truffle.api.dsl.GenerateInline; +import com.oracle.truffle.api.dsl.GenerateUncached; +import com.oracle.truffle.api.dsl.ImportStatic; +import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.NodeInfo; +import java.util.ArrayList; +import raw.compiler.rql2.source.Rql2Type; +import raw.runtime.truffle.ast.TypeGuards; +import raw.runtime.truffle.runtime.exceptions.RawTruffleInternalErrorException; +import raw.runtime.truffle.runtime.list.*; + +public class ArrayOperationNodes { + + @NodeInfo(shortName = "ArrayOperation.Build") + @GenerateUncached + @GenerateInline + @ImportStatic(TypeGuards.class) + public abstract static class ArrayBuildNode extends Node { + + public abstract Object execute(Node node, Rql2Type resultType, int size); + + @Specialization(guards = "isByteKind(resultType)") + static byte[] buildByte(Node node, Rql2Type resultType, int size) { + return new byte[size]; + } + + @Specialization(guards = "isShortKind(resultType)") + static short[] buildShort(Node node, Rql2Type resultType, int size) { + return new short[size]; + } + + @Specialization(guards = "isIntKind(resultType)") + static int[] buildInt(Node node, Rql2Type resultType, int size) { + return new int[size]; + } + + @Specialization(guards = "isLongKind(resultType)") + static long[] buildLong(Node node, Rql2Type resultType, int size) { + return new long[size]; + } + + @Specialization(guards = "isFloatKind(resultType)") + static float[] buildFloat(Node node, Rql2Type resultType, int size) { + return new float[size]; + } + + @Specialization(guards = "isDoubleKind(resultType)") + static double[] buildDouble(Node node, Rql2Type resultType, int size) { + return new double[size]; + } + + @Specialization(guards = "isBooleanKind(resultType)") + static boolean[] buildBoolean(Node node, Rql2Type resultType, int size) { + return new boolean[size]; + } + + @Specialization(guards = "isStringKind(resultType)") + static String[] buildString(Node node, Rql2Type resultType, int size) { + return new String[size]; + } + + @Specialization + static Object[] buildObject(Node node, Rql2Type resultType, int size) { + return new Object[size]; + } + } + + @NodeInfo(shortName = "ArrayOperation.BuildList") + @GenerateUncached + @GenerateInline + @ImportStatic(TypeGuards.class) + public abstract static class ArrayBuildListNode extends Node { + + public abstract Object execute(Node node, Object array); + + @Specialization + static ByteList buildByte(Node node, byte[] array) { + return new ByteList(array); + } + + @Specialization + static ShortList buildShort(Node node, short[] array) { + return new ShortList(array); + } + + @Specialization + static IntList buildInt(Node node, int[] array) { + return new IntList(array); + } + + @Specialization + static LongList buildLong(Node node, long[] array) { + return new LongList(array); + } + + @Specialization + static FloatList buildFloat(Node node, float[] array) { + return new FloatList(array); + } + + @Specialization + static DoubleList buildDouble(Node node, double[] array) { + return new DoubleList(array); + } + + @Specialization + static BooleanList buildBoolean(Node node, boolean[] array) { + return new BooleanList(array); + } + + @Specialization + static StringList buildString(Node node, String[] array) { + return new StringList(array); + } + + @Specialization + static ObjectList buildObject(Node node, Object[] array) { + return new ObjectList(array); + } + + @Specialization + static RawArrayList buildObject(Node node, Object array) { + try { + @SuppressWarnings("unchecked") + ArrayList arrayList = (ArrayList) array; + return new RawArrayList(arrayList); + } catch (ClassCastException e) { + throw new RawTruffleInternalErrorException(e.getMessage(), e); + } + } + } + + @NodeInfo(shortName = "ArrayOperation.BuildList") + @GenerateUncached + @GenerateInline + @ImportStatic(TypeGuards.class) + public abstract static class ArraySetArrayItemNode extends Node { + + public abstract void execute(Node node, Object array, Object item, int idx); + + @Specialization + static void buildByte(Node node, byte[] array, byte item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildShort(Node node, short[] array, short item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildInt(Node node, int[] array, int item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildLong(Node node, long[] array, long item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildFloat(Node node, float[] array, float item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildDouble(Node node, double[] array, double item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildBoolean(Node node, boolean[] array, boolean item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildString(Node node, String[] array, String item, int idx) { + array[idx] = item; + } + + @Specialization + static void buildObject(Node node, Object[] array, Object item, int idx) { + array[idx] = item; + } + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionCountNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionCountNode.java deleted file mode 100644 index 3ce0f16d5..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionCountNode.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.collection; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; -import raw.runtime.truffle.runtime.primitives.ErrorObject; - -// A.Z. Need to cache count somehow -@NodeInfo(shortName = "Collection.Count") -@NodeChild("parent") -public abstract class CollectionCountNode extends ExpressionNode { - - private final Object aggregation = new SingleAggregation(Aggregators.COUNT); - - @Specialization - protected Object doCount( - Object iterable, @Cached(inline = true) AggregationNodes.Aggregate aggregate) { - try { - return aggregate.execute(this, aggregation, iterable); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionDistinctNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionDistinctNode.java index 5bc67f535..4f9b7b78c 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionDistinctNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionDistinctNode.java @@ -16,11 +16,13 @@ import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawContext; import raw.runtime.truffle.RawLanguage; +import raw.runtime.truffle.ast.osr.AuxiliarySlots; import raw.runtime.truffle.runtime.iterable.operations.DistinctCollection; @NodeInfo(shortName = "Collection.Distinct") @@ -32,8 +34,18 @@ public abstract class CollectionDistinctNode extends ExpressionNode { protected abstract Rql2TypeWithProperties getValueType(); @Specialization - protected Object doDistinct(Object iterable) { + protected Object doDistinct(VirtualFrame frame, Object iterable) { + int generatorSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.GENERATOR_SLOT); + int offHeapDistinctSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.OFF_HEAP_DISTINCT_SLOT); return new DistinctCollection( - iterable, getValueType(), RawLanguage.get(this), RawContext.get(this).getSourceContext()); + iterable, + getValueType(), + RawLanguage.get(this), + RawContext.get(this).getSourceContext(), + frame.materialize(), + generatorSlot, + offHeapDistinctSlot); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionEquiJoinNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionEquiJoinNode.java index 98b0f02e3..49259157a 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionEquiJoinNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionEquiJoinNode.java @@ -18,6 +18,7 @@ import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawContext; import raw.runtime.truffle.RawLanguage; +import raw.runtime.truffle.ast.osr.AuxiliarySlots; import raw.runtime.truffle.runtime.iterable.operations.EquiJoinCollection; @NodeInfo(shortName = "Collection.EquiJoin") @@ -60,6 +61,15 @@ public Object executeGeneric(VirtualFrame frame) { Object rightIterable = right.executeGeneric(frame); Object rightKeyF = rightKeyFun.executeGeneric(frame); Object remapF = remapFun.executeGeneric(frame); + int computeNextSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.COMPUTE_NEXT_SLOT); + int shouldContinueSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.SHOULD_CONTINUE_SLOT); + int generatorSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.GENERATOR_SLOT); + int keyFunctionSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.FUNCTION_SLOT); + int mapSlot = frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.MAP_SLOT); return new EquiJoinCollection( leftIterable, leftKeyF, @@ -70,6 +80,12 @@ public Object executeGeneric(VirtualFrame frame) { keyType, remapF, RawLanguage.get(this), - RawContext.get(this).getSourceContext()); + RawContext.get(this).getSourceContext(), + frame.materialize(), + computeNextSlot, + shouldContinueSlot, + generatorSlot, + keyFunctionSlot, + mapSlot); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionExistsNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionExistsNode.java index 11b564812..2c5be4483 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionExistsNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionExistsNode.java @@ -12,54 +12,84 @@ package raw.runtime.truffle.ast.expressions.iterable.collection; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRExistsBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRExistsConditionNode; import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; -import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.primitives.ErrorObject; -import raw.runtime.truffle.tryable_nullable.TryableNullable; @NodeInfo(shortName = "Collection.Exists") -@NodeChild("iterable") -@NodeChild("function") -public abstract class CollectionExistsNode extends ExpressionNode { +public class CollectionExistsNode extends ExpressionNode { + @Child private ExpressionNode iterableNode; + @Child private ExpressionNode functionNode; + @Child private LoopNode existsLoopNode; - @Specialization - protected static Object doIterable( - Object iterable, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorCloseNode generatorCloseNode, - @Cached(inline = true) FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object generator = getGeneratorNode.execute(thisNode, iterable); + @Child + private GeneratorNodes.GeneratorInitNode generatorInitNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorCloseNode generatorCloseNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + private final int generatorSlot; + private final int functionSlot; + private final int predicateResultSlot; + + public CollectionExistsNode( + ExpressionNode iterableNode, + ExpressionNode functionNode, + int generatorSlot, + int functionSlot, + int predicateResultSlot) { + this.iterableNode = iterableNode; + this.functionNode = functionNode; + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.predicateResultSlot = predicateResultSlot; + + this.existsLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRExistsConditionNode(generatorSlot, predicateResultSlot), + new OSRExistsBodyNode(generatorSlot, functionSlot, predicateResultSlot))); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object function = functionNode.executeGeneric(frame); + Object iterable = iterableNode.executeGeneric(frame); + Object generator = getGeneratorNode.execute(this, iterable); try { - generatorInitNode.execute(thisNode, generator); - while (generatorHasNextNode.execute(thisNode, generator)) { - boolean predicate = - TryableNullable.handlePredicate( - functionExecuteOneNode.execute( - thisNode, function, generatorNextNode.execute(thisNode, generator)), - false); - if (predicate) { - return true; - } - } - return false; + generatorInitNode.execute(this, generator); + frame.setObject(generatorSlot, generator); + frame.setObject(functionSlot, function); + frame.setBoolean(predicateResultSlot, false); + existsLoopNode.execute(frame); + return frame.getBoolean(predicateResultSlot); } catch (RawTruffleRuntimeException ex) { return new ErrorObject(ex.getMessage()); } finally { - generatorCloseNode.execute(thisNode, generator); + generatorCloseNode.execute(this, generator); } } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) { + return (boolean) executeGeneric(virtualFrame); + } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionFilterNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionFilterNode.java index 2d9cb1f97..9971c6060 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionFilterNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionFilterNode.java @@ -12,19 +12,36 @@ package raw.runtime.truffle.ast.expressions.iterable.collection; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.osr.AuxiliarySlots; import raw.runtime.truffle.runtime.iterable.operations.FilterCollection; @NodeInfo(shortName = "Collection.Filter") -@NodeChild("iterable") -@NodeChild("predicate") -public abstract class CollectionFilterNode extends ExpressionNode { +public class CollectionFilterNode extends ExpressionNode { - @Specialization - protected Object doFilter(Object iterable, Object predicate) { - return new FilterCollection(iterable, predicate); + @Child private ExpressionNode iterableNode; + + @Child private ExpressionNode predicateNode; + + public CollectionFilterNode(ExpressionNode iterableNode, ExpressionNode predicateNode) { + this.iterableNode = iterableNode; + this.predicateNode = predicateNode; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object iterable = iterableNode.executeGeneric(frame); + Object predicate = predicateNode.executeGeneric(frame); + + int collectionSLot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.COLLECTION_SLOT); + int functionSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.FUNCTION_SLOT); + int resultSlot = frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.RESULT_SLOT); + + return new FilterCollection( + iterable, predicate, frame.materialize(), collectionSLot, functionSlot, resultSlot); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionGroupByNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionGroupByNode.java index 054b1c091..473a23233 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionGroupByNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionGroupByNode.java @@ -16,11 +16,13 @@ import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawContext; import raw.runtime.truffle.RawLanguage; +import raw.runtime.truffle.ast.osr.AuxiliarySlots; import raw.runtime.truffle.runtime.iterable.operations.GroupByCollection; @NodeInfo(shortName = "Collection.GroupBy") @@ -37,13 +39,22 @@ public abstract class CollectionGroupByNode extends ExpressionNode { protected abstract Rql2TypeWithProperties getRowType(); @Specialization - protected Object doGroup(Object iterable, Object keyFun) { + protected Object doGroup(VirtualFrame frame, Object iterable, Object keyFun) { + int generatorSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.GENERATOR_SLOT); + int keyFunctionSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.FUNCTION_SLOT); + int mapSlot = frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.MAP_SLOT); return new GroupByCollection( iterable, keyFun, getKeyType(), getRowType(), RawLanguage.get(this), - RawContext.get(this).getSourceContext()); + RawContext.get(this).getSourceContext(), + frame.materialize(), + generatorSlot, + keyFunctionSlot, + mapSlot); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionJoinNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionJoinNode.java index c26f51438..43ff4d573 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionJoinNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionJoinNode.java @@ -16,11 +16,13 @@ import com.oracle.truffle.api.dsl.NodeChild; import com.oracle.truffle.api.dsl.NodeField; import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.nodes.NodeInfo; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawContext; import raw.runtime.truffle.RawLanguage; +import raw.runtime.truffle.ast.osr.AuxiliarySlots; import raw.runtime.truffle.runtime.iterable.operations.JoinCollection; @NodeInfo(shortName = "Collection.Join") @@ -40,7 +42,20 @@ public abstract class CollectionJoinNode extends ExpressionNode { @Specialization protected Object doJoin( - Object leftIterable, Object rightIterable, Object remap, Object predicate) { + VirtualFrame frame, + Object leftIterable, + Object rightIterable, + Object remap, + Object predicate) { + int computeNextSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.COMPUTE_NEXT_SLOT); + int shouldContinueSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.SHOULD_CONTINUE_SLOT); + int resultSlot = frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.RESULT_SLOT); + int generatorSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.GENERATOR_SLOT); + int outputBufferSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.OUTPUT_BUFFER_SLOT); return new JoinCollection( leftIterable, rightIterable, @@ -49,6 +64,12 @@ protected Object doJoin( getRightType(), getReshapeBeforePredicate(), RawContext.get(this).getSourceContext(), - RawLanguage.get(this)); + RawLanguage.get(this), + frame.materialize(), + computeNextSlot, + shouldContinueSlot, + resultSlot, + generatorSlot, + outputBufferSlot); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionLastNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionLastNode.java deleted file mode 100644 index 8bbca726c..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionLastNode.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.collection; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; -import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; -import raw.runtime.truffle.runtime.iterable.IterableNodes; -import raw.runtime.truffle.runtime.primitives.ErrorObject; -import raw.runtime.truffle.runtime.primitives.NullObject; - -@NodeInfo(shortName = "Collection.Last") -@NodeChild("parent") -public abstract class CollectionLastNode extends ExpressionNode { - @Specialization - protected Object doObject( - Object iterable, - @Cached(inline = true) IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorNextNode nextNode, - @Cached(inline = true) GeneratorNodes.GeneratorCloseNode closeNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initNode.execute(this, generator); - if (!hasNextNode.execute(this, generator)) { - return NullObject.INSTANCE; - } - Object next = nextNode.execute(this, generator); - while (hasNextNode.execute(this, generator)) { - next = nextNode.execute(this, generator); - } - return next; - } catch (RawTruffleRuntimeException e) { - return new ErrorObject(e.getMessage()); - } finally { - closeNode.execute(this, generator); - } - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMaxNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMaxNode.java deleted file mode 100644 index cb0eb28be..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMaxNode.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.collection; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; -import raw.runtime.truffle.runtime.primitives.ErrorObject; - -@NodeInfo(shortName = "Collection.Max") -@NodeChild("iterable") -public abstract class CollectionMaxNode extends ExpressionNode { - private final SingleAggregation aggregation = new SingleAggregation(Aggregators.MAX); - - @Specialization - protected Object doCollection( - Object iterable, @Cached(inline = true) AggregationNodes.Aggregate aggregate) { - try { - return aggregate.execute(this, aggregation, iterable); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMinNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMinNode.java deleted file mode 100644 index e99e850b9..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMinNode.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.collection; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; -import raw.runtime.truffle.runtime.primitives.ErrorObject; - -@NodeInfo(shortName = "Collection.Min") -@NodeChild("iterable") -public abstract class CollectionMinNode extends ExpressionNode { - - private final SingleAggregation aggregation = new SingleAggregation(Aggregators.MIN); - - @Specialization - protected Object doCollection( - Object iterable, @Cached(inline = true) AggregationNodes.Aggregate aggregate) { - try { - return aggregate.execute(this, aggregation, iterable); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMkStringNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMkStringNode.java index cf68a967b..1a05b0477 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMkStringNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionMkStringNode.java @@ -12,35 +12,87 @@ package raw.runtime.truffle.ast.expressions.iterable.collection; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRCollectionMkStringBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.operators.OperatorNodes; +import raw.runtime.truffle.runtime.operators.OperatorNodesFactory; import raw.runtime.truffle.runtime.primitives.ErrorObject; @NodeInfo(shortName = "Collection.MkString") -@NodeChild("iterable") -@NodeChild("start") -@NodeChild("sep") -@NodeChild("end") -public abstract class CollectionMkStringNode extends ExpressionNode { - @Specialization - protected Object doCollection( - Object iterable, - String start, - String sep, - String end, - @Cached(inline = true) OperatorNodes.AddNode add, - @Cached(inline = true) IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorNextNode nextNode, - @Cached(inline = true) GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) GeneratorNodes.GeneratorCloseNode closeNode) { +public class CollectionMkStringNode extends ExpressionNode { + + @Child private ExpressionNode iterableNode; + @Child private ExpressionNode startNode; + @Child private ExpressionNode sepNode; + @Child private ExpressionNode endNode; + @Child private LoopNode mkStringLoopNode; + + @Child + private GeneratorNodes.GeneratorInitNode initNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorCloseNode closeNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child private OperatorNodes.AddNode add = OperatorNodesFactory.AddNodeGen.create(); + + private final int generatorSlot; + private final int sepSlot; + private final int resultSlot; + + public CollectionMkStringNode( + ExpressionNode iterableNode, + ExpressionNode startNode, + ExpressionNode sepNode, + ExpressionNode endNode, + int generatorSlot, + int sepSlot, + int resultSlot) { + this.iterableNode = iterableNode; + this.startNode = startNode; + this.sepNode = sepNode; + this.endNode = endNode; + this.generatorSlot = generatorSlot; + this.sepSlot = sepSlot; + this.resultSlot = resultSlot; + this.mkStringLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(generatorSlot), + new OSRCollectionMkStringBodyNode(generatorSlot, sepSlot, resultSlot))); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object iterable = iterableNode.executeGeneric(frame); + String start = (String) startNode.executeGeneric(frame); + String sep = (String) sepNode.executeGeneric(frame); + String end = (String) endNode.executeGeneric(frame); Object generator = getGeneratorNode.execute(this, iterable); try { initNode.execute(this, generator); @@ -51,10 +103,13 @@ protected Object doCollection( Object next = nextNode.execute(this, generator); currentString = (String) add.execute(this, currentString, next); } - while (hasNextNode.execute(this, generator)) { - Object next = nextNode.execute(this, generator); - currentString = (String) add.execute(this, currentString + sep, next); - } + + frame.setObject(generatorSlot, generator); + frame.setObject(sepSlot, sep); + frame.setObject(resultSlot, currentString); + mkStringLoopNode.execute(frame); + currentString = (String) frame.getObject(resultSlot); + return currentString + end; } catch (RawTruffleRuntimeException ex) { return new ErrorObject(ex.getMessage()); diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionOrderByNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionOrderByNode.java index 1bd0088ec..6e959d869 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionOrderByNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionOrderByNode.java @@ -20,6 +20,7 @@ import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawContext; import raw.runtime.truffle.RawLanguage; +import raw.runtime.truffle.ast.osr.AuxiliarySlots; import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; import raw.runtime.truffle.runtime.iterable.operations.OrderByCollection; @@ -63,6 +64,16 @@ public Object executeGeneric(VirtualFrame frame) { for (int i = 0; i < this.keyFuns.length; i++) { keyFunctions[i] = this.keyFuns[i].executeGeneric(frame); } + + int generatorSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.GENERATOR_SLOT); + int collectionSlot = + frame.getFrameDescriptor().findOrAddAuxiliarySlot(AuxiliarySlots.COLLECTION_SLOT); + int offHeapGroupByKeysSlot = + frame + .getFrameDescriptor() + .findOrAddAuxiliarySlot(AuxiliarySlots.OFF_HEAP_GROUP_BY_KEYS_SLOT); + return new OrderByCollection( iterable, keyFunctions, @@ -70,6 +81,10 @@ public Object executeGeneric(VirtualFrame frame) { keyTypes, valueType, RawLanguage.get(this), - RawContext.get(this).getSourceContext()); + RawContext.get(this).getSourceContext(), + frame.materialize(), + generatorSlot, + collectionSlot, + offHeapGroupByKeysSlot); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionSumNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionSumNode.java deleted file mode 100644 index 91bf0e7ee..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionSumNode.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.collection; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; -import raw.runtime.truffle.runtime.primitives.ErrorObject; - -@NodeInfo(shortName = "Collection.Sum") -@NodeChild("iterable") -public abstract class CollectionSumNode extends ExpressionNode { - - private final SingleAggregation aggregation = new SingleAggregation(Aggregators.SUM); - - @Specialization - protected Object doCollection( - Object iterable, @Cached(inline = true) AggregationNodes.Aggregate aggregate) { - try { - return aggregate.execute(this, aggregation, iterable); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionTupleAvgNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionTupleAvgNode.java index b9c7e1d02..ad02e8438 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionTupleAvgNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/collection/CollectionTupleAvgNode.java @@ -12,45 +12,42 @@ package raw.runtime.truffle.ast.expressions.iterable.collection; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; +import com.oracle.truffle.api.frame.VirtualFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.UnknownIdentifierException; import com.oracle.truffle.api.interop.UnsupportedMessageException; import com.oracle.truffle.api.interop.UnsupportedTypeException; -import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.NodeInfo; import java.math.BigDecimal; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.MultiAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.AggregatorNodes; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; +import raw.runtime.truffle.ast.expressions.aggregation.*; import raw.runtime.truffle.runtime.exceptions.RawTruffleInternalErrorException; import raw.runtime.truffle.runtime.primitives.DecimalObject; import raw.runtime.truffle.runtime.record.RecordObject; @NodeInfo(shortName = "Collection.TupleAvg") -@NodeChild("iterable") -public abstract class CollectionTupleAvgNode extends ExpressionNode { +public class CollectionTupleAvgNode extends ExpressionNode { + @Child InteropLibrary records = InteropLibrary.getFactory().createDispatched(2); + @Child AggregateMultipleNode aggregate; + @Child AggregatorNodes.Zero zeroNode = AggregatorNodesFactory.ZeroNodeGen.create(); - private final Object aggregation = - new MultiAggregation(new byte[] {Aggregators.SUM, Aggregators.COUNT}); + public CollectionTupleAvgNode(ExpressionNode iterableNode, int generatorSlot, int resultSlot) { + aggregate = + new AggregateMultipleNode( + iterableNode, + new byte[] {Aggregations.SUM, Aggregations.COUNT}, + generatorSlot, + resultSlot); + } - @Specialization - protected Object doCollection( - Object iterable, - @Cached(inline = true) AggregationNodes.Aggregate aggregate, - @Cached(inline = true) AggregatorNodes.Zero zero, - @CachedLibrary(limit = "1") InteropLibrary records) { + @Override + public Object executeGeneric(VirtualFrame virtualFrame) { try { - - Object[] results = (Object[]) aggregate.execute(this, aggregation, iterable); + Object[] results = (Object[]) aggregate.executeGeneric(virtualFrame); RecordObject record = RawLanguage.get(this).createRecord(); - if ((long) results[1] == (long) zero.execute(this, Aggregators.COUNT)) { - records.writeMember(record, "sum", zero.execute(this, Aggregators.SUM)); + if ((long) results[1] == (long) zeroNode.execute(this, Aggregations.COUNT)) { + records.writeMember(record, "sum", zeroNode.execute(this, Aggregations.SUM)); } else { records.writeMember( record, "sum", new DecimalObject(new BigDecimal(results[0].toString()))); diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListExistsNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListExistsNode.java index 73dd89be9..e16a3c277 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListExistsNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListExistsNode.java @@ -12,53 +12,86 @@ package raw.runtime.truffle.ast.expressions.iterable.list; -import com.oracle.truffle.api.dsl.Bind; -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRExistsBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRExistsConditionNode; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.list.ListNodes; -import raw.runtime.truffle.tryable_nullable.TryableNullable; +import raw.runtime.truffle.runtime.list.ListNodesFactory; @NodeInfo(shortName = "List.Exists") -@NodeChild("list") -@NodeChild("function") -public abstract class ListExistsNode extends ExpressionNode { +public class ListExistsNode extends ExpressionNode { - @Specialization - protected static boolean doList( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorCloseNode generatorCloseNode, - @Cached(inline = true) ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); + @Child private ExpressionNode listNode; + @Child private ExpressionNode functionNode; + @Child private LoopNode existsLoopNode; + + @Child + private GeneratorNodes.GeneratorInitNode generatorInitNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child + private ListNodes.ToIterableNode toIterableNode = ListNodesFactory.ToIterableNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorCloseNode generatorCloseNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + private final int generatorSlot; + private final int functionSlot; + private final int predicateResultSlot; + + public ListExistsNode( + ExpressionNode listNode, + ExpressionNode functionNode, + int generatorSlot, + int functionSlot, + int predicateResultSlot) { + this.listNode = listNode; + this.functionNode = functionNode; + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.predicateResultSlot = predicateResultSlot; + this.existsLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRExistsConditionNode(generatorSlot, predicateResultSlot), + new OSRExistsBodyNode(generatorSlot, functionSlot, predicateResultSlot))); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object list = listNode.executeGeneric(frame); + Object function = functionNode.executeGeneric(frame); + Object iterable = toIterableNode.execute(this, list); + Object generator = getGeneratorNode.execute(this, iterable); try { - generatorInitNode.execute(thisNode, generator); - while (generatorHasNextNode.execute(thisNode, generator)) { - boolean predicate = - TryableNullable.handlePredicate( - functionExecuteOneNode.execute( - thisNode, function, generatorNextNode.execute(thisNode, generator)), - false); - if (predicate) { - return true; - } - } - return false; + generatorInitNode.execute(this, generator); + frame.setObject(generatorSlot, generator); + frame.setObject(functionSlot, function); + frame.setBoolean(predicateResultSlot, false); + existsLoopNode.execute(frame); + return frame.getBoolean(predicateResultSlot); } finally { - generatorCloseNode.execute(thisNode, generator); + generatorCloseNode.execute(this, generator); } } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) { + return (boolean) executeGeneric(virtualFrame); + } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFilterNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFilterNode.java index 25e3a6a9b..5f4d632d9 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFilterNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFilterNode.java @@ -12,54 +12,122 @@ package raw.runtime.truffle.ast.expressions.iterable.list; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import java.util.ArrayList; +import raw.compiler.rql2.source.Rql2Type; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.ast.TypeGuards; -import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListFilterBodyNode; +import raw.runtime.truffle.ast.osr.bodies.OSRToArrayBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; +import raw.runtime.truffle.ast.osr.conditions.OSRIsLessThanSizeConditionNode; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.list.*; -import raw.runtime.truffle.tryable_nullable.TryableNullable; -@ImportStatic(value = TypeGuards.class) @NodeInfo(shortName = "List.Filter") -@NodeChild("list") -@NodeChild("function") -public abstract class ListFilterNode extends ExpressionNode { +public class ListFilterNode extends ExpressionNode { - @Specialization - protected static RawArrayList doFilter( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) GeneratorNodes.GeneratorCloseNode generatorCloseNode, - @Cached(inline = true) GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - ArrayList llist = new ArrayList<>(); - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); + @Child private ExpressionNode listNode; + @Child private ExpressionNode functionNode; + @Child private LoopNode filterLoopNode; + @Child private LoopNode toArrayLoopNode; + + @Child + private GeneratorNodes.GeneratorInitNode generatorInitNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child + private ListNodes.ToIterableNode toIterableNode = ListNodesFactory.ToIterableNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorCloseNode generatorCloseNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + @Child + ArrayOperationNodes.ArrayBuildNode arrayBuildNode = + ArrayOperationNodesFactory.ArrayBuildNodeGen.create(); + + @Child + ArrayOperationNodes.ArrayBuildListNode arrayBuildListNode = + ArrayOperationNodesFactory.ArrayBuildListNodeGen.create(); + + private final Rql2Type resultType; + + private final int generatorSlot; + private final int functionSlot; + private final int llistSlot; + private final int currentIdxSlot; + private final int listSizeSlot; + private final int resultSlot; + + public ListFilterNode( + ExpressionNode listNode, + ExpressionNode functionNode, + Rql2Type resultType, + int generatorSlot, + int functionSlot, + int listSlot, + int currentIdxSlot, + int listSizeSlot, + int resultSlot) { + this.resultType = resultType; + this.listNode = listNode; + this.functionNode = functionNode; + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.llistSlot = listSlot; + this.currentIdxSlot = currentIdxSlot; + this.listSizeSlot = listSizeSlot; + this.resultSlot = resultSlot; + this.filterLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(generatorSlot), + new OSRListFilterBodyNode(generatorSlot, functionSlot, listSlot))); + toArrayLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRIsLessThanSizeConditionNode(currentIdxSlot, listSizeSlot), + new OSRToArrayBodyNode(resultType, listSlot, currentIdxSlot, resultSlot))); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object list = listNode.executeGeneric(frame); + Object function = functionNode.executeGeneric(frame); + Object iterable = toIterableNode.execute(this, list); + Object generator = getGeneratorNode.execute(this, iterable); try { - generatorInitNode.execute(thisNode, generator); - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - Boolean predicate = null; - predicate = - TryableNullable.handlePredicate( - functionExecuteOneNode.execute(thisNode, function, v), false); - if (predicate) { - llist.add(v); - } - } - return new RawArrayList(llist); + generatorInitNode.execute(this, generator); + frame.setObject(generatorSlot, generator); + frame.setObject(functionSlot, function); + frame.setObject(llistSlot, new ArrayList<>()); + filterLoopNode.execute(frame); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(llistSlot); + int size = llist.size(); + frame.setObject(resultSlot, arrayBuildNode.execute(this, resultType, size)); + frame.setInt(currentIdxSlot, 0); + frame.setInt(listSizeSlot, size); + frame.setObject(llistSlot, llist); + toArrayLoopNode.execute(frame); + return arrayBuildListNode.execute(this, frame.getObject(resultSlot)); } finally { - generatorCloseNode.execute(thisNode, generator); + generatorCloseNode.execute(this, generator); } } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromNode.java index a1ba4c87b..2f7e6ec82 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromNode.java @@ -12,308 +12,115 @@ package raw.runtime.truffle.ast.expressions.iterable.list; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.NodeInfo; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import java.util.ArrayList; import raw.compiler.rql2.source.Rql2Type; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.ast.TypeGuards; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListFromBodyNode; +import raw.runtime.truffle.ast.osr.bodies.OSRToArrayBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; +import raw.runtime.truffle.ast.osr.conditions.OSRIsLessThanSizeConditionNode; import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.list.*; import raw.runtime.truffle.runtime.primitives.ErrorObject; @ImportStatic(value = TypeGuards.class) -@NodeInfo(shortName = "List.From") -@NodeChild("list") -@NodeField(name = "resultType", type = Rql2Type.class) -public abstract class ListFromNode extends ExpressionNode { +public class ListFromNode extends ExpressionNode { - @Idempotent - protected abstract Rql2Type getResultType(); + @Child private ExpressionNode iterableNode; + @Child private LoopNode listFromLoopNode; + @Child private LoopNode toArrayLoopNode; - @Specialization(guards = {"isByteKind(getResultType())"}) - protected Object doByte( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((byte) nextGeneratorNode.execute(this, generator)); - } - byte[] list = new byte[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new ByteList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + @Child + private GeneratorNodes.GeneratorInitNode generatorInitNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); - @Specialization(guards = {"isShortKind(getResultType())"}) - protected Object doShort( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((short) nextGeneratorNode.execute(this, generator)); - } - short[] list = new short[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new ShortList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); - @Specialization(guards = {"isIntKind(getResultType())"}) - protected Object doInt( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((int) nextGeneratorNode.execute(this, generator)); - } - int[] list = new int[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new IntList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + @Child + private GeneratorNodes.GeneratorCloseNode generatorCloseNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); - @Specialization(guards = {"isLongKind(getResultType())"}) - protected Object doLong( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((long) nextGeneratorNode.execute(this, generator)); - } - long[] list = new long[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new LongList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + @Child + private ArrayOperationNodes.ArrayBuildNode arrayBuildNode = + ArrayOperationNodesFactory.ArrayBuildNodeGen.create(); - @Specialization(guards = {"isFloatKind(getResultType())"}) - protected Object doFloat( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((float) nextGeneratorNode.execute(this, generator)); - } - float[] list = new float[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new FloatList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + @Child + private ArrayOperationNodes.ArrayBuildListNode arrayBuildListNode = + ArrayOperationNodesFactory.ArrayBuildListNodeGen.create(); - @Specialization(guards = {"isDoubleKind(getResultType())"}) - protected Object doDouble( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((double) nextGeneratorNode.execute(this, generator)); - } - double[] list = new double[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new DoubleList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + private final Rql2Type resultType; - @Specialization(guards = {"isBooleanKind(getResultType())"}) - protected Object doBoolean( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((boolean) nextGeneratorNode.execute(this, generator)); - } - boolean[] list = new boolean[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new BooleanList(list); - } catch (RawTruffleRuntimeException ex) { - return new ErrorObject(ex.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } - } + private final int generatorSlot; + private final int listSlot; + private final int currentIdxSlot; + private final int listSizeSlot; + private final int resultSlot; - @Specialization(guards = {"isStringKind(getResultType())"}) - protected Object doString( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add((String) nextGeneratorNode.execute(this, generator)); - } - String[] list = new String[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new StringList(list); - } catch (RawTruffleRuntimeException e) { - return new ErrorObject(e.getMessage()); - } finally { - closeGeneratorNode.execute(this, generator); - } + public ListFromNode( + ExpressionNode iterableNode, + Rql2Type resultType, + int generatorSlot, + int listSlot, + int currentIdxSlot, + int listSizeSlot, + int resultSlot) { + this.resultType = resultType; + this.iterableNode = iterableNode; + this.generatorSlot = generatorSlot; + this.listSlot = listSlot; + this.currentIdxSlot = currentIdxSlot; + this.listSizeSlot = listSizeSlot; + this.resultSlot = resultSlot; + this.listFromLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(generatorSlot), + new OSRListFromBodyNode(generatorSlot, listSlot))); + toArrayLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRIsLessThanSizeConditionNode(currentIdxSlot, listSizeSlot), + new OSRToArrayBodyNode(resultType, listSlot, currentIdxSlot, resultSlot))); } - @Specialization - protected Object doObject( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGeneratorNode") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode initGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode hasNextGeneratorNode, - @Cached(inline = true) @Cached.Shared("nextNode") - GeneratorNodes.GeneratorNextNode nextGeneratorNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode closeGeneratorNode) { + @Override + public Object executeGeneric(VirtualFrame frame) { + Object iterable = iterableNode.executeGeneric(frame); Object generator = getGeneratorNode.execute(this, iterable); try { - initGeneratorNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (hasNextGeneratorNode.execute(this, generator)) { - llist.add(nextGeneratorNode.execute(this, generator)); - } - return new RawArrayList(llist); - } catch (RawTruffleRuntimeException e) { - return new ErrorObject(e.getMessage()); + generatorInitNode.execute(this, generator); + frame.setObject(generatorSlot, generator); + frame.setObject(listSlot, new ArrayList<>()); + listFromLoopNode.execute(frame); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(listSlot); + int size = llist.size(); + frame.setObject(resultSlot, arrayBuildNode.execute(this, resultType, size)); + frame.setInt(currentIdxSlot, 0); + frame.setInt(listSizeSlot, size); + frame.setObject(listSlot, llist); + toArrayLoopNode.execute(frame); + return arrayBuildListNode.execute(this, frame.getObject(resultSlot)); + } catch (RawTruffleRuntimeException ex) { + return new ErrorObject(ex.getMessage()); } finally { - closeGeneratorNode.execute(this, generator); + generatorCloseNode.execute(this, generator); } } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromUnsafe.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromUnsafe.java index 524ecdaf2..f9099861c 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromUnsafe.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListFromUnsafe.java @@ -12,290 +12,108 @@ package raw.runtime.truffle.ast.expressions.iterable.list; -import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import java.util.ArrayList; import raw.compiler.rql2.source.Rql2Type; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.ast.TypeGuards; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListFromBodyNode; +import raw.runtime.truffle.ast.osr.bodies.OSRToArrayBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; +import raw.runtime.truffle.ast.osr.conditions.OSRIsLessThanSizeConditionNode; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.list.*; -@ImportStatic(value = TypeGuards.class) @NodeInfo(shortName = "List.FromUnsafe") -@NodeChild("list") -@NodeField(name = "resultType", type = Rql2Type.class) -public abstract class ListFromUnsafe extends ExpressionNode { +public class ListFromUnsafe extends ExpressionNode { - @Idempotent - protected abstract Rql2Type getResultType(); + @Child private ExpressionNode iterableNode; + @Child private LoopNode listFromLoopNode; + @Child private LoopNode toArrayLoopNode; - @Specialization(guards = {"isByteKind(getResultType())"}) - protected ByteList doByte( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((byte) generatorNextNode.execute(this, generator)); - } - byte[] list = new byte[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new ByteList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + @Child + private GeneratorNodes.GeneratorInitNode generatorInitNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); - @Specialization(guards = {"isShortKind(getResultType())"}) - protected ShortList doShort( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((short) generatorNextNode.execute(this, generator)); - } - short[] list = new short[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new ShortList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); - @Specialization(guards = {"isIntKind(getResultType())"}) - protected IntList doInt( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((int) generatorNextNode.execute(this, generator)); - } - int[] list = new int[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new IntList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + @Child + private GeneratorNodes.GeneratorCloseNode generatorCloseNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); - @Specialization(guards = {"isLongKind(getResultType())"}) - protected LongList doLong( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((long) generatorNextNode.execute(this, generator)); - } - long[] list = new long[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new LongList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + @Child + private ArrayOperationNodes.ArrayBuildNode arrayBuildNode = + ArrayOperationNodesFactory.ArrayBuildNodeGen.create(); - @Specialization(guards = {"isFloatKind(getResultType())"}) - protected FloatList doFloat( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((float) generatorNextNode.execute(this, generator)); - } - float[] list = new float[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new FloatList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + @Child + private ArrayOperationNodes.ArrayBuildListNode arrayBuildListNode = + ArrayOperationNodesFactory.ArrayBuildListNodeGen.create(); - @Specialization(guards = {"isDoubleKind(getResultType())"}) - protected DoubleList doDouble( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((double) generatorNextNode.execute(this, generator)); - } - double[] list = new double[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new DoubleList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + private final Rql2Type resultType; - @Specialization(guards = {"isBooleanKind(getResultType())"}) - protected BooleanList doBoolean( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((boolean) generatorNextNode.execute(this, generator)); - } - boolean[] list = new boolean[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new BooleanList(list); - } finally { - generatorCloseNode.execute(this, generator); - } - } + private final int generatorSlot; + private final int listSlot; + private final int currentIdxSlot; + private final int listSizeSlot; + private final int resultSlot; - @Specialization(guards = {"isStringKind(getResultType())"}) - protected StringList doString( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { - Object generator = getGeneratorNode.execute(this, iterable); - try { - generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add((String) generatorNextNode.execute(this, generator)); - } - String[] list = new String[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new StringList(list); - } finally { - generatorCloseNode.execute(this, generator); - } + public ListFromUnsafe( + ExpressionNode iterableNode, + Rql2Type resultType, + int generatorSlot, + int listSlot, + int currentIdxSlot, + int listSizeSlot, + int resultSlot) { + this.resultType = resultType; + this.iterableNode = iterableNode; + this.generatorSlot = generatorSlot; + this.listSlot = listSlot; + this.currentIdxSlot = currentIdxSlot; + this.listSizeSlot = listSizeSlot; + this.resultSlot = resultSlot; + this.listFromLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(generatorSlot), + new OSRListFromBodyNode(generatorSlot, listSlot))); + toArrayLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRIsLessThanSizeConditionNode(currentIdxSlot, listSizeSlot), + new OSRToArrayBodyNode(resultType, listSlot, currentIdxSlot, resultSlot))); } - @Specialization - protected ObjectList doObject( - Object iterable, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("initNode") - GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached(inline = true) @Cached.Shared("hasNextNode") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("closeNode") - GeneratorNodes.GeneratorCloseNode generatorCloseNode) { + @Override + public Object executeGeneric(VirtualFrame frame) { + Object iterable = iterableNode.executeGeneric(frame); Object generator = getGeneratorNode.execute(this, iterable); try { generatorInitNode.execute(this, generator); - ArrayList llist = new ArrayList<>(); - while (generatorHasNextNode.execute(this, generator)) { - llist.add(generatorNextNode.execute(this, generator)); - } - Object[] list = new Object[llist.size()]; - for (int i = 0; i < list.length; i++) { - list[i] = llist.get(i); - } - return new ObjectList(list); + frame.setObject(generatorSlot, generator); + frame.setObject(listSlot, new ArrayList<>()); + listFromLoopNode.execute(frame); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(listSlot); + int size = llist.size(); + frame.setObject(resultSlot, arrayBuildNode.execute(this, resultType, size)); + frame.setInt(currentIdxSlot, 0); + frame.setInt(listSizeSlot, size); + frame.setObject(listSlot, llist); + toArrayLoopNode.execute(frame); + return arrayBuildListNode.execute(this, frame.getObject(resultSlot)); } finally { generatorCloseNode.execute(this, generator); } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListGroupByNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListGroupByNode.java index 10bcc62fd..76c3ce0bd 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListGroupByNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListGroupByNode.java @@ -12,85 +12,146 @@ package raw.runtime.truffle.ast.expressions.iterable.list; -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.Truffle; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import java.util.ArrayList; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.runtime.truffle.ExpressionNode; import raw.runtime.truffle.RawContext; import raw.runtime.truffle.RawLanguage; -import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListEquiJoinInitBodyNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListFromBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionNode; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodes; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodesFactory; import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.group_by.OffHeapGroupByKey; import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.record_shaper.RecordShaper; import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.runtime.iterable.IterableNodesFactory; import raw.runtime.truffle.runtime.list.ListNodes; -import raw.runtime.truffle.runtime.list.ObjectList; -import raw.runtime.truffle.runtime.record.RecordObject; +import raw.runtime.truffle.runtime.list.ListNodesFactory; +import raw.runtime.truffle.runtime.list.RawArrayList; import raw.sources.api.SourceContext; @NodeInfo(shortName = "List.GroupBy") -@NodeChild("input") -@NodeChild("keyFun") -@NodeField(name = "keyType", type = Rql2TypeWithProperties.class) -@NodeField(name = "rowType", type = Rql2TypeWithProperties.class) -public abstract class ListGroupByNode extends ExpressionNode { - - @Idempotent - public abstract Rql2TypeWithProperties getKeyType(); - - @Idempotent - public abstract Rql2TypeWithProperties getRowType(); - - static final int LIB_LIMIT = 2; - - @Specialization - protected static Object doGroup( - Object input, - Object keyFun, - @Bind("this") Node thisNode, - @Cached(inline = true) IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) GeneratorNodes.GeneratorNextNode nextNode, - @Cached(inline = true) GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = true) GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) OffHeapNodes.OffHeapGroupByPutNode putNode, - @Cached(inline = true) OffHeapNodes.OffHeapGeneratorNode generatorNode, - @Cached(inline = true) FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode, - @Cached(inline = true) ListNodes.ToIterableNode toIterableNode) { - Object iterable = toIterableNode.execute(thisNode, input); - SourceContext context = RawContext.get(thisNode).getSourceContext(); +public class ListGroupByNode extends ExpressionNode { + + @Child private ExpressionNode inputNode; + @Child private ExpressionNode keyFunNode; + @Child private LoopNode equiJoinInitLoopNode; + @Child private LoopNode listFromLoopNode; + + @Child + private GeneratorNodes.GeneratorInitNode generatorInitNode = + GeneratorNodesFactory.GeneratorInitNodeGen.create(); + + @Child + private IterableNodes.GetGeneratorNode getGeneratorNode = + IterableNodesFactory.GetGeneratorNodeGen.create(); + + @Child + private ListNodes.ToIterableNode toIterableNode = ListNodesFactory.ToIterableNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorCloseNode generatorCloseNode = + GeneratorNodesFactory.GeneratorCloseNodeGen.create(); + + @Child + OffHeapNodes.OffHeapGeneratorNode generatorNode = + OffHeapNodesFactory.OffHeapGeneratorNodeGen.create(); + + @Child + private ArrayOperationNodes.ArrayBuildNode arrayBuildNode = + ArrayOperationNodesFactory.ArrayBuildNodeGen.create(); + + @Child + private ArrayOperationNodes.ArrayBuildListNode arrayBuildListNode = + ArrayOperationNodesFactory.ArrayBuildListNodeGen.create(); + + private final Rql2TypeWithProperties rowType; + private final Rql2TypeWithProperties keyType; + + private final int generatorSlot; + private final int keyFunctionSlot; + private final int mapSlot; + private final int listSlot; + + public ListGroupByNode( + ExpressionNode inputNode, + ExpressionNode keyFunNode, + Rql2TypeWithProperties rowType, + Rql2TypeWithProperties keyType, + int generatorSlot, + int keyFunctionSlot, + int mapSlot, + int listSlot) { + this.inputNode = inputNode; + this.keyFunNode = keyFunNode; + this.rowType = rowType; + this.keyType = keyType; + + this.generatorSlot = generatorSlot; + this.keyFunctionSlot = keyFunctionSlot; + + this.mapSlot = mapSlot; + this.listSlot = listSlot; + this.equiJoinInitLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(this.generatorSlot), + new OSRListEquiJoinInitBodyNode( + this.generatorSlot, this.keyFunctionSlot, this.mapSlot))); + + this.listFromLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionNode(this.generatorSlot), + new OSRListFromBodyNode(this.generatorSlot, this.listSlot))); + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object input = inputNode.executeGeneric(frame); + Object keyFun = keyFunNode.executeGeneric(frame); + Object iterable = toIterableNode.execute(this, input); + SourceContext context = RawContext.get(this).getSourceContext(); OffHeapGroupByKey map = new OffHeapGroupByKey( - ((ListGroupByNode) thisNode).getKeyType(), - ((ListGroupByNode) thisNode).getRowType(), - RawLanguage.get(thisNode), + this.keyType, + this.rowType, + RawLanguage.get(this), context, - new RecordShaper(RawLanguage.get(thisNode), true)); - Object generator = getGeneratorNode.execute(thisNode, iterable); + new RecordShaper(RawLanguage.get(this), true)); + Object generator = getGeneratorNode.execute(this, iterable); try { - initNode.execute(thisNode, generator); - while (hasNextNode.execute(thisNode, generator)) { - Object v = nextNode.execute(thisNode, generator); - Object key = functionExecuteOneNode.execute(thisNode, keyFun, v); - putNode.execute(thisNode, map, key, v); - } + generatorInitNode.execute(this, generator); + frame.setObject(generatorSlot, generator); + frame.setObject(keyFunctionSlot, keyFun); + frame.setObject(mapSlot, map); + equiJoinInitLoopNode.execute(frame); } finally { - closeNode.execute(thisNode, generator); + generatorCloseNode.execute(this, generator); } - ArrayList items = new ArrayList<>(); - Object mapGenerator = generatorNode.execute(thisNode, map); + Object mapGenerator = generatorNode.execute(this, map); try { - initNode.execute(thisNode, mapGenerator); - while (hasNextNode.execute(thisNode, mapGenerator)) { - RecordObject record = (RecordObject) nextNode.execute(thisNode, mapGenerator); - items.add(record); - } + generatorInitNode.execute(this, mapGenerator); + frame.setObject(generatorSlot, mapGenerator); + frame.setObject(listSlot, new ArrayList<>()); + listFromLoopNode.execute(frame); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(listSlot); + return new RawArrayList(llist); } finally { - closeNode.execute(thisNode, mapGenerator); + generatorCloseNode.execute(this, mapGenerator); } - return new ObjectList(items.toArray()); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListMaxNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListMaxNode.java deleted file mode 100644 index 59be7fb75..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListMaxNode.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.list; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.list.ListNodes; - -@NodeInfo(shortName = "List.Max") -@NodeChild("list") -public abstract class ListMaxNode extends ExpressionNode { - - private final SingleAggregation aggregation = new SingleAggregation(Aggregators.MAX); - - @Specialization - protected Object doCollection( - Object list, - @Cached(inline = true) AggregationNodes.Aggregate aggregate, - @Cached(inline = true) ListNodes.ToIterableNode toIterableNode) { - Object iterable = toIterableNode.execute(this, list); - return aggregate.execute(this, aggregation, iterable); - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListMinNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListMinNode.java deleted file mode 100644 index 24c4a3fe5..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListMinNode.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.list; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.list.ListNodes; - -@NodeInfo(shortName = "List.Min") -@NodeChild("list") -public abstract class ListMinNode extends ExpressionNode { - - private final SingleAggregation aggregation = new SingleAggregation(Aggregators.MIN); - - @Specialization - protected Object doCollection( - Object list, - @Cached(inline = true) AggregationNodes.Aggregate aggregate, - @Cached(inline = true) ListNodes.ToIterableNode toIterableNode) { - Object iterable = toIterableNode.execute(this, list); - return aggregate.execute(this, aggregation, iterable); - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListSumNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListSumNode.java deleted file mode 100644 index 3bd8e8e2e..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListSumNode.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.ast.expressions.iterable.list; - -import com.oracle.truffle.api.dsl.Cached; -import com.oracle.truffle.api.dsl.NodeChild; -import com.oracle.truffle.api.dsl.Specialization; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.runtime.aggregation.AggregationNodes; -import raw.runtime.truffle.runtime.aggregation.SingleAggregation; -import raw.runtime.truffle.runtime.aggregation.aggregator.Aggregators; -import raw.runtime.truffle.runtime.list.ListNodes; - -@NodeInfo(shortName = "List.Sum") -@NodeChild("list") -public abstract class ListSumNode extends ExpressionNode { - - private final SingleAggregation aggregation = new SingleAggregation(Aggregators.SUM); - - @Specialization - protected Object doCollection( - Object list, - @Cached(inline = true) AggregationNodes.Aggregate aggregate, - @Cached(inline = true) ListNodes.ToIterableNode toIterableNode) { - Object iterable = toIterableNode.execute(this, list); - return aggregate.execute(this, aggregation, iterable); - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListTransformNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListTransformNode.java index 390a60cae..9a3898b9d 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListTransformNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/expressions/iterable/list/ListTransformNode.java @@ -12,332 +12,93 @@ package raw.runtime.truffle.ast.expressions.iterable.list; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import raw.compiler.rql2.source.*; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.ast.TypeGuards; -import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; -import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; -import raw.runtime.truffle.runtime.iterable.IterableNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListTransformBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRIsLessThanSizeConditionNode; import raw.runtime.truffle.runtime.list.*; -@ImportStatic(value = TypeGuards.class) @NodeInfo(shortName = "List.Transform") -@NodeChild("list") -@NodeChild("function") -@NodeField(name = "resultType", type = Rql2Type.class) -public abstract class ListTransformNode extends ExpressionNode { +public class ListTransformNode extends ExpressionNode { - static final int LIB_LIMIT = 2; + @Child private ExpressionNode listNode; + @Child private ExpressionNode functionNode; + @Child private LoopNode listTransformLoopNode; - @Idempotent - protected abstract Rql2Type getResultType(); + @Child + private ArrayOperationNodes.ArrayBuildListNode arrayBuildListNode = + ArrayOperationNodesFactory.ArrayBuildListNodeGen.create(); - @Specialization(guards = {"isByteKind(getResultType())"}) - protected static ByteList doByte( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - byte[] values = new byte[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (byte) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new ByteList(values); - } finally { - closeNode.execute(thisNode, generator); - } - } + @Child + private ArrayOperationNodes.ArrayBuildNode arrayBuildNode = + ArrayOperationNodesFactory.ArrayBuildNodeGen.create(); - @Specialization(guards = {"isShortKind(getResultType())"}) - protected static ShortList doShort( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - short[] values = new short[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (short) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new ShortList(values); - } finally { - closeNode.execute(thisNode, generator); - } - } + @Child private ListNodes.SizeNode sizeNode = ListNodesFactory.SizeNodeGen.create(); - @Specialization(guards = {"isIntKind(getResultType())"}) - protected static IntList doInt( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - int[] values = new int[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (int) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new IntList(values); - } finally { - closeNode.execute(thisNode, generator); - } - } + private final Rql2Type resultType; - @Specialization(guards = {"isLongKind(getResultType())"}) - protected static LongList doLong( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - long[] values = new long[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (long) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new LongList(values); - } finally { - closeNode.execute(thisNode, generator); - } - } + private final int currentIndexSlot; + private final int listSizeSlot; + private final int listSlot; + private final int functionSlot; + private final int resultSlot; - @Specialization(guards = {"isFloatKind(getResultType())"}) - protected static FloatList doFloat( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - float[] values = new float[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (float) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new FloatList(values); - } finally { - closeNode.execute(thisNode, generator); - } - } + public ListTransformNode( + ExpressionNode listNode, + ExpressionNode functionNode, + Rql2Type resultType, + int listSlot, + int functionSlot, + int currentIndexSlot, + int listSizeSlot, + int resultSlot) { + this.listNode = listNode; + this.functionNode = functionNode; + this.resultType = resultType; + this.listSizeSlot = listSizeSlot; + this.currentIndexSlot = currentIndexSlot; + this.functionSlot = functionSlot; + this.resultSlot = resultSlot; + this.listSlot = listSlot; - @Specialization(guards = {"isDoubleKind(getResultType())"}) - protected static DoubleList doDouble( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - double[] values = new double[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (double) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new DoubleList(values); - } finally { - closeNode.execute(thisNode, generator); - } + this.listTransformLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRIsLessThanSizeConditionNode(this.currentIndexSlot, this.listSizeSlot), + new OSRListTransformBodyNode( + this.listSlot, this.functionSlot, this.currentIndexSlot, this.resultSlot))); } - @Specialization(guards = {"isBooleanKind(getResultType())"}) - protected BooleanList doBoolean( - Object list, - Object function, - @Bind("$node") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - boolean[] values = new boolean[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (boolean) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new BooleanList(values); - } finally { - closeNode.execute(thisNode, generator); - } - } + @Override + public Object executeGeneric(VirtualFrame frame) { + Object list = listNode.executeGeneric(frame); + Object function = functionNode.executeGeneric(frame); + + int listSize = (int) sizeNode.execute(this, list); + + frame.setObject(this.listSlot, list); + frame.setObject(this.functionSlot, function); + frame.setInt(this.currentIndexSlot, 0); + frame.setInt(this.listSizeSlot, listSize); + frame.setObject(this.resultSlot, arrayBuildNode.execute(this, this.resultType, listSize)); + + listTransformLoopNode.execute(frame); + Object result = frame.getObject(this.resultSlot); - @Specialization(guards = {"isStringKind(getResultType())"}) - protected static StringList doString( - Object list, - Object function, - @Bind("this") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - String[] values = new String[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = (String) functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new StringList(values); - } finally { - closeNode.execute(thisNode, generator); - } + return arrayBuildListNode.execute(this, result); } - @Specialization - protected ObjectList doObject( - Object list, - Object function, - @Bind("$node") Node thisNode, - @Cached(inline = true) @Cached.Shared("getGenerator") - IterableNodes.GetGeneratorNode getGeneratorNode, - @Cached(inline = true) @Cached.Shared("hasNext") - GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached(inline = true) @Cached.Shared("next") - GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached(inline = true) @Cached.Shared("toIterable") ListNodes.ToIterableNode toIterableNode, - @Cached(inline = true) @Cached.Shared("size") ListNodes.SizeNode sizeNode, - @Cached(inline = true) @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached(inline = true) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached(inline = true) @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - Object iterable = toIterableNode.execute(thisNode, list); - Object generator = getGeneratorNode.execute(thisNode, iterable); - try { - initNode.execute(thisNode, generator); - Object[] values = new Object[(int) sizeNode.execute(thisNode, list)]; - int cnt = 0; - while (generatorHasNextNode.execute(thisNode, generator)) { - Object v = generatorNextNode.execute(thisNode, generator); - values[cnt] = functionExecuteOneNode.execute(thisNode, function, v); - cnt++; - } - return new ObjectList(values); - } finally { - closeNode.execute(thisNode, generator); - } + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) { + return (boolean) executeGeneric(virtualFrame); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/JsonParserNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/JsonParserNodes.java index ba856acc9..c63e909ee 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/JsonParserNodes.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/JsonParserNodes.java @@ -44,7 +44,7 @@ import raw.runtime.truffle.runtime.exceptions.json.JsonParserRawTruffleException; import raw.runtime.truffle.runtime.exceptions.json.JsonReaderRawTruffleException; import raw.runtime.truffle.runtime.exceptions.json.JsonUnexpectedTokenException; -import raw.runtime.truffle.runtime.list.ObjectList; +import raw.runtime.truffle.runtime.list.RawArrayList; import raw.runtime.truffle.runtime.primitives.*; import raw.runtime.truffle.runtime.record.RecordObject; import raw.runtime.truffle.utils.TruffleCharInputStream; @@ -607,7 +607,7 @@ public boolean isNull(JsonParser parser) { } @Specialization(guards = {"isArray(parser)"}) - protected static ObjectList doParseList( + protected static RawArrayList doParseList( Node node, JsonParser parser, @Bind("$node") Node thisNode, @@ -625,17 +625,13 @@ protected static ObjectList doParseList( ArrayList alist = new ArrayList<>(); + // (az) To do, make OSR when we use any type while (currentToken.execute(thisNode, parser) != JsonToken.END_ARRAY) { alist.add(parse.execute(thisNode, parser)); } - nextToken.execute(thisNode, parser); - - Object[] result = new Object[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - return new ObjectList(result); + nextToken.execute(thisNode, parser); + return new RawArrayList(alist); } @Specialization(guards = {"isObject(parser)"}) diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/parser/ListParseJsonNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/parser/ListParseJsonNode.java index 7cb2d9eb6..c7819c879 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/parser/ListParseJsonNode.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/io/json/reader/parser/ListParseJsonNode.java @@ -15,105 +15,91 @@ import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.oracle.truffle.api.RootCallTarget; -import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.frame.VirtualFrame; -import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.NodeInfo; import java.util.ArrayList; import raw.compiler.rql2.source.Rql2Type; import raw.runtime.truffle.ExpressionNode; -import raw.runtime.truffle.ast.TypeGuards; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; import raw.runtime.truffle.ast.io.json.reader.JsonParserNodes; +import raw.runtime.truffle.ast.io.json.reader.JsonParserNodesFactory; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRListParseJsonBodyNode; +import raw.runtime.truffle.ast.osr.bodies.OSRToArrayBodyNode; +import raw.runtime.truffle.ast.osr.conditions.OSRIsLessThanSizeConditionNode; +import raw.runtime.truffle.ast.osr.conditions.OSRListParseJsonConditionNode; import raw.runtime.truffle.runtime.exceptions.json.JsonUnexpectedTokenException; import raw.runtime.truffle.runtime.list.*; -@ImportStatic(value = TypeGuards.class) @NodeInfo(shortName = "IterableParseJson") -@NodeField(name = "resultType", type = Rql2Type.class) -@NodeField(name = "childCallTarget", type = RootCallTarget.class) -public abstract class ListParseJsonNode extends ExpressionNode { - - @Idempotent - protected abstract Rql2Type getResultType(); - - @Idempotent - protected abstract RootCallTarget getChildCallTarget(); - - @Specialization(guards = {"isByteKind(getResultType())"}) - protected ByteList doByte( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Byte) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - byte[] result = new byte[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new ByteList(result); - } - - @Specialization(guards = {"isShortKind(getResultType())"}) - protected ShortList doShort( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Short) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - short[] result = new short[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new ShortList(result); +public class ListParseJsonNode extends ExpressionNode { + + @Child private LoopNode listParseLoopNode; + + @Child private LoopNode toArrayLoopNode; + + @Child + private JsonParserNodes.CurrentTokenJsonParserNode currentToken = + JsonParserNodesFactory.CurrentTokenJsonParserNodeGen.create(); + + @Child + private JsonParserNodes.NextTokenJsonParserNode nextToken = + JsonParserNodesFactory.NextTokenJsonParserNodeGen.create(); + + @Child + private ArrayOperationNodes.ArrayBuildListNode arrayBuildListNode = + ArrayOperationNodesFactory.ArrayBuildListNodeGen.create(); + + @Child + private ArrayOperationNodes.ArrayBuildNode arrayBuildNode = + ArrayOperationNodesFactory.ArrayBuildNodeGen.create(); + + private final Rql2Type resultType; + + private final int currentIdxSlot; + private final int listSizeSlot; + private final int llistSlot; + private final int resultSlot; + + private final int parserSlot; + + public ListParseJsonNode( + Rql2Type resultType, + RootCallTarget childCallTarget, + int parserSlot, + int llistSlot, + int currentIdxSlot, + int listSizeSlot, + int resultSlot) { + this.parserSlot = parserSlot; + this.resultType = resultType; + this.listSizeSlot = listSizeSlot; + this.currentIdxSlot = currentIdxSlot; + this.resultSlot = resultSlot; + this.llistSlot = llistSlot; + + this.listParseLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRListParseJsonConditionNode(this.parserSlot), + new OSRListParseJsonBodyNode( + childCallTarget, this.llistSlot, this.parserSlot))); + + toArrayLoopNode = + Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRIsLessThanSizeConditionNode(currentIdxSlot, listSizeSlot), + new OSRToArrayBodyNode( + this.resultType, this.llistSlot, this.currentIdxSlot, this.resultSlot))); } - @Specialization(guards = {"isIntKind(getResultType())"}) - protected IntList doInt( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { + @Override + public Object executeGeneric(VirtualFrame frame) { Object[] args = frame.getArguments(); JsonParser parser = (JsonParser) args[0]; @@ -123,216 +109,21 @@ protected IntList doInt( } nextToken.execute(this, parser); - ArrayList alist = new ArrayList<>(); + frame.setObject(parserSlot, parser); + frame.setObject(llistSlot, new ArrayList<>()); + listParseLoopNode.execute(frame); - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Integer) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - int[] result = new int[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new IntList(result); - } - - @Specialization(guards = {"isLongKind(getResultType())"}) - protected LongList doLong( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Long) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - long[] result = new long[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new LongList(result); - } - - @Specialization(guards = {"isFloatKind(getResultType())"}) - protected FloatList doFloat( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Float) childCallNode.call(parser)); - } nextToken.execute(this, parser); - float[] result = new float[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new FloatList(result); - } - - @Specialization(guards = {"isDoubleKind(getResultType())"}) - protected DoubleList doDouble( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Double) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - double[] result = new double[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new DoubleList(result); - } - - @Specialization(guards = {"isBooleanKind(getResultType())"}) - protected BooleanList doBoolean( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((Boolean) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - boolean[] result = new boolean[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new BooleanList(result); - } - - @Specialization(guards = {"isStringKind(getResultType())"}) - protected StringList doString( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add((String) childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - String[] result = new String[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } - - return new StringList(result); - } - - @Specialization - protected ObjectList doObject( - VirtualFrame frame, - @Cached("create(getChildCallTarget())") @Cached.Shared("callTarget") - DirectCallNode childCallNode, - @Cached(inline = true) @Cached.Shared("currentToken") - JsonParserNodes.CurrentTokenJsonParserNode currentToken, - @Cached(inline = true) @Cached.Shared("nextToken") - JsonParserNodes.NextTokenJsonParserNode nextToken) { - Object[] args = frame.getArguments(); - JsonParser parser = (JsonParser) args[0]; - - if (currentToken.execute(this, parser) != JsonToken.START_ARRAY) { - throw new JsonUnexpectedTokenException( - JsonToken.START_ARRAY.asString(), currentToken.execute(this, parser).toString(), this); - } - nextToken.execute(this, parser); - - ArrayList alist = new ArrayList<>(); - - while (currentToken.execute(this, parser) != JsonToken.END_ARRAY) { - alist.add(childCallNode.call(parser)); - } - nextToken.execute(this, parser); - - Object[] result = new Object[alist.size()]; - for (int i = 0; i < result.length; i++) { - result[i] = alist.get(i); - } + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(llistSlot); + int size = llist.size(); - return new ObjectList(result); + frame.setObject(resultSlot, arrayBuildNode.execute(this, resultType, size)); + frame.setInt(this.currentIdxSlot, 0); + frame.setInt(listSizeSlot, size); + frame.setObject(llistSlot, llist); + toArrayLoopNode.execute(frame); + return arrayBuildListNode.execute(this, frame.getObject(resultSlot)); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/AuxiliarySlots.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/AuxiliarySlots.java new file mode 100644 index 000000000..9d311459e --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/AuxiliarySlots.java @@ -0,0 +1,26 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr; + +public final class AuxiliarySlots { + public static final String GENERATOR_SLOT = "generatorSlot"; + public static final String RESULT_SLOT = "resultSlot"; + public static final String FUNCTION_SLOT = "functionSlot"; + public static final String MAP_SLOT = "mapSlot"; + public static final String SHOULD_CONTINUE_SLOT = "shouldContinueSlot"; + public static final String COMPUTE_NEXT_SLOT = "computeNextSlot"; + public static final String OUTPUT_BUFFER_SLOT = "outputBufferSlot"; + public static final String OFF_HEAP_DISTINCT_SLOT = "offHeapDistinctSlot"; + public static final String OFF_HEAP_GROUP_BY_KEYS_SLOT = "offHeapGroupByKeysSlot"; + public static final String COLLECTION_SLOT = "collectionSlot"; +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/OSRGeneratorNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/OSRGeneratorNode.java new file mode 100644 index 000000000..4c436b602 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/OSRGeneratorNode.java @@ -0,0 +1,44 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import com.oracle.truffle.api.nodes.RepeatingNode; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.exceptions.RawTruffleInternalErrorException; + +public class OSRGeneratorNode extends Node implements RepeatingNode { + + @Child private ExpressionNode conditionNode; + + @Child private ExpressionNode bodyNode; + + public OSRGeneratorNode(ExpressionNode conditionNode, ExpressionNode bodyNode) { + this.conditionNode = conditionNode; + this.bodyNode = bodyNode; + } + + public boolean executeRepeating(VirtualFrame frame) { + try { + if (conditionNode.executeBoolean(frame)) { + bodyNode.executeVoid(frame); + return true; + } + return false; + } catch (UnexpectedResultException e) { + throw new RawTruffleInternalErrorException(e); + } + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionEquiJoinInitBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionEquiJoinInitBodyNode.java new file mode 100644 index 000000000..3bdbcbaac --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionEquiJoinInitBodyNode.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodes; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodesFactory; + +public class OSRCollectionEquiJoinInitBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + @Child + OffHeapNodes.OffHeapGroupByPutNode putNode = + OffHeapNodesFactory.OffHeapGroupByPutNodeGen.create(); + + private final int generatorSlot; + private final int keyFunctionSlot; + private final int mapSlot; + + public OSRCollectionEquiJoinInitBodyNode(int generatorSlot, int keyFunctionSlot, int mapSlot) { + this.generatorSlot = generatorSlot; + this.keyFunctionSlot = keyFunctionSlot; + this.mapSlot = mapSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getAuxiliarySlot(generatorSlot); + Object keyFunc = frame.getAuxiliarySlot(keyFunctionSlot); + Object map = frame.getAuxiliarySlot(mapSlot); + Object item = nextNode.execute(this, generator); + Object key = functionExecuteOneNode.execute(this, keyFunc, item); + putNode.execute(this, map, key, item); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionFilterBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionFilterBodyNode.java new file mode 100644 index 000000000..5406539d2 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionFilterBodyNode.java @@ -0,0 +1,65 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.tryable_nullable.TryableNullable; + +public class OSRCollectionFilterBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + private final int generatorSlot; + + private final int functionSlot; + + private final int resultSlot; + + public OSRCollectionFilterBodyNode(int generatorSlot, int functionSlot, int resultSlot) { + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.resultSlot = resultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); + Object generator = frame.getAuxiliarySlot(generatorSlot); + Object predicate = frame.getAuxiliarySlot(functionSlot); + Object v = nextNode.execute(this, generator); + + boolean isPredicateTrue = + TryableNullable.handlePredicate(functionExecuteOneNode.execute(this, predicate, v), false); + if (isPredicateTrue) { + frame.setAuxiliarySlot(resultSlot, v); + } + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionJoinInitBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionJoinInitBodyNode.java new file mode 100644 index 000000000..aedb5c2c5 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionJoinInitBodyNode.java @@ -0,0 +1,58 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.esotericsoftware.kryo.io.Output; +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations.JoinComputeNext; +import raw.runtime.truffle.runtime.kryo.KryoNodes; +import raw.runtime.truffle.runtime.kryo.KryoNodesFactory; + +public class OSRCollectionJoinInitBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child KryoNodes.KryoWriteNode kryoWrite = KryoNodesFactory.KryoWriteNodeGen.create(); + + private final int generatorSlot; + private final int computeNextSlot; + private final int outputBufferSlot; + + public OSRCollectionJoinInitBodyNode( + int generatorSlot, int computeNextSlot, int outputBufferSlot) { + this.generatorSlot = generatorSlot; + this.computeNextSlot = computeNextSlot; + this.outputBufferSlot = outputBufferSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getAuxiliarySlot(generatorSlot); + JoinComputeNext computeNext = (JoinComputeNext) frame.getAuxiliarySlot(computeNextSlot); + Output buffer = (Output) frame.getAuxiliarySlot(outputBufferSlot); + Object row = nextNode.execute(this, generator); + kryoWrite.execute(this, buffer, computeNext.getRightRowType(), row); + computeNext.setSpilledRight(computeNext.getSpilledRight() + 1); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionMkStringBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionMkStringBodyNode.java new file mode 100644 index 000000000..f66002f64 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRCollectionMkStringBodyNode.java @@ -0,0 +1,57 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.operators.OperatorNodes; +import raw.runtime.truffle.runtime.operators.OperatorNodesFactory; + +public class OSRCollectionMkStringBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child OperatorNodes.AddNode add = OperatorNodesFactory.AddNodeGen.create(); + + private final int generatorSlot; + + private final int sepSlot; + + private final int resultSlot; + + public OSRCollectionMkStringBodyNode(int generatorSlot, int sepSlot, int resultSlot) { + this.generatorSlot = generatorSlot; + this.sepSlot = sepSlot; + this.resultSlot = resultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + Object next = nextNode.execute(this, generator); + String sep = frame.getObject(sepSlot).toString(); + String resultString = frame.getObject(resultSlot).toString(); + String newResult = (String) add.execute(this, resultString + sep, next); + frame.setObject(resultSlot, newResult); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRDistinctGetGeneratorNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRDistinctGetGeneratorNode.java new file mode 100644 index 000000000..0cff3585a --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRDistinctGetGeneratorNode.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodes; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.distinct.OffHeapDistinct; + +public class OSRDistinctGetGeneratorNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + OffHeapNodes.OffHeapGroupByPutNode putNode = + OffHeapNodesFactory.OffHeapGroupByPutNodeGen.create(); + + private final int generatorSlot; + + private final int offHeapDistinctSlot; + + public OSRDistinctGetGeneratorNode(int generatorSlot, int offHeapDistinctSlot) { + this.generatorSlot = generatorSlot; + this.offHeapDistinctSlot = offHeapDistinctSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getAuxiliarySlot(generatorSlot); + OffHeapDistinct index = (OffHeapDistinct) frame.getAuxiliarySlot(offHeapDistinctSlot); + + Object next = nextNode.execute(this, generator); + putNode.execute(this, index, next, null); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSREquiJoinNextBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSREquiJoinNextBodyNode.java new file mode 100644 index 000000000..9d99f6d4b --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSREquiJoinNextBodyNode.java @@ -0,0 +1,98 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.exceptions.BreakException; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations.EquiJoinComputeNext; +import raw.runtime.truffle.runtime.operators.OperatorNodes; +import raw.runtime.truffle.runtime.operators.OperatorNodesFactory; + +public class OSREquiJoinNextBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child OperatorNodes.CompareNode compareKey = OperatorNodesFactory.CompareNodeGen.create(); + + private final int computeNextSlot; + private final int shouldContinueSlot; + + public OSREquiJoinNextBodyNode(int computeNextSlot, int shouldContinueSlot) { + this.computeNextSlot = computeNextSlot; + this.shouldContinueSlot = shouldContinueSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + EquiJoinComputeNext computeNext = (EquiJoinComputeNext) frame.getAuxiliarySlot(computeNextSlot); + if (computeNext.getLeftKey() == null || computeNext.getRightKey() == null) { + if (computeNext.getLeftKey() == null) { + if (hasNextNode.execute(this, computeNext.getLeftMapGenerator())) { + computeNext.setLeftEntry( + (Object[]) nextNode.execute(this, computeNext.getLeftMapGenerator())); + computeNext.setLeftKey(computeNext.getLeftEntry()[0]); + } else { + throw new BreakException(); + } + } + + if (computeNext.getRightKey() == null) { + if (hasNextNode.execute(this, computeNext.getRightMapGenerator())) { + computeNext.setRightEntry( + (Object[]) nextNode.execute(this, computeNext.getRightMapGenerator())); + computeNext.setRightKey(computeNext.getRightEntry()[0]); + } else { + throw new BreakException(); + } + } + + int compare = compareKey.execute(this, computeNext.getLeftKey(), computeNext.getRightKey()); + // if keys aren't equal, reset the smallest of both (it will be read in the next + // iteration and + // will be larger) + if (compare < 0) { + computeNext.setLeftKey(null); + } else if (compare > 0) { + computeNext.setRightKey(null); + } else { + // keys are equal, prepare to do the cartesian product between both. + // leftRows and rightRows are the arrays of rows with the same key. + // We'll iterate over them to produce the cartesian product. + computeNext.setLeftRows((Object[]) computeNext.getLeftEntry()[1]); + computeNext.setRightRows((Object[]) computeNext.getRightEntry()[1]); + computeNext.setLeftIndex(0); + computeNext.setRightIndex(0); + frame.setAuxiliarySlot(shouldContinueSlot, false); + return null; + } + frame.setAuxiliarySlot(shouldContinueSlot, true); + return null; + } + frame.setAuxiliarySlot(shouldContinueSlot, false); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRExistsBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRExistsBodyNode.java new file mode 100644 index 000000000..af52a8662 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRExistsBodyNode.java @@ -0,0 +1,59 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.tryable_nullable.TryableNullable; + +public class OSRExistsBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + private final int generatorSlot; + private final int functionSlot; + private final int predicateResultSlot; + + public OSRExistsBodyNode(int generatorSlot, int functionSlot, int predicateResultSlot) { + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.predicateResultSlot = predicateResultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + Object function = frame.getObject(functionSlot); + boolean result = + TryableNullable.handlePredicate( + functionExecuteOneNode.execute(this, function, nextNode.execute(this, generator)), + false); + frame.setBoolean(predicateResultSlot, result); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRJoinNextBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRJoinNextBodyNode.java new file mode 100644 index 000000000..0a4d33587 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRJoinNextBodyNode.java @@ -0,0 +1,150 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.esotericsoftware.kryo.io.Input; +import com.oracle.truffle.api.CompilerDirectives; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.Node; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.exceptions.BreakException; +import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations.JoinComputeNext; +import raw.runtime.truffle.runtime.kryo.KryoNodes; +import raw.runtime.truffle.runtime.kryo.KryoNodesFactory; +import raw.runtime.truffle.tryable_nullable.TryableNullable; + +public class OSRJoinNextBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteTwo functionExecuteTwoNode = + FunctionExecuteNodesFactory.FunctionExecuteTwoNodeGen.create(); + + @Child KryoNodes.KryoReadNode kryoReadNode = KryoNodesFactory.KryoReadNodeGen.create(); + + private final int computeNextSlot; + private final int shouldContinueSlot; + private final int resultSlot; + + public OSRJoinNextBodyNode(int computeNextSlot, int shouldContinueSlot, int resultSlot) { + this.computeNextSlot = computeNextSlot; + this.shouldContinueSlot = shouldContinueSlot; + this.resultSlot = resultSlot; + } + + @CompilerDirectives.TruffleBoundary + private Input createInput(File file, Node node) { + try { + return new Input(new FileInputStream(file)); + } catch (FileNotFoundException e) { + throw new RawTruffleRuntimeException(e.getMessage(), e, node); + } + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object row = null; + JoinComputeNext computeNext = (JoinComputeNext) frame.getAuxiliarySlot(computeNextSlot); + if (computeNext.getLeftRow() == null || computeNext.getRightRow() == null) { + if (computeNext.getLeftRow() == null) { + if (hasNextNode.execute(this, computeNext.getLeftGen())) { + computeNext.setLeftRow(nextNode.execute(this, computeNext.getLeftGen())); + } else { + // end of left, nothing else to read + throw new BreakException(); + } + } + if (computeNext.getKryoRight() == null) { + computeNext.setKryoRight(createInput(computeNext.getDiskRight(), this)); + computeNext.setReadRight(0); + } + if (computeNext.getRightRow() == null) { + if (computeNext.getReadRight() < computeNext.getSpilledRight()) { + computeNext.setRightRow( + kryoReadNode.execute( + this, + computeNext.getLanguage(), + computeNext.getKryoRight(), + computeNext.getRightRowType())); + boolean pass; + if (computeNext.getReshapeBeforePredicate()) { + row = + functionExecuteTwoNode.execute( + this, + computeNext.getRemap(), + computeNext.getLeftRow(), + computeNext.getRightRow()); + pass = + TryableNullable.handlePredicate( + functionExecuteOneNode.execute(this, computeNext.getPredicate(), row), false); + if (!pass) row = null; + } else { + pass = + TryableNullable.handlePredicate( + functionExecuteTwoNode.execute( + this, + computeNext.getPredicate(), + computeNext.getLeftRow(), + computeNext.getRightRow()), + false); + if (pass) + row = + functionExecuteTwoNode.execute( + this, + computeNext.getRemap(), + computeNext.getLeftRow(), + computeNext.getRightRow()); + } + + computeNext.setReadRight(computeNext.getReadRight() + 1); + computeNext.setRightRow(null); + } else { + // end of right, reset currentLeft to make sure we try another round + computeNext.setLeftRow(null); + computeNext.getKryoRight().close(); + computeNext.setRightRow(null); + computeNext.setKryoRight(null); + } + } + } + if (row != null) { + frame.setAuxiliarySlot(shouldContinueSlot, false); + frame.setAuxiliarySlot(resultSlot, row); + } + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListEquiJoinInitBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListEquiJoinInitBodyNode.java new file mode 100644 index 000000000..ee9dad301 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListEquiJoinInitBodyNode.java @@ -0,0 +1,63 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodes; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodesFactory; + +public class OSRListEquiJoinInitBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + @Child + OffHeapNodes.OffHeapGroupByPutNode putNode = + OffHeapNodesFactory.OffHeapGroupByPutNodeGen.create(); + + private final int generatorSlot; + private final int keyFunctionSlot; + private final int mapSlot; + + public OSRListEquiJoinInitBodyNode(int generatorSlot, int keyFunctionSlot, int mapSlot) { + this.generatorSlot = generatorSlot; + this.keyFunctionSlot = keyFunctionSlot; + this.mapSlot = mapSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + Object keyFunc = frame.getObject(keyFunctionSlot); + Object map = frame.getObject(mapSlot); + Object item = nextNode.execute(this, generator); + Object key = functionExecuteOneNode.execute(this, keyFunc, item); + putNode.execute(this, map, key, item); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListFilterBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListFilterBodyNode.java new file mode 100644 index 000000000..819bbfafe --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListFilterBodyNode.java @@ -0,0 +1,64 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import java.util.ArrayList; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.tryable_nullable.TryableNullable; + +public class OSRListFilterBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + private final int generatorSlot; + private final int functionSlot; + private final int llistSlot; + + public OSRListFilterBodyNode(int generatorSlot, int functionSlot, int llistSlot) { + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.llistSlot = llistSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + Object v = nextNode.execute(this, generator); + Boolean predicate = null; + Object function = frame.getObject(functionSlot); + predicate = + TryableNullable.handlePredicate(functionExecuteOneNode.execute(this, function, v), false); + if (predicate) { + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(llistSlot); + llist.add(v); + } + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListFromBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListFromBodyNode.java new file mode 100644 index 000000000..486b620bf --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListFromBodyNode.java @@ -0,0 +1,48 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import java.util.ArrayList; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRListFromBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + private final int generatorSlot; + private final int llistSlot; + + public OSRListFromBodyNode(int generatorSlot, int llistSlot) { + this.generatorSlot = generatorSlot; + this.llistSlot = llistSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(llistSlot); + llist.add(nextNode.execute(this, generator)); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListParseJsonBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListParseJsonBodyNode.java new file mode 100644 index 000000000..0be92ba6e --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListParseJsonBodyNode.java @@ -0,0 +1,48 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.DirectCallNode; +import java.util.ArrayList; +import raw.runtime.truffle.ExpressionNode; + +public class OSRListParseJsonBodyNode extends ExpressionNode { + + @Child DirectCallNode childCallNode; + + private final int llistSlot; + private final int parserSlot; + + public OSRListParseJsonBodyNode( + RootCallTarget childRootCallTarget, int llistSlot, int parserSlot) { + this.childCallNode = DirectCallNode.create(childRootCallTarget); + this.llistSlot = llistSlot; + this.parserSlot = parserSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object parser = frame.getObject(parserSlot); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(llistSlot); + llist.add(childCallNode.call(parser)); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListTransformBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListTransformBodyNode.java new file mode 100644 index 000000000..1c712c08a --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRListTransformBodyNode.java @@ -0,0 +1,70 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodes; +import raw.runtime.truffle.ast.expressions.iterable.ArrayOperationNodesFactory; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.list.ListNodes; +import raw.runtime.truffle.runtime.list.ListNodesFactory; + +public class OSRListTransformBodyNode extends ExpressionNode { + + @Child + FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + @Child ListNodes.GetNode getNode = ListNodesFactory.GetNodeGen.create(); + + @Child + ArrayOperationNodes.ArraySetArrayItemNode arraySetNode = + ArrayOperationNodesFactory.ArraySetArrayItemNodeGen.create(); + + private final int listSlot; + private final int functionSlot; + private final int currentIdxSlot; + private final int resultSlot; + + public OSRListTransformBodyNode( + int listSlot, int functionSlot, int currentIdxSlot, int resultSlot) { + this.currentIdxSlot = currentIdxSlot; + this.resultSlot = resultSlot; + this.listSlot = listSlot; + this.functionSlot = functionSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + int currentIdx = frame.getInt(currentIdxSlot); + Object transformFunction = frame.getObject(functionSlot); + Object transformingList = frame.getObject(listSlot); + Object resultArray = frame.getObject(resultSlot); + + Object transformedItem = + functionExecuteOneNode.execute( + this, transformFunction, getNode.execute(this, transformingList, currentIdx)); + + arraySetNode.execute(this, resultArray, transformedItem, currentIdx); + + frame.setInt(currentIdxSlot, currentIdx + 1); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRMultiAggregationBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRMultiAggregationBodyNode.java new file mode 100644 index 000000000..60866c4f2 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRMultiAggregationBodyNode.java @@ -0,0 +1,56 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.expressions.aggregation.AggregatorNodes; +import raw.runtime.truffle.ast.expressions.aggregation.AggregatorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRMultiAggregationBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child AggregatorNodes.Merge mergeNode = AggregatorNodesFactory.MergeNodeGen.create(); + + private final byte[] aggregationTypes; + private final int resultSlot; + private final int generatorSlot; + + public OSRMultiAggregationBodyNode(byte[] aggregationTypes, int generatorSlot, int resultSlot) { + this.resultSlot = resultSlot; + this.generatorSlot = generatorSlot; + this.aggregationTypes = aggregationTypes; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + Object next = nextNode.execute(this, generator); + Object[] currentResults = (Object[]) frame.getObject(resultSlot); + for (int i = 0; i < aggregationTypes.length; i++) { + currentResults[i] = mergeNode.execute(this, aggregationTypes[i], currentResults[i], next); + } + frame.setObject(resultSlot, currentResults); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSROrderByGetGeneratorNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSROrderByGetGeneratorNode.java new file mode 100644 index 000000000..9f8429a40 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSROrderByGetGeneratorNode.java @@ -0,0 +1,77 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.FrameDescriptor; +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.runtime.function.FunctionExecuteNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodes; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.OffHeapNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.order_by.OffHeapGroupByKeys; +import raw.runtime.truffle.runtime.iterable.operations.OrderByCollection; + +public class OSROrderByGetGeneratorNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child + OffHeapNodes.OffHeapGroupByPutNode putNode = + OffHeapNodesFactory.OffHeapGroupByPutNodeGen.create(); + + @Child + private FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode = + FunctionExecuteNodesFactory.FunctionExecuteOneNodeGen.create(); + + private final int generatorSlot; + private final int collectionSlot; + private final int offHeapGroupByKeysSlot; + + public OSROrderByGetGeneratorNode( + int generatorSlot, int collectionSlot, int offHeapGroupByKeysSlot) { + this.generatorSlot = generatorSlot; + this.collectionSlot = collectionSlot; + this.offHeapGroupByKeysSlot = offHeapGroupByKeysSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + FrameDescriptor frameDescriptor = frame.getFrameDescriptor(); + Object generator = frame.getAuxiliarySlot(generatorSlot); + + OrderByCollection collection = (OrderByCollection) frame.getAuxiliarySlot(collectionSlot); + + OffHeapGroupByKeys groupByKeys = + (OffHeapGroupByKeys) frame.getAuxiliarySlot(offHeapGroupByKeysSlot); + + int funLen = collection.getKeyFunctions().length; + + Object v = nextNode.execute(this, generator); + Object[] key = new Object[funLen]; + for (int i = 0; i < funLen; i++) { + key[i] = functionExecuteOneNode.execute(this, collection.getKeyFunctions()[i], v); + } + putNode.execute(this, groupByKeys, key, v); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRSingleAggregationBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRSingleAggregationBodyNode.java new file mode 100644 index 000000000..b1c1af1a6 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRSingleAggregationBodyNode.java @@ -0,0 +1,54 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.expressions.aggregation.AggregatorNodes; +import raw.runtime.truffle.ast.expressions.aggregation.AggregatorNodesFactory; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRSingleAggregationBodyNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorNextNode nextNode = + GeneratorNodesFactory.GeneratorNextNodeGen.create(); + + @Child AggregatorNodes.Merge mergeNode = AggregatorNodesFactory.MergeNodeGen.create(); + + private final byte aggregationType; + private final int resultSlot; + private final int generatorSlot; + + public OSRSingleAggregationBodyNode(byte aggregationType, int generatorSlot, int resultSlot) { + this.resultSlot = resultSlot; + this.generatorSlot = generatorSlot; + this.aggregationType = aggregationType; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + Object next = nextNode.execute(this, generator); + Object currentResult = frame.getObject(resultSlot); + Object newResult = mergeNode.execute(this, aggregationType, currentResult, next); + frame.setObject(resultSlot, newResult); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRToArrayBodyNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRToArrayBodyNode.java new file mode 100644 index 000000000..b20f81438 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/bodies/OSRToArrayBodyNode.java @@ -0,0 +1,72 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.bodies; + +import com.oracle.truffle.api.frame.VirtualFrame; +import java.util.ArrayList; +import raw.compiler.rql2.source.Rql2Type; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.TypeGuards; + +public class OSRToArrayBodyNode extends ExpressionNode { + + private final Rql2Type resultType; + + private final int listSlot; + + private final int currentIdxSlot; + + private final int resultSlot; + + public OSRToArrayBodyNode(Rql2Type resultType, int listSlot, int currentIdxSlot, int resultSlot) { + this.resultType = resultType; + this.currentIdxSlot = currentIdxSlot; + this.resultSlot = resultSlot; + this.listSlot = listSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + int currentIdx = frame.getInt(currentIdxSlot); + Object result = frame.getObject(resultSlot); + @SuppressWarnings("unchecked") + ArrayList llist = (ArrayList) frame.getObject(listSlot); + + if (TypeGuards.isByteKind(resultType)) { + ((byte[]) result)[currentIdx] = (byte) llist.get(currentIdx); + } else if (TypeGuards.isShortKind(resultType)) { + ((short[]) result)[currentIdx] = (short) llist.get(currentIdx); + } else if (TypeGuards.isIntKind(resultType)) { + ((int[]) result)[currentIdx] = (int) llist.get(currentIdx); + } else if (TypeGuards.isLongKind(resultType)) { + ((long[]) result)[currentIdx] = (long) llist.get(currentIdx); + } else if (TypeGuards.isFloatKind(resultType)) { + ((float[]) result)[currentIdx] = (float) llist.get(currentIdx); + } else if (TypeGuards.isDoubleKind(resultType)) { + ((double[]) result)[currentIdx] = (double) llist.get(currentIdx); + } else if (TypeGuards.isBooleanKind(resultType)) { + ((boolean[]) result)[currentIdx] = (boolean) llist.get(currentIdx); + } else if (TypeGuards.isStringKind(resultType)) { + ((String[]) result)[currentIdx] = (String) llist.get(currentIdx); + } else { + ((Object[]) result)[currentIdx] = llist.get(currentIdx); + } + frame.setInt(currentIdxSlot, currentIdx + 1); + return null; + } + + @Override + public void executeVoid(VirtualFrame virtualFrame) { + executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRCollectionFilterConditionNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRCollectionFilterConditionNode.java new file mode 100644 index 000000000..1672ddbd5 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRCollectionFilterConditionNode.java @@ -0,0 +1,47 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRCollectionFilterConditionNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + private final int generatorSlot; + + private final int resultSlot; + + public OSRCollectionFilterConditionNode(int generatorSlot, int resultSlot) { + this.generatorSlot = generatorSlot; + this.resultSlot = resultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getAuxiliarySlot(generatorSlot); + Object result = frame.getAuxiliarySlot(resultSlot); + return result == null && hasNextNode.execute(this, generator); + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRExistsConditionNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRExistsConditionNode.java new file mode 100644 index 000000000..733e21813 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRExistsConditionNode.java @@ -0,0 +1,46 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRExistsConditionNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + private final int generatorSlot; + + private final int predicateResultSlot; + + public OSRExistsConditionNode(int generatorSlot, int predicateResultSlot) { + this.generatorSlot = generatorSlot; + this.predicateResultSlot = predicateResultSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + return !frame.getBoolean(predicateResultSlot) + && hasNextNode.execute(this, frame.getObject(generatorSlot)); + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRFromBodyConditionNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRFromBodyConditionNode.java new file mode 100644 index 000000000..445626145 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRFromBodyConditionNode.java @@ -0,0 +1,36 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; + +public class OSRFromBodyConditionNode extends ExpressionNode { + + private final int shouldContinueSlot; + + public OSRFromBodyConditionNode(int shouldContinueSlot) { + this.shouldContinueSlot = shouldContinueSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + return frame.getAuxiliarySlot(shouldContinueSlot); + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRHasNextConditionAuxNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRHasNextConditionAuxNode.java new file mode 100644 index 000000000..438428849 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRHasNextConditionAuxNode.java @@ -0,0 +1,43 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRHasNextConditionAuxNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + private final int generatorSlot; + + public OSRHasNextConditionAuxNode(int generatorSlot) { + this.generatorSlot = generatorSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getAuxiliarySlot(generatorSlot); + return hasNextNode.execute(this, generator); + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRHasNextConditionNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRHasNextConditionNode.java new file mode 100644 index 000000000..f4fb2d1e5 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRHasNextConditionNode.java @@ -0,0 +1,43 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; +import raw.runtime.truffle.runtime.generator.collection.GeneratorNodesFactory; + +public class OSRHasNextConditionNode extends ExpressionNode { + + @Child + private GeneratorNodes.GeneratorHasNextNode hasNextNode = + GeneratorNodesFactory.GeneratorHasNextNodeGen.create(); + + private final int generatorSlot; + + public OSRHasNextConditionNode(int generatorSlot) { + this.generatorSlot = generatorSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + Object generator = frame.getObject(generatorSlot); + return hasNextNode.execute(this, generator); + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRIsLessThanSizeConditionNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRIsLessThanSizeConditionNode.java new file mode 100644 index 000000000..ba84f5465 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRIsLessThanSizeConditionNode.java @@ -0,0 +1,40 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; + +public class OSRIsLessThanSizeConditionNode extends ExpressionNode { + + private final int currentIdxSlot; + private final int sizeSlot; + + public OSRIsLessThanSizeConditionNode(int currentIdxSlot, int listSizeSlot) { + this.currentIdxSlot = currentIdxSlot; + this.sizeSlot = listSizeSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + int currentIdx = frame.getInt(currentIdxSlot); + int listSize = frame.getInt(sizeSlot); + return currentIdx < listSize; + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRListParseJsonConditionNode.java b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRListParseJsonConditionNode.java new file mode 100644 index 000000000..9152c4296 --- /dev/null +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/ast/osr/conditions/OSRListParseJsonConditionNode.java @@ -0,0 +1,45 @@ +/* + * Copyright 2023 RAW Labs S.A. + * + * Use of this software is governed by the Business Source License + * included in the file licenses/BSL.txt. + * + * As of the Change Date specified in that file, in accordance with + * the Business Source License, use of this software will be governed + * by the Apache License, Version 2.0, included in the file + * licenses/APL.txt. + */ + +package raw.runtime.truffle.ast.osr.conditions; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonToken; +import com.oracle.truffle.api.frame.VirtualFrame; +import com.oracle.truffle.api.nodes.UnexpectedResultException; +import raw.runtime.truffle.ExpressionNode; +import raw.runtime.truffle.ast.io.json.reader.JsonParserNodes; +import raw.runtime.truffle.ast.io.json.reader.JsonParserNodesFactory; + +public class OSRListParseJsonConditionNode extends ExpressionNode { + + @Child + JsonParserNodes.CurrentTokenJsonParserNode currentToken = + JsonParserNodesFactory.CurrentTokenJsonParserNodeGen.create(); + + private final int parserSlot; + + public OSRListParseJsonConditionNode(int parserSlot) { + this.parserSlot = parserSlot; + } + + @Override + public Object executeGeneric(VirtualFrame frame) { + JsonParser parser = (JsonParser) frame.getObject(parserSlot); + return currentToken.execute(this, parser) != JsonToken.END_ARRAY; + } + + @Override + public boolean executeBoolean(VirtualFrame virtualFrame) throws UnexpectedResultException { + return (boolean) executeGeneric(virtualFrame); + } +} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/AggregationNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/AggregationNodes.java deleted file mode 100644 index c2bf17c41..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/AggregationNodes.java +++ /dev/null @@ -1,96 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.runtime.aggregation; - -import com.oracle.truffle.api.dsl.*; -import com.oracle.truffle.api.nodes.Node; -import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.runtime.aggregation.aggregator.AggregatorNodes; -import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; -import raw.runtime.truffle.runtime.iterable.IterableNodes; - -public class AggregationNodes { - @NodeInfo(shortName = "Aggregation.Aggregate") - @GenerateUncached - @GenerateInline - public abstract static class Aggregate extends Node { - - public abstract Object execute(Node node, Object aggregation, Object iterable); - - @Specialization - static Object aggregate( - Node node, - SingleAggregation aggregation, - Object iterable, - @Bind("$node") Node thisNode, - @Cached @Cached.Shared("getGenerator") IterableNodes.GetGeneratorNode getGenerator, - @Cached @Cached.Shared("init") GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached @Cached.Shared("hasNext") GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached @Cached.Shared("next") GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode generatorCloseNode, - @Cached @Cached.Shared("merge") AggregatorNodes.Merge mergeNode, - @Cached @Cached.Shared("zero") AggregatorNodes.Zero zeroNode) { - Object generator = getGenerator.execute(thisNode, iterable); - try { - generatorInitNode.execute(thisNode, generator); - if (!generatorHasNextNode.execute(thisNode, generator)) { - return zeroNode.execute(thisNode, aggregation.getAggregationType()); - } - Object result = zeroNode.execute(thisNode, aggregation.getAggregationType()); - while (generatorHasNextNode.execute(thisNode, generator)) { - Object next = generatorNextNode.execute(thisNode, generator); - result = mergeNode.execute(thisNode, aggregation.getAggregationType(), result, next); - } - return result; - } finally { - generatorCloseNode.execute(thisNode, generator); - } - } - - @Specialization - static Object aggregate( - Node node, - MultiAggregation aggregation, - Object iterable, - @Bind("$node") Node thisNode, - @Cached @Cached.Shared("getGenerator") IterableNodes.GetGeneratorNode getGenerator, - @Cached @Cached.Shared("init") GeneratorNodes.GeneratorInitNode generatorInitNode, - @Cached @Cached.Shared("hasNext") GeneratorNodes.GeneratorHasNextNode generatorHasNextNode, - @Cached @Cached.Shared("next") GeneratorNodes.GeneratorNextNode generatorNextNode, - @Cached @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode generatorCloseNode, - @Cached @Cached.Shared("merge") AggregatorNodes.Merge mergeNode, - @Cached @Cached.Shared("zero") AggregatorNodes.Zero zeroNode) { - Object generator = getGenerator.execute(thisNode, iterable); - try { - generatorInitNode.execute(thisNode, generator); - Object[] results = new Object[aggregation.getAggregationTypes().length]; - for (int i = 0; i < aggregation.getAggregationTypes().length; i++) { - results[i] = zeroNode.execute(thisNode, aggregation.getAggregationTypes()[i]); - } - if (!generatorHasNextNode.execute(thisNode, generator)) { - return results; - } - while (generatorHasNextNode.execute(thisNode, generator)) { - Object next = generatorNextNode.execute(thisNode, generator); - for (int i = 0; i < aggregation.getAggregationTypes().length; i++) { - results[i] = - mergeNode.execute(thisNode, aggregation.getAggregationTypes()[i], results[i], next); - } - } - return results; - } finally { - generatorCloseNode.execute(thisNode, generator); - } - } - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/MultiAggregation.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/MultiAggregation.java deleted file mode 100644 index 3544e702f..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/MultiAggregation.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.runtime.aggregation; - -public class MultiAggregation { - private final byte[] aggregationTypes; - - public MultiAggregation(byte[] aggregationTypes) { - this.aggregationTypes = aggregationTypes; - } - - public byte[] getAggregationTypes() { - return aggregationTypes; - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/SingleAggregation.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/SingleAggregation.java deleted file mode 100644 index 82c64fa08..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/aggregation/SingleAggregation.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.runtime.aggregation; - -public class SingleAggregation { - private final byte aggregationType; - - public SingleAggregation(byte aggregationType) { - this.aggregationType = aggregationType; - } - - public byte getAggregationType() { - return aggregationType; - } -} diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/ComputeNextNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/ComputeNextNodes.java index b0f9260a7..be281f826 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/ComputeNextNodes.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/ComputeNextNodes.java @@ -17,10 +17,13 @@ import com.fasterxml.jackson.core.JsonToken; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; import com.oracle.truffle.api.RootCallTarget; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.Frame; import com.oracle.truffle.api.interop.*; import com.oracle.truffle.api.library.CachedLibrary; import com.oracle.truffle.api.nodes.DirectCallNode; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; import java.io.File; @@ -30,6 +33,11 @@ import raw.runtime.truffle.ast.io.csv.reader.CsvParserNodes; import raw.runtime.truffle.ast.io.json.reader.JsonParserNodes; import raw.runtime.truffle.ast.io.xml.parser.RawTruffleXmlParser; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.*; +import raw.runtime.truffle.ast.osr.conditions.OSRCollectionFilterConditionNode; +import raw.runtime.truffle.ast.osr.conditions.OSRFromBodyConditionNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionAuxNode; import raw.runtime.truffle.runtime.exceptions.BreakException; import raw.runtime.truffle.runtime.exceptions.RawTruffleInternalErrorException; import raw.runtime.truffle.runtime.exceptions.RawTruffleRuntimeException; @@ -46,8 +54,6 @@ import raw.runtime.truffle.runtime.generator.collection.off_heap_generator.off_heap.group_by.OffHeapGroupByKey; import raw.runtime.truffle.runtime.iterable.IterableNodes; import raw.runtime.truffle.runtime.iterable.sources.EmptyCollection; -import raw.runtime.truffle.runtime.kryo.KryoNodes; -import raw.runtime.truffle.runtime.operators.OperatorNodes; import raw.runtime.truffle.runtime.record.RecordObject; import raw.runtime.truffle.tryable_nullable.TryableNullable; import raw.runtime.truffle.utils.RawTruffleStringCharStream; @@ -243,26 +249,37 @@ static Object next(Node node, EmptyComputeNext computeNext) { throw new BreakException(); } + public static LoopNode getFilterLoopNode(FilterComputeNext computeNext) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRCollectionFilterConditionNode( + computeNext.getGeneratorSlot(), computeNext.getResultSlot()), + new OSRCollectionFilterBodyNode( + computeNext.getGeneratorSlot(), + computeNext.getFunctionSlot(), + computeNext.getResultSlot()))); + } + @Specialization static Object next( Node node, FilterComputeNext computeNext, @Bind("$node") Node thisNode, - @Cached @Cached.Shared("hasNext1") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = false) @Cached.Shared("next1") GeneratorNodes.GeneratorNextNode nextNode, - @Cached @Cached.Shared("executeOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { - while (hasNextNode.execute(thisNode, computeNext.getParent())) { - Object v = nextNode.execute(thisNode, computeNext.getParent()); - Boolean isPredicateTrue = null; - isPredicateTrue = - TryableNullable.handlePredicate( - functionExecuteOneNode.execute(thisNode, computeNext.getPredicate(), v), false); - if (isPredicateTrue) { - return v; - } + @Cached( + value = "getFilterLoopNode(computeNext)", + inline = false, + allowUncached = true, + neverDefault = true) + LoopNode loopNode) { + Frame frame = computeNext.getFrame(); + frame.setAuxiliarySlot(computeNext.getResultSlot(), null); + loopNode.execute(computeNext.getFrame()); + Object result = frame.getAuxiliarySlot(computeNext.getResultSlot()); + if (result == null) { + throw new BreakException(); } - throw new BreakException(); + return result; } @Specialization @@ -365,62 +382,36 @@ static Object next( } } + public static LoopNode getEquiJoinNextLoopNode(EquiJoinComputeNext computeNext) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRFromBodyConditionNode(computeNext.getShouldContinueSlot()), + new OSREquiJoinNextBodyNode( + computeNext.getComputeNextSlot(), computeNext.getShouldContinueSlot()))); + } + @Specialization static Object next( Node node, EquiJoinComputeNext computeNext, @Bind("$node") Node thisNode, - @Cached @Cached.Shared("hasNext2") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = false) @Cached.Shared("next2") GeneratorNodes.GeneratorNextNode nextNode, - @Cached OperatorNodes.CompareNode compareKey, - @Cached @Cached.Shared("executeTwo") - FunctionExecuteNodes.FunctionExecuteTwo functionExecuteTwoNode) { + @Cached( + value = "getEquiJoinNextLoopNode(computeNext)", + inline = false, + allowUncached = true) + LoopNode loopNode, + @Cached FunctionExecuteNodes.FunctionExecuteTwo functionExecuteTwoNode) { assert (computeNext.getLeftMapGenerator() != null); assert (computeNext.getRightMapGenerator() != null); - // keep iterating until we find matching keys - while (computeNext.getLeftKey() == null || computeNext.getRightKey() == null) { - if (computeNext.getLeftKey() == null) { - if (hasNextNode.execute(thisNode, computeNext.getLeftMapGenerator())) { - computeNext.setLeftEntry( - (Object[]) nextNode.execute(thisNode, computeNext.getLeftMapGenerator())); - computeNext.setLeftKey(computeNext.getLeftEntry()[0]); - } else { - throw new BreakException(); - } - } + Frame frame = computeNext.getFrame(); - if (computeNext.getRightKey() == null) { - if (hasNextNode.execute(thisNode, computeNext.getRightMapGenerator())) { - computeNext.setRightEntry( - (Object[]) nextNode.execute(thisNode, computeNext.getRightMapGenerator())); - computeNext.setRightKey(computeNext.getRightEntry()[0]); - } else { - throw new BreakException(); - } - } + frame.setAuxiliarySlot(computeNext.getComputeNextSlot(), computeNext); + frame.setAuxiliarySlot(computeNext.getShouldContinueSlot(), true); - int compare = - compareKey.execute(thisNode, computeNext.getLeftKey(), computeNext.getRightKey()); - // if keys aren't equal, reset the smallest of both (it will be read in the next - // iteration and - // will be larger) - if (compare < 0) { - computeNext.setLeftKey(null); - } else if (compare > 0) { - computeNext.setRightKey(null); - } else { - // keys are equal, prepare to do the cartesian product between both. - // leftRows and rightRows are the arrays of rows with the same key. - // We'll iterate over them to produce the cartesian product. - computeNext.setLeftRows((Object[]) computeNext.getLeftEntry()[1]); - computeNext.setRightRows((Object[]) computeNext.getRightEntry()[1]); - computeNext.setLeftIndex(0); - computeNext.setRightIndex(0); - break; - } - } + loopNode.execute(computeNext.getFrame()); // record to return Object joinedRow = null; @@ -460,84 +451,31 @@ private static Input createInput(File file, Node node) { } } + public static LoopNode getJoinNextLoopNode(JoinComputeNext computeNext) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRFromBodyConditionNode(computeNext.getShouldContinueSlot()), + new OSRJoinNextBodyNode( + computeNext.getComputeNextSlot(), + computeNext.getShouldContinueSlot(), + computeNext.getResultSlot()))); + } + @Specialization static Object next( Node node, JoinComputeNext computeNext, - @Bind("$node") Node thisNode, - @Cached @Cached.Shared("hasNext2") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = false) @Cached.Shared("next2") GeneratorNodes.GeneratorNextNode nextNode, - @Cached KryoNodes.KryoReadNode kryoReadNode, - @Cached @Cached.Shared("executeOne") FunctionExecuteNodes.FunctionExecuteOne executeOneNode, - @Cached @Cached.Shared("executeTwo") - FunctionExecuteNodes.FunctionExecuteTwo executeTwoNode) { - Object row = null; - - while (row == null) { - if (computeNext.getLeftRow() == null || computeNext.getRightRow() == null) { - if (computeNext.getLeftRow() == null) { - if (hasNextNode.execute(thisNode, computeNext.getLeftGen())) { - computeNext.setLeftRow(nextNode.execute(thisNode, computeNext.getLeftGen())); - } else { - // end of left, nothing else to read - throw new BreakException(); - } - } - if (computeNext.getKryoRight() == null) { - computeNext.setKryoRight(createInput(computeNext.getDiskRight(), thisNode)); - computeNext.setReadRight(0); - } - if (computeNext.getRightRow() == null) { - if (computeNext.getReadRight() < computeNext.getSpilledRight()) { - computeNext.setRightRow( - kryoReadNode.execute( - thisNode, - computeNext.getLanguage(), - computeNext.getKryoRight(), - computeNext.getRightRowType())); - boolean pass; - if (computeNext.getReshapeBeforePredicate()) { - row = - executeTwoNode.execute( - thisNode, - computeNext.getRemap(), - computeNext.getLeftRow(), - computeNext.getRightRow()); - pass = - TryableNullable.handlePredicate( - executeOneNode.execute(thisNode, computeNext.getPredicate(), row), false); - if (!pass) row = null; - } else { - pass = - TryableNullable.handlePredicate( - executeTwoNode.execute( - thisNode, - computeNext.getPredicate(), - computeNext.getLeftRow(), - computeNext.getRightRow()), - false); - if (pass) - row = - executeTwoNode.execute( - thisNode, - computeNext.getRemap(), - computeNext.getLeftRow(), - computeNext.getRightRow()); - } - - computeNext.setReadRight(computeNext.getReadRight() + 1); - computeNext.setRightRow(null); - } else { - // end of right, reset currentLeft to make sure we try another round - computeNext.setLeftRow(null); - computeNext.getKryoRight().close(); - computeNext.setRightRow(null); - computeNext.setKryoRight(null); - } - } - } - } - return row; + @Cached( + value = "getJoinNextLoopNode(computeNext)", + inline = false, + allowUncached = true, + neverDefault = true) + LoopNode loopNode) { + computeNext.getFrame().setAuxiliarySlot(computeNext.getComputeNextSlot(), computeNext); + computeNext.getFrame().setAuxiliarySlot(computeNext.getShouldContinueSlot(), true); + loopNode.execute(computeNext.getFrame()); + return computeNext.getFrame().getAuxiliarySlot(computeNext.getResultSlot()); } } @@ -694,6 +632,9 @@ static void init( @Bind("$node") Node thisNode, @Cached(inline = false) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode) { initNode.execute(thisNode, computeNext.getParent()); + Frame frame = computeNext.getFrame(); + frame.setAuxiliarySlot(computeNext.getGeneratorSlot(), computeNext.getParent()); + frame.setAuxiliarySlot(computeNext.getFunctionSlot(), computeNext.getPredicate()); } @Specialization @@ -734,31 +675,43 @@ static void init( initNode2.execute(thisNode, computeNext.getParent2()); } + public static LoopNode getEquiJoinInitLoopNode(EquiJoinComputeNext computeNext) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionAuxNode(computeNext.getGeneratorSlot()), + new OSRCollectionEquiJoinInitBodyNode( + computeNext.getGeneratorSlot(), + computeNext.getKeyFunctionSlot(), + computeNext.getMapSlot()))); + } + @Specialization static void init( Node node, EquiJoinComputeNext computeNext, @Bind("$node") Node thisNode, + @Cached( + value = "getEquiJoinInitLoopNode(computeNext)", + inline = false, + allowUncached = true) + LoopNode loopNode1, + @Cached( + value = "getEquiJoinInitLoopNode(computeNext)", + inline = false, + allowUncached = true) + LoopNode loopNode2, @Cached @Cached.Shared("getGenerator") IterableNodes.GetGeneratorNode getGenerator, @Cached(inline = false) @Cached.Shared("init1") GeneratorNodes.GeneratorInitNode initLeftNode, @Cached(inline = false) @Cached.Shared("init2") GeneratorNodes.GeneratorInitNode initRightNode, - @Cached @Cached.Shared("hasNext1") GeneratorNodes.GeneratorHasNextNode hasNextLeftNode, - @SuppressWarnings("truffle-sharing") @Cached - GeneratorNodes.GeneratorHasNextNode hasNextRightNode, - @Cached(inline = false) @Cached.Shared("next1") - GeneratorNodes.GeneratorNextNode nextLeftNode, - @SuppressWarnings("truffle-sharing") @Cached(inline = false) - GeneratorNodes.GeneratorNextNode nextRightNode, @Cached @Cached.Shared("close1") GeneratorNodes.GeneratorCloseNode closeLeftNode, @SuppressWarnings("truffle-sharing") @Cached GeneratorNodes.GeneratorCloseNode closeRightNode, - @Cached OffHeapNodes.OffHeapGroupByPutNode putLeftNode, - @Cached OffHeapNodes.OffHeapGroupByPutNode putRightNode, @Cached OffHeapNodes.OffHeapGeneratorNode offHeapGeneratorLeft, - @Cached OffHeapNodes.OffHeapGeneratorNode offHeapGeneratorRight, - @Cached FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { + @Cached OffHeapNodes.OffHeapGeneratorNode offHeapGeneratorRight) { + Frame frame = computeNext.getFrame(); // left side (get a generator, then fill a map, set leftMapGenerator to the map generator) OffHeapGroupByKey leftMap = new OffHeapGroupByKey( @@ -770,17 +723,15 @@ static void init( Object leftGenerator = getGenerator.execute(thisNode, computeNext.getLeftIterable()); try { initLeftNode.execute(thisNode, leftGenerator); - while (hasNextLeftNode.execute(thisNode, leftGenerator)) { - Object leftItem = nextLeftNode.execute(thisNode, leftGenerator); - Object leftKey = - functionExecuteOneNode.execute(thisNode, computeNext.getLeftKeyF(), leftItem); - putLeftNode.execute(thisNode, leftMap, leftKey, leftItem); - } + frame.setAuxiliarySlot(computeNext.getMapSlot(), leftMap); + frame.setAuxiliarySlot(computeNext.getGeneratorSlot(), leftGenerator); + frame.setAuxiliarySlot(computeNext.getKeyFunctionSlot(), computeNext.getLeftKeyF()); + loopNode1.execute(computeNext.getFrame()); } finally { closeLeftNode.execute(thisNode, leftGenerator); } computeNext.setLeftMapGenerator(offHeapGeneratorLeft.execute(thisNode, leftMap)); - initRightNode.execute(thisNode, computeNext.getLeftMapGenerator()); + initLeftNode.execute(thisNode, computeNext.getLeftMapGenerator()); // same with right side OffHeapGroupByKey rightMap = @@ -793,12 +744,10 @@ static void init( Object rightGenerator = getGenerator.execute(thisNode, computeNext.getRightIterable()); try { initRightNode.execute(thisNode, rightGenerator); - while (hasNextRightNode.execute(thisNode, rightGenerator)) { - Object rightItem = nextRightNode.execute(thisNode, rightGenerator); - Object rightKey = - functionExecuteOneNode.execute(thisNode, computeNext.getRightKeyF(), rightItem); - putRightNode.execute(thisNode, rightMap, rightKey, rightItem); - } + frame.setAuxiliarySlot(computeNext.getMapSlot(), rightMap); + frame.setAuxiliarySlot(computeNext.getGeneratorSlot(), rightGenerator); + frame.setAuxiliarySlot(computeNext.getKeyFunctionSlot(), computeNext.getRightKeyF()); + loopNode2.execute(computeNext.getFrame()); } finally { closeRightNode.execute(thisNode, rightGenerator); } @@ -817,33 +766,46 @@ private static Output createOutput(JoinComputeNext computeNext, Node node) { } } + public static LoopNode getJoinInitLoopNode(JoinComputeNext computeNext) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionAuxNode(computeNext.getGeneratorSlot()), + new OSRCollectionJoinInitBodyNode( + computeNext.getGeneratorSlot(), + computeNext.getComputeNextSlot(), + computeNext.getOutputBufferSlot()))); + } + @Specialization static void init( Node node, JoinComputeNext computeNext, @Bind("$node") Node thisNode, + @Cached( + value = "getJoinInitLoopNode(computeNext)", + inline = false, + allowUncached = true, + neverDefault = true) + LoopNode loopNode, @Cached @Cached.Shared("getGenerator") IterableNodes.GetGeneratorNode getGeneratorNode, @Cached(inline = false) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached @Cached.Shared("hasNext1") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached(inline = false) @Cached.Shared("next1") GeneratorNodes.GeneratorNextNode nextNode, - @Cached @Cached.Shared("close1") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached KryoNodes.KryoWriteNode kryoWrite) { - // initialize left - computeNext.setLeftGen(getGeneratorNode.execute(thisNode, computeNext.getLeftIterable())); - initNode.execute(thisNode, computeNext.getLeftGen()); - + @Cached @Cached.Shared("close1") GeneratorNodes.GeneratorCloseNode closeNode) { // save right to disk Object rightGen = getGeneratorNode.execute(thisNode, computeNext.getRightIterable()); try (Output buffer = createOutput(computeNext, thisNode)) { initNode.execute(thisNode, rightGen); - while (hasNextNode.execute(thisNode, rightGen)) { - Object row = nextNode.execute(thisNode, rightGen); - kryoWrite.execute(thisNode, buffer, computeNext.getRightRowType(), row); - computeNext.setSpilledRight(computeNext.getSpilledRight() + 1); - } + Frame frame = computeNext.getFrame(); + frame.setAuxiliarySlot(computeNext.getGeneratorSlot(), rightGen); + frame.setAuxiliarySlot(computeNext.getOutputBufferSlot(), buffer); + frame.setAuxiliarySlot(computeNext.getComputeNextSlot(), computeNext); + loopNode.execute(computeNext.getFrame()); } finally { closeNode.execute(thisNode, rightGen); } + // initialize left + computeNext.setLeftGen(getGeneratorNode.execute(thisNode, computeNext.getLeftIterable())); + initNode.execute(thisNode, computeNext.getLeftGen()); } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/EquiJoinComputeNext.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/EquiJoinComputeNext.java index 9a1f74e18..13c1b7b4e 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/EquiJoinComputeNext.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/EquiJoinComputeNext.java @@ -12,6 +12,7 @@ package raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations; +import com.oracle.truffle.api.frame.MaterializedFrame; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.runtime.truffle.RawLanguage; import raw.sources.api.SourceContext; @@ -30,6 +31,12 @@ public class EquiJoinComputeNext { private int leftIndex = -1, rightIndex = -1; private Object leftKey = null, rightKey = null; private Object[] leftRows = null, rightRows = null; + private final MaterializedFrame frame; + private final int computeNextSlot; + private final int shouldContinueSlot; + private final int generatorSlot; + private final int keyFunctionSlot; + private final int mapSlot; public EquiJoinComputeNext( Object leftIterable, @@ -41,7 +48,13 @@ public EquiJoinComputeNext( Rql2TypeWithProperties keyType, Object mkJoinedRecord, RawLanguage language, - SourceContext context) { + SourceContext context, + MaterializedFrame frame, + int computeNextSlot, + int shouldContinueSlot, + int generatorSlot, + int keyFunctionSlot, + int mapSlot) { this.leftIterable = leftIterable; this.leftKeyF = leftKeyF; this.leftRowType = leftRowType; @@ -52,6 +65,12 @@ public EquiJoinComputeNext( this.mkJoinedRecord = mkJoinedRecord; this.language = language; this.context = context; + this.frame = frame; + this.computeNextSlot = computeNextSlot; + this.shouldContinueSlot = shouldContinueSlot; + this.generatorSlot = generatorSlot; + this.keyFunctionSlot = keyFunctionSlot; + this.mapSlot = mapSlot; } public Object getLeftIterable() { @@ -173,4 +192,28 @@ public Object[] getRightRows() { public void setRightRows(Object[] rightRows) { this.rightRows = rightRows; } + + public MaterializedFrame getFrame() { + return frame; + } + + public int getComputeNextSlot() { + return computeNextSlot; + } + + public int getShouldContinueSlot() { + return shouldContinueSlot; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getKeyFunctionSlot() { + return keyFunctionSlot; + } + + public int getMapSlot() { + return mapSlot; + } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/FilterComputeNext.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/FilterComputeNext.java index 86c253e45..c74b7ea66 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/FilterComputeNext.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/FilterComputeNext.java @@ -12,13 +12,31 @@ package raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations; +import com.oracle.truffle.api.frame.MaterializedFrame; + public class FilterComputeNext { private final Object parent; private final Object predicate; + private final MaterializedFrame frame; + private final int generatorSlot; + + private final int functionSlot; + + private final int resultSlot; - public FilterComputeNext(Object parent, Object predicate) { + public FilterComputeNext( + Object parent, + Object predicate, + MaterializedFrame frame, + int generatorSlot, + int functionSlot, + int resultSlot) { this.parent = parent; this.predicate = predicate; + this.frame = frame; + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.resultSlot = resultSlot; } public Object getParent() { @@ -28,4 +46,20 @@ public Object getParent() { public Object getPredicate() { return predicate; } + + public MaterializedFrame getFrame() { + return frame; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getFunctionSlot() { + return functionSlot; + } + + public int getResultSlot() { + return resultSlot; + } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/JoinComputeNext.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/JoinComputeNext.java index 45bac583b..fbae829cd 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/JoinComputeNext.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/generator/collection/abstract_generator/compute_next/operations/JoinComputeNext.java @@ -13,7 +13,9 @@ package raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations; import com.esotericsoftware.kryo.io.Input; +import com.oracle.truffle.api.CompilerDirectives.CompilationFinal; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; +import com.oracle.truffle.api.frame.MaterializedFrame; import java.io.File; import raw.compiler.rql2.source.Rql2TypeWithProperties; import raw.runtime.truffle.RawLanguage; @@ -21,25 +23,28 @@ import raw.sources.api.SourceContext; public class JoinComputeNext { + @CompilationFinal private int kryoOutputBufferSize; + @CompilationFinal private File diskRight; protected final Object leftIterable; protected final Object rightIterable; private Object leftGen = null; private final Object remap; private final Object predicate; - private Object leftRow = null; private Object rightRow = null; Input kryoRight = null; - private final int kryoOutputBufferSize; private final Rql2TypeWithProperties rightRowType; // grouped key and value types. private int spilledRight = 0; private int readRight = 0; - private final File diskRight; private final Boolean reshapeBeforePredicate; - private final RawLanguage language; + private final MaterializedFrame frame; + private final int computeNextSlot; + private final int shouldContinueSlot; + private final int resultSlot; + private final int generatorSlot; + private final int outputBufferSlot; - @TruffleBoundary // Needed because of SourceContext public JoinComputeNext( Object leftIterable, Object rightIterable, @@ -48,16 +53,33 @@ public JoinComputeNext( Boolean reshapeBeforePredicate, Rql2TypeWithProperties rightRowType, SourceContext context, - RawLanguage language) { + RawLanguage language, + MaterializedFrame frame, + int computeNextSlot, + int shouldContinueSlot, + int resultSlot, + int generatorSlot, + int outputBufferSlot) { this.leftIterable = leftIterable; this.rightIterable = rightIterable; this.remap = remap; this.predicate = predicate; - this.kryoOutputBufferSize = - (int) context.settings().getMemorySize("raw.runtime.kryo.output-buffer-size"); this.language = language; this.rightRowType = rightRowType; this.reshapeBeforePredicate = reshapeBeforePredicate; + this.frame = frame; + this.computeNextSlot = computeNextSlot; + this.shouldContinueSlot = shouldContinueSlot; + this.resultSlot = resultSlot; + this.generatorSlot = generatorSlot; + this.outputBufferSlot = outputBufferSlot; + init(context); + } + + @TruffleBoundary // Needed because of SourceContext + private void init(SourceContext context) { + this.kryoOutputBufferSize = + (int) context.settings().getMemorySize("raw.runtime.kryo.output-buffer-size"); this.diskRight = IOUtils.getScratchFile("cartesian.", ".kryo", context).toFile(); } @@ -144,4 +166,28 @@ public Boolean getReshapeBeforePredicate() { public RawLanguage getLanguage() { return language; } + + public MaterializedFrame getFrame() { + return frame; + } + + public int getComputeNextSlot() { + return computeNextSlot; + } + + public int getShouldContinueSlot() { + return shouldContinueSlot; + } + + public int getResultSlot() { + return resultSlot; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getOutputBufferSlot() { + return outputBufferSlot; + } } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/IterableNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/IterableNodes.java index d4d6826ed..d66dd647e 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/IterableNodes.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/IterableNodes.java @@ -12,10 +12,18 @@ package raw.runtime.truffle.runtime.iterable; +import com.oracle.truffle.api.Truffle; import com.oracle.truffle.api.dsl.*; +import com.oracle.truffle.api.frame.Frame; +import com.oracle.truffle.api.frame.MaterializedFrame; +import com.oracle.truffle.api.nodes.LoopNode; import com.oracle.truffle.api.nodes.Node; import com.oracle.truffle.api.nodes.NodeInfo; -import raw.runtime.truffle.runtime.function.FunctionExecuteNodes; +import raw.runtime.truffle.ast.osr.OSRGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSRCollectionEquiJoinInitBodyNode; +import raw.runtime.truffle.ast.osr.bodies.OSRDistinctGetGeneratorNode; +import raw.runtime.truffle.ast.osr.bodies.OSROrderByGetGeneratorNode; +import raw.runtime.truffle.ast.osr.conditions.OSRHasNextConditionAuxNode; import raw.runtime.truffle.runtime.generator.collection.GeneratorNodes; import raw.runtime.truffle.runtime.generator.collection.abstract_generator.AbstractGenerator; import raw.runtime.truffle.runtime.generator.collection.abstract_generator.compute_next.operations.*; @@ -110,7 +118,13 @@ static Object getGenerator( IterableNodes.GetGeneratorNode getGeneratorNode) { Object parentGenerator = getGeneratorNode.execute(thisNode, collection.getParentIterable()); return new AbstractGenerator( - new FilterComputeNext(parentGenerator, collection.getPredicate())); + new FilterComputeNext( + parentGenerator, + collection.getPredicate(), + collection.getFrame(), + collection.getGeneratorSlot(), + collection.getFunctionSlot(), + collection.getResultSlot())); } @Specialization @@ -166,18 +180,26 @@ static Object getGenerator( new ZipComputeNext(parentGenerator1, parentGenerator2, collection.getLang())); } + public static LoopNode getDistinctGenLoopNode(DistinctCollection collection) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionAuxNode(collection.getGeneratorSlot()), + new OSRDistinctGetGeneratorNode( + collection.getGeneratorSlot(), collection.getOffHeapDistinctSlot()))); + } + @Specialization static Object getGenerator( Node node, DistinctCollection collection, @Bind("$node") Node thisNode, + @Cached(value = "getDistinctGenLoopNode(collection)", inline = false, allowUncached = true) + LoopNode loopNode, @Cached(inline = false) @Cached.Shared("getGenerator1") IterableNodes.GetGeneratorNode getGeneratorNode, @Cached GeneratorNodes.GeneratorInitNode initNode, - @Cached @Cached.Shared("hasNext") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached @Cached.Shared("next") GeneratorNodes.GeneratorNextNode nextNode, @Cached @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached @Cached.Shared("put") OffHeapNodes.OffHeapGroupByPutNode putNode, @Cached @Cached.Shared("generator") OffHeapNodes.OffHeapGeneratorNode generatorNode) { OffHeapDistinct index = new OffHeapDistinct( @@ -185,10 +207,12 @@ static Object getGenerator( Object generator = getGeneratorNode.execute(thisNode, collection.getIterable()); try { initNode.execute(thisNode, generator); - while (hasNextNode.execute(thisNode, generator)) { - Object next = nextNode.execute(thisNode, generator); - putNode.execute(thisNode, index, next, null); - } + + MaterializedFrame frame = collection.getFrame(); + frame.setAuxiliarySlot(collection.getGeneratorSlot(), generator); + frame.setAuxiliarySlot(collection.getOffHeapDistinctSlot(), index); + + loopNode.execute(frame); } finally { closeNode.execute(thisNode, generator); } @@ -200,21 +224,34 @@ static Object getGenerator(Node node, EquiJoinCollection collection) { return collection.getGenerator(); } + public static LoopNode getEquiJoinInitLoopNode(GroupByCollection collection) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionAuxNode(collection.getGeneratorSlot()), + new OSRCollectionEquiJoinInitBodyNode( + collection.getGeneratorSlot(), + collection.getKeyFunctionSlot(), + collection.getMapSlot()))); + } + @Specialization static Object getGenerator( Node node, GroupByCollection collection, @Bind("$node") Node thisNode, + @Cached( + value = "getEquiJoinInitLoopNode(collection)", + inline = false, + allowUncached = true, + neverDefault = true) + LoopNode loopNode, @Cached(inline = false) @Cached.Shared("getGenerator1") IterableNodes.GetGeneratorNode getGeneratorNode, @Cached(inline = false) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached @Cached.Shared("hasNext") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached @Cached.Shared("next") GeneratorNodes.GeneratorNextNode nextNode, @Cached @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached @Cached.Shared("put") OffHeapNodes.OffHeapGroupByPutNode putNode, - @Cached @Cached.Shared("generator") OffHeapNodes.OffHeapGeneratorNode generatorNode, - @Cached @Cached.Shared("functionOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { + @Cached @Cached.Shared("generator") OffHeapNodes.OffHeapGeneratorNode generatorNode) { + Frame frame = collection.getFrame(); OffHeapGroupByKey map = new OffHeapGroupByKey( collection.getKeyType(), @@ -225,11 +262,10 @@ static Object getGenerator( Object inputGenerator = getGeneratorNode.execute(thisNode, collection.getIterable()); try { initNode.execute(thisNode, inputGenerator); - while (hasNextNode.execute(thisNode, inputGenerator)) { - Object v = nextNode.execute(thisNode, inputGenerator); - Object key = functionExecuteOneNode.execute(thisNode, collection.getKeyFun(), v); - putNode.execute(thisNode, map, key, v); - } + frame.setAuxiliarySlot(collection.getGeneratorSlot(), inputGenerator); + frame.setAuxiliarySlot(collection.getMapSlot(), map); + frame.setAuxiliarySlot(collection.getKeyFunctionSlot(), collection.getKeyFun()); + loopNode.execute(collection.getFrame()); } finally { closeNode.execute(thisNode, inputGenerator); } @@ -241,21 +277,33 @@ static Object getGenerator(Node node, JoinCollection collection) { return collection.getGenerator(); } + public static LoopNode getOrderByGenNode(OrderByCollection collection) { + return Truffle.getRuntime() + .createLoopNode( + new OSRGeneratorNode( + new OSRHasNextConditionAuxNode(collection.getGeneratorSlot()), + new OSROrderByGetGeneratorNode( + collection.getGeneratorSlot(), + collection.getCollectionSlot(), + collection.getOffHeapGroupByKeysSlot()))); + } + @Specialization static Object getGenerator( Node node, OrderByCollection collection, @Bind("$node") Node thisNode, + @Cached( + value = "getOrderByGenNode(collection)", + inline = false, + allowUncached = true, + neverDefault = true) + LoopNode loopNode, @Cached(inline = false) @Cached.Shared("getGenerator1") IterableNodes.GetGeneratorNode getGeneratorNode, @Cached(inline = false) @Cached.Shared("init") GeneratorNodes.GeneratorInitNode initNode, - @Cached @Cached.Shared("hasNext") GeneratorNodes.GeneratorHasNextNode hasNextNode, - @Cached @Cached.Shared("next") GeneratorNodes.GeneratorNextNode nextNode, @Cached @Cached.Shared("close") GeneratorNodes.GeneratorCloseNode closeNode, - @Cached @Cached.Shared("put") OffHeapNodes.OffHeapGroupByPutNode putNode, - @Cached @Cached.Shared("generator") OffHeapNodes.OffHeapGeneratorNode generatorNode, - @Cached @Cached.Shared("functionOne") - FunctionExecuteNodes.FunctionExecuteOne functionExecuteOneNode) { + @Cached @Cached.Shared("generator") OffHeapNodes.OffHeapGeneratorNode generatorNode) { Object generator = getGeneratorNode.execute(thisNode, collection.getParentIterable()); OffHeapGroupByKeys groupByKeys = new OffHeapGroupByKeys( @@ -266,15 +314,13 @@ static Object getGenerator( collection.getContext()); try { initNode.execute(thisNode, generator); - while (hasNextNode.execute(thisNode, generator)) { - Object v = nextNode.execute(thisNode, generator); - int len = collection.getKeyFunctions().length; - Object[] key = new Object[len]; - for (int i = 0; i < len; i++) { - key[i] = functionExecuteOneNode.execute(thisNode, collection.getKeyFunctions()[i], v); - } - putNode.execute(thisNode, groupByKeys, key, v); - } + + Frame frame = collection.getFrame(); + frame.setAuxiliarySlot(collection.getGeneratorSlot(), generator); + frame.setAuxiliarySlot(collection.getOffHeapGroupByKeysSlot(), groupByKeys); + frame.setAuxiliarySlot(collection.getCollectionSlot(), collection); + + loopNode.execute(collection.getFrame()); } finally { closeNode.execute(thisNode, generator); } diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/DistinctCollection.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/DistinctCollection.java index f828befe4..7fa3e32c4 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/DistinctCollection.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/DistinctCollection.java @@ -14,6 +14,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; @@ -28,18 +29,28 @@ @ExportLibrary(InteropLibrary.class) public class DistinctCollection implements TruffleObject { final Object iterable; - final RawLanguage language; - final Rql2TypeWithProperties rowType; private final SourceContext context; + private final MaterializedFrame frame; + private final int generatorSlot; + private final int offHeapDistinctSlot; public DistinctCollection( - Object iterable, Rql2TypeWithProperties vType, RawLanguage language, SourceContext context) { + Object iterable, + Rql2TypeWithProperties vType, + RawLanguage language, + SourceContext context, + MaterializedFrame frame, + int generatorSlot, + int offHeapDistinctSlot) { this.iterable = iterable; this.language = language; this.rowType = vType; this.context = context; + this.frame = frame; + this.generatorSlot = generatorSlot; + this.offHeapDistinctSlot = offHeapDistinctSlot; } public Object getIterable() { @@ -58,6 +69,18 @@ public RawLanguage getLang() { return language; } + public MaterializedFrame getFrame() { + return frame; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getOffHeapDistinctSlot() { + return offHeapDistinctSlot; + } + // InteropLibrary: Iterable @ExportMessage diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/EquiJoinCollection.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/EquiJoinCollection.java index de871281b..21bad0b60 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/EquiJoinCollection.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/EquiJoinCollection.java @@ -14,6 +14,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; @@ -35,6 +36,12 @@ public class EquiJoinCollection implements TruffleObject { final Rql2TypeWithProperties keyType; private final RawLanguage language; private final SourceContext context; + private final MaterializedFrame frame; + private final int computeNextSlot; + private final int shouldContinueSlot; + private final int generatorSlot; + private final int keyFunctionSlot; + private final int mapSlot; public EquiJoinCollection( Object leftIterable, @@ -46,7 +53,13 @@ public EquiJoinCollection( Rql2TypeWithProperties keyType, Object reshapeFun, RawLanguage language, - SourceContext context) { + SourceContext context, + MaterializedFrame frame, + int computeNextSlot, + int shouldContinueSlot, + int generatorSlot, + int keyFunctionSlot, + int mapSlot) { this.leftIterable = leftIterable; this.leftKeyF = leftKeyF; this.leftRowType = leftRowType; @@ -57,6 +70,12 @@ public EquiJoinCollection( this.reshapeFun = reshapeFun; this.language = language; this.context = context; + this.frame = frame; + this.computeNextSlot = computeNextSlot; + this.shouldContinueSlot = shouldContinueSlot; + this.generatorSlot = generatorSlot; + this.keyFunctionSlot = keyFunctionSlot; + this.mapSlot = mapSlot; } public Object getGenerator() { @@ -71,7 +90,13 @@ public Object getGenerator() { keyType, reshapeFun, language, - context)); + context, + frame, + computeNextSlot, + shouldContinueSlot, + generatorSlot, + keyFunctionSlot, + mapSlot)); } @ExportMessage diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/FilterCollection.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/FilterCollection.java index c98bf55cf..8de52370c 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/FilterCollection.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/FilterCollection.java @@ -14,6 +14,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; @@ -26,10 +27,27 @@ public class FilterCollection implements TruffleObject { private final Object parentIterable; private final Object predicate; + private final MaterializedFrame frame; - public FilterCollection(Object iterable, Object predicate) { + private final int generatorSlot; + + private final int functionSlot; + + private final int resultSlot; + + public FilterCollection( + Object iterable, + Object predicate, + MaterializedFrame frame, + int generatorSlot, + int functionSlot, + int resultSlot) { this.parentIterable = iterable; this.predicate = predicate; + this.frame = frame; + this.generatorSlot = generatorSlot; + this.functionSlot = functionSlot; + this.resultSlot = resultSlot; } public Object getParentIterable() { @@ -40,6 +58,22 @@ public Object getPredicate() { return predicate; } + public MaterializedFrame getFrame() { + return frame; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getFunctionSlot() { + return functionSlot; + } + + public int getResultSlot() { + return resultSlot; + } + // InteropLibrary: Iterable @ExportMessage boolean hasIterator() { diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/GroupByCollection.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/GroupByCollection.java index 8e210c504..9fcddd869 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/GroupByCollection.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/GroupByCollection.java @@ -14,6 +14,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; @@ -29,12 +30,14 @@ public class GroupByCollection implements TruffleObject { final Object iterable; final Object keyFun; - final RawLanguage language; - final Rql2TypeWithProperties keyType; final Rql2TypeWithProperties rowType; private final SourceContext context; + private final MaterializedFrame frame; + private final int generatorSlot; + private final int keyFunctionSlot; + private final int mapSlot; public GroupByCollection( Object iterable, @@ -42,13 +45,21 @@ public GroupByCollection( Rql2TypeWithProperties kType, Rql2TypeWithProperties rowType, RawLanguage language, - SourceContext context) { + SourceContext context, + MaterializedFrame frame, + int generatorSlot, + int keyFunctionSlot, + int mapSlot) { this.iterable = iterable; this.keyFun = keyFun; this.language = language; this.keyType = kType; this.rowType = rowType; this.context = context; + this.frame = frame; + this.generatorSlot = generatorSlot; + this.keyFunctionSlot = keyFunctionSlot; + this.mapSlot = mapSlot; } public Object getIterable() { @@ -75,6 +86,22 @@ public RawLanguage getLang() { return language; } + public MaterializedFrame getFrame() { + return frame; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getKeyFunctionSlot() { + return keyFunctionSlot; + } + + public int getMapSlot() { + return mapSlot; + } + // InteropLibrary: Iterable @ExportMessage boolean hasIterator() { diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/JoinCollection.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/JoinCollection.java index 121c2d167..8bf10b66b 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/JoinCollection.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/JoinCollection.java @@ -14,6 +14,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; @@ -36,6 +37,12 @@ public class JoinCollection implements TruffleObject { final SourceContext context; final RawLanguage language; private final Boolean reshapeBeforePredicate; + private final MaterializedFrame frame; + private final int computeNextSlot; + private final int shouldContinueSlot; + private final int resultSlot; + private final int generatorSlot; + private final int outputBufferSlot; public JoinCollection( Object leftIterable, @@ -45,7 +52,13 @@ public JoinCollection( Rql2TypeWithProperties rightType, Boolean reshapeBeforePredicate, SourceContext context, - RawLanguage language) { + RawLanguage language, + MaterializedFrame frame, + int computeNextSlot, + int shouldContinueSlot, + int resultSlot, + int generatorSlot, + int outputBufferSlot) { this.leftIterable = leftIterable; this.rightIterable = rightIterable; this.remap = remap; @@ -54,6 +67,12 @@ public JoinCollection( this.context = context; this.language = language; this.reshapeBeforePredicate = reshapeBeforePredicate; + this.frame = frame; + this.computeNextSlot = computeNextSlot; + this.shouldContinueSlot = shouldContinueSlot; + this.resultSlot = resultSlot; + this.generatorSlot = generatorSlot; + this.outputBufferSlot = outputBufferSlot; } public Object getGenerator() { @@ -66,7 +85,13 @@ public Object getGenerator() { reshapeBeforePredicate, rightType, context, - language)); + language, + frame, + computeNextSlot, + shouldContinueSlot, + resultSlot, + generatorSlot, + outputBufferSlot)); } // InteropLibrary: Iterable diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/OrderByCollection.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/OrderByCollection.java index 55f8d1aaf..b0fd2484a 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/OrderByCollection.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/iterable/operations/OrderByCollection.java @@ -14,6 +14,7 @@ import com.oracle.truffle.api.dsl.Bind; import com.oracle.truffle.api.dsl.Cached; +import com.oracle.truffle.api.frame.MaterializedFrame; import com.oracle.truffle.api.interop.InteropLibrary; import com.oracle.truffle.api.interop.TruffleObject; import com.oracle.truffle.api.library.ExportLibrary; @@ -29,12 +30,15 @@ public class OrderByCollection implements TruffleObject { final Object parentIterable; final Object[] keyFunctions; - final int[] keyOrderings; final Rql2TypeWithProperties[] keyTypes; final Rql2TypeWithProperties rowType; private final RawLanguage language; private final SourceContext context; + private final MaterializedFrame frame; + private final int generatorSlot; + private final int collectionSlot; + private final int offHeapGroupByKeysSlot; public OrderByCollection( Object iterable, @@ -43,7 +47,11 @@ public OrderByCollection( Rql2TypeWithProperties[] keyTypes, Rql2TypeWithProperties rowType, RawLanguage language, - SourceContext context) { + SourceContext context, + MaterializedFrame frame, + int generatorSlot, + int collectionSlot, + int offHeapGroupByKeysSlot) { this.parentIterable = iterable; this.keyFunctions = keyFunctions; this.keyOrderings = keyOrderings; @@ -51,6 +59,10 @@ public OrderByCollection( this.rowType = rowType; this.language = language; this.context = context; + this.frame = frame; + this.generatorSlot = generatorSlot; + this.collectionSlot = collectionSlot; + this.offHeapGroupByKeysSlot = offHeapGroupByKeysSlot; } public Object getParentIterable() { @@ -81,6 +93,22 @@ public RawLanguage getLang() { return language; } + public MaterializedFrame getFrame() { + return frame; + } + + public int getGeneratorSlot() { + return generatorSlot; + } + + public int getCollectionSlot() { + return collectionSlot; + } + + public int getOffHeapGroupByKeysSlot() { + return offHeapGroupByKeysSlot; + } + // InteropLibrary: Iterable @ExportMessage boolean hasIterator() { diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordNodes.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordNodes.java index fddd16e6a..03c29771f 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordNodes.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordNodes.java @@ -34,11 +34,11 @@ static Object exec( Node node, RecordObject record, int idx, - @CachedLibrary("record.values") DynamicObjectLibrary valuesLibrary) { + @CachedLibrary("record") DynamicObjectLibrary valuesLibrary) { if (idx < 0 || idx >= record.keys.size()) { throw new RawTruffleInternalErrorException(InvalidArrayIndexException.create(idx)); } - return valuesLibrary.getOrDefault(record.values, idx, null); + return valuesLibrary.getOrDefault(record, idx, null); } } @@ -74,13 +74,13 @@ static void exec( int idx, String key, Object value, - @CachedLibrary("record.values") DynamicObjectLibrary valuesLibrary) { + @CachedLibrary("record") DynamicObjectLibrary valuesLibrary) { if (idx >= record.keys.size()) { record.keys.setSize(idx + 1); } record.keys.set(idx, key); record.invalidateDistinctKeys(); - valuesLibrary.put(record.values, idx, value); + valuesLibrary.put(record, idx, value); } } @@ -97,9 +97,9 @@ static void exec( RecordObject record, String key, Object value, - @CachedLibrary("record.values") DynamicObjectLibrary valuesLibrary) { + @CachedLibrary("record") DynamicObjectLibrary valuesLibrary) { valuesLibrary.put( - record.values, + record, record.keys.size(), value); // "key" to use in the dynamic object is the current index. addKey(record, key); // the original key is added (possible duplicate) diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordObject.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordObject.java index cf86a8ab5..dcbd613b1 100644 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordObject.java +++ b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordObject.java @@ -29,15 +29,14 @@ import raw.utils.RecordFieldsNaming; @ExportLibrary(InteropLibrary.class) -public final class RecordObject implements TruffleObject { +public final class RecordObject extends DynamicObject implements TruffleObject { public final Vector keys = new Vector<>(); private final Vector distinctKeys; private boolean validDistinctKeys = true; - public final DynamicObject values; public RecordObject(Shape shape) { - this.values = new RecordStorageObject(shape); + super(shape); this.distinctKeys = new Vector<>(); } @@ -136,11 +135,11 @@ boolean isMemberRemovable(String member, @CachedLibrary("this") InteropLibrary r } @ExportMessage - Object readMember(String name, @CachedLibrary("this.values") DynamicObjectLibrary valuesLibrary) + Object readMember(String name, @CachedLibrary("this") DynamicObjectLibrary valuesLibrary) throws UnknownIdentifierException { // Interop API, we assume the searched key should be found in the distinct keys. int idx = getDistinctKeys().indexOf(name); - Object result = valuesLibrary.getOrDefault(values, idx, null); + Object result = valuesLibrary.getOrDefault(this, idx, null); if (result == null) { /* Property does not exist. */ throw UnknownIdentifierException.create(name); @@ -166,8 +165,8 @@ public void writeMember( } @ExportMessage - void removeMember(String name, @CachedLibrary("this.values") DynamicObjectLibrary valuesLibrary) { - valuesLibrary.removeKey(values, name); + void removeMember(String name, @CachedLibrary("this") DynamicObjectLibrary valuesLibrary) { + valuesLibrary.removeKey(this, name); } void invalidateDistinctKeys() { diff --git a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordStorageObject.java b/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordStorageObject.java deleted file mode 100644 index 0d102fce9..000000000 --- a/snapi-truffle/src/main/java/raw/runtime/truffle/runtime/record/RecordStorageObject.java +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2023 RAW Labs S.A. - * - * Use of this software is governed by the Business Source License - * included in the file licenses/BSL.txt. - * - * As of the Change Date specified in that file, in accordance with - * the Business Source License, use of this software will be governed - * by the Apache License, Version 2.0, included in the file - * licenses/APL.txt. - */ - -package raw.runtime.truffle.runtime.record; - -import com.oracle.truffle.api.object.DynamicObject; -import com.oracle.truffle.api.object.Shape; - -// This is an implementation of `DynamicObject` used as an internal storage of our RecordObject. -class RecordStorageObject extends DynamicObject { - - protected RecordStorageObject(Shape shape) { - super(shape); - } -}