about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMarijn Haverbeke <marijnh@gmail.com>2011-08-29 22:46:25 +0200
committerMarijn Haverbeke <marijnh@gmail.com>2011-08-29 22:46:49 +0200
commitb099b1e3f7fd0956c0fd0be5901eb2ffce0e956e (patch)
treef9f139308378da84884cb5f295521f9cccb5d678
parent14567c5eb05b6dd7ba9706a605c8d3ee8c5d8742 (diff)
downloadrust-b099b1e3f7fd0956c0fd0be5901eb2ffce0e956e.tar.gz
rust-b099b1e3f7fd0956c0fd0be5901eb2ffce0e956e.zip
Make std::istr::push_byte efficient
It used to allocate two (!) heap values per pushed byte. It now goes through
a runtime function that simply grows the istr and writes the byte.
-rw-r--r--src/lib/istr.rs8
-rw-r--r--src/rt/rust_builtin.cpp9
-rw-r--r--src/rt/rust_upcall.cpp3
-rw-r--r--src/rt/rustrt.def.in1
4 files changed, 17 insertions, 4 deletions
diff --git a/src/lib/istr.rs b/src/lib/istr.rs
index 808ce458eb2..e94c5a4904d 100644
--- a/src/lib/istr.rs
+++ b/src/lib/istr.rs
@@ -8,6 +8,10 @@ as_buf, push_byte;
 
 export from_estr, to_estr, from_estrs, to_estrs;
 
+native "rust" mod rustrt {
+    fn rust_istr_push(s: &mutable istr, ch: u8);
+}
+
 fn from_estr(s: &str) -> istr {
     let s2 = ~"";
     for u in s {
@@ -361,12 +365,12 @@ fn pop_byte(s: &mutable istr) -> u8 {
 }
 
 fn push_byte(s: &mutable istr, b: u8) {
-    s += unsafe_from_byte(b);
+    rustrt::rust_istr_push(s, b);
 }
 
 fn push_bytes(s: &mutable istr, bytes: &[u8]) {
     for byte in bytes {
-        push_byte(s, byte);
+        rustrt::rust_istr_push(s, byte);
     }
 }
 
diff --git a/src/rt/rust_builtin.cpp b/src/rt/rust_builtin.cpp
index 049fe71384e..679a04b93d6 100644
--- a/src/rt/rust_builtin.cpp
+++ b/src/rt/rust_builtin.cpp
@@ -243,6 +243,15 @@ vec_from_buf_shared(rust_task *task, type_desc *ty,
     return v;
 }
 
+extern "C" CDECL void
+rust_istr_push(rust_task* task, rust_vec** sp, uint8_t byte) {
+    size_t fill = (*sp)->fill;
+    reserve_vec(task, sp, fill + 1);
+    (*sp)->data[fill-1] = byte;
+    (*sp)->data[fill] = 0;
+    (*sp)->fill = fill + 1;
+}
+
 extern "C" CDECL rust_str *
 str_from_cstr(rust_task *task, char *sbuf)
 {
diff --git a/src/rt/rust_upcall.cpp b/src/rt/rust_upcall.cpp
index 9f453d49046..77c7cf1a113 100644
--- a/src/rt/rust_upcall.cpp
+++ b/src/rt/rust_upcall.cpp
@@ -353,7 +353,7 @@ upcall_vec_grow(rust_task* task, rust_vec** vp, size_t new_sz) {
 
 extern "C" CDECL void
 upcall_vec_push(rust_task* task, rust_vec** vp, type_desc* elt_ty,
-                 void* elt) {
+                void* elt) {
     LOG_UPCALL_ENTRY(task);
     size_t new_sz = (*vp)->fill + elt_ty->size;
     reserve_vec(task, vp, new_sz);
@@ -362,7 +362,6 @@ upcall_vec_push(rust_task* task, rust_vec** vp, type_desc* elt_ty,
     v->fill += elt_ty->size;
 }
 
-
 /**
  * Returns a token that can be used to deallocate all of the allocated space
  * space in the dynamic stack.
diff --git a/src/rt/rustrt.def.in b/src/rt/rustrt.def.in
index 3157b474b60..ea71a05a88d 100644
--- a/src/rt/rustrt.def.in
+++ b/src/rt/rustrt.def.in
@@ -84,6 +84,7 @@ upcall_get_type_desc
 upcall_grow_task
 upcall_vec_grow
 upcall_vec_push
+upcall_istr_push
 upcall_kill
 upcall_log_double
 upcall_log_float