-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support of LDC for Strings, including adding trivial string pool
- Loading branch information
1 parent
f8f5d7c
commit 15dd6e7
Showing
15 changed files
with
207 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package samples.javacore.strings.cpool.advanced; | ||
|
||
public class StringPoolAdvanced { | ||
public static void main(String[] args) { | ||
// Example 0: String literals of same class are stored in the string pool | ||
String str1 = "Hello"; | ||
String str2 = "Hello"; | ||
// Both str1 and str2 refer to the same string literal from the pool | ||
int bit0 = str1 == str2 ? 1 : 0; | ||
|
||
// Example 1: Creating a string with new keyword | ||
String str3 = new String("Hello"); | ||
// str3 is created in the heap, not in the string pool | ||
int bit1 = str1 == str3 ? 1 : 0; | ||
|
||
// Example 2: Comparing strings with equals method | ||
int bit2 = str1.equals(str3) ? 1 : 0; | ||
|
||
// Example 3: Concatenation with literals at compile-time | ||
String str5 = "Hel" + "lo"; // Compiler optimizes this to "Hello" | ||
int bit3 = str1 == str5 ? 1 : 0; | ||
|
||
// Example 4: Creating a string in another class | ||
String str4 = new AnotherClass().getAnotherString(); | ||
int bit4 = str1 == str4 ? 1 : 0; | ||
|
||
// Example X: Concatenation with non-literals at runtime | ||
//String part1 = "Hel"; | ||
//String part2 = "lo"; | ||
//String str6 = part1 + part2; // New object is created in the heap | ||
//System.out.println("str1 == str6 : " + (str1 == str6)); // false | ||
|
||
// Example X: Interning the string (forcing it into the pool) | ||
//String str4 = str3.intern(); | ||
// Now str4 refers to the string from the pool | ||
//System.out.println("str1 == str4 : " + (str1 == str4)); // true | ||
|
||
int result = 0; | ||
result = setBit(result, 0, bit0); | ||
result = setBit(result, 1, bit1); | ||
result = setBit(result, 2, bit2); | ||
result = setBit(result, 3, bit3); | ||
result = setBit(result, 4, bit4); | ||
} | ||
|
||
private static int setBit(int num, int position, int value) { | ||
return value == 0 ? num & ~(1 << position) : num | (1 << position); | ||
} | ||
} | ||
|
||
class AnotherClass { | ||
public String getAnotherString() { | ||
return "Hello"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package samples.javacore.strings.cpool.trivial; | ||
|
||
public class TrivialStringsCPool { | ||
public static void main(String[] args) { | ||
String text = "Java is flexible"; | ||
String search = new String("flexible"); | ||
|
||
int index = text.indexOf(search); | ||
} | ||
} |
Binary file added
BIN
+338 Bytes
tests/test_data/samples/javacore/strings/cpool/advanced/AnotherClass.class
Binary file not shown.
Binary file added
BIN
+926 Bytes
tests/test_data/samples/javacore/strings/cpool/advanced/StringPoolAdvanced.class
Binary file not shown.
Binary file added
BIN
+489 Bytes
tests/test_data/samples/javacore/strings/cpool/trivial/TrivialStringsCPool.class
Binary file not shown.
Binary file modified
BIN
+0 Bytes
(100%)
tests/test_data/samples/javacore/strings/trivial/TrivialStrings.class
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
pub(crate) mod engine; | ||
pub(crate) mod ldc_resolution_manager; | ||
pub(crate) mod opcode; | ||
mod string_pool_helper; | ||
mod system_native_table; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
use crate::error::Error; | ||
use crate::execution_engine::engine::Engine; | ||
use crate::heap::heap::{with_heap_read_lock, with_heap_write_lock}; | ||
use crate::method_area::method_area::with_method_area; | ||
|
||
pub struct StringPoolHelper {} | ||
|
||
impl StringPoolHelper { | ||
pub(crate) fn get_string(cpool_string: String) -> crate::error::Result<i32> { | ||
if let Some(value) = with_heap_read_lock(|heap| heap.get_const_string_ref(&cpool_string)) { | ||
return Ok(value); | ||
} | ||
// todo: possible race condition here | ||
let string_ref = Self::create_string(&cpool_string)?; | ||
with_heap_write_lock(|heap| heap.put_const_string_ref(&cpool_string, string_ref)); | ||
Ok(string_ref) | ||
} | ||
|
||
fn create_string(string: &str) -> crate::error::Result<i32> { | ||
let codepoints = Self::string_to_codepoints(&string); | ||
|
||
let array_ref = with_heap_write_lock(|heap| heap.create_array_with_values(&codepoints)); | ||
let string_class_name = "java/lang/String".to_string(); | ||
let instance_with_default_fields = with_method_area(|method_area| { | ||
method_area.create_instance_with_default_fields(&string_class_name) | ||
}); | ||
|
||
let string_instance_ref = | ||
with_heap_write_lock(|heap| heap.create_instance(instance_with_default_fields)); | ||
|
||
let full_signature = "<init>:([III)V"; | ||
let rc = with_method_area(|method_area| method_area.get(string_class_name.as_str()))?; | ||
let special_method = rc | ||
.methods | ||
.method_by_signature | ||
.get(full_signature) | ||
.ok_or_else(|| Error::new_constant_pool(&format!("Error getting JavaMethod by class name {string_class_name} and full signature {full_signature} invoking special")))?; | ||
|
||
let mut engine = Engine::new(); | ||
let mut stack_frame = special_method.new_stack_frame()?; | ||
stack_frame.set_local(0, string_instance_ref); | ||
stack_frame.set_local(1, array_ref); | ||
stack_frame.set_local(2, 0); | ||
stack_frame.set_local(3, codepoints.len() as i32); | ||
|
||
engine.execute(stack_frame)?; | ||
|
||
// todo: ensure that array_ref is collected by GC | ||
Ok(string_instance_ref) | ||
} | ||
|
||
fn string_to_codepoints(s: &str) -> Vec<i32> { | ||
s.chars().map(|c| c as i32).collect() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters