Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge commit 'v0.1.94'

  • Loading branch information...
commit 861c23229edaabefcea67780789bf98005ad5188 2 parents 1769ec8 + f711d53
@herby herby authored
Showing with 11,122 additions and 2,402 deletions.
  1. +4 −0 AUTHORS
  2. +29 −1 ChangeLog
  3. +2 −4 Makefile
  4. +19 −1 benchmark/http_simple.js
  5. +112 −0 deps/c-ares/linux-arm/ares_build.h
  6. +513 −0 deps/c-ares/linux-arm/ares_config.h
  7. +198 −0 deps/c-ares/linux-arm/ares_setup.h
  8. +16 −3 deps/v8/ChangeLog
  9. +1 −1  deps/v8/include/v8.h
  10. +3 −0  deps/v8/src/api.cc
  11. +719 −462 deps/v8/src/arm/codegen-arm.cc
  12. +122 −42 deps/v8/src/arm/codegen-arm.h
  13. +2 −1  deps/v8/src/arm/debug-arm.cc
  14. +9 −4 deps/v8/src/arm/full-codegen-arm.cc
  15. +75 −28 deps/v8/src/arm/ic-arm.cc
  16. +90 −41 deps/v8/src/arm/macro-assembler-arm.cc
  17. +26 −1 deps/v8/src/arm/macro-assembler-arm.h
  18. +345 −120 deps/v8/src/arm/stub-cache-arm.cc
  19. +78 −1 deps/v8/src/arm/virtual-frame-arm.cc
  20. +11 −2 deps/v8/src/arm/virtual-frame-arm.h
  21. +3 −6 deps/v8/src/array.js
  22. +55 −32 deps/v8/src/bootstrapper.cc
  23. +1 −2  deps/v8/src/builtins.h
  24. +1 −6 deps/v8/src/codegen.cc
  25. +1 −0  deps/v8/src/codegen.h
  26. +6 −0 deps/v8/src/compiler.cc
  27. +2 −0  deps/v8/src/contexts.h
  28. +4 −2 deps/v8/src/conversions.cc
  29. +3 −2 deps/v8/src/d8.cc
  30. +4 −4 deps/v8/src/date.js
  31. +11 −2 deps/v8/src/dateparser-inl.h
  32. +15 −1 deps/v8/src/dateparser.cc
  33. +8 −4 deps/v8/src/dateparser.h
  34. +38 −27 deps/v8/src/debug-debugger.js
  35. +28 −0 deps/v8/src/factory.cc
  36. +8 −0 deps/v8/src/factory.h
  37. +8 −4 deps/v8/src/fast-dtoa.cc
  38. +5 −1 deps/v8/src/fast-dtoa.h
  39. +1 −4 deps/v8/src/full-codegen.cc
  40. +1 −0  deps/v8/src/handles.cc
  41. +1 −1  deps/v8/src/handles.h
  42. +39 −44 deps/v8/src/heap.cc
  43. +2 −13 deps/v8/src/heap.h
  44. +275 −85 deps/v8/src/ia32/codegen-ia32.cc
  45. +13 −6 deps/v8/src/ia32/codegen-ia32.h
  46. +8 −10 deps/v8/src/ia32/ic-ia32.cc
  47. +16 −3 deps/v8/src/ia32/macro-assembler-ia32.cc
  48. +3 −1 deps/v8/src/ia32/macro-assembler-ia32.h
  49. +7 −4 deps/v8/src/ia32/regexp-macro-assembler-ia32.cc
  50. +5 −110 deps/v8/src/ia32/stub-cache-ia32.cc
  51. +4 −2 deps/v8/src/ic.cc
  52. +1 −1  deps/v8/src/ic.h
  53. +369 −271 deps/v8/src/liveedit-debugger.js
  54. +125 −69 deps/v8/src/liveedit.cc
  55. +22 −9 deps/v8/src/liveedit.h
  56. +26 −0 deps/v8/src/objects-debug.cc
  57. +52 −5 deps/v8/src/objects-inl.h
  58. +9 −0 deps/v8/src/objects.cc
  59. +26 −1 deps/v8/src/objects.h
  60. +106 −44 deps/v8/src/runtime.cc
  61. +4 −1 deps/v8/src/runtime.h
  62. +0 −11 deps/v8/src/runtime.js
  63. +67 −0 deps/v8/src/stub-cache.cc
  64. +49 −0 deps/v8/src/stub-cache.h
  65. +1 −0  deps/v8/src/v8natives.js
  66. +1 −1  deps/v8/src/version.cc
  67. +11 −0 deps/v8/src/x64/assembler-x64-inl.h
  68. +75 −3 deps/v8/src/x64/assembler-x64.cc
  69. +14 −2 deps/v8/src/x64/assembler-x64.h
  70. +1,072 −286 deps/v8/src/x64/codegen-x64.cc
  71. +128 −40 deps/v8/src/x64/codegen-x64.h
  72. +38 −15 deps/v8/src/x64/disasm-x64.cc
  73. +59 −20 deps/v8/src/x64/ic-x64.cc
  74. +175 −98 deps/v8/src/x64/macro-assembler-x64.cc
  75. +36 −3 deps/v8/src/x64/macro-assembler-x64.h
  76. +531 −181 deps/v8/src/x64/stub-cache-x64.cc
  77. +25 −0 deps/v8/src/x64/virtual-frame-x64.cc
  78. +4 −0 deps/v8/src/x64/virtual-frame-x64.h
  79. +9 −0 deps/v8/test/cctest/test-debug.cc
  80. +14 −12 deps/v8/test/cctest/test-fast-dtoa.cc
  81. +2 −1  deps/v8/test/cctest/test-serialize.cc
  82. +84 −0 deps/v8/test/cctest/test-threads.cc
  83. +23 −0 deps/v8/test/mjsunit/array-pop.js
  84. +27 −1 deps/v8/test/mjsunit/date-parse.js
  85. +1 −1  deps/v8/test/mjsunit/debug-liveedit-1.js
  86. +1 −1  deps/v8/test/mjsunit/debug-liveedit-2.js
  87. +69 −0 deps/v8/test/mjsunit/debug-liveedit-3.js
  88. +97 −0 deps/v8/test/mjsunit/debug-liveedit-breakpoints.js
  89. +1 −1  deps/v8/test/mjsunit/debug-liveedit-check-stack.js
  90. +1 −1  deps/v8/test/mjsunit/debug-liveedit-diff.js
  91. +1 −1  deps/v8/test/mjsunit/debug-liveedit-patch-positions-replace.js
  92. +1 −1  deps/v8/test/mjsunit/debug-liveedit-patch-positions.js
  93. +97 −0 deps/v8/test/mjsunit/debug-liveedit-utils.js
  94. +54 −0 deps/v8/test/mjsunit/function-without-prototype.js
  95. +2 −9 deps/v8/test/mjsunit/fuzz-natives.js
  96. +40 −0 deps/v8/test/mjsunit/string-index.js
  97. +1 −4 deps/v8/test/mjsunit/unusual-constructor.js
  98. +0 −73 deps/v8/test/sputnik/sputnik.status
  99. +213 −20 doc/api.markdown
  100. +1 −1  doc/api_header.html
  101. +3 −0  doc/changelog_footer.html
  102. +11 −0 doc/changelog_header.html
  103. +3 −3 doc/index.html
  104. +3,623 −1 lib/crypto.js
  105. +3 −3 lib/fs.js
  106. +54 −33 lib/http.js
  107. +1 −1  lib/module.js
  108. +28 −9 lib/net.js
  109. +8 −0 src/node.cc
  110. +3 −3 src/node_buffer.cc
  111. +35 −23 src/node_crypto.cc
  112. +2 −0  src/node_crypto.h
  113. +143 −37 src/node_file.cc
  114. +2 −2 src/node_net2.cc
  115. +72 −0 test/simple/test-crypto.js
  116. +3 −3 test/simple/test-http-304.js
  117. +95 −0 test/simple/test-http-client-race-2.js
  118. +5 −5 test/simple/test-http-tls.js
  119. +161 −0 test/simple/test-http-upgrade.js
  120. +53 −0 test/simple/test-http-upgrade2.js
  121. +96 −0 test/simple/test-tcp-tls.js
  122. +3 −3 wscript
View
4 AUTHORS
@@ -68,3 +68,7 @@ Brian Hammond <brian@fictorial.com>
Mathias Pettersson <mape@mape.me>
Trevor Blackwell <tlb@tlb.org>
Thomas Lee <tom@tom-debian.sensis.com.au>
+dpb587 <code+node@dpbis.net>
+Paulo Matias <paulo.matias@usp.br>
+Peter Griess <pg@std.in>
+Jonathan Knezek <jdknezek@gmail.com>
View
30 ChangeLog
@@ -1,4 +1,32 @@
-2010.04.29, Version 0.1.93
+2010.05.06, Version 0.1.94
+
+* Look in /usr/local/lib/node for modules, so that there's a way
+ to install modules globally (Issac Schlueter)
+
+* SSL improvements (Rhys Jones, Paulo Matias)
+
+* Added c-ares headers for linux-arm (Jonathan Knezek)
+
+* Add symbols to release build
+
+* HTTP upgrade improvements, docs (Micheil Smith)
+
+* HTTP server emits 'clientError' instead of printing message
+
+* Bugfix: Don't emit 'error' twice from http.Client
+
+* Bugfix: Ignore SIGPIPE
+
+* Bugfix: destroy() instead of end() http connection at end of
+ pipeline
+
+* Bugfix: http.Client may be prematurely released back to the
+ free pool. (Thomas Lee)
+
+* Upgrade V8 to 2.2.8
+
+
+2010.04.29, Version 0.1.93, 557ba6bd97bad3afe0f9bd3ac07efac0a39978c1
* Fixed no 'end' event on long chunked HTTP messages
http://github.com/ry/node/issues/#issue/77
View
6 Makefile
@@ -49,10 +49,8 @@ doc/api.html: doc/api.markdown doc/api_header.html doc/api_footer.html
| sed "s/<h2>\(.*\)<\/h2>/<h2 id=\"\1\">\1<\/h2>/g" \
| cat doc/api_header.html - doc/api_footer.html > doc/api.html
-doc/changelog.html: ChangeLog
- echo '<html><head><title>Node.js ChangeLog</title> <link rel="stylesheet" href="./pipe.css" type="text/css" /> <link rel="stylesheet" href="./pipe-quirks.css" type="text/css" /> <body><h1>Node.js ChangeLog</h1> <pre>' > doc/changelog.html
- cat ChangeLog >> doc/changelog.html
- echo '</pre></body></html>' >> doc/changelog.html
+doc/changelog.html: ChangeLog doc/changelog_header.html doc/changelog_footer.html
+ cat doc/changelog_header.html ChangeLog doc/changelog_footer.html > doc/changelog.html
doc/node.1: doc/api.markdown
ronn --roff doc/api.markdown > doc/node.1
View
20 benchmark/http_simple.js
@@ -1,4 +1,7 @@
path = require("path");
+Buffer = require("buffer").Buffer;
+
+port = parseInt(process.env.PORT || 8000);
var puts = require("sys").puts;
@@ -15,6 +18,7 @@ for (var i = 0; i < 20*1024; i++) {
}
stored = {};
+storedBuffer = {};
http.createServer(function (req, res) {
var commands = req.url.split("/");
@@ -36,6 +40,18 @@ http.createServer(function (req, res) {
}
body = stored[n];
+ } else if (command == "buffer") {
+ var n = parseInt(arg, 10)
+ if (n <= 0) throw new Error("bytes called with n <= 0");
+ if (storedBuffer[n] === undefined) {
+ puts("create storedBuffer[n]");
+ storedBuffer[n] = new Buffer(n);
+ for (var i = 0; i < n; i++) {
+ storedBuffer[n][i] = "C".charCodeAt(0);
+ }
+ }
+ body = storedBuffer[n];
+
} else if (command == "quit") {
res.connection.server.close();
body = "quitting";
@@ -61,4 +77,6 @@ http.createServer(function (req, res) {
} else {
res.end(body, 'ascii');
}
-}).listen(8000);
+}).listen(port);
+
+puts('Listening at http://127.0.0.1:'+port+'/');
View
112 deps/c-ares/linux-arm/ares_build.h
@@ -0,0 +1,112 @@
+/* ares_build.h. Generated from ares_build.h.in by configure. */
+#ifndef __CARES_BUILD_H
+#define __CARES_BUILD_H
+
+/* $Id$ */
+
+/* Copyright (C) 2009 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/* ================================================================ */
+/* NOTES FOR CONFIGURE CAPABLE SYSTEMS */
+/* ================================================================ */
+
+/*
+ * NOTE 1:
+ * -------
+ *
+ * Nothing in this file is intended to be modified or adjusted by the
+ * c-ares library user nor by the c-ares library builder.
+ *
+ * If you think that something actually needs to be changed, adjusted
+ * or fixed in this file, then, report it on the c-ares development
+ * mailing list: http://cool.haxx.se/mailman/listinfo/c-ares/
+ *
+ * This header file shall only export symbols which are 'cares' or 'CARES'
+ * prefixed, otherwise public name space would be polluted.
+ *
+ * NOTE 2:
+ * -------
+ *
+ * Right now you might be staring at file ares_build.h.in or ares_build.h,
+ * this is due to the following reason:
+ *
+ * On systems capable of running the configure script, the configure process
+ * will overwrite the distributed ares_build.h file with one that is suitable
+ * and specific to the library being configured and built, which is generated
+ * from the ares_build.h.in template file.
+ *
+ */
+
+/* ================================================================ */
+/* DEFINITION OF THESE SYMBOLS SHALL NOT TAKE PLACE ANYWHERE ELSE */
+/* ================================================================ */
+
+#ifdef CARES_SIZEOF_LONG
+# error "CARES_SIZEOF_LONG shall not be defined except in ares_build.h"
+ Error Compilation_aborted_CARES_SIZEOF_LONG_already_defined
+#endif
+
+#ifdef CARES_TYPEOF_ARES_SOCKLEN_T
+# error "CARES_TYPEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h"
+ Error Compilation_aborted_CARES_TYPEOF_ARES_SOCKLEN_T_already_defined
+#endif
+
+#ifdef CARES_SIZEOF_ARES_SOCKLEN_T
+# error "CARES_SIZEOF_ARES_SOCKLEN_T shall not be defined except in ares_build.h"
+ Error Compilation_aborted_CARES_SIZEOF_ARES_SOCKLEN_T_already_defined
+#endif
+
+/* ================================================================ */
+/* EXTERNAL INTERFACE SETTINGS FOR CONFIGURE CAPABLE SYSTEMS ONLY */
+/* ================================================================ */
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file ws2tcpip.h must be included by the external interface. */
+/* #undef CARES_PULL_WS2TCPIP_H */
+#ifdef CARES_PULL_WS2TCPIP_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# include <winsock2.h>
+# include <ws2tcpip.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/types.h must be included by the external interface. */
+#define CARES_PULL_SYS_TYPES_H 1
+#ifdef CARES_PULL_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+
+/* Configure process defines this to 1 when it finds out that system */
+/* header file sys/socket.h must be included by the external interface. */
+#define CARES_PULL_SYS_SOCKET_H 1
+#ifdef CARES_PULL_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+
+/* The size of `long', as computed by sizeof. */
+#define CARES_SIZEOF_LONG 4
+
+/* Integral data type used for ares_socklen_t. */
+#define CARES_TYPEOF_ARES_SOCKLEN_T socklen_t
+
+/* The size of `ares_socklen_t', as computed by sizeof. */
+#define CARES_SIZEOF_ARES_SOCKLEN_T 4
+
+/* Data type definition of ares_socklen_t. */
+typedef CARES_TYPEOF_ARES_SOCKLEN_T ares_socklen_t;
+
+#endif /* __CARES_BUILD_H */
View
513 deps/c-ares/linux-arm/ares_config.h
@@ -0,0 +1,513 @@
+/* ares_config.h. Generated from ares_config.h.in by configure. */
+/* ares_config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* define this if ares is built for a big endian system */
+/* #undef ARES_BIG_ENDIAN */
+
+/* when building as static part of libcurl */
+/* #undef BUILDING_LIBCURL */
+
+/* when building c-ares library */
+/* #undef CARES_BUILDING_LIBRARY */
+
+/* when not building a shared library */
+/* #undef CARES_STATICLIB */
+
+/* Define to 1 to enable hiding of library internal symbols. */
+#define CARES_SYMBOL_HIDING 1
+
+/* Definition to make a library symbol externally visible. */
+#define CARES_SYMBOL_SCOPE_EXTERN __attribute__ ((visibility ("default")))
+
+/* if a /etc/inet dir is being used */
+/* #undef ETC_INET */
+
+/* Define to the type qualifier of arg 1 for getnameinfo. */
+#define GETNAMEINFO_QUAL_ARG1 const
+
+/* Define to the type of arg 1 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG1 struct sockaddr *
+
+/* Define to the type of arg 2 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG2 socklen_t
+
+/* Define to the type of args 4 and 6 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG46 size_t
+
+/* Define to the type of arg 7 for getnameinfo. */
+#define GETNAMEINFO_TYPE_ARG7 unsigned int
+
+/* Specifies the number of arguments to getservbyport_r */
+#define GETSERVBYPORT_R_ARGS 6
+
+/* Specifies the size of the buffer to pass to getservbyport_r */
+#define GETSERVBYPORT_R_BUFSIZE 4096
+
+/* Define to 1 if you have AF_INET6. */
+#define HAVE_AF_INET6 1
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#define HAVE_ARPA_INET_H 1
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+#define HAVE_ARPA_NAMESER_COMPAT_H 1
+
+/* Define to 1 if you have the <arpa/nameser.h> header file. */
+#define HAVE_ARPA_NAMESER_H 1
+
+/* Define to 1 if you have the <assert.h> header file. */
+#define HAVE_ASSERT_H 1
+
+/* Define to 1 if you have the `bitncmp' function. */
+/* #undef HAVE_BITNCMP */
+
+/* Define to 1 if bool is an available type. */
+#define HAVE_BOOL_T 1
+
+/* Define to 1 if you have the clock_gettime function and monotonic timer. */
+#define HAVE_CLOCK_GETTIME_MONOTONIC 1
+
+/* Define to 1 if you have the closesocket function. */
+/* #undef HAVE_CLOSESOCKET */
+
+/* Define to 1 if you have the CloseSocket camel case function. */
+/* #undef HAVE_CLOSESOCKET_CAMEL */
+
+/* Define to 1 if you have the connect function. */
+#define HAVE_CONNECT 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you have the <errno.h> header file. */
+#define HAVE_ERRNO_H 1
+
+/* Define to 1 if you have the fcntl function. */
+#define HAVE_FCNTL 1
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define to 1 if you have a working fcntl O_NONBLOCK function. */
+#define HAVE_FCNTL_O_NONBLOCK 1
+
+/* Define to 1 if you have the freeaddrinfo function. */
+#define HAVE_FREEADDRINFO 1
+
+/* Define to 1 if you have a working getaddrinfo function. */
+#define HAVE_GETADDRINFO 1
+
+/* Define to 1 if the getaddrinfo function is threadsafe. */
+#define HAVE_GETADDRINFO_THREADSAFE 1
+
+/* Define to 1 if you have the gethostbyaddr function. */
+#define HAVE_GETHOSTBYADDR 1
+
+/* Define to 1 if you have the gethostbyname function. */
+#define HAVE_GETHOSTBYNAME 1
+
+/* Define to 1 if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define to 1 if you have the getnameinfo function. */
+#define HAVE_GETNAMEINFO 1
+
+/* Define to 1 if you have the getservbyport_r function. */
+#define HAVE_GETSERVBYPORT_R 1
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define to 1 if you have the `if_indextoname' function. */
+#define HAVE_IF_INDEXTONAME 1
+
+/* Define to 1 if you have the `inet_net_pton' function. */
+/* #undef HAVE_INET_NET_PTON */
+
+/* Define to 1 if inet_net_pton supports IPv6. */
+/* #undef HAVE_INET_NET_PTON_IPV6 */
+
+/* Define to 1 if you have a IPv6 capable working inet_ntop function. */
+#define HAVE_INET_NTOP 1
+
+/* Define to 1 if you have a IPv6 capable working inet_pton function. */
+#define HAVE_INET_PTON 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define to 1 if you have the ioctl function. */
+#define HAVE_IOCTL 1
+
+/* Define to 1 if you have the ioctlsocket function. */
+/* #undef HAVE_IOCTLSOCKET */
+
+/* Define to 1 if you have the IoctlSocket camel case function. */
+/* #undef HAVE_IOCTLSOCKET_CAMEL */
+
+/* Define to 1 if you have a working IoctlSocket camel case FIONBIO function.
+ */
+/* #undef HAVE_IOCTLSOCKET_CAMEL_FIONBIO */
+
+/* Define to 1 if you have a working ioctlsocket FIONBIO function. */
+/* #undef HAVE_IOCTLSOCKET_FIONBIO */
+
+/* Define to 1 if you have a working ioctl FIONBIO function. */
+#define HAVE_IOCTL_FIONBIO 1
+
+/* Define to 1 if you have a working ioctl SIOCGIFADDR function. */
+#define HAVE_IOCTL_SIOCGIFADDR 1
+
+/* Define to 1 if you have the `resolve' library (-lresolve). */
+/* #undef HAVE_LIBRESOLVE */
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* if your compiler supports LL */
+#define HAVE_LL 1
+
+/* Define to 1 if the compiler supports the 'long long' data type. */
+#define HAVE_LONGLONG 1
+
+/* Define to 1 if you have the malloc.h header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the memory.h header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the MSG_NOSIGNAL flag. */
+#define HAVE_MSG_NOSIGNAL 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the <netinet/tcp.h> header file. */
+#define HAVE_NETINET_TCP_H 1
+
+/* Define to 1 if you have the <net/if.h> header file. */
+#define HAVE_NET_IF_H 1
+
+/* Define to 1 if you have PF_INET6. */
+#define HAVE_PF_INET6 1
+
+/* Define to 1 if you have the recv function. */
+#define HAVE_RECV 1
+
+/* Define to 1 if you have the recvfrom function. */
+#define HAVE_RECVFROM 1
+
+/* Define to 1 if you have the send function. */
+#define HAVE_SEND 1
+
+/* Define to 1 if you have the setsockopt function. */
+#define HAVE_SETSOCKOPT 1
+
+/* Define to 1 if you have a working setsockopt SO_NONBLOCK function. */
+/* #undef HAVE_SETSOCKOPT_SO_NONBLOCK */
+
+/* Define to 1 if you have the <signal.h> header file. */
+#define HAVE_SIGNAL_H 1
+
+/* Define to 1 if sig_atomic_t is an available typedef. */
+#define HAVE_SIG_ATOMIC_T 1
+
+/* Define to 1 if sig_atomic_t is already defined as volatile. */
+/* #undef HAVE_SIG_ATOMIC_T_VOLATILE */
+
+/* Define to 1 if your struct sockaddr_in6 has sin6_scope_id. */
+#define HAVE_SOCKADDR_IN6_SIN6_SCOPE_ID 1
+
+/* Define to 1 if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define to 1 if you have the <socket.h> header file. */
+/* #undef HAVE_SOCKET_H */
+
+/* Define to 1 if you have the <stdbool.h> header file. */
+#define HAVE_STDBOOL_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the strcasecmp function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the strcmpi function. */
+/* #undef HAVE_STRCMPI */
+
+/* Define to 1 if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define to 1 if you have the stricmp function. */
+/* #undef HAVE_STRICMP */
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Define to 1 if you have the strncasecmp function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the strncmpi function. */
+/* #undef HAVE_STRNCMPI */
+
+/* Define to 1 if you have the strnicmp function. */
+/* #undef HAVE_STRNICMP */
+
+/* Define to 1 if you have the <stropts.h> header file. */
+#define HAVE_STROPTS_H 1
+
+/* Define to 1 if you have struct addrinfo. */
+#define HAVE_STRUCT_ADDRINFO 1
+
+/* Define to 1 if you have struct in6_addr. */
+#define HAVE_STRUCT_IN6_ADDR 1
+
+/* Define to 1 if you have struct sockaddr_in6. */
+#define HAVE_STRUCT_SOCKADDR_IN6 1
+
+/* if struct sockaddr_storage is defined */
+#define HAVE_STRUCT_SOCKADDR_STORAGE 1
+
+/* Define to 1 if you have the timeval struct. */
+#define HAVE_STRUCT_TIMEVAL 1
+
+/* Define to 1 if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#define HAVE_SYS_SOCKET_H 1
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <time.h> header file. */
+#define HAVE_TIME_H 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define to 1 if you have the windows.h header file. */
+/* #undef HAVE_WINDOWS_H */
+
+/* Define to 1 if you have the winsock2.h header file. */
+/* #undef HAVE_WINSOCK2_H */
+
+/* Define to 1 if you have the winsock.h header file. */
+/* #undef HAVE_WINSOCK_H */
+
+/* Define to 1 if you have the writev function. */
+#define HAVE_WRITEV 1
+
+/* Define to 1 if you have the ws2tcpip.h header file. */
+/* #undef HAVE_WS2TCPIP_H */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+ */
+#define LT_OBJDIR ".libs/"
+
+/* Define to 1 if you are building a native Windows target. */
+/* #undef NATIVE_WINDOWS */
+
+/* Define to 1 if you need the malloc.h header file even with stdlib.h */
+/* #undef NEED_MALLOC_H */
+
+/* Define to 1 if you need the memory.h header file even with stdlib.h */
+/* #undef NEED_MEMORY_H */
+
+/* Define to 1 if _REENTRANT preprocessor symbol must be defined. */
+/* #undef NEED_REENTRANT */
+
+/* Define to 1 if _THREAD_SAFE preprocessor symbol must be defined. */
+/* #undef NEED_THREAD_SAFE */
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* cpu-machine-OS */
+#define OS "armv5tel-unknown-linux-gnueabi"
+
+/* Name of package */
+#define PACKAGE "c-ares"
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "c-ares mailing list => http://cool.haxx.se/mailman/listinfo/c-ares"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "c-ares"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "c-ares 1.7.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "c-ares"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "1.7.1"
+
+/* a suitable file/device to read random data from */
+#define RANDOM_FILE "/dev/urandom"
+
+/* Define to the type of arg 1 for recvfrom. */
+#define RECVFROM_TYPE_ARG1 int
+
+/* Define to the type pointed by arg 2 for recvfrom. */
+#define RECVFROM_TYPE_ARG2 void
+
+/* Define to 1 if the type pointed by arg 2 for recvfrom is void. */
+#define RECVFROM_TYPE_ARG2_IS_VOID 1
+
+/* Define to the type of arg 3 for recvfrom. */
+#define RECVFROM_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recvfrom. */
+#define RECVFROM_TYPE_ARG4 int
+
+/* Define to the type pointed by arg 5 for recvfrom. */
+#define RECVFROM_TYPE_ARG5 struct sockaddr
+
+/* Define to 1 if the type pointed by arg 5 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG5_IS_VOID */
+
+/* Define to the type pointed by arg 6 for recvfrom. */
+#define RECVFROM_TYPE_ARG6 socklen_t
+
+/* Define to 1 if the type pointed by arg 6 for recvfrom is void. */
+/* #undef RECVFROM_TYPE_ARG6_IS_VOID */
+
+/* Define to the function return type for recvfrom. */
+#define RECVFROM_TYPE_RETV int
+
+/* Define to the type of arg 1 for recv. */
+#define RECV_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for recv. */
+#define RECV_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for recv. */
+#define RECV_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for recv. */
+#define RECV_TYPE_ARG4 int
+
+/* Define to the function return type for recv. */
+#define RECV_TYPE_RETV int
+
+/* Define as the return type of signal handlers (`int' or `void'). */
+#define RETSIGTYPE void
+
+/* Define to the type qualifier of arg 2 for send. */
+#define SEND_QUAL_ARG2 const
+
+/* Define to the type of arg 1 for send. */
+#define SEND_TYPE_ARG1 int
+
+/* Define to the type of arg 2 for send. */
+#define SEND_TYPE_ARG2 void *
+
+/* Define to the type of arg 3 for send. */
+#define SEND_TYPE_ARG3 size_t
+
+/* Define to the type of arg 4 for send. */
+#define SEND_TYPE_ARG4 int
+
+/* Define to the function return type for send. */
+#define SEND_TYPE_RETV int
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `struct in6_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN6_ADDR 16
+
+/* The size of `struct in_addr', as computed by sizeof. */
+#define SIZEOF_STRUCT_IN_ADDR 4
+
+/* The size of `time_t', as computed by sizeof. */
+#define SIZEOF_TIME_T 4
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define to disable non-blocking sockets. */
+/* #undef USE_BLOCKING_SOCKETS */
+
+/* Version number of package */
+#define VERSION "1.7.1"
+
+/* Define to avoid automatic inclusion of winsock.h */
+/* #undef WIN32_LEAN_AND_MEAN */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+ significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+# define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* # undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Define to 1 if OS is AIX. */
+#ifndef _ALL_SOURCE
+/* # undef _ALL_SOURCE */
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#define _FILE_OFFSET_BITS 64
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Type to use in place of in_addr_t when system does not provide it. */
+/* #undef in_addr_t */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* the signed version of size_t */
+/* #undef ssize_t */
View
198 deps/c-ares/linux-arm/ares_setup.h
@@ -0,0 +1,198 @@
+#ifndef HEADER_CARES_SETUP_H
+#define HEADER_CARES_SETUP_H
+
+/* $Id$ */
+
+/* Copyright (C) 2004 - 2009 by Daniel Stenberg et al
+ *
+ * Permission to use, copy, modify, and distribute this software and its
+ * documentation for any purpose and without fee is hereby granted, provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of M.I.T. not be used in advertising or
+ * publicity pertaining to distribution of the software without specific,
+ * written prior permission. M.I.T. makes no representations about the
+ * suitability of this software for any purpose. It is provided "as is"
+ * without express or implied warranty.
+ */
+
+/*
+ * Define WIN32 when build target is Win32 API
+ */
+
+#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
+#define WIN32
+#endif
+
+/*
+ * Include configuration script results or hand-crafted
+ * configuration file for platforms which lack config tool.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "ares_config.h"
+#else
+
+#ifdef WIN32
+#include "config-win32.h"
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+/* ================================================================ */
+/* Definition of preprocessor macros/symbols which modify compiler */
+/* behaviour or generated code characteristics must be done here, */
+/* as appropriate, before any system header file is included. It is */
+/* also possible to have them defined in the config file included */
+/* before this point. As a result of all this we frown inclusion of */
+/* system header files in our config files, avoid this at any cost. */
+/* ================================================================ */
+
+/*
+ * AIX 4.3 and newer needs _THREAD_SAFE defined to build
+ * proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_THREAD_SAFE
+# ifndef _THREAD_SAFE
+# define _THREAD_SAFE
+# endif
+#endif
+
+/*
+ * Tru64 needs _REENTRANT set for a few function prototypes and
+ * things to appear in the system header files. Unixware needs it
+ * to build proper reentrant code. Others may also need it.
+ */
+
+#ifdef NEED_REENTRANT
+# ifndef _REENTRANT
+# define _REENTRANT
+# endif
+#endif
+
+/* ================================================================ */
+/* If you need to include a system header file for your platform, */
+/* please, do it beyond the point further indicated in this file. */
+/* ================================================================ */
+
+/*
+ * c-ares external interface definitions are also used internally,
+ * and might also include required system header files to define them.
+ */
+
+#include <ares_build.h>
+
+/*
+ * Compile time sanity checks must also be done when building the library.
+ */
+
+#include <ares_rules.h>
+
+/* ================================================================= */
+/* No system header file shall be included in this file before this */
+/* point. The only allowed ones are those included from ares_build.h */
+/* ================================================================= */
+
+/*
+ * Include header files for windows builds before redefining anything.
+ * Use this preproessor block only to include or exclude windows.h,
+ * winsock2.h, ws2tcpip.h or winsock.h. Any other windows thing belongs
+ * to any other further and independent block. Under Cygwin things work
+ * just as under linux (e.g. <sys/socket.h>) and the winsock headers should
+ * never be included when __CYGWIN__ is defined. configure script takes
+ * care of this, not defining HAVE_WINDOWS_H, HAVE_WINSOCK_H, HAVE_WINSOCK2_H,
+ * neither HAVE_WS2TCPIP_H when __CYGWIN__ is defined.
+ */
+
+#ifdef HAVE_WINDOWS_H
+# ifndef WIN32_LEAN_AND_MEAN
+# define WIN32_LEAN_AND_MEAN
+# endif
+# include <windows.h>
+# ifdef HAVE_WINSOCK2_H
+# include <winsock2.h>
+# ifdef HAVE_WS2TCPIP_H
+# include <ws2tcpip.h>
+# endif
+# else
+# ifdef HAVE_WINSOCK_H
+# include <winsock.h>
+# endif
+# endif
+#endif
+
+/*
+ * Define USE_WINSOCK to 2 if we have and use WINSOCK2 API, else
+ * define USE_WINSOCK to 1 if we have and use WINSOCK API, else
+ * undefine USE_WINSOCK.
+ */
+
+#undef USE_WINSOCK
+
+#ifdef HAVE_WINSOCK2_H
+# define USE_WINSOCK 2
+#else
+# ifdef HAVE_WINSOCK_H
+# define USE_WINSOCK 1
+# endif
+#endif
+
+/*
+ * Work-arounds for systems without configure support
+ */
+
+#ifndef HAVE_CONFIG_H
+
+#if !defined(HAVE_SYS_TIME_H) && !defined(_MSC_VER) && !defined(__WATCOMC__)
+#define HAVE_SYS_TIME_H
+#endif
+
+#if !defined(HAVE_UNISTD_H) && !defined(_MSC_VER)
+#define HAVE_UNISTD_H 1
+#endif
+
+#if !defined(HAVE_SYS_UIO_H) && !defined(WIN32) && !defined(MSDOS)
+#define HAVE_SYS_UIO_H
+#endif
+
+#endif /* HAVE_CONFIG_H */
+
+#ifdef __POCC__
+# include <sys/types.h>
+# include <unistd.h>
+# define ESRCH 3
+#endif
+
+/*
+ * Recent autoconf versions define these symbols in ares_config.h. We don't
+ * want them (since they collide with the libcurl ones when we build
+ * --enable-debug) so we undef them again here.
+ */
+
+#undef PACKAGE_STRING
+#undef PACKAGE_TARNAME
+#undef PACKAGE_VERSION
+#undef PACKAGE_BUGREPORT
+#undef PACKAGE_NAME
+#undef VERSION
+#undef PACKAGE
+
+/* IPv6 compatibility */
+#if !defined(HAVE_AF_INET6)
+#if defined(HAVE_PF_INET6)
+#define AF_INET6 PF_INET6
+#else
+#define AF_INET6 AF_MAX+1
+#endif
+#endif
+
+/*
+ * Include macros and defines that should only be processed once.
+ */
+
+#ifndef __SETUP_ONCE_H
+#include "setup_once.h"
+#endif
+
+#endif /* HEADER_CARES_SETUP_H */
View
19 deps/v8/ChangeLog
@@ -1,14 +1,27 @@
+2010-05-05: Version 2.2.8
+
+ Performance improvements in the x64 and ARM backends.
+
+
+2010-05-03: Version 2.2.7
+
+ Added support for ES5 date time string format to Date.parse.
+
+ Performance improvements in the x64 backend.
+
+
2010-04-28: Version 2.2.6
- Add "amd64" as recognized architecture in scons build script
+ Added "amd64" as recognized architecture in scons build script
(by Ryan Dahl <coldredlemur@gmail.com>).
- Fix bug in String search and replace with very simple RegExps.
+ Fixed bug in String search and replace with very simple RegExps.
- Fix bug in RegExp containing "\b^".
+ Fixed bug in RegExp containing "\b^".
Performance improvements on all platforms.
+
2010-04-26: Version 2.2.5
Various performance improvements (especially for ARM and x64)
View
2  deps/v8/include/v8.h
@@ -3014,7 +3014,7 @@ template <> struct InternalConstants<4> {
// Internal constants for 64-bit systems.
template <> struct InternalConstants<8> {
- static const int kStringResourceOffset = 2 * sizeof(void*);
+ static const int kStringResourceOffset = 3 * sizeof(void*);
};
/**
View
3  deps/v8/src/api.cc
@@ -3646,6 +3646,8 @@ void V8::ResumeProfilerEx(int flags, int tag) {
// those modules which haven't been started prior to making a
// snapshot.
+ // Make a GC prior to taking a snapshot.
+ i::Heap::CollectAllGarbage(false);
// Reset snapshot flag and CPU module flags.
flags &= ~(PROFILER_MODULE_HEAP_SNAPSHOT | PROFILER_MODULE_CPU);
const int current_flags = i::Logger::GetActiveProfilerModules();
@@ -4020,6 +4022,7 @@ void Debug::ProcessDebugMessages() {
}
Local<Context> Debug::GetDebugContext() {
+ EnsureInitialized("v8::Debug::GetDebugContext()");
ENTER_V8;
return Utils::ToLocal(i::Debugger::GetDebugContext());
}
View
1,181 deps/v8/src/arm/codegen-arm.cc
@@ -565,7 +565,7 @@ void CodeGenerator::Load(Expression* expr) {
}
ASSERT(has_valid_frame());
ASSERT(!has_cc());
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -1008,10 +1008,10 @@ static int BitPosition(unsigned x) {
}
-void CodeGenerator::VirtualFrameSmiOperation(Token::Value op,
- Handle<Object> value,
- bool reversed,
- OverwriteMode mode) {
+void CodeGenerator::SmiOperation(Token::Value op,
+ Handle<Object> value,
+ bool reversed,
+ OverwriteMode mode) {
int int_value = Smi::cast(*value)->value();
bool something_to_inline;
@@ -1232,189 +1232,6 @@ void CodeGenerator::VirtualFrameSmiOperation(Token::Value op,
}
-void CodeGenerator::SmiOperation(Token::Value op,
- Handle<Object> value,
- bool reversed,
- OverwriteMode mode) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
- // NOTE: This is an attempt to inline (a bit) more of the code for
- // some possible smi operations (like + and -) when (at least) one
- // of the operands is a literal smi. With this optimization, the
- // performance of the system is increased by ~15%, and the generated
- // code size is increased by ~1% (measured on a combination of
- // different benchmarks).
-
- // sp[0] : operand
-
- int int_value = Smi::cast(*value)->value();
-
- JumpTarget exit;
- frame_->EmitPop(r0);
-
- bool something_to_inline = true;
- switch (op) {
- case Token::ADD: {
- DeferredCode* deferred =
- new DeferredInlineSmiOperation(op, int_value, reversed, mode, r0);
-
- __ add(r0, r0, Operand(value), SetCC);
- deferred->Branch(vs);
- __ tst(r0, Operand(kSmiTagMask));
- deferred->Branch(ne);
- deferred->BindExit();
- break;
- }
-
- case Token::SUB: {
- DeferredCode* deferred =
- new DeferredInlineSmiOperation(op, int_value, reversed, mode, r0);
-
- if (reversed) {
- __ rsb(r0, r0, Operand(value), SetCC);
- } else {
- __ sub(r0, r0, Operand(value), SetCC);
- }
- deferred->Branch(vs);
- __ tst(r0, Operand(kSmiTagMask));
- deferred->Branch(ne);
- deferred->BindExit();
- break;
- }
-
-
- case Token::BIT_OR:
- case Token::BIT_XOR:
- case Token::BIT_AND: {
- DeferredCode* deferred =
- new DeferredInlineSmiOperation(op, int_value, reversed, mode, r0);
- __ tst(r0, Operand(kSmiTagMask));
- deferred->Branch(ne);
- switch (op) {
- case Token::BIT_OR: __ orr(r0, r0, Operand(value)); break;
- case Token::BIT_XOR: __ eor(r0, r0, Operand(value)); break;
- case Token::BIT_AND: __ and_(r0, r0, Operand(value)); break;
- default: UNREACHABLE();
- }
- deferred->BindExit();
- break;
- }
-
- case Token::SHL:
- case Token::SHR:
- case Token::SAR: {
- if (reversed) {
- something_to_inline = false;
- break;
- }
- int shift_value = int_value & 0x1f; // least significant 5 bits
- DeferredCode* deferred =
- new DeferredInlineSmiOperation(op, shift_value, false, mode, r0);
- __ tst(r0, Operand(kSmiTagMask));
- deferred->Branch(ne);
- __ mov(r2, Operand(r0, ASR, kSmiTagSize)); // remove tags
- switch (op) {
- case Token::SHL: {
- if (shift_value != 0) {
- __ mov(r2, Operand(r2, LSL, shift_value));
- }
- // check that the *unsigned* result fits in a smi
- __ add(r3, r2, Operand(0x40000000), SetCC);
- deferred->Branch(mi);
- break;
- }
- case Token::SHR: {
- // LSR by immediate 0 means shifting 32 bits.
- if (shift_value != 0) {
- __ mov(r2, Operand(r2, LSR, shift_value));
- }
- // check that the *unsigned* result fits in a smi
- // neither of the two high-order bits can be set:
- // - 0x80000000: high bit would be lost when smi tagging
- // - 0x40000000: this number would convert to negative when
- // smi tagging these two cases can only happen with shifts
- // by 0 or 1 when handed a valid smi
- __ and_(r3, r2, Operand(0xc0000000), SetCC);
- deferred->Branch(ne);
- break;
- }
- case Token::SAR: {
- if (shift_value != 0) {
- // ASR by immediate 0 means shifting 32 bits.
- __ mov(r2, Operand(r2, ASR, shift_value));
- }
- break;
- }
- default: UNREACHABLE();
- }
- __ mov(r0, Operand(r2, LSL, kSmiTagSize));
- deferred->BindExit();
- break;
- }
-
- case Token::MOD: {
- if (reversed || int_value < 2 || !IsPowerOf2(int_value)) {
- something_to_inline = false;
- break;
- }
- DeferredCode* deferred =
- new DeferredInlineSmiOperation(op, int_value, reversed, mode, r0);
- unsigned mask = (0x80000000u | kSmiTagMask);
- __ tst(r0, Operand(mask));
- deferred->Branch(ne); // Go to deferred code on non-Smis and negative.
- mask = (int_value << kSmiTagSize) - 1;
- __ and_(r0, r0, Operand(mask));
- deferred->BindExit();
- break;
- }
-
- case Token::MUL: {
- if (!IsEasyToMultiplyBy(int_value)) {
- something_to_inline = false;
- break;
- }
- DeferredCode* deferred =
- new DeferredInlineSmiOperation(op, int_value, reversed, mode, r0);
- unsigned max_smi_that_wont_overflow = Smi::kMaxValue / int_value;
- max_smi_that_wont_overflow <<= kSmiTagSize;
- unsigned mask = 0x80000000u;
- while ((mask & max_smi_that_wont_overflow) == 0) {
- mask |= mask >> 1;
- }
- mask |= kSmiTagMask;
- // This does a single mask that checks for a too high value in a
- // conservative way and for a non-Smi. It also filters out negative
- // numbers, unfortunately, but since this code is inline we prefer
- // brevity to comprehensiveness.
- __ tst(r0, Operand(mask));
- deferred->Branch(ne);
- MultiplyByKnownInt(masm_, r0, r0, int_value);
- deferred->BindExit();
- break;
- }
-
- default:
- something_to_inline = false;
- break;
- }
-
- if (!something_to_inline) {
- if (!reversed) {
- frame_->EmitPush(r0);
- __ mov(r0, Operand(value));
- frame_->EmitPush(r0);
- GenericBinaryOperation(op, mode, int_value);
- } else {
- __ mov(ip, Operand(value));
- frame_->EmitPush(ip);
- frame_->EmitPush(r0);
- GenericBinaryOperation(op, mode, kUnknownIntValue);
- }
- }
-
- exit.Bind();
-}
-
-
void CodeGenerator::Comparison(Condition cc,
Expression* left,
Expression* right,
@@ -1526,9 +1343,7 @@ void CodeGenerator::CallApplyLazy(Expression* applicand,
// give us a megamorphic load site. Not super, but it works.
LoadAndSpill(applicand);
Handle<String> name = Factory::LookupAsciiSymbol("apply");
- __ mov(r2, Operand(name));
- __ ldr(r0, MemOperand(sp, 0));
- frame_->CallLoadIC(RelocInfo::CODE_TARGET);
+ frame_->CallLoadIC(name, RelocInfo::CODE_TARGET);
frame_->EmitPush(r0);
// Load the receiver and the existing arguments object onto the
@@ -1746,12 +1561,11 @@ void CodeGenerator::VisitBlock(Block* node) {
void CodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
- VirtualFrame::SpilledScope spilled_scope(frame_);
frame_->EmitPush(cp);
- __ mov(r0, Operand(pairs));
- frame_->EmitPush(r0);
- __ mov(r0, Operand(Smi::FromInt(is_eval() ? 1 : 0)));
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(pairs));
+ frame_->EmitPush(Operand(Smi::FromInt(is_eval() ? 1 : 0)));
+
+ VirtualFrame::SpilledScope spilled_scope(frame_);
frame_->CallRuntime(Runtime::kDeclareGlobals, 3);
// The result is discarded.
}
@@ -1761,7 +1575,6 @@ void CodeGenerator::VisitDeclaration(Declaration* node) {
#ifdef DEBUG
int original_height = frame_->height();
#endif
- VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ Declaration");
Variable* var = node->proxy()->var();
ASSERT(var != NULL); // must have been resolved
@@ -1776,28 +1589,27 @@ void CodeGenerator::VisitDeclaration(Declaration* node) {
ASSERT(var->is_dynamic());
// For now, just do a runtime call.
frame_->EmitPush(cp);
- __ mov(r0, Operand(var->name()));
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(var->name()));
// Declaration nodes are always declared in only two modes.
ASSERT(node->mode() == Variable::VAR || node->mode() == Variable::CONST);
PropertyAttributes attr = node->mode() == Variable::VAR ? NONE : READ_ONLY;
- __ mov(r0, Operand(Smi::FromInt(attr)));
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(Smi::FromInt(attr)));
// Push initial value, if any.
// Note: For variables we must not push an initial value (such as
// 'undefined') because we may have a (legal) redeclaration and we
// must not destroy the current value.
if (node->mode() == Variable::CONST) {
- __ LoadRoot(r0, Heap::kTheHoleValueRootIndex);
- frame_->EmitPush(r0);
+ frame_->EmitPushRoot(Heap::kTheHoleValueRootIndex);
} else if (node->fun() != NULL) {
- LoadAndSpill(node->fun());
+ Load(node->fun());
} else {
- __ mov(r0, Operand(0)); // no initial value!
- frame_->EmitPush(r0);
+ frame_->EmitPush(Operand(0));
}
+
+ VirtualFrame::SpilledScope spilled_scope(frame_);
frame_->CallRuntime(Runtime::kDeclareContextSlot, 4);
// Ignore the return value (declarations are statements).
+
ASSERT(frame_->height() == original_height);
return;
}
@@ -1813,12 +1625,11 @@ void CodeGenerator::VisitDeclaration(Declaration* node) {
}
if (val != NULL) {
- {
- // Set initial value.
- Reference target(this, node->proxy());
- LoadAndSpill(val);
- target.SetValue(NOT_CONST_INIT);
- }
+ // Set initial value.
+ Reference target(this, node->proxy());
+ Load(val);
+ target.SetValue(NOT_CONST_INIT);
+
// Get rid of the assigned value (declarations are statements).
frame_->Drop();
}
@@ -2904,7 +2715,7 @@ void CodeGenerator::VisitFunctionLiteral(FunctionLiteral* node) {
return;
}
InstantiateFunction(function_info);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -2916,7 +2727,7 @@ void CodeGenerator::VisitSharedFunctionInfoLiteral(
VirtualFrame::SpilledScope spilled_scope(frame_);
Comment cmnt(masm_, "[ SharedFunctionInfoLiteral");
InstantiateFunction(node->shared_function_info());
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -2943,7 +2754,7 @@ void CodeGenerator::VisitConditional(Conditional* node) {
LoadAndSpill(node->else_expression());
if (exit.is_linked()) exit.Bind();
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3199,11 +3010,10 @@ void CodeGenerator::LoadFromGlobalSlotCheckExtensions(Slot* slot,
// Load the global object.
LoadGlobal();
// Setup the name register and call load IC.
- frame_->SpillAllButCopyTOSToR0();
- __ mov(r2, Operand(slot->var()->name()));
- frame_->CallLoadIC(typeof_state == INSIDE_TYPEOF
- ? RelocInfo::CODE_TARGET
- : RelocInfo::CODE_TARGET_CONTEXT);
+ frame_->CallLoadIC(slot->var()->name(),
+ typeof_state == INSIDE_TYPEOF
+ ? RelocInfo::CODE_TARGET
+ : RelocInfo::CODE_TARGET_CONTEXT);
// Drop the global object. The result is in r0.
frame_->Drop();
}
@@ -3215,7 +3025,7 @@ void CodeGenerator::VisitSlot(Slot* node) {
#endif
Comment cmnt(masm_, "[ Slot");
LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3234,7 +3044,7 @@ void CodeGenerator::VisitVariableProxy(VariableProxy* node) {
Reference ref(this, node);
ref.GetValue();
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3246,7 +3056,7 @@ void CodeGenerator::VisitLiteral(Literal* node) {
Register reg = frame_->GetTOSRegister();
__ mov(reg, Operand(node->handle()));
frame_->EmitPush(reg);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3290,7 +3100,7 @@ void CodeGenerator::VisitRegExpLiteral(RegExpLiteral* node) {
done.Bind();
// Push the literal.
frame_->EmitPush(r2);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3371,7 +3181,7 @@ void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
}
}
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3430,7 +3240,7 @@ void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
__ mov(r3, Operand(offset));
__ RecordWrite(r1, r3, r2);
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3446,70 +3256,318 @@ void CodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* node) {
LoadAndSpill(node->value());
frame_->CallRuntime(Runtime::kCreateCatchExtensionObject, 2);
frame_->EmitPush(r0);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
-void CodeGenerator::VisitAssignment(Assignment* node) {
- VirtualFrame::RegisterAllocationScope scope(this);
+void CodeGenerator::EmitSlotAssignment(Assignment* node) {
#ifdef DEBUG
int original_height = frame_->height();
#endif
- Comment cmnt(masm_, "[ Assignment");
+ Comment cmnt(masm(), "[ Variable Assignment");
+ Variable* var = node->target()->AsVariableProxy()->AsVariable();
+ ASSERT(var != NULL);
+ Slot* slot = var->slot();
+ ASSERT(slot != NULL);
- { Reference target(this, node->target(), node->is_compound());
- if (target.is_illegal()) {
- // Fool the virtual frame into thinking that we left the assignment's
- // value on the frame.
- Register tos = frame_->GetTOSRegister();
- __ mov(tos, Operand(Smi::FromInt(0)));
- frame_->EmitPush(tos);
- ASSERT(frame_->height() == original_height + 1);
- return;
+ // Evaluate the right-hand side.
+ if (node->is_compound()) {
+ // For a compound assignment the right-hand side is a binary operation
+ // between the current property value and the actual right-hand side.
+ LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF);
+
+ // Perform the binary operation.
+ Literal* literal = node->value()->AsLiteral();
+ bool overwrite_value =
+ (node->value()->AsBinaryOperation() != NULL &&
+ node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
+ if (literal != NULL && literal->handle()->IsSmi()) {
+ SmiOperation(node->binary_op(),
+ literal->handle(),
+ false,
+ overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+ } else {
+ Load(node->value());
+ VirtualFrameBinaryOperation(
+ node->binary_op(), overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+ }
+ } else {
+ Load(node->value());
+ }
+
+ // Perform the assignment.
+ if (var->mode() != Variable::CONST || node->op() == Token::INIT_CONST) {
+ CodeForSourcePosition(node->position());
+ StoreToSlot(slot,
+ node->op() == Token::INIT_CONST ? CONST_INIT : NOT_CONST_INIT);
+ }
+ ASSERT_EQ(original_height + 1, frame_->height());
+}
+
+
+void CodeGenerator::EmitNamedPropertyAssignment(Assignment* node) {
+#ifdef DEBUG
+ int original_height = frame_->height();
+#endif
+ Comment cmnt(masm(), "[ Named Property Assignment");
+ Variable* var = node->target()->AsVariableProxy()->AsVariable();
+ Property* prop = node->target()->AsProperty();
+ ASSERT(var == NULL || (prop == NULL && var->is_global()));
+
+ // Initialize name and evaluate the receiver sub-expression if necessary. If
+ // the receiver is trivial it is not placed on the stack at this point, but
+ // loaded whenever actually needed.
+ Handle<String> name;
+ bool is_trivial_receiver = false;
+ if (var != NULL) {
+ name = var->name();
+ } else {
+ Literal* lit = prop->key()->AsLiteral();
+ ASSERT_NOT_NULL(lit);
+ name = Handle<String>::cast(lit->handle());
+ // Do not materialize the receiver on the frame if it is trivial.
+ is_trivial_receiver = prop->obj()->IsTrivial();
+ if (!is_trivial_receiver) Load(prop->obj());
+ }
+
+ // Change to slow case in the beginning of an initialization block to
+ // avoid the quadratic behavior of repeatedly adding fast properties.
+ if (node->starts_initialization_block()) {
+ // Initialization block consists of assignments of the form expr.x = ..., so
+ // this will never be an assignment to a variable, so there must be a
+ // receiver object.
+ ASSERT_EQ(NULL, var);
+ if (is_trivial_receiver) {
+ Load(prop->obj());
+ } else {
+ frame_->Dup();
+ }
+ frame_->CallRuntime(Runtime::kToSlowProperties, 1);
+ }
+
+ // Change to fast case at the end of an initialization block. To prepare for
+ // that add an extra copy of the receiver to the frame, so that it can be
+ // converted back to fast case after the assignment.
+ if (node->ends_initialization_block() && !is_trivial_receiver) {
+ frame_->Dup();
+ }
+
+ // Stack layout:
+ // [tos] : receiver (only materialized if non-trivial)
+ // [tos+1] : receiver if at the end of an initialization block
+
+ // Evaluate the right-hand side.
+ if (node->is_compound()) {
+ // For a compound assignment the right-hand side is a binary operation
+ // between the current property value and the actual right-hand side.
+ if (is_trivial_receiver) {
+ Load(prop->obj());
+ } else if (var != NULL) {
+ LoadGlobal();
+ } else {
+ frame_->Dup();
}
+ EmitNamedLoad(name, var != NULL);
+ frame_->Drop(); // Receiver is left on the stack.
+ frame_->EmitPush(r0);
- if (node->op() == Token::ASSIGN ||
- node->op() == Token::INIT_VAR ||
- node->op() == Token::INIT_CONST) {
+ // Perform the binary operation.
+ Literal* literal = node->value()->AsLiteral();
+ bool overwrite_value =
+ (node->value()->AsBinaryOperation() != NULL &&
+ node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
+ if (literal != NULL && literal->handle()->IsSmi()) {
+ SmiOperation(node->binary_op(),
+ literal->handle(),
+ false,
+ overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+ } else {
Load(node->value());
+ VirtualFrameBinaryOperation(
+ node->binary_op(), overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
+ }
+ } else {
+ // For non-compound assignment just load the right-hand side.
+ Load(node->value());
+ }
+
+ // Stack layout:
+ // [tos] : value
+ // [tos+1] : receiver (only materialized if non-trivial)
+ // [tos+2] : receiver if at the end of an initialization block
+
+ // Perform the assignment. It is safe to ignore constants here.
+ ASSERT(var == NULL || var->mode() != Variable::CONST);
+ ASSERT_NE(Token::INIT_CONST, node->op());
+ if (is_trivial_receiver) {
+ // Load the receiver and swap with the value.
+ Load(prop->obj());
+ Register t0 = frame_->PopToRegister();
+ Register t1 = frame_->PopToRegister(t0);
+ frame_->EmitPush(t0);
+ frame_->EmitPush(t1);
+ }
+ CodeForSourcePosition(node->position());
+ bool is_contextual = (var != NULL);
+ EmitNamedStore(name, is_contextual);
+ frame_->EmitPush(r0);
- } else { // Assignment is a compound assignment.
- // Get the old value of the lhs.
- target.GetValue();
- Literal* literal = node->value()->AsLiteral();
- bool overwrite =
- (node->value()->AsBinaryOperation() != NULL &&
- node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
- if (literal != NULL && literal->handle()->IsSmi()) {
- VirtualFrameSmiOperation(node->binary_op(),
- literal->handle(),
- false,
- overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
- } else {
- Load(node->value());
- VirtualFrameBinaryOperation(node->binary_op(),
- overwrite ? OVERWRITE_RIGHT : NO_OVERWRITE);
- }
+ // Change to fast case at the end of an initialization block.
+ if (node->ends_initialization_block()) {
+ ASSERT_EQ(NULL, var);
+ // The argument to the runtime call is the receiver.
+ if (is_trivial_receiver) {
+ Load(prop->obj());
+ } else {
+ // A copy of the receiver is below the value of the assignment. Swap
+ // the receiver and the value of the assignment expression.
+ Register t0 = frame_->PopToRegister();
+ Register t1 = frame_->PopToRegister(t0);
+ frame_->EmitPush(t0);
+ frame_->EmitPush(t1);
}
- Variable* var = node->target()->AsVariableProxy()->AsVariable();
- if (var != NULL &&
- (var->mode() == Variable::CONST) &&
- node->op() != Token::INIT_VAR && node->op() != Token::INIT_CONST) {
- // Assignment ignored - leave the value on the stack.
- UnloadReference(&target);
+ frame_->CallRuntime(Runtime::kToFastProperties, 1);
+ }
+
+ // Stack layout:
+ // [tos] : result
+
+ ASSERT_EQ(original_height + 1, frame_->height());
+}
+
+
+void CodeGenerator::EmitKeyedPropertyAssignment(Assignment* node) {
+#ifdef DEBUG
+ int original_height = frame_->height();
+#endif
+ Comment cmnt(masm_, "[ Keyed Property Assignment");
+ Property* prop = node->target()->AsProperty();
+ ASSERT_NOT_NULL(prop);
+
+ // Evaluate the receiver subexpression.
+ Load(prop->obj());
+
+ // Change to slow case in the beginning of an initialization block to
+ // avoid the quadratic behavior of repeatedly adding fast properties.
+ if (node->starts_initialization_block()) {
+ frame_->Dup();
+ frame_->CallRuntime(Runtime::kToSlowProperties, 1);
+ }
+
+ // Change to fast case at the end of an initialization block. To prepare for
+ // that add an extra copy of the receiver to the frame, so that it can be
+ // converted back to fast case after the assignment.
+ if (node->ends_initialization_block()) {
+ frame_->Dup();
+ }
+
+ // Evaluate the key subexpression.
+ Load(prop->key());
+
+ // Stack layout:
+ // [tos] : key
+ // [tos+1] : receiver
+ // [tos+2] : receiver if at the end of an initialization block
+
+ // Evaluate the right-hand side.
+ if (node->is_compound()) {
+ // For a compound assignment the right-hand side is a binary operation
+ // between the current property value and the actual right-hand side.
+ // Load of the current value leaves receiver and key on the stack.
+ EmitKeyedLoad();
+ frame_->EmitPush(r0);
+
+ // Perform the binary operation.
+ Literal* literal = node->value()->AsLiteral();
+ bool overwrite_value =
+ (node->value()->AsBinaryOperation() != NULL &&
+ node->value()->AsBinaryOperation()->ResultOverwriteAllowed());
+ if (literal != NULL && literal->handle()->IsSmi()) {
+ SmiOperation(node->binary_op(),
+ literal->handle(),
+ false,
+ overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else {
- CodeForSourcePosition(node->position());
- if (node->op() == Token::INIT_CONST) {
- // Dynamic constant initializations must use the function context
- // and initialize the actual constant declared. Dynamic variable
- // initializations are simply assignments and use SetValue.
- target.SetValue(CONST_INIT);
- } else {
- target.SetValue(NOT_CONST_INIT);
- }
+ Load(node->value());
+ VirtualFrameBinaryOperation(
+ node->binary_op(), overwrite_value ? OVERWRITE_RIGHT : NO_OVERWRITE);
}
+ } else {
+ // For non-compound assignment just load the right-hand side.
+ Load(node->value());
}
- ASSERT(frame_->height() == original_height + 1);
+
+ // Stack layout:
+ // [tos] : value
+ // [tos+1] : key
+ // [tos+2] : receiver
+ // [tos+3] : receiver if at the end of an initialization block
+
+ // Perform the assignment. It is safe to ignore constants here.
+ ASSERT(node->op() != Token::INIT_CONST);
+ CodeForSourcePosition(node->position());
+ frame_->PopToR0();
+ EmitKeyedStore(prop->key()->type());
+ frame_->Drop(2); // Key and receiver are left on the stack.
+ frame_->EmitPush(r0);
+
+ // Stack layout:
+ // [tos] : result
+ // [tos+1] : receiver if at the end of an initialization block
+
+ // Change to fast case at the end of an initialization block.
+ if (node->ends_initialization_block()) {
+ // The argument to the runtime call is the extra copy of the receiver,
+ // which is below the value of the assignment. Swap the receiver and
+ // the value of the assignment expression.
+ Register t0 = frame_->PopToRegister();
+ Register t1 = frame_->PopToRegister(t0);
+ frame_->EmitPush(t1);
+ frame_->EmitPush(t0);
+ frame_->CallRuntime(Runtime::kToFastProperties, 1);
+ }
+
+ // Stack layout:
+ // [tos] : result
+
+ ASSERT_EQ(original_height + 1, frame_->height());
+}
+
+
+void CodeGenerator::VisitAssignment(Assignment* node) {
+ VirtualFrame::RegisterAllocationScope scope(this);
+#ifdef DEBUG
+ int original_height = frame_->height();
+#endif
+ Comment cmnt(masm_, "[ Assignment");
+
+ Variable* var = node->target()->AsVariableProxy()->AsVariable();
+ Property* prop = node->target()->AsProperty();
+
+ if (var != NULL && !var->is_global()) {
+ EmitSlotAssignment(node);
+
+ } else if ((prop != NULL && prop->key()->IsPropertyName()) ||
+ (var != NULL && var->is_global())) {
+ // Properties whose keys are property names and global variables are
+ // treated as named property references. We do not need to consider
+ // global 'this' because it is not a valid left-hand side.
+ EmitNamedPropertyAssignment(node);
+
+ } else if (prop != NULL) {
+ // Other properties (including rewritten parameters for a function that
+ // uses arguments) are keyed property assignments.
+ EmitKeyedPropertyAssignment(node);
+
+ } else {
+ // Invalid left-hand side.
+ Load(node->target());
+ frame_->CallRuntime(Runtime::kThrowReferenceError, 1);
+ // The runtime call doesn't actually return but the code generator will
+ // still generate code and expects a certain frame height.
+ frame_->EmitPush(r0);
+ }
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3524,7 +3582,7 @@ void CodeGenerator::VisitThrow(Throw* node) {
CodeForSourcePosition(node->position());
frame_->CallRuntime(Runtime::kThrow, 1);
frame_->EmitPush(r0);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3537,7 +3595,7 @@ void CodeGenerator::VisitProperty(Property* node) {
{ Reference property(this, node);
property.GetValue();
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3744,7 +3802,7 @@ void CodeGenerator::VisitCall(Call* node) {
CallWithArguments(args, NO_CALL_FUNCTION_FLAGS, node->position());
frame_->EmitPush(r0);
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3787,7 +3845,7 @@ void CodeGenerator::VisitCallNew(CallNew* node) {
// Discard old TOS value and push r0 on the stack (same as Pop(), push(r0)).
__ str(r0, frame_->Top());
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -3950,9 +4008,12 @@ void CodeGenerator::GenerateMathSqrt(ZoneList<Expression*>* args) {
}
-// This should generate code that performs a charCodeAt() call or returns
+// This generates code that performs a charCodeAt() call or returns
// undefined in order to trigger the slow case, Runtime_StringCharCodeAt.
-// It is not yet implemented on ARM, so it always goes to the slow case.
+// It can handle flat, 8 and 16 bit characters and cons strings where the
+// answer is found in the left hand branch of the cons. The slow case will
+// flatten the string, which will ensure that the answer is in the left hand
+// side the next time around.
void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
VirtualFrame::SpilledScope spilled_scope(frame_);
ASSERT(args->length() == 2);
@@ -3960,75 +4021,28 @@ void CodeGenerator::GenerateFastCharCodeAt(ZoneList<Expression*>* args) {
LoadAndSpill(args->at(0));
LoadAndSpill(args->at(1));
- frame_->EmitPop(r0); // Index.
- frame_->EmitPop(r1); // String.
-
- Label slow, end, not_a_flat_string, ascii_string, try_again_with_new_string;
+ frame_->EmitPop(r1); // Index.
+ frame_->EmitPop(r2); // String.
- __ tst(r1, Operand(kSmiTagMask));
- __ b(eq, &slow); // The 'string' was a Smi.
-
- ASSERT(kSmiTag == 0);
- __ tst(r0, Operand(kSmiTagMask | 0x80000000u));
- __ b(ne, &slow); // The index was negative or not a Smi.
-
- __ bind(&try_again_with_new_string);
- __ CompareObjectType(r1, r2, r2, FIRST_NONSTRING_TYPE);
- __ b(ge, &slow);
-
- // Now r2 has the string type.
- __ ldr(r3, FieldMemOperand(r1, String::kLengthOffset));
- // Now r3 has the length of the string. Compare with the index.
- __ cmp(r3, Operand(r0, LSR, kSmiTagSize));
- __ b(le, &slow);
-
- // Here we know the index is in range. Check that string is sequential.
- ASSERT_EQ(0, kSeqStringTag);
- __ tst(r2, Operand(kStringRepresentationMask));
- __ b(ne, &not_a_flat_string);
-
- // Check whether it is an ASCII string.
- ASSERT_EQ(0, kTwoByteStringTag);
- __ tst(r2, Operand(kStringEncodingMask));
- __ b(ne, &ascii_string);
-
- // 2-byte string. We can add without shifting since the Smi tag size is the
- // log2 of the number of bytes in a two-byte character.
- ASSERT_EQ(1, kSmiTagSize);
- ASSERT_EQ(0, kSmiShiftSize);
- __ add(r1, r1, Operand(r0));
- __ ldrh(r0, FieldMemOperand(r1, SeqTwoByteString::kHeaderSize));
- __ mov(r0, Operand(r0, LSL, kSmiTagSize));
- __ jmp(&end);
-
- __ bind(&ascii_string);
- __ add(r1, r1, Operand(r0, LSR, kSmiTagSize));
- __ ldrb(r0, FieldMemOperand(r1, SeqAsciiString::kHeaderSize));
- __ mov(r0, Operand(r0, LSL, kSmiTagSize));
- __ jmp(&end);
-
- __ bind(&not_a_flat_string);
- __ and_(r2, r2, Operand(kStringRepresentationMask));
- __ cmp(r2, Operand(kConsStringTag));
- __ b(ne, &slow);
-
- // ConsString.
- // Check that the right hand side is the empty string (ie if this is really a
- // flat string in a cons string). If that is not the case we would rather go
- // to the runtime system now, to flatten the string.
- __ ldr(r2, FieldMemOperand(r1, ConsString::kSecondOffset));
- __ LoadRoot(r3, Heap::kEmptyStringRootIndex);
- __ cmp(r2, Operand(r3));
- __ b(ne, &slow);
-
- // Get the first of the two strings.
- __ ldr(r1, FieldMemOperand(r1, ConsString::kFirstOffset));
- __ jmp(&try_again_with_new_string);
+ Label slow_case;
+ Label exit;
+ StringHelper::GenerateFastCharCodeAt(masm_,
+ r2,
+ r1,
+ r3,
+ r0,
+ &slow_case,
+ &slow_case,
+ &slow_case,
+ &slow_case);
+ __ jmp(&exit);
- __ bind(&slow);
+ __ bind(&slow_case);
+ // Move the undefined value into the result register, which will
+ // trigger the slow case.
__ LoadRoot(r0, Heap::kUndefinedValueRootIndex);
- __ bind(&end);
+ __ bind(&exit);
frame_->EmitPush(r0);
}
@@ -4037,37 +4051,19 @@ void CodeGenerator::GenerateCharFromCode(ZoneList<Expression*>* args) {
Comment(masm_, "[ GenerateCharFromCode");
ASSERT(args->length() == 1);
- LoadAndSpill(args->at(0));
- frame_->EmitPop(r0);
-
- JumpTarget slow_case;
- JumpTarget exit;
-
- // Fast case of Heap::LookupSingleCharacterStringFromCode.
- ASSERT(kSmiTag == 0);
- ASSERT(kSmiShiftSize == 0);
- ASSERT(IsPowerOf2(String::kMaxAsciiCharCode + 1));
- __ tst(r0, Operand(kSmiTagMask |
- ((~String::kMaxAsciiCharCode) << kSmiTagSize)));
- slow_case.Branch(nz);
-
- ASSERT(kSmiTag == 0);
- __ mov(r1, Operand(Factory::single_character_string_cache()));
- __ add(r1, r1, Operand(r0, LSL, kPointerSizeLog2 - kSmiTagSize));
- __ ldr(r1, MemOperand(r1, FixedArray::kHeaderSize - kHeapObjectTag));
- __ LoadRoot(ip, Heap::kUndefinedValueRootIndex);
- __ cmp(r1, ip);
- slow_case.Branch(eq);
-
- frame_->EmitPush(r1);
- exit.Jump();
+ Register code = r1;
+ Register scratch = ip;
+ Register result = r0;
- slow_case.Bind();
- frame_->EmitPush(r0);
- frame_->CallRuntime(Runtime::kCharFromCode, 1);
- frame_->EmitPush(r0);
+ LoadAndSpill(args->at(0));
+ frame_->EmitPop(code);
- exit.Bind();
+ StringHelper::GenerateCharFromCode(masm_,
+ code,
+ scratch,
+ result,
+ CALL_FUNCTION);
+ frame_->EmitPush(result);
}
@@ -4508,6 +4504,110 @@ void CodeGenerator::GenerateNumberToString(ZoneList<Expression*>* args) {
}
+class DeferredSwapElements: public DeferredCode {
+ public:
+ DeferredSwapElements(Register object, Register index1, Register index2)
+ : object_(object), index1_(index1), index2_(index2) {
+ set_comment("[ DeferredSwapElements");
+ }
+
+ virtual void Generate();
+
+ private:
+ Register object_, index1_, index2_;
+};
+
+
+void DeferredSwapElements::Generate() {
+ __ push(object_);
+ __ push(index1_);
+ __ push(index2_);
+ __ CallRuntime(Runtime::kSwapElements, 3);
+}
+
+
+void CodeGenerator::GenerateSwapElements(ZoneList<Expression*>* args) {
+ Comment cmnt(masm_, "[ GenerateSwapElements");
+
+ ASSERT_EQ(3, args->length());
+
+ Load(args->at(0));
+ Load(args->at(1));
+ Load(args->at(2));
+
+ Register index2 = r2;
+ Register index1 = r1;
+ Register object = r0;
+ Register tmp1 = r3;
+ Register tmp2 = r4;
+
+ frame_->EmitPop(index2);
+ frame_->EmitPop(index1);
+ frame_->EmitPop(object);
+
+ DeferredSwapElements* deferred =
+ new DeferredSwapElements(object, index1, index2);
+
+ // Fetch the map and check if array is in fast case.
+ // Check that object doesn't require security checks and
+ // has no indexed interceptor.
+ __ CompareObjectType(object, tmp1, tmp2, FIRST_JS_OBJECT_TYPE);
+ deferred->Branch(lt);
+ __ ldrb(tmp2, FieldMemOperand(tmp1, Map::kBitFieldOffset));
+ __ tst(tmp2, Operand(KeyedLoadIC::kSlowCaseBitFieldMask));
+ deferred->Branch(nz);
+
+ // Check the object's elements are in fast case.
+ __ ldr(tmp1, FieldMemOperand(object, JSObject::kElementsOffset));
+ __ ldr(tmp2, FieldMemOperand(tmp1, HeapObject::kMapOffset));
+ __ LoadRoot(ip, Heap::kFixedArrayMapRootIndex);
+ __ cmp(tmp2, ip);
+ deferred->Branch(ne);
+
+ // Smi-tagging is equivalent to multiplying by 2.
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagSize == 1);
+
+ // Check that both indices are smis.
+ __ mov(tmp2, index1);
+ __ orr(tmp2, tmp2, index2);
+ __ tst(tmp2, Operand(kSmiTagMask));
+ deferred->Branch(nz);
+
+ // Bring the offsets into the fixed array in tmp1 into index1 and
+ // index2.
+ __ mov(tmp2, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
+ __ add(index1, tmp2, Operand(index1, LSL, kPointerSizeLog2 - kSmiTagSize));
+ __ add(index2, tmp2, Operand(index2, LSL, kPointerSizeLog2 - kSmiTagSize));
+
+ // Swap elements.
+ Register tmp3 = object;
+ object = no_reg;
+ __ ldr(tmp3, MemOperand(tmp1, index1));
+ __ ldr(tmp2, MemOperand(tmp1, index2));
+ __ str(tmp3, MemOperand(tmp1, index2));
+ __ str(tmp2, MemOperand(tmp1, index1));
+
+ Label done;
+ __ InNewSpace(tmp1, tmp2, eq, &done);
+ // Possible optimization: do a check that both values are Smis
+ // (or them and test against Smi mask.)
+
+ __ mov(tmp2, tmp1);
+ RecordWriteStub recordWrite1(tmp1, index1, tmp3);
+ __ CallStub(&recordWrite1);
+
+ RecordWriteStub recordWrite2(tmp2, index2, tmp3);
+ __ CallStub(&recordWrite2);
+
+ __ bind(&done);
+
+ deferred->BindExit();
+ __ LoadRoot(tmp1, Heap::kUndefinedValueRootIndex);
+ frame_->EmitPush(tmp1);
+}
+
+
void CodeGenerator::GenerateCallFunction(ZoneList<Expression*>* args) {
Comment cmnt(masm_, "[ GenerateCallFunction");
@@ -4598,7 +4698,7 @@ void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
frame_->CallRuntime(function, arg_count);
frame_->EmitPush(r0);
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -4762,7 +4862,7 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
__ mov(r0, Operand(Smi::FromInt(0)));
frame_->EmitPush(r0);
}
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
return;
}
target.GetValue();
@@ -4830,7 +4930,7 @@ void CodeGenerator::VisitCountOperation(CountOperation* node) {
// Postfix: Discard the new value and use the old.
if (is_postfix) frame_->EmitPop(r0);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -4968,18 +5068,17 @@ void CodeGenerator::VisitBinaryOperation(BinaryOperation* node) {
if (rliteral != NULL && rliteral->handle()->IsSmi()) {
VirtualFrame::RegisterAllocationScope scope(this);
Load(node->left());
- VirtualFrameSmiOperation(
- node->op(),
- rliteral->handle(),
- false,
- overwrite_right ? OVERWRITE_RIGHT : NO_OVERWRITE);
+ SmiOperation(node->op(),
+ rliteral->handle(),
+ false,
+ overwrite_right ? OVERWRITE_RIGHT : NO_OVERWRITE);
} else if (lliteral != NULL && lliteral->handle()->IsSmi()) {
VirtualFrame::RegisterAllocationScope scope(this);
Load(node->right());
- VirtualFrameSmiOperation(node->op(),
- lliteral->handle(),
- true,
- overwrite_left ? OVERWRITE_LEFT : NO_OVERWRITE);
+ SmiOperation(node->op(),
+ lliteral->handle(),
+ true,
+ overwrite_left ? OVERWRITE_LEFT : NO_OVERWRITE);
} else {
VirtualFrame::RegisterAllocationScope scope(this);
OverwriteMode overwrite_mode = NO_OVERWRITE;
@@ -5006,7 +5105,7 @@ void CodeGenerator::VisitThisFunction(ThisFunction* node) {
VirtualFrame::SpilledScope spilled_scope(frame_);
__ ldr(r0, frame_->Function());
frame_->EmitPush(r0);
- ASSERT(frame_->height() == original_height + 1);
+ ASSERT_EQ(original_height + 1, frame_->height());
}
@@ -5289,7 +5388,8 @@ void DeferredReferenceGetKeyedValue::Generate() {
// The rest of the instructions in the deferred code must be together.
{ Assembler::BlockConstPoolScope block_const_pool(masm_);
- // Call keyed load IC. It has all arguments on the stack.
+ // Call keyed load IC. It has all arguments on the stack and the key in r0.
+ __ ldr(r0, MemOperand(sp, 0));
Handle<Code> ic(Builtins::builtin(Builtins::KeyedLoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// The call must be followed by a nop instruction to indicate that the
@@ -5343,11 +5443,10 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
if (is_contextual || scope()->is_global_scope() || loop_nesting() == 0) {
Comment cmnt(masm(), "[ Load from named Property");
// Setup the name register and call load IC.
- frame_->SpillAllButCopyTOSToR0();
- __ mov(r2, Operand(name));
- frame_->CallLoadIC(is_contextual
- ? RelocInfo::CODE_TARGET_CONTEXT
- : RelocInfo::CODE_TARGET);
+ frame_->CallLoadIC(name,
+ is_contextual
+ ? RelocInfo::CODE_TARGET_CONTEXT
+ : RelocInfo::CODE_TARGET);
} else {
// Inline the in-object property case.
Comment cmnt(masm(), "[ Inlined named property load");
@@ -5400,9 +5499,18 @@ void CodeGenerator::EmitNamedLoad(Handle<String> name, bool is_contextual) {
}
+void CodeGenerator::EmitNamedStore(Handle<String> name, bool is_contextual) {
+#ifdef DEBUG
+ int expected_height = frame_->height() - (is_contextual ? 1 : 2);
+#endif
+ frame_->CallStoreIC(name, is_contextual);
+
+ ASSERT_EQ(expected_height, frame_->height());
+}
+
+
void CodeGenerator::EmitKeyedLoad() {
if (loop_nesting() == 0) {
- VirtualFrame::SpilledScope spilled(frame_);
Comment cmnt(masm_, "[ Load from keyed property");
frame_->CallKeyedLoadIC();
} else {
@@ -5414,7 +5522,7 @@ void CodeGenerator::EmitKeyedLoad() {
__ IncrementCounter(&Counters::keyed_load_inline, 1,
frame_->scratch0(), frame_->scratch1());
- // Load the receiver and key from the stack.
+ // Load the receiver and key from the stack.
frame_->SpillAllButCopyTOSToR1R0();
Register receiver = r0;
Register key = r1;
@@ -5489,7 +5597,7 @@ void CodeGenerator::EmitKeyedLoad() {
void CodeGenerator::EmitKeyedStore(StaticType* key_type) {
- frame_->AssertIsSpilled();
+ VirtualFrame::SpilledScope scope(frame_);
// Generate inlined version of the keyed store if the code is in a loop
// and the key is likely to be a smi.
if (loop_nesting() > 0 && key_type->IsLikelySmi()) {
@@ -5657,21 +5765,13 @@ void Reference::SetValue(InitState init_state) {
Comment cmnt(masm, "[ Store to Slot");
Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot();
cgen_->StoreToSlot(slot, init_state);
- cgen_->UnloadReference(this);
+ set_unloaded();
break;
}
case NAMED: {
- VirtualFrame::SpilledScope scope(frame);
Comment cmnt(masm, "[ Store to named Property");
- // Call the appropriate IC code.
- Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
- Handle<String> name(GetName());
-
- frame->EmitPop(r0);
- frame->EmitPop(r1);
- __ mov(r2, Operand(name));
- frame->CallCodeObject(ic, RelocInfo::CODE_TARGET, 0);
+ cgen_->EmitNamedStore(GetName(), false);
frame->EmitPush(r0);
set_unloaded();
break;
@@ -6489,6 +6589,12 @@ void NumberToStringStub::Generate(MacroAssembler* masm) {
}
+void RecordWriteStub::Generate(MacroAssembler* masm) {
+ __ RecordWriteHelper(object_, offset_, scratch_);
+ __ Ret();
+}
+
+
// On entry r0 (rhs) and r1 (lhs) are the values to be compared.
// On exit r0 is 0, positive or negative to indicate the result of
// the comparison.
@@ -8388,14 +8494,16 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ ldr(r3, FieldMemOperand(subject, String::kLengthOffset));
// r2: Number of capture registers
- // r3: Length of subject string
+ // r3: Length of subject string as a smi
// subject: Subject string
// regexp_data: RegExp data (FixedArray)
// Check that the third argument is a positive smi less than the subject
// string length. A negative value will be greater (unsigned comparison).
__ ldr(r0, MemOperand(sp, kPreviousIndexOffset));
- __ cmp(r3, Operand(r0, ASR, kSmiTagSize + kSmiShiftSize));
- __ b(ls, &runtime);
+ __ tst(r0, Operand(kSmiTagMask));
+ __ b(eq, &runtime);
+ __ cmp(r3, Operand(r0));
+ __ b(le, &runtime);
// r2: Number of capture registers
// subject: Subject string
@@ -8521,6 +8629,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// For arguments 4 and 3 get string length, calculate start of string data and
// calculate the shift of the index (0 for ASCII and 1 for two byte).
__ ldr(r0, FieldMemOperand(subject, String::kLengthOffset));
+ __ mov(r0, Operand(r0, ASR, kSmiTagSize));
ASSERT_EQ(SeqAsciiString::kHeaderSize, SeqTwoByteString::kHeaderSize);
__ add(r9, subject, Operand(SeqAsciiString::kHeaderSize - kHeapObjectTag));
__ eor(r3, r3, Operand(1));
@@ -8750,12 +8859,151 @@ int CompareStub::MinorKey() {
}
-void StringStubBase::GenerateCopyCharacters(MacroAssembler* masm,
- Register dest,
- Register src,
- Register count,
- Register scratch,
- bool ascii) {
+void StringHelper::GenerateFastCharCodeAt(MacroAssembler* masm,
+ Register object,
+ Register index,
+ Register scratch,
+ Register result,
+ Label* receiver_not_string,
+ Label* index_not_smi,
+ Label* index_out_of_range,
+ Label* slow_case) {
+ Label not_a_flat_string;
+ Label try_again_with_new_string;
+ Label ascii_string;
+ Label got_char_code;
+
+ // If the receiver is a smi trigger the non-string case.
+ __ BranchOnSmi(object, receiver_not_string);
+
+ // Fetch the instance type of the receiver into result register.
+ __ ldr(result, FieldMemOperand(object, HeapObject::kMapOffset));
+ __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
+ // If the receiver is not a string trigger the non-string case.
+ __ tst(result, Operand(kIsNotStringMask));
+ __ b(ne, receiver_not_string);
+
+ // If the index is non-smi trigger the non-smi case.
+ __ BranchOnNotSmi(index, index_not_smi);
+
+ // Check for index out of range.
+ __ ldr(scratch, FieldMemOperand(object, String::kLengthOffset));
+ // Now scratch has the length of the string. Compare with the index.
+ __ cmp(scratch, Operand(index));
+ __ b(ls, index_out_of_range);
+
+ __ bind(&try_again_with_new_string);
+ // ----------- S t a t e -------------
+ // -- object : string to access
+ // -- result : instance type of the string
+ // -- scratch : non-negative index < length
+ // -----------------------------------
+
+ // We need special handling for non-flat strings.
+ ASSERT_EQ(0, kSeqStringTag);
+ __ tst(result, Operand(kStringRepresentationMask));
+ __ b(ne, &not_a_flat_string);
+
+ // Check for 1-byte or 2-byte string.
+ ASSERT_EQ(0, kTwoByteStringTag);
+ __ tst(result, Operand(kStringEncodingMask));
+ __ b(ne, &ascii_string);
+
+ // 2-byte string. We can add without shifting since the Smi tag size is the
+ // log2 of the number of bytes in a two-byte character.
+ ASSERT_EQ(1, kSmiTagSize);
+ ASSERT_EQ(0, kSmiShiftSize);
+ __ add(scratch, object, Operand(index));
+ __ ldrh(result, FieldMemOperand(scratch, SeqTwoByteString::kHeaderSize));
+ __ jmp(&got_char_code);
+
+ // Handle non-flat strings.
+ __ bind(&not_a_flat_string);
+ __ and_(result, result, Operand(kStringRepresentationMask));
+ __ cmp(result, Operand(kConsStringTag));
+ __ b(ne, slow_case);
+
+ // ConsString.
+ // Check whether the right hand side is the empty string (i.e. if
+ // this is really a flat string in a cons string). If that is not
+ // the case we would rather go to the runtime system now to flatten
+ // the string.
+ __ ldr(result, FieldMemOperand(object, ConsString::kSecondOffset));
+ __ LoadRoot(scratch, Heap::kEmptyStringRootIndex);
+ __ cmp(result, Operand(scratch));
+ __ b(ne, slow_case);
+
+ // Get the first of the two strings and load its instance type.
+ __ ldr(object, FieldMemOperand(object, ConsString::kFirstOffset));
+ __ ldr(result, FieldMemOperand(object, HeapObject::kMapOffset));
+ __ ldrb(result, FieldMemOperand(result, Map::kInstanceTypeOffset));
+ __ jmp(&try_again_with_new_string);
+
+ // ASCII string.
+ __ bind(&ascii_string);