Browse Source

Upgrade V8 to 3.6.4

Ryan Dahl 13 years ago
parent
commit
1b15af9dd2
  1. 1
      deps/v8/AUTHORS
  2. 21
      deps/v8/ChangeLog
  3. 4
      deps/v8/build/README.txt
  4. 37
      deps/v8/include/v8.h
  5. 2
      deps/v8/samples/process.cc
  6. 1
      deps/v8/src/accessors.cc
  7. 41
      deps/v8/src/api.cc
  8. 1
      deps/v8/src/arguments.h
  9. 86
      deps/v8/src/arm/builtins-arm.cc
  10. 33
      deps/v8/src/arm/code-stubs-arm.cc
  11. 18
      deps/v8/src/arm/full-codegen-arm.cc
  12. 18
      deps/v8/src/arm/ic-arm.cc
  13. 33
      deps/v8/src/arm/lithium-arm.cc
  14. 4
      deps/v8/src/arm/lithium-arm.h
  15. 93
      deps/v8/src/arm/lithium-codegen-arm.cc
  16. 1
      deps/v8/src/arm/lithium-gap-resolver-arm.h
  17. 26
      deps/v8/src/arm/macro-assembler-arm.cc
  18. 4
      deps/v8/src/arm/macro-assembler-arm.h
  19. 1
      deps/v8/src/arm/regexp-macro-assembler-arm.h
  20. 160
      deps/v8/src/arm/stub-cache-arm.cc
  21. 18
      deps/v8/src/array.js
  22. 4
      deps/v8/src/ast.cc
  23. 2
      deps/v8/src/ast.h
  24. 1
      deps/v8/src/bignum.h
  25. 4
      deps/v8/src/bootstrapper.cc
  26. 1
      deps/v8/src/builtins.cc
  27. 2
      deps/v8/src/builtins.h
  28. 1
      deps/v8/src/cached-powers.h
  29. 8
      deps/v8/src/circular-queue-inl.h
  30. 65
      deps/v8/src/code-stubs.cc
  31. 32
      deps/v8/src/code-stubs.h
  32. 1
      deps/v8/src/compilation-cache.h
  33. 10
      deps/v8/src/compiler.h
  34. 5
      deps/v8/src/cpu-profiler-inl.h
  35. 11
      deps/v8/src/cpu-profiler.cc
  36. 9
      deps/v8/src/cpu-profiler.h
  37. 12
      deps/v8/src/d8-debug.cc
  38. 8
      deps/v8/src/d8-debug.h
  39. 1
      deps/v8/src/d8-posix.cc
  40. 23
      deps/v8/src/d8-readline.cc
  41. 162
      deps/v8/src/d8.cc
  42. 74
      deps/v8/src/d8.h
  43. 4
      deps/v8/src/dateparser.h
  44. 17
      deps/v8/src/debug-agent.cc
  45. 4
      deps/v8/src/debug-agent.h
  46. 112
      deps/v8/src/debug.cc
  47. 6
      deps/v8/src/debug.h
  48. 5
      deps/v8/src/disassembler.cc
  49. 24
      deps/v8/src/elements.cc
  50. 4
      deps/v8/src/elements.h
  51. 65
      deps/v8/src/execution.cc
  52. 7
      deps/v8/src/execution.h
  53. 19
      deps/v8/src/factory.cc
  54. 9
      deps/v8/src/factory.h
  55. 6
      deps/v8/src/flags.cc
  56. 1
      deps/v8/src/frames.h
  57. 4
      deps/v8/src/full-codegen.cc
  58. 4
      deps/v8/src/gdb-jit.cc
  59. 17
      deps/v8/src/handles.cc
  60. 2
      deps/v8/src/handles.h
  61. 70
      deps/v8/src/heap.cc
  62. 18
      deps/v8/src/heap.h
  63. 60
      deps/v8/src/hydrogen-instructions.cc
  64. 29
      deps/v8/src/hydrogen-instructions.h
  65. 135
      deps/v8/src/hydrogen.cc
  66. 3
      deps/v8/src/hydrogen.h
  67. 3
      deps/v8/src/ia32/assembler-ia32.h
  68. 89
      deps/v8/src/ia32/builtins-ia32.cc
  69. 35
      deps/v8/src/ia32/code-stubs-ia32.cc
  70. 19
      deps/v8/src/ia32/full-codegen-ia32.cc
  71. 17
      deps/v8/src/ia32/ic-ia32.cc
  72. 93
      deps/v8/src/ia32/lithium-codegen-ia32.cc
  73. 2
      deps/v8/src/ia32/lithium-codegen-ia32.h
  74. 35
      deps/v8/src/ia32/lithium-ia32.cc
  75. 4
      deps/v8/src/ia32/lithium-ia32.h
  76. 26
      deps/v8/src/ia32/macro-assembler-ia32.cc
  77. 86
      deps/v8/src/ia32/stub-cache-ia32.cc
  78. 50
      deps/v8/src/ic.cc
  79. 9
      deps/v8/src/ic.h
  80. 2
      deps/v8/src/inspector.h
  81. 9
      deps/v8/src/isolate.cc
  82. 22
      deps/v8/src/isolate.h
  83. 8
      deps/v8/src/json.js
  84. 8
      deps/v8/src/jsregexp.h
  85. 29
      deps/v8/src/list-inl.h
  86. 10
      deps/v8/src/list.h
  87. 28
      deps/v8/src/lithium.cc
  88. 8
      deps/v8/src/lithium.h
  89. 2
      deps/v8/src/liveedit.cc
  90. 12
      deps/v8/src/liveobjectlist.cc
  91. 3
      deps/v8/src/liveobjectlist.h
  92. 2
      deps/v8/src/log-utils.cc
  93. 1
      deps/v8/src/log-utils.h
  94. 64
      deps/v8/src/log.cc
  95. 2
      deps/v8/src/log.h
  96. 10
      deps/v8/src/macros.py
  97. 7
      deps/v8/src/messages.cc
  98. 2
      deps/v8/src/messages.h
  99. 3
      deps/v8/src/messages.js
  100. 13
      deps/v8/src/mips/assembler-mips-inl.h

1
deps/v8/AUTHORS

@ -21,6 +21,7 @@ Daniel Andersson <kodandersson@gmail.com>
Daniel James <dnljms@gmail.com> Daniel James <dnljms@gmail.com>
Dineel D Sule <dsule@codeaurora.org> Dineel D Sule <dsule@codeaurora.org>
Erich Ocean <erich.ocean@me.com> Erich Ocean <erich.ocean@me.com>
Fedor Indutny <fedor@indutny.com>
Jan de Mooij <jandemooij@gmail.com> Jan de Mooij <jandemooij@gmail.com>
Jay Freeman <saurik@saurik.com> Jay Freeman <saurik@saurik.com>
Joel Stanley <joel.stan@gmail.com> Joel Stanley <joel.stan@gmail.com>

21
deps/v8/ChangeLog

@ -1,3 +1,24 @@
2011-09-15: Version 3.6.4
Fixed d8's broken readline history.
Removed the need for code delete events in CPU profiler (Issue 1466).
Fixed debugger stepping next with trycatch recursion (Issue 1639).
Fixing parallel execution in d8 (with -p) and some memory leaks.
Support for precise stepping in functions compiled before debugging was
started (step 1).
2011-09-13: Version 3.6.3
Implemented better support of typed arrays in the d8 shell.
Bug fixes and performance improvements on all platforms.
2011-09-08: Version 3.6.2 2011-09-08: Version 3.6.2
Added "dependencies" target to top-level Makefile. Added "dependencies" target to top-level Makefile.

4
deps/v8/build/README.txt

@ -53,11 +53,11 @@ from the Chromium repository. From the root of the V8 project do the following:
> svn co http://src.chromium.org/svn/trunk/deps/third_party/cygwin@66844 third_party/cygwin > svn co http://src.chromium.org/svn/trunk/deps/third_party/cygwin@66844 third_party/cygwin
To run GYP Python is required and it is reccomended to use the same version as To run GYP Python is required and it is recommended to use the same version as
is used by the Chromium project. This can also be checked out from the Chromium is used by the Chromium project. This can also be checked out from the Chromium
repository. From the root of the V8 project do the following: repository. From the root of the V8 project do the following:
> svn co http://src.chromium.org/svn/trunk/tools/third_party/python_26@70627 third_party/python_26 > svn co http://src.chromium.org/svn/trunk/tools/third_party/python_26@89111 third_party/python_26
Now generate Visual Studio solution and project files for the ia32 architecture: Now generate Visual Studio solution and project files for the ia32 architecture:

37
deps/v8/include/v8.h

@ -1051,18 +1051,21 @@ class String : public Primitive {
NO_NULL_TERMINATION = 2 NO_NULL_TERMINATION = 2
}; };
// 16-bit character codes.
V8EXPORT int Write(uint16_t* buffer, V8EXPORT int Write(uint16_t* buffer,
int start = 0, int start = 0,
int length = -1, int length = -1,
int options = NO_OPTIONS) const; // UTF-16 int options = NO_OPTIONS) const;
// ASCII characters.
V8EXPORT int WriteAscii(char* buffer, V8EXPORT int WriteAscii(char* buffer,
int start = 0, int start = 0,
int length = -1, int length = -1,
int options = NO_OPTIONS) const; // ASCII int options = NO_OPTIONS) const;
// UTF-8 encoded characters.
V8EXPORT int WriteUtf8(char* buffer, V8EXPORT int WriteUtf8(char* buffer,
int length = -1, int length = -1,
int* nchars_ref = NULL, int* nchars_ref = NULL,
int options = NO_OPTIONS) const; // UTF-8 int options = NO_OPTIONS) const;
/** /**
* A zero length string. * A zero length string.
@ -1075,7 +1078,7 @@ class String : public Primitive {
V8EXPORT bool IsExternal() const; V8EXPORT bool IsExternal() const;
/** /**
* Returns true if the string is both external and ascii * Returns true if the string is both external and ASCII
*/ */
V8EXPORT bool IsExternalAscii() const; V8EXPORT bool IsExternalAscii() const;
@ -1132,11 +1135,11 @@ class String : public Primitive {
}; };
/** /**
* An ExternalAsciiStringResource is a wrapper around an ascii * An ExternalAsciiStringResource is a wrapper around an ASCII
* string buffer that resides outside V8's heap. Implement an * string buffer that resides outside V8's heap. Implement an
* ExternalAsciiStringResource to manage the life cycle of the * ExternalAsciiStringResource to manage the life cycle of the
* underlying buffer. Note that the string data must be immutable * underlying buffer. Note that the string data must be immutable
* and that the data must be strict 7-bit ASCII, not Latin1 or * and that the data must be strict (7-bit) ASCII, not Latin-1 or
* UTF-8, which would require special treatment internally in the * UTF-8, which would require special treatment internally in the
* engine and, in the case of UTF-8, do not allow efficient indexing. * engine and, in the case of UTF-8, do not allow efficient indexing.
* Use String::New or convert to 16 bit data for non-ASCII. * Use String::New or convert to 16 bit data for non-ASCII.
@ -1152,7 +1155,7 @@ class String : public Primitive {
virtual ~ExternalAsciiStringResource() {} virtual ~ExternalAsciiStringResource() {}
/** The string data from the underlying buffer.*/ /** The string data from the underlying buffer.*/
virtual const char* data() const = 0; virtual const char* data() const = 0;
/** The number of ascii characters in the string.*/ /** The number of ASCII characters in the string.*/
virtual size_t length() const = 0; virtual size_t length() const = 0;
protected: protected:
ExternalAsciiStringResource() {} ExternalAsciiStringResource() {}
@ -1165,7 +1168,7 @@ class String : public Primitive {
inline ExternalStringResource* GetExternalStringResource() const; inline ExternalStringResource* GetExternalStringResource() const;
/** /**
* Get the ExternalAsciiStringResource for an external ascii string. * Get the ExternalAsciiStringResource for an external ASCII string.
* Returns NULL if IsExternalAscii() doesn't return true. * Returns NULL if IsExternalAscii() doesn't return true.
*/ */
V8EXPORT ExternalAsciiStringResource* GetExternalAsciiStringResource() const; V8EXPORT ExternalAsciiStringResource* GetExternalAsciiStringResource() const;
@ -1173,9 +1176,9 @@ class String : public Primitive {
static inline String* Cast(v8::Value* obj); static inline String* Cast(v8::Value* obj);
/** /**
* Allocates a new string from either utf-8 encoded or ascii data. * Allocates a new string from either UTF-8 encoded or ASCII data.
* The second parameter 'length' gives the buffer length. * The second parameter 'length' gives the buffer length.
* If the data is utf-8 encoded, the caller must * If the data is UTF-8 encoded, the caller must
* be careful to supply the length parameter. * be careful to supply the length parameter.
* If it is not given, the function calls * If it is not given, the function calls
* 'strlen' to determine the buffer length, it might be * 'strlen' to determine the buffer length, it might be
@ -1183,7 +1186,7 @@ class String : public Primitive {
*/ */
V8EXPORT static Local<String> New(const char* data, int length = -1); V8EXPORT static Local<String> New(const char* data, int length = -1);
/** Allocates a new string from utf16 data.*/ /** Allocates a new string from 16-bit character codes.*/
V8EXPORT static Local<String> New(const uint16_t* data, int length = -1); V8EXPORT static Local<String> New(const uint16_t* data, int length = -1);
/** Creates a symbol. Returns one if it exists already.*/ /** Creates a symbol. Returns one if it exists already.*/
@ -1218,7 +1221,7 @@ class String : public Primitive {
V8EXPORT bool MakeExternal(ExternalStringResource* resource); V8EXPORT bool MakeExternal(ExternalStringResource* resource);
/** /**
* Creates a new external string using the ascii data defined in the given * Creates a new external string using the ASCII data defined in the given
* resource. When the external string is no longer live on V8's heap the * resource. When the external string is no longer live on V8's heap the
* resource will be disposed by calling its Dispose method. The caller of * resource will be disposed by calling its Dispose method. The caller of
* this function should not otherwise delete or modify the resource. Neither * this function should not otherwise delete or modify the resource. Neither
@ -1244,18 +1247,18 @@ class String : public Primitive {
*/ */
V8EXPORT bool CanMakeExternal(); V8EXPORT bool CanMakeExternal();
/** Creates an undetectable string from the supplied ascii or utf-8 data.*/ /** Creates an undetectable string from the supplied ASCII or UTF-8 data.*/
V8EXPORT static Local<String> NewUndetectable(const char* data, V8EXPORT static Local<String> NewUndetectable(const char* data,
int length = -1); int length = -1);
/** Creates an undetectable string from the supplied utf-16 data.*/ /** Creates an undetectable string from the supplied 16-bit character codes.*/
V8EXPORT static Local<String> NewUndetectable(const uint16_t* data, V8EXPORT static Local<String> NewUndetectable(const uint16_t* data,
int length = -1); int length = -1);
/** /**
* Converts an object to a utf8-encoded character array. Useful if * Converts an object to a UTF-8-encoded character array. Useful if
* you want to print the object. If conversion to a string fails * you want to print the object. If conversion to a string fails
* (eg. due to an exception in the toString() method of the object) * (e.g. due to an exception in the toString() method of the object)
* then the length() method returns 0 and the * operator returns * then the length() method returns 0 and the * operator returns
* NULL. * NULL.
*/ */
@ -1276,7 +1279,7 @@ class String : public Primitive {
}; };
/** /**
* Converts an object to an ascii string. * Converts an object to an ASCII string.
* Useful if you want to print the object. * Useful if you want to print the object.
* If conversion to a string fails (eg. due to an exception in the toString() * If conversion to a string fails (eg. due to an exception in the toString()
* method of the object) then the length() method returns 0 and the * operator * method of the object) then the length() method returns 0 and the * operator

2
deps/v8/samples/process.cc

@ -77,7 +77,6 @@ class HttpRequestProcessor {
*/ */
class JsHttpRequestProcessor : public HttpRequestProcessor { class JsHttpRequestProcessor : public HttpRequestProcessor {
public: public:
// Creates a new processor that processes requests by invoking the // Creates a new processor that processes requests by invoking the
// Process function of the JavaScript script given as an argument. // Process function of the JavaScript script given as an argument.
explicit JsHttpRequestProcessor(Handle<String> script) : script_(script) { } explicit JsHttpRequestProcessor(Handle<String> script) : script_(script) { }
@ -88,7 +87,6 @@ class JsHttpRequestProcessor : public HttpRequestProcessor {
virtual bool Process(HttpRequest* req); virtual bool Process(HttpRequest* req);
private: private:
// Execute the script associated with this processor and extract the // Execute the script associated with this processor and extract the
// Process function. Returns true if this succeeded, otherwise false. // Process function. Returns true if this succeeded, otherwise false.
bool ExecuteScript(Handle<String> script); bool ExecuteScript(Handle<String> script);

1
deps/v8/src/accessors.cc

@ -710,6 +710,7 @@ class FrameFunctionIterator {
} while (next_function != NULL); } while (next_function != NULL);
return false; return false;
} }
private: private:
void GetFunctions() { void GetFunctions() {
functions_.Rewind(0); functions_.Rewind(0);

41
deps/v8/src/api.cc

@ -3266,6 +3266,42 @@ bool v8::Object::DeleteHiddenValue(v8::Handle<v8::String> key) {
namespace { namespace {
static i::ElementsKind GetElementsKindFromExternalArrayType(
ExternalArrayType array_type) {
switch (array_type) {
case kExternalByteArray:
return i::EXTERNAL_BYTE_ELEMENTS;
break;
case kExternalUnsignedByteArray:
return i::EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
break;
case kExternalShortArray:
return i::EXTERNAL_SHORT_ELEMENTS;
break;
case kExternalUnsignedShortArray:
return i::EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
break;
case kExternalIntArray:
return i::EXTERNAL_INT_ELEMENTS;
break;
case kExternalUnsignedIntArray:
return i::EXTERNAL_UNSIGNED_INT_ELEMENTS;
break;
case kExternalFloatArray:
return i::EXTERNAL_FLOAT_ELEMENTS;
break;
case kExternalDoubleArray:
return i::EXTERNAL_DOUBLE_ELEMENTS;
break;
case kExternalPixelArray:
return i::EXTERNAL_PIXEL_ELEMENTS;
break;
}
UNREACHABLE();
return i::DICTIONARY_ELEMENTS;
}
void PrepareExternalArrayElements(i::Handle<i::JSObject> object, void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
void* data, void* data,
ExternalArrayType array_type, ExternalArrayType array_type,
@ -3284,9 +3320,9 @@ void PrepareExternalArrayElements(i::Handle<i::JSObject> object,
elements->map() != isolate->heap()->MapForExternalArrayType(array_type); elements->map() != isolate->heap()->MapForExternalArrayType(array_type);
if (cant_reuse_map) { if (cant_reuse_map) {
i::Handle<i::Map> external_array_map = i::Handle<i::Map> external_array_map =
isolate->factory()->GetExternalArrayElementsMap( isolate->factory()->GetElementsTransitionMap(
i::Handle<i::Map>(object->map()), i::Handle<i::Map>(object->map()),
array_type, GetElementsKindFromExternalArrayType(array_type),
object->HasFastProperties()); object->HasFastProperties());
object->set_map(*external_array_map); object->set_map(*external_array_map);
} }
@ -3348,6 +3384,7 @@ int v8::Object::GetIndexedPropertiesPixelDataLength() {
} }
} }
void v8::Object::SetIndexedPropertiesToExternalArrayData( void v8::Object::SetIndexedPropertiesToExternalArrayData(
void* data, void* data,
ExternalArrayType array_type, ExternalArrayType array_type,

1
deps/v8/src/arguments.h

@ -75,6 +75,7 @@ class Arguments BASE_EMBEDDED {
int length() const { return length_; } int length() const { return length_; }
Object** arguments() { return arguments_; } Object** arguments() { return arguments_; }
private: private:
int length_; int length_;
Object** arguments_; Object** arguments_;

86
deps/v8/src/arm/builtins-arm.cc

@ -1230,16 +1230,17 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// 2. Get the function to call (passed as receiver) from the stack, check // 2. Get the function to call (passed as receiver) from the stack, check
// if it is a function. // if it is a function.
// r0: actual number of arguments // r0: actual number of arguments
Label non_function; Label slow, non_function;
__ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
__ JumpIfSmi(r1, &non_function); __ JumpIfSmi(r1, &non_function);
__ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
__ b(ne, &non_function); __ b(ne, &slow);
// 3a. Patch the first argument if necessary when calling a function. // 3a. Patch the first argument if necessary when calling a function.
// r0: actual number of arguments // r0: actual number of arguments
// r1: function // r1: function
Label shift_arguments; Label shift_arguments;
__ mov(r4, Operand(0, RelocInfo::NONE)); // indicate regular JS_FUNCTION
{ Label convert_to_object, use_global_receiver, patch_receiver; { Label convert_to_object, use_global_receiver, patch_receiver;
// Change context eagerly in case we need the global receiver. // Change context eagerly in case we need the global receiver.
__ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset)); __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
@ -1286,8 +1287,9 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ pop(r0); __ pop(r0);
__ mov(r0, Operand(r0, ASR, kSmiTagSize)); __ mov(r0, Operand(r0, ASR, kSmiTagSize));
__ LeaveInternalFrame(); __ LeaveInternalFrame();
// Restore the function to r1. // Restore the function to r1, and the flag to r4.
__ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2)); __ ldr(r1, MemOperand(sp, r0, LSL, kPointerSizeLog2));
__ mov(r4, Operand(0, RelocInfo::NONE));
__ jmp(&patch_receiver); __ jmp(&patch_receiver);
// Use the global receiver object from the called function as the // Use the global receiver object from the called function as the
@ -1307,23 +1309,30 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ jmp(&shift_arguments); __ jmp(&shift_arguments);
} }
// 3b. Patch the first argument when calling a non-function. The // 3b. Check for function proxy.
__ bind(&slow);
__ mov(r4, Operand(1, RelocInfo::NONE)); // indicate function proxy
__ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE));
__ b(eq, &shift_arguments);
__ bind(&non_function);
__ mov(r4, Operand(2, RelocInfo::NONE)); // indicate non-function
// 3c. Patch the first argument when calling a non-function. The
// CALL_NON_FUNCTION builtin expects the non-function callee as // CALL_NON_FUNCTION builtin expects the non-function callee as
// receiver, so overwrite the first argument which will ultimately // receiver, so overwrite the first argument which will ultimately
// become the receiver. // become the receiver.
// r0: actual number of arguments // r0: actual number of arguments
// r1: function // r1: function
__ bind(&non_function); // r4: call type (0: JS function, 1: function proxy, 2: non-function)
__ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2)); __ add(r2, sp, Operand(r0, LSL, kPointerSizeLog2));
__ str(r1, MemOperand(r2, -kPointerSize)); __ str(r1, MemOperand(r2, -kPointerSize));
// Clear r1 to indicate a non-function being called.
__ mov(r1, Operand(0, RelocInfo::NONE));
// 4. Shift arguments and return address one slot down on the stack // 4. Shift arguments and return address one slot down on the stack
// (overwriting the original receiver). Adjust argument count to make // (overwriting the original receiver). Adjust argument count to make
// the original first argument the new receiver. // the original first argument the new receiver.
// r0: actual number of arguments // r0: actual number of arguments
// r1: function // r1: function
// r4: call type (0: JS function, 1: function proxy, 2: non-function)
__ bind(&shift_arguments); __ bind(&shift_arguments);
{ Label loop; { Label loop;
// Calculate the copy start address (destination). Copy end address is sp. // Calculate the copy start address (destination). Copy end address is sp.
@ -1341,16 +1350,28 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ pop(); __ pop();
} }
// 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
// or a function proxy via CALL_FUNCTION_PROXY.
// r0: actual number of arguments // r0: actual number of arguments
// r1: function // r1: function
{ Label function; // r4: call type (0: JS function, 1: function proxy, 2: non-function)
__ tst(r1, r1); { Label function, non_proxy;
__ b(ne, &function); __ tst(r4, r4);
__ b(eq, &function);
// Expected number of arguments is 0 for CALL_NON_FUNCTION. // Expected number of arguments is 0 for CALL_NON_FUNCTION.
__ mov(r2, Operand(0, RelocInfo::NONE)); __ mov(r2, Operand(0, RelocInfo::NONE));
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
__ SetCallKind(r5, CALL_AS_METHOD); __ SetCallKind(r5, CALL_AS_METHOD);
__ cmp(r4, Operand(1));
__ b(ne, &non_proxy);
__ push(r1); // re-add proxy object as additional argument
__ add(r0, r0, Operand(1));
__ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
__ bind(&non_proxy);
__ GetBuiltinEntry(r3, Builtins::CALL_NON_FUNCTION);
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), __ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET); RelocInfo::CODE_TARGET);
__ bind(&function); __ bind(&function);
@ -1393,7 +1414,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ push(r0); __ push(r0);
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
// Check the stack for overflow. We are not trying need to catch // Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack // interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked. // limit" is checked.
Label okay; Label okay;
@ -1418,18 +1439,24 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ mov(r1, Operand(0, RelocInfo::NONE)); // initial index __ mov(r1, Operand(0, RelocInfo::NONE)); // initial index
__ push(r1); __ push(r1);
// Get the receiver.
__ ldr(r0, MemOperand(fp, kRecvOffset));
// Check that the function is a JS function (otherwise it must be a proxy).
Label push_receiver;
__ ldr(r1, MemOperand(fp, kFunctionOffset));
__ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
__ b(ne, &push_receiver);
// Change context eagerly to get the right global object if necessary. // Change context eagerly to get the right global object if necessary.
__ ldr(r0, MemOperand(fp, kFunctionOffset)); __ ldr(cp, FieldMemOperand(r1, JSFunction::kContextOffset));
__ ldr(cp, FieldMemOperand(r0, JSFunction::kContextOffset)); // Load the shared function info while the function is still in r1.
// Load the shared function info while the function is still in r0. __ ldr(r2, FieldMemOperand(r1, JSFunction::kSharedFunctionInfoOffset));
__ ldr(r1, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
// Compute the receiver. // Compute the receiver.
Label call_to_object, use_global_receiver, push_receiver;
__ ldr(r0, MemOperand(fp, kRecvOffset));
// Do not transform the receiver for strict mode functions. // Do not transform the receiver for strict mode functions.
__ ldr(r2, FieldMemOperand(r1, SharedFunctionInfo::kCompilerHintsOffset)); Label call_to_object, use_global_receiver;
__ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCompilerHintsOffset));
__ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction + __ tst(r2, Operand(1 << (SharedFunctionInfo::kStrictModeFunction +
kSmiTagSize))); kSmiTagSize)));
__ b(ne, &push_receiver); __ b(ne, &push_receiver);
@ -1504,9 +1531,12 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ b(ne, &loop); __ b(ne, &loop);
// Invoke the function. // Invoke the function.
Label call_proxy;
ParameterCount actual(r0); ParameterCount actual(r0);
__ mov(r0, Operand(r0, ASR, kSmiTagSize)); __ mov(r0, Operand(r0, ASR, kSmiTagSize));
__ ldr(r1, MemOperand(fp, kFunctionOffset)); __ ldr(r1, MemOperand(fp, kFunctionOffset));
__ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
__ b(ne, &call_proxy);
__ InvokeFunction(r1, actual, CALL_FUNCTION, __ InvokeFunction(r1, actual, CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD); NullCallWrapper(), CALL_AS_METHOD);
@ -1514,6 +1544,20 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ LeaveInternalFrame(); __ LeaveInternalFrame();
__ add(sp, sp, Operand(3 * kPointerSize)); __ add(sp, sp, Operand(3 * kPointerSize));
__ Jump(lr); __ Jump(lr);
// Invoke the function proxy.
__ bind(&call_proxy);
__ push(r1); // add function proxy as last argument
__ add(r0, r0, Operand(1));
__ mov(r2, Operand(0, RelocInfo::NONE));
__ SetCallKind(r5, CALL_AS_METHOD);
__ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
__ Call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
__ LeaveInternalFrame();
__ add(sp, sp, Operand(3 * kPointerSize));
__ Jump(lr);
} }

33
deps/v8/src/arm/code-stubs-arm.cc

@ -3432,7 +3432,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
// Retrieve the pending exception and clear the variable. // Retrieve the pending exception and clear the variable.
__ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate))); __ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate)));
__ ldr(r3, MemOperand(ip)); __ ldr(r3, MemOperand(ip));
__ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
__ ldr(r0, MemOperand(ip)); __ ldr(r0, MemOperand(ip));
__ str(r3, MemOperand(ip)); __ str(r3, MemOperand(ip));
@ -3567,7 +3567,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ mov(r7, Operand(Smi::FromInt(marker))); __ mov(r7, Operand(Smi::FromInt(marker)));
__ mov(r6, Operand(Smi::FromInt(marker))); __ mov(r6, Operand(Smi::FromInt(marker)));
__ mov(r5, __ mov(r5,
Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
__ ldr(r5, MemOperand(r5)); __ ldr(r5, MemOperand(r5));
__ Push(r8, r7, r6, r5); __ Push(r8, r7, r6, r5);
@ -3576,7 +3576,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// If this is the outermost JS call, set js_entry_sp value. // If this is the outermost JS call, set js_entry_sp value.
Label non_outermost_js; Label non_outermost_js;
ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, isolate); ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress, isolate);
__ mov(r5, Operand(ExternalReference(js_entry_sp))); __ mov(r5, Operand(ExternalReference(js_entry_sp)));
__ ldr(r6, MemOperand(r5)); __ ldr(r6, MemOperand(r5));
__ cmp(r6, Operand::Zero()); __ cmp(r6, Operand::Zero());
@ -3597,7 +3597,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// exception field in the JSEnv and return a failure sentinel. // exception field in the JSEnv and return a failure sentinel.
// Coming in here the fp will be invalid because the PushTryHandler below // Coming in here the fp will be invalid because the PushTryHandler below
// sets it to 0 to signal the existence of the JSEntry frame. // sets it to 0 to signal the existence of the JSEntry frame.
__ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
__ str(r0, MemOperand(ip)); __ str(r0, MemOperand(ip));
__ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception()))); __ mov(r0, Operand(reinterpret_cast<int32_t>(Failure::Exception())));
@ -3615,7 +3615,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Clear any pending exceptions. // Clear any pending exceptions.
__ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate))); __ mov(ip, Operand(ExternalReference::the_hole_value_location(isolate)));
__ ldr(r5, MemOperand(ip)); __ ldr(r5, MemOperand(ip));
__ mov(ip, Operand(ExternalReference(Isolate::k_pending_exception_address, __ mov(ip, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
__ str(r5, MemOperand(ip)); __ str(r5, MemOperand(ip));
@ -3662,7 +3662,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Restore the top frame descriptors from the stack. // Restore the top frame descriptors from the stack.
__ pop(r3); __ pop(r3);
__ mov(ip, __ mov(ip,
Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate))); Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate)));
__ str(r3, MemOperand(ip)); __ str(r3, MemOperand(ip));
// Reset the stack to the callee saved registers. // Reset the stack to the callee saved registers.
@ -4534,7 +4534,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// TODO(592): Rerunning the RegExp to get the stack overflow exception. // TODO(592): Rerunning the RegExp to get the stack overflow exception.
__ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate))); __ mov(r1, Operand(ExternalReference::the_hole_value_location(isolate)));
__ ldr(r1, MemOperand(r1, 0)); __ ldr(r1, MemOperand(r1, 0));
__ mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, __ mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate))); isolate)));
__ ldr(r0, MemOperand(r2, 0)); __ ldr(r0, MemOperand(r2, 0));
__ cmp(r0, r1); __ cmp(r0, r1);
@ -4713,7 +4713,7 @@ void RegExpConstructResultStub::Generate(MacroAssembler* masm) {
void CallFunctionStub::Generate(MacroAssembler* masm) { void CallFunctionStub::Generate(MacroAssembler* masm) {
Label slow; Label slow, non_function;
// The receiver might implicitly be the global object. This is // The receiver might implicitly be the global object. This is
// indicated by passing the hole as the receiver to the call // indicated by passing the hole as the receiver to the call
@ -4739,7 +4739,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Check that the function is really a JavaScript function. // Check that the function is really a JavaScript function.
// r1: pushed function (to be verified) // r1: pushed function (to be verified)
__ JumpIfSmi(r1, &slow); __ JumpIfSmi(r1, &non_function);
// Get the map of the function object. // Get the map of the function object.
__ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE); __ CompareObjectType(r1, r2, r2, JS_FUNCTION_TYPE);
__ b(ne, &slow); __ b(ne, &slow);
@ -4767,8 +4767,23 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Slow-case: Non-function called. // Slow-case: Non-function called.
__ bind(&slow); __ bind(&slow);
// Check for function proxy.
__ cmp(r2, Operand(JS_FUNCTION_PROXY_TYPE));
__ b(ne, &non_function);
__ push(r1); // put proxy as additional argument
__ mov(r0, Operand(argc_ + 1, RelocInfo::NONE));
__ mov(r2, Operand(0, RelocInfo::NONE));
__ GetBuiltinEntry(r3, Builtins::CALL_FUNCTION_PROXY);
__ SetCallKind(r5, CALL_AS_FUNCTION);
{
Handle<Code> adaptor =
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
__ Jump(adaptor, RelocInfo::CODE_TARGET);
}
// CALL_NON_FUNCTION expects the non-function callee as receiver (instead // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
// of the original receiver from the call site). // of the original receiver from the call site).
__ bind(&non_function);
__ str(r1, MemOperand(sp, argc_ * kPointerSize)); __ str(r1, MemOperand(sp, argc_ * kPointerSize));
__ mov(r0, Operand(argc_)); // Setup the number of arguments. __ mov(r0, Operand(argc_)); // Setup the number of arguments.
__ mov(r2, Operand(0, RelocInfo::NONE)); __ mov(r2, Operand(0, RelocInfo::NONE));

18
deps/v8/src/arm/full-codegen-arm.cc

@ -2028,9 +2028,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
// Record source position for debugger. // Record source position for debugger.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
// Call the IC initialization code. // Call the IC initialization code.
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
__ Call(ic, mode, expr->id()); __ Call(ic, mode, expr->id());
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
@ -2061,9 +2060,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
// Record source position for debugger. // Record source position for debugger.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
// Call the IC initialization code. // Call the IC initialization code.
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count, in_loop); isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
__ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key. __ ldr(r2, MemOperand(sp, (arg_count + 1) * kPointerSize)); // Key.
__ Call(ic, RelocInfo::CODE_TARGET, expr->id()); __ Call(ic, RelocInfo::CODE_TARGET, expr->id());
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
@ -2084,8 +2082,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
} }
// Record source position for debugger. // Record source position for debugger.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; CallFunctionStub stub(arg_count, flags);
CallFunctionStub stub(arg_count, in_loop, flags);
__ CallStub(&stub); __ CallStub(&stub);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
@ -2184,8 +2181,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
// Record source position for debugger. // Record source position for debugger.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
__ CallStub(&stub); __ CallStub(&stub);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
@ -2514,7 +2510,7 @@ void FullCodeGenerator::EmitIsFunction(ZoneList<Expression*>* args) {
&if_true, &if_false, &fall_through); &if_true, &if_false, &fall_through);
__ JumpIfSmi(r0, if_false); __ JumpIfSmi(r0, if_false);
__ CompareObjectType(r0, r1, r1, JS_FUNCTION_TYPE); __ CompareObjectType(r0, r1, r2, JS_FUNCTION_TYPE);
PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false); PrepareForBailoutBeforeSplit(TOS_REG, true, if_true, if_false);
Split(eq, if_true, if_false, fall_through); Split(eq, if_true, if_false, fall_through);
@ -3553,9 +3549,7 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
__ mov(r2, Operand(expr->name())); __ mov(r2, Operand(expr->name()));
RelocInfo::Mode mode = RelocInfo::CODE_TARGET; RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
NOT_IN_LOOP,
mode);
__ Call(ic, mode, expr->id()); __ Call(ic, mode, expr->id());
// Restore context register. // Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));

18
deps/v8/src/arm/ic-arm.cc

@ -146,7 +146,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm,
StringDictionary::kElementsStartIndex * kPointerSize; StringDictionary::kElementsStartIndex * kPointerSize;
const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
__ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
__ tst(scratch1, Operand(PropertyDetails::TypeField::mask() << kSmiTagSize)); __ tst(scratch1, Operand(PropertyDetails::TypeField::kMask << kSmiTagSize));
__ b(ne, miss); __ b(ne, miss);
// Get the value at the masked, scaled index and return. // Get the value at the masked, scaled index and return.
@ -194,8 +194,8 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
const int kElementsStartOffset = StringDictionary::kHeaderSize + const int kElementsStartOffset = StringDictionary::kHeaderSize +
StringDictionary::kElementsStartIndex * kPointerSize; StringDictionary::kElementsStartIndex * kPointerSize;
const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
const int kTypeAndReadOnlyMask const int kTypeAndReadOnlyMask =
= (PropertyDetails::TypeField::mask() | (PropertyDetails::TypeField::kMask |
PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
__ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset)); __ ldr(scratch1, FieldMemOperand(scratch2, kDetailsOffset));
__ tst(scratch1, Operand(kTypeAndReadOnlyMask)); __ tst(scratch1, Operand(kTypeAndReadOnlyMask));
@ -393,7 +393,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind, Code::Flags flags = Code::ComputeFlags(kind,
NOT_IN_LOOP,
MONOMORPHIC, MONOMORPHIC,
extra_ic_state, extra_ic_state,
NORMAL, NORMAL,
@ -734,9 +733,8 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, Code::Flags flags =
NOT_IN_LOOP, Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
MONOMORPHIC);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, r0, r2, r3, r4, r5); masm, flags, r0, r2, r3, r4, r5);
@ -1380,10 +1378,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
// ----------------------------------- // -----------------------------------
// Get the receiver from the stack and probe the stub cache. // Get the receiver from the stack and probe the stub cache.
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, Code::Flags flags =
NOT_IN_LOOP, Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode);
MONOMORPHIC,
strict_mode);
Isolate::Current()->stub_cache()->GenerateProbe( Isolate::Current()->stub_cache()->GenerateProbe(
masm, flags, r1, r2, r3, r4, r5); masm, flags, r1, r2, r3, r4, r5);

33
deps/v8/src/arm/lithium-arm.cc

@ -311,13 +311,13 @@ void LCallKeyed::PrintDataTo(StringStream* stream) {
void LCallNamed::PrintDataTo(StringStream* stream) { void LCallNamed::PrintDataTo(StringStream* stream) {
SmartPointer<char> name_string = name()->ToCString(); SmartArrayPointer<char> name_string = name()->ToCString();
stream->Add("%s #%d / ", *name_string, arity()); stream->Add("%s #%d / ", *name_string, arity());
} }
void LCallGlobal::PrintDataTo(StringStream* stream) { void LCallGlobal::PrintDataTo(StringStream* stream) {
SmartPointer<char> name_string = name()->ToCString(); SmartArrayPointer<char> name_string = name()->ToCString();
stream->Add("%s #%d / ", *name_string, arity()); stream->Add("%s #%d / ", *name_string, arity());
} }
@ -546,7 +546,8 @@ LChunk* LChunkBuilder::Build() {
void LChunkBuilder::Abort(const char* format, ...) { void LChunkBuilder::Abort(const char* format, ...) {
if (FLAG_trace_bailout) { if (FLAG_trace_bailout) {
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); SmartArrayPointer<char> name(
info()->shared_info()->DebugName()->ToCString());
PrintF("Aborting LChunk building in @\"%s\": ", *name); PrintF("Aborting LChunk building in @\"%s\": ", *name);
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
@ -1860,15 +1861,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) { HLoadKeyedSpecializedArrayElement* instr) {
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Representation representation(instr->representation()); Representation representation(instr->representation());
ASSERT( ASSERT(
(representation.IsInteger32() && (representation.IsInteger32() &&
(elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (representation.IsDouble() &&
((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegisterOrConstant(instr->key()); LOperand* key = UseRegisterOrConstant(instr->key());
@ -1877,7 +1878,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
LInstruction* load_instr = DefineAsRegister(result); LInstruction* load_instr = DefineAsRegister(result);
// An unsigned int array load might overflow and cause a deopt, make sure it // An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment. // has an environment.
return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) ? return (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) ?
AssignEnvironment(load_instr) : load_instr; AssignEnvironment(load_instr) : load_instr;
} }
@ -1928,21 +1929,21 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) { HStoreKeyedSpecializedArrayElement* instr) {
Representation representation(instr->value()->representation()); Representation representation(instr->value()->representation());
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
ASSERT( ASSERT(
(representation.IsInteger32() && (representation.IsInteger32() &&
(elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (representation.IsDouble() &&
((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* external_pointer = UseRegister(instr->external_pointer());
bool val_is_temp_register = bool val_is_temp_register =
elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS || elements_kind == EXTERNAL_PIXEL_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS; elements_kind == EXTERNAL_FLOAT_ELEMENTS;
LOperand* val = val_is_temp_register LOperand* val = val_is_temp_register
? UseTempRegister(instr->value()) ? UseTempRegister(instr->value())
: UseRegister(instr->value()); : UseRegister(instr->value());

4
deps/v8/src/arm/lithium-arm.h

@ -1158,7 +1158,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
LOperand* external_pointer() { return inputs_[0]; } LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
JSObject::ElementsKind elements_kind() const { ElementsKind elements_kind() const {
return hydrogen()->elements_kind(); return hydrogen()->elements_kind();
} }
}; };
@ -1662,7 +1662,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
LOperand* external_pointer() { return inputs_[0]; } LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; } LOperand* value() { return inputs_[2]; }
JSObject::ElementsKind elements_kind() const { ElementsKind elements_kind() const {
return hydrogen()->elements_kind(); return hydrogen()->elements_kind();
} }
}; };

93
deps/v8/src/arm/lithium-codegen-arm.cc

@ -101,7 +101,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
void LCodeGen::Abort(const char* format, ...) { void LCodeGen::Abort(const char* format, ...) {
if (FLAG_trace_bailout) { if (FLAG_trace_bailout) {
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); SmartArrayPointer<char> name(
info()->shared_info()->DebugName()->ToCString());
PrintF("Aborting LCodeGen in @\"%s\": ", *name); PrintF("Aborting LCodeGen in @\"%s\": ", *name);
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
@ -2410,11 +2411,11 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
__ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset)); __ ldr(scratch, FieldMemOperand(scratch, Map::kBitField2Offset));
__ ubfx(scratch, scratch, Map::kElementsKindShift, __ ubfx(scratch, scratch, Map::kElementsKindShift,
Map::kElementsKindBitCount); Map::kElementsKindBitCount);
__ cmp(scratch, Operand(JSObject::FAST_ELEMENTS)); __ cmp(scratch, Operand(FAST_ELEMENTS));
__ b(eq, &done); __ b(eq, &done);
__ cmp(scratch, Operand(JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND)); __ cmp(scratch, Operand(FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND));
__ b(lt, &fail); __ b(lt, &fail);
__ cmp(scratch, Operand(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND)); __ cmp(scratch, Operand(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND));
__ b(le, &done); __ b(le, &done);
__ bind(&fail); __ bind(&fail);
__ Abort("Check for fast or external elements failed."); __ Abort("Check for fast or external elements failed.");
@ -2478,7 +2479,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Register scratch = scratch0(); Register scratch = scratch0();
int shift_size = int shift_size =
ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS); ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
int constant_key = 0; int constant_key = 0;
if (key_is_constant) { if (key_is_constant) {
constant_key = ToInteger32(LConstantOperand::cast(instr->key())); constant_key = ToInteger32(LConstantOperand::cast(instr->key()));
@ -2515,7 +2516,7 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) { LLoadKeyedSpecializedArrayElement* instr) {
Register external_pointer = ToRegister(instr->external_pointer()); Register external_pointer = ToRegister(instr->external_pointer());
Register key = no_reg; Register key = no_reg;
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
bool key_is_constant = instr->key()->IsConstantOperand(); bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0; int constant_key = 0;
if (key_is_constant) { if (key_is_constant) {
@ -2528,18 +2529,18 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
} }
int shift_size = ElementsKindToShiftSize(elements_kind); int shift_size = ElementsKindToShiftSize(elements_kind);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
DwVfpRegister result = ToDoubleRegister(instr->result()); DwVfpRegister result = ToDoubleRegister(instr->result());
Operand operand = key_is_constant Operand operand = key_is_constant
? Operand(constant_key * (1 << shift_size)) ? Operand(constant_key * (1 << shift_size))
: Operand(key, LSL, shift_size); : Operand(key, LSL, shift_size);
__ add(scratch0(), external_pointer, operand); __ add(scratch0(), external_pointer, operand);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ vldr(result.low(), scratch0(), 0); __ vldr(result.low(), scratch0(), 0);
__ vcvt_f64_f32(result, result.low()); __ vcvt_f64_f32(result, result.low());
} else { // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ vldr(result, scratch0(), 0); __ vldr(result, scratch0(), 0);
} }
} else { } else {
@ -2548,23 +2549,23 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
? MemOperand(external_pointer, constant_key * (1 << shift_size)) ? MemOperand(external_pointer, constant_key * (1 << shift_size))
: MemOperand(external_pointer, key, LSL, shift_size)); : MemOperand(external_pointer, key, LSL, shift_size));
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
__ ldrsb(result, mem_operand); __ ldrsb(result, mem_operand);
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ ldrb(result, mem_operand); __ ldrb(result, mem_operand);
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
__ ldrsh(result, mem_operand); __ ldrsh(result, mem_operand);
break; break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ ldrh(result, mem_operand); __ ldrh(result, mem_operand);
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
__ ldr(result, mem_operand); __ ldr(result, mem_operand);
break; break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ ldr(result, mem_operand); __ ldr(result, mem_operand);
__ cmp(result, Operand(0x80000000)); __ cmp(result, Operand(0x80000000));
// TODO(danno): we could be more clever here, perhaps having a special // TODO(danno): we could be more clever here, perhaps having a special
@ -2572,12 +2573,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
// happens, and generate code that returns a double rather than int. // happens, and generate code that returns a double rather than int.
DeoptimizeIf(cs, instr->environment()); DeoptimizeIf(cs, instr->environment());
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -3177,7 +3178,7 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
int arity = instr->arity(); int arity = instr->arity();
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
} }
@ -3189,7 +3190,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
int arity = instr->arity(); int arity = instr->arity();
RelocInfo::Mode mode = RelocInfo::CODE_TARGET; RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
__ mov(r2, Operand(instr->name())); __ mov(r2, Operand(instr->name()));
CallCode(ic, mode, instr); CallCode(ic, mode, instr);
// Restore context register. // Restore context register.
@ -3201,7 +3202,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(r0)); ASSERT(ToRegister(instr->result()).is(r0));
int arity = instr->arity(); int arity = instr->arity();
CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
__ Drop(1); __ Drop(1);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@ -3214,7 +3215,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
int arity = instr->arity(); int arity = instr->arity();
RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
__ mov(r2, Operand(instr->name())); __ mov(r2, Operand(instr->name()));
CallCode(ic, mode, instr); CallCode(ic, mode, instr);
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset)); __ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
@ -3340,7 +3341,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
} else { } else {
key = ToRegister(instr->key()); key = ToRegister(instr->key());
} }
int shift_size = ElementsKindToShiftSize(JSObject::FAST_DOUBLE_ELEMENTS); int shift_size = ElementsKindToShiftSize(FAST_DOUBLE_ELEMENTS);
Operand operand = key_is_constant Operand operand = key_is_constant
? Operand(constant_key * (1 << shift_size) + ? Operand(constant_key * (1 << shift_size) +
FixedDoubleArray::kHeaderSize - kHeapObjectTag) FixedDoubleArray::kHeaderSize - kHeapObjectTag)
@ -3367,7 +3368,7 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
Register external_pointer = ToRegister(instr->external_pointer()); Register external_pointer = ToRegister(instr->external_pointer());
Register key = no_reg; Register key = no_reg;
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
bool key_is_constant = instr->key()->IsConstantOperand(); bool key_is_constant = instr->key()->IsConstantOperand();
int constant_key = 0; int constant_key = 0;
if (key_is_constant) { if (key_is_constant) {
@ -3380,17 +3381,17 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
} }
int shift_size = ElementsKindToShiftSize(elements_kind); int shift_size = ElementsKindToShiftSize(elements_kind);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
DwVfpRegister value(ToDoubleRegister(instr->value())); DwVfpRegister value(ToDoubleRegister(instr->value()));
Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size)) Operand operand(key_is_constant ? Operand(constant_key * (1 << shift_size))
: Operand(key, LSL, shift_size)); : Operand(key, LSL, shift_size));
__ add(scratch0(), external_pointer, operand); __ add(scratch0(), external_pointer, operand);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ vcvt_f32_f64(double_scratch0().low(), value); __ vcvt_f32_f64(double_scratch0().low(), value);
__ vstr(double_scratch0().low(), scratch0(), 0); __ vstr(double_scratch0().low(), scratch0(), 0);
} else { // i.e. elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS } else { // i.e. elements_kind == EXTERNAL_DOUBLE_ELEMENTS
__ vstr(value, scratch0(), 0); __ vstr(value, scratch0(), 0);
} }
} else { } else {
@ -3399,25 +3400,25 @@ void LCodeGen::DoStoreKeyedSpecializedArrayElement(
? MemOperand(external_pointer, constant_key * (1 << shift_size)) ? MemOperand(external_pointer, constant_key * (1 << shift_size))
: MemOperand(external_pointer, key, LSL, shift_size)); : MemOperand(external_pointer, key, LSL, shift_size));
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ strb(value, mem_operand); __ strb(value, mem_operand);
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ strh(value, mem_operand); __ strh(value, mem_operand);
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ str(value, mem_operand); __ str(value, mem_operand);
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }

1
deps/v8/src/arm/lithium-gap-resolver-arm.h

@ -40,7 +40,6 @@ class LGapResolver;
class LGapResolver BASE_EMBEDDED { class LGapResolver BASE_EMBEDDED {
public: public:
explicit LGapResolver(LCodeGen* owner); explicit LGapResolver(LCodeGen* owner);
// Resolve a set of parallel moves, emitting assembler instructions. // Resolve a set of parallel moves, emitting assembler instructions.

26
deps/v8/src/arm/macro-assembler-arm.cc

@ -760,9 +760,9 @@ void MacroAssembler::EnterExitFrame(bool save_doubles, int stack_space) {
str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset)); str(ip, MemOperand(fp, ExitFrameConstants::kCodeOffset));
// Save the frame pointer and the context in top. // Save the frame pointer and the context in top.
mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
str(fp, MemOperand(ip)); str(fp, MemOperand(ip));
mov(ip, Operand(ExternalReference(Isolate::k_context_address, isolate()))); mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
str(cp, MemOperand(ip)); str(cp, MemOperand(ip));
// Optionally save all double registers. // Optionally save all double registers.
@ -838,11 +838,11 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles,
// Clear top frame. // Clear top frame.
mov(r3, Operand(0, RelocInfo::NONE)); mov(r3, Operand(0, RelocInfo::NONE));
mov(ip, Operand(ExternalReference(Isolate::k_c_entry_fp_address, isolate()))); mov(ip, Operand(ExternalReference(Isolate::kCEntryFPAddress, isolate())));
str(r3, MemOperand(ip)); str(r3, MemOperand(ip));
// Restore current context from top and clear it in debug mode. // Restore current context from top and clear it in debug mode.
mov(ip, Operand(ExternalReference(Isolate::k_context_address, isolate()))); mov(ip, Operand(ExternalReference(Isolate::kContextAddress, isolate())));
ldr(cp, MemOperand(ip)); ldr(cp, MemOperand(ip));
#ifdef DEBUG #ifdef DEBUG
str(r3, MemOperand(ip)); str(r3, MemOperand(ip));
@ -1118,7 +1118,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
} }
stm(db_w, sp, r3.bit() | cp.bit() | fp.bit() | lr.bit()); stm(db_w, sp, r3.bit() | cp.bit() | fp.bit() | lr.bit());
// Save the current handler as the next handler. // Save the current handler as the next handler.
mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
ldr(r1, MemOperand(r3)); ldr(r1, MemOperand(r3));
push(r1); push(r1);
// Link this handler as the new current one. // Link this handler as the new current one.
@ -1134,7 +1134,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
mov(r7, Operand(0, RelocInfo::NONE)); // NULL frame pointer. mov(r7, Operand(0, RelocInfo::NONE)); // NULL frame pointer.
stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | lr.bit()); stm(db_w, sp, r5.bit() | r6.bit() | r7.bit() | lr.bit());
// Save the current handler as the next handler. // Save the current handler as the next handler.
mov(r7, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); mov(r7, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
ldr(r6, MemOperand(r7)); ldr(r6, MemOperand(r7));
push(r6); push(r6);
// Link this handler as the new current one. // Link this handler as the new current one.
@ -1146,7 +1146,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
void MacroAssembler::PopTryHandler() { void MacroAssembler::PopTryHandler() {
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
pop(r1); pop(r1);
mov(ip, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); mov(ip, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize)); add(sp, sp, Operand(StackHandlerConstants::kSize - kPointerSize));
str(r1, MemOperand(ip)); str(r1, MemOperand(ip));
} }
@ -1166,7 +1166,7 @@ void MacroAssembler::Throw(Register value) {
} }
// Drop the sp to the top of the handler. // Drop the sp to the top of the handler.
mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
ldr(sp, MemOperand(r3)); ldr(sp, MemOperand(r3));
// Restore the next handler. // Restore the next handler.
@ -1206,7 +1206,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
} }
// Drop sp to the top stack handler. // Drop sp to the top stack handler.
mov(r3, Operand(ExternalReference(Isolate::k_handler_address, isolate()))); mov(r3, Operand(ExternalReference(Isolate::kHandlerAddress, isolate())));
ldr(sp, MemOperand(r3)); ldr(sp, MemOperand(r3));
// Unwind the handlers until the ENTRY handler is found. // Unwind the handlers until the ENTRY handler is found.
@ -1230,7 +1230,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
if (type == OUT_OF_MEMORY) { if (type == OUT_OF_MEMORY) {
// Set external caught exception to false. // Set external caught exception to false.
ExternalReference external_caught( ExternalReference external_caught(
Isolate::k_external_caught_exception_address, isolate()); Isolate::kExternalCaughtExceptionAddress, isolate());
mov(r0, Operand(false, RelocInfo::NONE)); mov(r0, Operand(false, RelocInfo::NONE));
mov(r2, Operand(external_caught)); mov(r2, Operand(external_caught));
str(r0, MemOperand(r2)); str(r0, MemOperand(r2));
@ -1238,7 +1238,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
// Set pending exception and r0 to out of memory exception. // Set pending exception and r0 to out of memory exception.
Failure* out_of_memory = Failure::OutOfMemoryException(); Failure* out_of_memory = Failure::OutOfMemoryException();
mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory))); mov(r0, Operand(reinterpret_cast<int32_t>(out_of_memory)));
mov(r2, Operand(ExternalReference(Isolate::k_pending_exception_address, mov(r2, Operand(ExternalReference(Isolate::kPendingExceptionAddress,
isolate()))); isolate())));
str(r0, MemOperand(r2)); str(r0, MemOperand(r2));
} }
@ -1421,7 +1421,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
const int kDetailsOffset = const int kDetailsOffset =
NumberDictionary::kElementsStartOffset + 2 * kPointerSize; NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
ldr(t1, FieldMemOperand(t2, kDetailsOffset)); ldr(t1, FieldMemOperand(t2, kDetailsOffset));
tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::mask()))); tst(t1, Operand(Smi::FromInt(PropertyDetails::TypeField::kMask)));
b(ne, miss); b(ne, miss);
// Get the value at the masked, scaled index and return. // Get the value at the masked, scaled index and return.
@ -1793,7 +1793,7 @@ void MacroAssembler::CompareRoot(Register obj,
void MacroAssembler::CheckFastElements(Register map, void MacroAssembler::CheckFastElements(Register map,
Register scratch, Register scratch,
Label* fail) { Label* fail) {
STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); STATIC_ASSERT(FAST_ELEMENTS == 0);
ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset)); ldrb(scratch, FieldMemOperand(map, Map::kBitField2Offset));
cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue)); cmp(scratch, Operand(Map::kMaximumBitField2FastElementValue));
b(hi, fail); b(hi, fail);

4
deps/v8/src/arm/macro-assembler-arm.h

@ -596,9 +596,7 @@ class MacroAssembler: public Assembler {
// Compare instance type in a map. map contains a valid map object whose // Compare instance type in a map. map contains a valid map object whose
// object type should be compared with the given type. This both // object type should be compared with the given type. This both
// sets the flags and leaves the object type in the type_reg register. It // sets the flags and leaves the object type in the type_reg register.
// leaves the heap object in the heap_object register unless the heap_object
// register is the same register as type_reg.
void CompareInstanceType(Register map, void CompareInstanceType(Register map,
Register type_reg, Register type_reg,
InstanceType type); InstanceType type);

1
deps/v8/src/arm/regexp-macro-assembler-arm.h

@ -116,6 +116,7 @@ class RegExpMacroAssemblerARM: public NativeRegExpMacroAssembler {
static int CheckStackGuardState(Address* return_address, static int CheckStackGuardState(Address* return_address,
Code* re_code, Code* re_code,
Address re_frame); Address re_frame);
private: private:
// Offsets from frame_pointer() of function parameters and stored registers. // Offsets from frame_pointer() of function parameters and stored registers.
static const int kFramePointer = 0; static const int kFramePointer = 0;

160
deps/v8/src/arm/stub-cache-arm.cc

@ -3099,7 +3099,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
// -- r1 : receiver // -- r1 : receiver
// ----------------------------------- // -----------------------------------
Code* stub; Code* stub;
JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); ElementsKind elements_kind = receiver_map->elements_kind();
MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
if (!maybe_stub->To(&stub)) return maybe_stub; if (!maybe_stub->To(&stub)) return maybe_stub;
__ DispatchMap(r1, __ DispatchMap(r1,
@ -3193,7 +3193,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
// -- r3 : scratch // -- r3 : scratch
// ----------------------------------- // -----------------------------------
Code* stub; Code* stub;
JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); ElementsKind elements_kind = receiver_map->elements_kind();
bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE; bool is_js_array = receiver_map->instance_type() == JS_ARRAY_TYPE;
MaybeObject* maybe_stub = MaybeObject* maybe_stub =
KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
@ -3438,25 +3438,25 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
} }
static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) { static bool IsElementTypeSigned(ElementsKind elements_kind) {
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
return true; return true;
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
return false; return false;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
return false; return false;
} }
@ -3466,7 +3466,7 @@ static bool IsElementTypeSigned(JSObject::ElementsKind elements_kind) {
void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedLoadStubCompiler::GenerateLoadExternalArray(
MacroAssembler* masm, MacroAssembler* masm,
JSObject::ElementsKind elements_kind) { ElementsKind elements_kind) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- lr : return address // -- lr : return address
// -- r0 : key // -- r0 : key
@ -3501,24 +3501,24 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
Register value = r2; Register value = r2;
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
__ ldrsb(value, MemOperand(r3, key, LSR, 1)); __ ldrsb(value, MemOperand(r3, key, LSR, 1));
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ ldrb(value, MemOperand(r3, key, LSR, 1)); __ ldrb(value, MemOperand(r3, key, LSR, 1));
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
__ ldrsh(value, MemOperand(r3, key, LSL, 0)); __ ldrsh(value, MemOperand(r3, key, LSL, 0));
break; break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ ldrh(value, MemOperand(r3, key, LSL, 0)); __ ldrh(value, MemOperand(r3, key, LSL, 0));
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ ldr(value, MemOperand(r3, key, LSL, 1)); __ ldr(value, MemOperand(r3, key, LSL, 1));
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
if (CpuFeatures::IsSupported(VFP3)) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
__ add(r2, r3, Operand(key, LSL, 1)); __ add(r2, r3, Operand(key, LSL, 1));
@ -3527,7 +3527,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ ldr(value, MemOperand(r3, key, LSL, 1)); __ ldr(value, MemOperand(r3, key, LSL, 1));
} }
break; break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
if (CpuFeatures::IsSupported(VFP3)) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
__ add(r2, r3, Operand(key, LSL, 2)); __ add(r2, r3, Operand(key, LSL, 2));
@ -3539,10 +3539,10 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ ldr(r3, MemOperand(r4, Register::kSizeInBytes)); __ ldr(r3, MemOperand(r4, Register::kSizeInBytes));
} }
break; break;
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -3556,7 +3556,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// d0: value (if VFP3 is supported) // d0: value (if VFP3 is supported)
// r2/r3: value (if VFP3 is not supported) // r2/r3: value (if VFP3 is not supported)
if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { if (elements_kind == EXTERNAL_INT_ELEMENTS) {
// For the Int and UnsignedInt array types, we need to see whether // For the Int and UnsignedInt array types, we need to see whether
// the value can be represented in a Smi. If not, we need to convert // the value can be represented in a Smi. If not, we need to convert
// it to a HeapNumber. // it to a HeapNumber.
@ -3600,7 +3600,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset)); __ str(dst2, FieldMemOperand(r0, HeapNumber::kExponentOffset));
__ Ret(); __ Ret();
} }
} else if (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { } else if (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
// The test is different for unsigned int values. Since we need // The test is different for unsigned int values. Since we need
// the value to be in the range of a positive smi, we can't // the value to be in the range of a positive smi, we can't
// handle either of the top two bits being set in the value. // handle either of the top two bits being set in the value.
@ -3665,7 +3665,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ mov(r0, r4); __ mov(r0, r4);
__ Ret(); __ Ret();
} }
} else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
// For the floating-point array type, we need to always allocate a // For the floating-point array type, we need to always allocate a
// HeapNumber. // HeapNumber.
if (CpuFeatures::IsSupported(VFP3)) { if (CpuFeatures::IsSupported(VFP3)) {
@ -3735,7 +3735,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ mov(r0, r3); __ mov(r0, r3);
__ Ret(); __ Ret();
} }
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
if (CpuFeatures::IsSupported(VFP3)) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
// Allocate a HeapNumber for the result. Don't use r0 and r1 as // Allocate a HeapNumber for the result. Don't use r0 and r1 as
@ -3792,7 +3792,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
void KeyedStoreStubCompiler::GenerateStoreExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray(
MacroAssembler* masm, MacroAssembler* masm,
JSObject::ElementsKind elements_kind) { ElementsKind elements_kind) {
// ---------- S t a t e -------------- // ---------- S t a t e --------------
// -- r0 : value // -- r0 : value
// -- r1 : key // -- r1 : key
@ -3824,7 +3824,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// Handle both smis and HeapNumbers in the fast path. Go to the // Handle both smis and HeapNumbers in the fast path. Go to the
// runtime for all other kinds of values. // runtime for all other kinds of values.
// r3: external array. // r3: external array.
if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
// Double to pixel conversion is only implemented in the runtime for now. // Double to pixel conversion is only implemented in the runtime for now.
__ JumpIfNotSmi(value, &slow); __ JumpIfNotSmi(value, &slow);
} else { } else {
@ -3836,29 +3836,29 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// r3: base pointer of external storage. // r3: base pointer of external storage.
// r5: value (integer). // r5: value (integer).
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
// Clamp the value to [0..255]. // Clamp the value to [0..255].
__ Usat(r5, 8, Operand(r5)); __ Usat(r5, 8, Operand(r5));
__ strb(r5, MemOperand(r3, key, LSR, 1)); __ strb(r5, MemOperand(r3, key, LSR, 1));
break; break;
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ strb(r5, MemOperand(r3, key, LSR, 1)); __ strb(r5, MemOperand(r3, key, LSR, 1));
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ strh(r5, MemOperand(r3, key, LSL, 0)); __ strh(r5, MemOperand(r3, key, LSL, 0));
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ str(r5, MemOperand(r3, key, LSL, 1)); __ str(r5, MemOperand(r3, key, LSL, 1));
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
// Perform int-to-float conversion and store to memory. // Perform int-to-float conversion and store to memory.
__ SmiUntag(r4, key); __ SmiUntag(r4, key);
StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9); StoreIntAsFloat(masm, r3, r4, r5, r6, r7, r9);
break; break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
__ add(r3, r3, Operand(key, LSL, 2)); __ add(r3, r3, Operand(key, LSL, 2));
// r3: effective address of the double element // r3: effective address of the double element
FloatingPointHelper::Destination destination; FloatingPointHelper::Destination destination;
@ -3879,10 +3879,10 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ str(r7, MemOperand(r3, Register::kSizeInBytes)); __ str(r7, MemOperand(r3, Register::kSizeInBytes));
} }
break; break;
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -3890,7 +3890,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// Entry registers are intact, r0 holds the value which is the return value. // Entry registers are intact, r0 holds the value which is the return value.
__ Ret(); __ Ret();
if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
// r3: external array. // r3: external array.
__ bind(&check_heap_number); __ bind(&check_heap_number);
__ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE); __ CompareObjectType(value, r5, r6, HEAP_NUMBER_TYPE);
@ -3906,7 +3906,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
if (CpuFeatures::IsSupported(VFP3)) { if (CpuFeatures::IsSupported(VFP3)) {
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
// vldr requires offset to be a multiple of 4 so we can not // vldr requires offset to be a multiple of 4 so we can not
// include -kHeapObjectTag into it. // include -kHeapObjectTag into it.
__ sub(r5, r0, Operand(kHeapObjectTag)); __ sub(r5, r0, Operand(kHeapObjectTag));
@ -3914,7 +3914,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ add(r5, r3, Operand(key, LSL, 1)); __ add(r5, r3, Operand(key, LSL, 1));
__ vcvt_f32_f64(s0, d0); __ vcvt_f32_f64(s0, d0);
__ vstr(s0, r5, 0); __ vstr(s0, r5, 0);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
__ sub(r5, r0, Operand(kHeapObjectTag)); __ sub(r5, r0, Operand(kHeapObjectTag));
__ vldr(d0, r5, HeapNumber::kValueOffset); __ vldr(d0, r5, HeapNumber::kValueOffset);
__ add(r5, r3, Operand(key, LSL, 2)); __ add(r5, r3, Operand(key, LSL, 2));
@ -3927,25 +3927,25 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ EmitECMATruncate(r5, d0, s2, r6, r7, r9); __ EmitECMATruncate(r5, d0, s2, r6, r7, r9);
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ strb(r5, MemOperand(r3, key, LSR, 1)); __ strb(r5, MemOperand(r3, key, LSR, 1));
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ strh(r5, MemOperand(r3, key, LSL, 0)); __ strh(r5, MemOperand(r3, key, LSL, 0));
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ str(r5, MemOperand(r3, key, LSL, 1)); __ str(r5, MemOperand(r3, key, LSL, 1));
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -3959,7 +3959,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset)); __ ldr(r5, FieldMemOperand(value, HeapNumber::kExponentOffset));
__ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset)); __ ldr(r6, FieldMemOperand(value, HeapNumber::kMantissaOffset));
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
Label done, nan_or_infinity_or_zero; Label done, nan_or_infinity_or_zero;
static const int kMantissaInHiWordShift = static const int kMantissaInHiWordShift =
kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord; kBinary32MantissaBits - HeapNumber::kMantissaBitsInTopWord;
@ -4011,7 +4011,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift)); __ orr(r9, r9, Operand(r5, LSL, kMantissaInHiWordShift));
__ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift)); __ orr(r5, r9, Operand(r6, LSR, kMantissaInLoWordShift));
__ b(&done); __ b(&done);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
__ add(r7, r3, Operand(key, LSL, 2)); __ add(r7, r3, Operand(key, LSL, 2));
// r7: effective address of destination element. // r7: effective address of destination element.
__ str(r6, MemOperand(r7, 0)); __ str(r6, MemOperand(r7, 0));
@ -4066,25 +4066,25 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ bind(&done); __ bind(&done);
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ strb(r5, MemOperand(r3, key, LSR, 1)); __ strb(r5, MemOperand(r3, key, LSR, 1));
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ strh(r5, MemOperand(r3, key, LSL, 0)); __ strh(r5, MemOperand(r3, key, LSL, 0));
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ str(r5, MemOperand(r3, key, LSL, 1)); __ str(r5, MemOperand(r3, key, LSL, 1));
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }

18
deps/v8/src/array.js

@ -208,7 +208,7 @@ function ConvertToLocaleString(e) {
// Call ToString if toLocaleString is not a function. // Call ToString if toLocaleString is not a function.
// See issue 877615. // See issue 877615.
var e_obj = ToObject(e); var e_obj = ToObject(e);
if (IS_FUNCTION(e_obj.toLocaleString)) if (IS_SPEC_FUNCTION(e_obj.toLocaleString))
return ToString(e_obj.toLocaleString()); return ToString(e_obj.toLocaleString());
else else
return ToString(e); return ToString(e);
@ -730,7 +730,7 @@ function ArraySort(comparefn) {
// In-place QuickSort algorithm. // In-place QuickSort algorithm.
// For short (length <= 22) arrays, insertion sort is used for efficiency. // For short (length <= 22) arrays, insertion sort is used for efficiency.
if (!IS_FUNCTION(comparefn)) { if (!IS_SPEC_FUNCTION(comparefn)) {
comparefn = function (x, y) { comparefn = function (x, y) {
if (x === y) return 0; if (x === y) return 0;
if (%_IsSmi(x) && %_IsSmi(y)) { if (%_IsSmi(x) && %_IsSmi(y)) {
@ -993,7 +993,7 @@ function ArrayFilter(f, receiver) {
["Array.prototype.filter"]); ["Array.prototype.filter"]);
} }
if (!IS_FUNCTION(f)) { if (!IS_SPEC_FUNCTION(f)) {
throw MakeTypeError('called_non_callable', [ f ]); throw MakeTypeError('called_non_callable', [ f ]);
} }
if (IS_NULL_OR_UNDEFINED(receiver)) { if (IS_NULL_OR_UNDEFINED(receiver)) {
@ -1022,7 +1022,7 @@ function ArrayForEach(f, receiver) {
["Array.prototype.forEach"]); ["Array.prototype.forEach"]);
} }
if (!IS_FUNCTION(f)) { if (!IS_SPEC_FUNCTION(f)) {
throw MakeTypeError('called_non_callable', [ f ]); throw MakeTypeError('called_non_callable', [ f ]);
} }
if (IS_NULL_OR_UNDEFINED(receiver)) { if (IS_NULL_OR_UNDEFINED(receiver)) {
@ -1048,7 +1048,7 @@ function ArraySome(f, receiver) {
["Array.prototype.some"]); ["Array.prototype.some"]);
} }
if (!IS_FUNCTION(f)) { if (!IS_SPEC_FUNCTION(f)) {
throw MakeTypeError('called_non_callable', [ f ]); throw MakeTypeError('called_non_callable', [ f ]);
} }
if (IS_NULL_OR_UNDEFINED(receiver)) { if (IS_NULL_OR_UNDEFINED(receiver)) {
@ -1073,7 +1073,7 @@ function ArrayEvery(f, receiver) {
["Array.prototype.every"]); ["Array.prototype.every"]);
} }
if (!IS_FUNCTION(f)) { if (!IS_SPEC_FUNCTION(f)) {
throw MakeTypeError('called_non_callable', [ f ]); throw MakeTypeError('called_non_callable', [ f ]);
} }
if (IS_NULL_OR_UNDEFINED(receiver)) { if (IS_NULL_OR_UNDEFINED(receiver)) {
@ -1097,7 +1097,7 @@ function ArrayMap(f, receiver) {
["Array.prototype.map"]); ["Array.prototype.map"]);
} }
if (!IS_FUNCTION(f)) { if (!IS_SPEC_FUNCTION(f)) {
throw MakeTypeError('called_non_callable', [ f ]); throw MakeTypeError('called_non_callable', [ f ]);
} }
if (IS_NULL_OR_UNDEFINED(receiver)) { if (IS_NULL_OR_UNDEFINED(receiver)) {
@ -1245,7 +1245,7 @@ function ArrayReduce(callback, current) {
["Array.prototype.reduce"]); ["Array.prototype.reduce"]);
} }
if (!IS_FUNCTION(callback)) { if (!IS_SPEC_FUNCTION(callback)) {
throw MakeTypeError('called_non_callable', [callback]); throw MakeTypeError('called_non_callable', [callback]);
} }
@ -1281,7 +1281,7 @@ function ArrayReduceRight(callback, current) {
["Array.prototype.reduceRight"]); ["Array.prototype.reduceRight"]);
} }
if (!IS_FUNCTION(callback)) { if (!IS_SPEC_FUNCTION(callback)) {
throw MakeTypeError('called_non_callable', [callback]); throw MakeTypeError('called_non_callable', [callback]);
} }
var i = ToUint32(this.length) - 1; var i = ToUint32(this.length) - 1;

4
deps/v8/src/ast.cc

@ -969,7 +969,7 @@ class RegExpUnparser: public RegExpVisitor {
public: public:
RegExpUnparser(); RegExpUnparser();
void VisitCharacterRange(CharacterRange that); void VisitCharacterRange(CharacterRange that);
SmartPointer<const char> ToString() { return stream_.ToCString(); } SmartArrayPointer<const char> ToString() { return stream_.ToCString(); }
#define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, void* data); #define MAKE_CASE(Name) virtual void* Visit##Name(RegExp##Name*, void* data);
FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE) FOR_EACH_REG_EXP_TREE_TYPE(MAKE_CASE)
#undef MAKE_CASE #undef MAKE_CASE
@ -1124,7 +1124,7 @@ void* RegExpUnparser::VisitEmpty(RegExpEmpty* that, void* data) {
} }
SmartPointer<const char> RegExpTree::ToString() { SmartArrayPointer<const char> RegExpTree::ToString() {
RegExpUnparser unparser; RegExpUnparser unparser;
Accept(&unparser, NULL); Accept(&unparser, NULL);
return unparser.ToString(); return unparser.ToString();

2
deps/v8/src/ast.h

@ -1775,7 +1775,7 @@ class RegExpTree: public ZoneObject {
// expression. // expression.
virtual Interval CaptureRegisters() { return Interval::Empty(); } virtual Interval CaptureRegisters() { return Interval::Empty(); }
virtual void AppendToText(RegExpText* text); virtual void AppendToText(RegExpText* text);
SmartPointer<const char> ToString(); SmartArrayPointer<const char> ToString();
#define MAKE_ASTYPE(Name) \ #define MAKE_ASTYPE(Name) \
virtual RegExp##Name* As##Name(); \ virtual RegExp##Name* As##Name(); \
virtual bool Is##Name(); virtual bool Is##Name();

1
deps/v8/src/bignum.h

@ -92,6 +92,7 @@ class Bignum {
static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) { static bool PlusLess(const Bignum& a, const Bignum& b, const Bignum& c) {
return PlusCompare(a, b, c) < 0; return PlusCompare(a, b, c) < 0;
} }
private: private:
typedef uint32_t Chunk; typedef uint32_t Chunk;
typedef uint64_t DoubleChunk; typedef uint64_t DoubleChunk;

4
deps/v8/src/bootstrapper.cc

@ -1067,7 +1067,7 @@ void Genesis::InitializeGlobal(Handle<GlobalObject> inner_global,
Handle<Map> new_map = factory->CopyMapDropTransitions(old_map); Handle<Map> new_map = factory->CopyMapDropTransitions(old_map);
new_map->set_pre_allocated_property_fields(2); new_map->set_pre_allocated_property_fields(2);
Handle<JSObject> result = factory->NewJSObjectFromMap(new_map); Handle<JSObject> result = factory->NewJSObjectFromMap(new_map);
new_map->set_elements_kind(JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); new_map->set_elements_kind(NON_STRICT_ARGUMENTS_ELEMENTS);
// Set up a well-formed parameter map to make assertions happy. // Set up a well-formed parameter map to make assertions happy.
Handle<FixedArray> elements = factory->NewFixedArray(2); Handle<FixedArray> elements = factory->NewFixedArray(2);
elements->set_map(heap->non_strict_arguments_elements_map()); elements->set_map(heap->non_strict_arguments_elements_map());
@ -2062,7 +2062,7 @@ void Genesis::TransferNamedProperties(Handle<JSObject> from,
break; break;
} }
case MAP_TRANSITION: case MAP_TRANSITION:
case EXTERNAL_ARRAY_TRANSITION: case ELEMENTS_TRANSITION:
case CONSTANT_TRANSITION: case CONSTANT_TRANSITION:
case NULL_DESCRIPTOR: case NULL_DESCRIPTOR:
// Ignore non-properties. // Ignore non-properties.

1
deps/v8/src/builtins.cc

@ -1583,7 +1583,6 @@ void Builtins::InitBuiltinFunctionTable() {
functions->s_name = #aname; \ functions->s_name = #aname; \
functions->name = k##aname; \ functions->name = k##aname; \
functions->flags = Code::ComputeFlags(Code::kind, \ functions->flags = Code::ComputeFlags(Code::kind, \
NOT_IN_LOOP, \
state, \ state, \
extra); \ extra); \
functions->extra_args = NO_EXTRA_ARGUMENTS; \ functions->extra_args = NO_EXTRA_ARGUMENTS; \

2
deps/v8/src/builtins.h

@ -238,6 +238,8 @@ enum BuiltinExtraArguments {
V(FILTER_KEY, 1) \ V(FILTER_KEY, 1) \
V(CALL_NON_FUNCTION, 0) \ V(CALL_NON_FUNCTION, 0) \
V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \ V(CALL_NON_FUNCTION_AS_CONSTRUCTOR, 0) \
V(CALL_FUNCTION_PROXY, 1) \
V(CALL_FUNCTION_PROXY_AS_CONSTRUCTOR, 1) \
V(TO_OBJECT, 0) \ V(TO_OBJECT, 0) \
V(TO_NUMBER, 0) \ V(TO_NUMBER, 0) \
V(TO_STRING, 0) \ V(TO_STRING, 0) \

1
deps/v8/src/cached-powers.h

@ -35,7 +35,6 @@ namespace internal {
class PowersOfTenCache { class PowersOfTenCache {
public: public:
// Not all powers of ten are cached. The decimal exponent of two neighboring // Not all powers of ten are cached. The decimal exponent of two neighboring
// cached numbers will differ by kDecimalExponentDistance. // cached numbers will differ by kDecimalExponentDistance.
static const int kDecimalExponentDistance; static const int kDecimalExponentDistance;

8
deps/v8/src/circular-queue-inl.h

@ -1,4 +1,4 @@
// Copyright 2010 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -25,8 +25,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#ifndef V8_CIRCULAR_BUFFER_INL_H_ #ifndef V8_CIRCULAR_QUEUE_INL_H_
#define V8_CIRCULAR_BUFFER_INL_H_ #define V8_CIRCULAR_QUEUE_INL_H_
#include "circular-queue.h" #include "circular-queue.h"
@ -50,4 +50,4 @@ void SamplingCircularQueue::WrapPositionIfNeeded(
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_CIRCULAR_BUFFER_INL_H_ #endif // V8_CIRCULAR_QUEUE_INL_H_

65
deps/v8/src/code-stubs.cc

@ -61,7 +61,7 @@ void CodeStub::GenerateCode(MacroAssembler* masm) {
} }
SmartPointer<const char> CodeStub::GetName() { SmartArrayPointer<const char> CodeStub::GetName() {
char buffer[100]; char buffer[100];
NoAllocationStringAllocator allocator(buffer, NoAllocationStringAllocator allocator(buffer,
static_cast<unsigned>(sizeof(buffer))); static_cast<unsigned>(sizeof(buffer)));
@ -75,7 +75,7 @@ void CodeStub::RecordCodeGeneration(Code* code, MacroAssembler* masm) {
code->set_major_key(MajorKey()); code->set_major_key(MajorKey());
Isolate* isolate = masm->isolate(); Isolate* isolate = masm->isolate();
SmartPointer<const char> name = GetName(); SmartArrayPointer<const char> name = GetName();
PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name)); PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
GDBJIT(AddCode(GDBJITInterface::STUB, *name, code)); GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
Counters* counters = isolate->counters(); Counters* counters = isolate->counters();
@ -114,7 +114,6 @@ Handle<Code> CodeStub::GetCode() {
// Copy the generated code into a heap object. // Copy the generated code into a heap object.
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
static_cast<Code::Kind>(GetCodeKind()), static_cast<Code::Kind>(GetCodeKind()),
InLoop(),
GetICState()); GetICState());
Handle<Code> new_object = factory->NewCode( Handle<Code> new_object = factory->NewCode(
desc, flags, masm.CodeObject(), NeedsImmovableCode()); desc, flags, masm.CodeObject(), NeedsImmovableCode());
@ -152,7 +151,6 @@ MaybeObject* CodeStub::TryGetCode() {
// Try to copy the generated code into a heap object. // Try to copy the generated code into a heap object.
Code::Flags flags = Code::ComputeFlags( Code::Flags flags = Code::ComputeFlags(
static_cast<Code::Kind>(GetCodeKind()), static_cast<Code::Kind>(GetCodeKind()),
InLoop(),
GetICState()); GetICState());
Object* new_object; Object* new_object;
{ MaybeObject* maybe_new_object = { MaybeObject* maybe_new_object =
@ -246,27 +244,27 @@ void InstanceofStub::PrintName(StringStream* stream) {
void KeyedLoadElementStub::Generate(MacroAssembler* masm) { void KeyedLoadElementStub::Generate(MacroAssembler* masm) {
switch (elements_kind_) { switch (elements_kind_) {
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
KeyedLoadStubCompiler::GenerateLoadFastElement(masm); KeyedLoadStubCompiler::GenerateLoadFastElement(masm);
break; break;
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm); KeyedLoadStubCompiler::GenerateLoadFastDoubleElement(masm);
break; break;
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_); KeyedLoadStubCompiler::GenerateLoadExternalArray(masm, elements_kind_);
break; break;
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm); KeyedLoadStubCompiler::GenerateLoadDictionaryElement(masm);
break; break;
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -275,28 +273,28 @@ void KeyedLoadElementStub::Generate(MacroAssembler* masm) {
void KeyedStoreElementStub::Generate(MacroAssembler* masm) { void KeyedStoreElementStub::Generate(MacroAssembler* masm) {
switch (elements_kind_) { switch (elements_kind_) {
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_); KeyedStoreStubCompiler::GenerateStoreFastElement(masm, is_js_array_);
break; break;
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm, KeyedStoreStubCompiler::GenerateStoreFastDoubleElement(masm,
is_js_array_); is_js_array_);
break; break;
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_); KeyedStoreStubCompiler::GenerateStoreExternalArray(masm, elements_kind_);
break; break;
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm); KeyedStoreStubCompiler::GenerateStoreDictionaryElement(masm);
break; break;
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -316,17 +314,12 @@ void ArgumentsAccessStub::PrintName(StringStream* stream) {
void CallFunctionStub::PrintName(StringStream* stream) { void CallFunctionStub::PrintName(StringStream* stream) {
const char* in_loop_name = NULL; // Make g++ happy.
switch (in_loop_) {
case NOT_IN_LOOP: in_loop_name = ""; break;
case IN_LOOP: in_loop_name = "_InLoop"; break;
}
const char* flags_name = NULL; // Make g++ happy. const char* flags_name = NULL; // Make g++ happy.
switch (flags_) { switch (flags_) {
case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break; case NO_CALL_FUNCTION_FLAGS: flags_name = ""; break;
case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break; case RECEIVER_MIGHT_BE_IMPLICIT: flags_name = "_Implicit"; break;
} }
stream->Add("CallFunctionStub_Args%d%s%s", argc_, in_loop_name, flags_name); stream->Add("CallFunctionStub_Args%d%s", argc_, flags_name);
} }

32
deps/v8/src/code-stubs.h

@ -168,10 +168,6 @@ class CodeStub BASE_EMBEDDED {
virtual Major MajorKey() = 0; virtual Major MajorKey() = 0;
virtual int MinorKey() = 0; virtual int MinorKey() = 0;
// The CallFunctionStub needs to override this so it can encode whether a
// lazily generated function should be fully optimized or not.
virtual InLoopFlag InLoop() { return NOT_IN_LOOP; }
// BinaryOpStub needs to override this. // BinaryOpStub needs to override this.
virtual int GetCodeKind(); virtual int GetCodeKind();
@ -181,7 +177,7 @@ class CodeStub BASE_EMBEDDED {
} }
// Returns a name for logging/debugging purposes. // Returns a name for logging/debugging purposes.
SmartPointer<const char> GetName(); SmartArrayPointer<const char> GetName();
virtual void PrintName(StringStream* stream) { virtual void PrintName(StringStream* stream) {
stream->Add("%s", MajorName(MajorKey(), false)); stream->Add("%s", MajorName(MajorKey(), false));
} }
@ -646,8 +642,8 @@ class RegExpConstructResultStub: public CodeStub {
class CallFunctionStub: public CodeStub { class CallFunctionStub: public CodeStub {
public: public:
CallFunctionStub(int argc, InLoopFlag in_loop, CallFunctionFlags flags) CallFunctionStub(int argc, CallFunctionFlags flags)
: argc_(argc), in_loop_(in_loop), flags_(flags) { } : argc_(argc), flags_(flags) { }
void Generate(MacroAssembler* masm); void Generate(MacroAssembler* masm);
@ -657,26 +653,20 @@ class CallFunctionStub: public CodeStub {
private: private:
int argc_; int argc_;
InLoopFlag in_loop_;
CallFunctionFlags flags_; CallFunctionFlags flags_;
virtual void PrintName(StringStream* stream); virtual void PrintName(StringStream* stream);
// Minor key encoding in 32 bits with Bitfield <Type, shift, size>. // Minor key encoding in 32 bits with Bitfield <Type, shift, size>.
class InLoopBits: public BitField<InLoopFlag, 0, 1> {}; class FlagBits: public BitField<CallFunctionFlags, 0, 1> {};
class FlagBits: public BitField<CallFunctionFlags, 1, 1> {}; class ArgcBits: public BitField<unsigned, 1, 32 - 1> {};
class ArgcBits: public BitField<int, 2, 32 - 2> {};
Major MajorKey() { return CallFunction; } Major MajorKey() { return CallFunction; }
int MinorKey() { int MinorKey() {
// Encode the parameters in a unique 32 bit value. // Encode the parameters in a unique 32 bit value.
return InLoopBits::encode(in_loop_) return FlagBits::encode(flags_) | ArgcBits::encode(argc_);
| FlagBits::encode(flags_)
| ArgcBits::encode(argc_);
} }
InLoopFlag InLoop() { return in_loop_; }
bool ReceiverMightBeImplicit() { bool ReceiverMightBeImplicit() {
return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0; return (flags_ & RECEIVER_MIGHT_BE_IMPLICIT) != 0;
} }
@ -860,7 +850,7 @@ class AllowStubCallsScope {
class KeyedLoadElementStub : public CodeStub { class KeyedLoadElementStub : public CodeStub {
public: public:
explicit KeyedLoadElementStub(JSObject::ElementsKind elements_kind) explicit KeyedLoadElementStub(ElementsKind elements_kind)
: elements_kind_(elements_kind) : elements_kind_(elements_kind)
{ } { }
@ -870,7 +860,7 @@ class KeyedLoadElementStub : public CodeStub {
void Generate(MacroAssembler* masm); void Generate(MacroAssembler* masm);
private: private:
JSObject::ElementsKind elements_kind_; ElementsKind elements_kind_;
DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub); DISALLOW_COPY_AND_ASSIGN(KeyedLoadElementStub);
}; };
@ -879,20 +869,20 @@ class KeyedLoadElementStub : public CodeStub {
class KeyedStoreElementStub : public CodeStub { class KeyedStoreElementStub : public CodeStub {
public: public:
KeyedStoreElementStub(bool is_js_array, KeyedStoreElementStub(bool is_js_array,
JSObject::ElementsKind elements_kind) ElementsKind elements_kind)
: is_js_array_(is_js_array), : is_js_array_(is_js_array),
elements_kind_(elements_kind) { } elements_kind_(elements_kind) { }
Major MajorKey() { return KeyedStoreElement; } Major MajorKey() { return KeyedStoreElement; }
int MinorKey() { int MinorKey() {
return (is_js_array_ ? 0 : JSObject::kElementsKindCount) + elements_kind_; return (is_js_array_ ? 0 : kElementsKindCount) + elements_kind_;
} }
void Generate(MacroAssembler* masm); void Generate(MacroAssembler* masm);
private: private:
bool is_js_array_; bool is_js_array_;
JSObject::ElementsKind elements_kind_; ElementsKind elements_kind_;
DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub); DISALLOW_COPY_AND_ASSIGN(KeyedStoreElementStub);
}; };

1
deps/v8/src/compilation-cache.h

@ -242,6 +242,7 @@ class CompilationCache {
// cache during debugging to make sure new scripts are always compiled. // cache during debugging to make sure new scripts are always compiled.
void Enable(); void Enable();
void Disable(); void Disable();
private: private:
explicit CompilationCache(Isolate* isolate); explicit CompilationCache(Isolate* isolate);
~CompilationCache(); ~CompilationCache();

10
deps/v8/src/compiler.h

@ -49,11 +49,11 @@ class CompilationInfo BASE_EMBEDDED {
ASSERT(Isolate::Current() == isolate_); ASSERT(Isolate::Current() == isolate_);
return isolate_; return isolate_;
} }
bool is_lazy() const { return (flags_ & IsLazy::mask()) != 0; } bool is_lazy() const { return IsLazy::decode(flags_); }
bool is_eval() const { return (flags_ & IsEval::mask()) != 0; } bool is_eval() const { return IsEval::decode(flags_); }
bool is_global() const { return (flags_ & IsGlobal::mask()) != 0; } bool is_global() const { return IsGlobal::decode(flags_); }
bool is_strict_mode() const { return (flags_ & IsStrictMode::mask()) != 0; } bool is_strict_mode() const { return IsStrictMode::decode(flags_); }
bool is_in_loop() const { return (flags_ & IsInLoop::mask()) != 0; } bool is_in_loop() const { return IsInLoop::decode(flags_); }
FunctionLiteral* function() const { return function_; } FunctionLiteral* function() const { return function_; }
Scope* scope() const { return scope_; } Scope* scope() const { return scope_; }
Handle<Code> code() const { return code_; } Handle<Code> code() const { return code_; }

5
deps/v8/src/cpu-profiler-inl.h

@ -51,11 +51,6 @@ void CodeMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
} }
void CodeDeleteEventRecord::UpdateCodeMap(CodeMap* code_map) {
code_map->DeleteCode(start);
}
void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) { void SharedFunctionInfoMoveEventRecord::UpdateCodeMap(CodeMap* code_map) {
code_map->MoveCode(from, to); code_map->MoveCode(from, to);
} }

11
deps/v8/src/cpu-profiler.cc

@ -137,16 +137,6 @@ void ProfilerEventsProcessor::CodeMoveEvent(Address from, Address to) {
} }
void ProfilerEventsProcessor::CodeDeleteEvent(Address from) {
CodeEventsContainer evt_rec;
CodeDeleteEventRecord* rec = &evt_rec.CodeDeleteEventRecord_;
rec->type = CodeEventRecord::CODE_DELETE;
rec->order = ++enqueue_order_;
rec->start = from;
events_buffer_.Enqueue(evt_rec);
}
void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from, void ProfilerEventsProcessor::SharedFunctionInfoMoveEvent(Address from,
Address to) { Address to) {
CodeEventsContainer evt_rec; CodeEventsContainer evt_rec;
@ -425,7 +415,6 @@ void CpuProfiler::CodeMoveEvent(Address from, Address to) {
void CpuProfiler::CodeDeleteEvent(Address from) { void CpuProfiler::CodeDeleteEvent(Address from) {
Isolate::Current()->cpu_profiler()->processor_->CodeDeleteEvent(from);
} }

9
deps/v8/src/cpu-profiler.h

@ -48,7 +48,6 @@ class TokenEnumerator;
#define CODE_EVENTS_TYPE_LIST(V) \ #define CODE_EVENTS_TYPE_LIST(V) \
V(CODE_CREATION, CodeCreateEventRecord) \ V(CODE_CREATION, CodeCreateEventRecord) \
V(CODE_MOVE, CodeMoveEventRecord) \ V(CODE_MOVE, CodeMoveEventRecord) \
V(CODE_DELETE, CodeDeleteEventRecord) \
V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord) V(SHARED_FUNC_MOVE, SharedFunctionInfoMoveEventRecord)
@ -87,14 +86,6 @@ class CodeMoveEventRecord : public CodeEventRecord {
}; };
class CodeDeleteEventRecord : public CodeEventRecord {
public:
Address start;
INLINE(void UpdateCodeMap(CodeMap* code_map));
};
class SharedFunctionInfoMoveEventRecord : public CodeEventRecord { class SharedFunctionInfoMoveEventRecord : public CodeEventRecord {
public: public:
Address from; Address from;

12
deps/v8/src/d8-debug.cc

@ -221,14 +221,14 @@ void RemoteDebugger::Run() {
} }
void RemoteDebugger::MessageReceived(i::SmartPointer<char> message) { void RemoteDebugger::MessageReceived(i::SmartArrayPointer<char> message) {
RemoteDebuggerEvent* event = RemoteDebuggerEvent* event =
new RemoteDebuggerEvent(RemoteDebuggerEvent::kMessage, message); new RemoteDebuggerEvent(RemoteDebuggerEvent::kMessage, message);
AddEvent(event); AddEvent(event);
} }
void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) { void RemoteDebugger::KeyboardCommand(i::SmartArrayPointer<char> command) {
RemoteDebuggerEvent* event = RemoteDebuggerEvent* event =
new RemoteDebuggerEvent(RemoteDebuggerEvent::kKeyboard, command); new RemoteDebuggerEvent(RemoteDebuggerEvent::kKeyboard, command);
AddEvent(event); AddEvent(event);
@ -238,7 +238,7 @@ void RemoteDebugger::KeyboardCommand(i::SmartPointer<char> command) {
void RemoteDebugger::ConnectionClosed() { void RemoteDebugger::ConnectionClosed() {
RemoteDebuggerEvent* event = RemoteDebuggerEvent* event =
new RemoteDebuggerEvent(RemoteDebuggerEvent::kDisconnect, new RemoteDebuggerEvent(RemoteDebuggerEvent::kDisconnect,
i::SmartPointer<char>()); i::SmartArrayPointer<char>());
AddEvent(event); AddEvent(event);
} }
@ -330,13 +330,13 @@ void RemoteDebugger::HandleKeyboardCommand(char* command) {
void ReceiverThread::Run() { void ReceiverThread::Run() {
// Receive the connect message (with empty body). // Receive the connect message (with empty body).
i::SmartPointer<char> message = i::SmartArrayPointer<char> message =
i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn()); i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
ASSERT(*message == NULL); ASSERT(*message == NULL);
while (true) { while (true) {
// Receive a message. // Receive a message.
i::SmartPointer<char> message = i::SmartArrayPointer<char> message =
i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn()); i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
if (*message == NULL) { if (*message == NULL) {
remote_debugger_->ConnectionClosed(); remote_debugger_->ConnectionClosed();
@ -361,7 +361,7 @@ void KeyboardThread::Run() {
// Pass the keyboard command to the main thread. // Pass the keyboard command to the main thread.
remote_debugger_->KeyboardCommand( remote_debugger_->KeyboardCommand(
i::SmartPointer<char>(i::StrDup(command))); i::SmartArrayPointer<char>(i::StrDup(command)));
} }
} }

8
deps/v8/src/d8-debug.h

@ -61,8 +61,8 @@ class RemoteDebugger {
void Run(); void Run();
// Handle events from the subordinate threads. // Handle events from the subordinate threads.
void MessageReceived(i::SmartPointer<char> message); void MessageReceived(i::SmartArrayPointer<char> message);
void KeyboardCommand(i::SmartPointer<char> command); void KeyboardCommand(i::SmartArrayPointer<char> command);
void ConnectionClosed(); void ConnectionClosed();
private: private:
@ -127,7 +127,7 @@ class KeyboardThread: public i::Thread {
// Events processed by the main deubgger thread. // Events processed by the main deubgger thread.
class RemoteDebuggerEvent { class RemoteDebuggerEvent {
public: public:
RemoteDebuggerEvent(int type, i::SmartPointer<char> data) RemoteDebuggerEvent(int type, i::SmartArrayPointer<char> data)
: type_(type), data_(data), next_(NULL) { : type_(type), data_(data), next_(NULL) {
ASSERT(type == kMessage || type == kKeyboard || type == kDisconnect); ASSERT(type == kMessage || type == kKeyboard || type == kDisconnect);
} }
@ -144,7 +144,7 @@ class RemoteDebuggerEvent {
RemoteDebuggerEvent* next() { return next_; } RemoteDebuggerEvent* next() { return next_; }
int type_; int type_;
i::SmartPointer<char> data_; i::SmartArrayPointer<char> data_;
RemoteDebuggerEvent* next_; RemoteDebuggerEvent* next_;
friend class RemoteDebugger; friend class RemoteDebugger;

1
deps/v8/src/d8-posix.cc

@ -231,6 +231,7 @@ class ExecArgs {
static const unsigned kMaxArgs = 1000; static const unsigned kMaxArgs = 1000;
char** arg_array() { return exec_args_; } char** arg_array() { return exec_args_; }
char* arg0() { return exec_args_[0]; } char* arg0() { return exec_args_[0]; }
private: private:
char* exec_args_[kMaxArgs + 1]; char* exec_args_[kMaxArgs + 1];
}; };

23
deps/v8/src/d8-readline.cc

@ -1,4 +1,4 @@
// Copyright 2008 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -49,7 +49,7 @@ namespace v8 {
class ReadLineEditor: public LineEditor { class ReadLineEditor: public LineEditor {
public: public:
ReadLineEditor() : LineEditor(LineEditor::READLINE, "readline") { } ReadLineEditor() : LineEditor(LineEditor::READLINE, "readline") { }
virtual i::SmartPointer<char> Prompt(const char* prompt); virtual i::SmartArrayPointer<char> Prompt(const char* prompt);
virtual bool Open(); virtual bool Open();
virtual bool Close(); virtual bool Close();
virtual void AddHistory(const char* str); virtual void AddHistory(const char* str);
@ -72,6 +72,7 @@ bool ReadLineEditor::Open() {
rl_completer_word_break_characters = kWordBreakCharacters; rl_completer_word_break_characters = kWordBreakCharacters;
rl_bind_key('\t', rl_complete); rl_bind_key('\t', rl_complete);
using_history(); using_history();
stifle_history(Shell::kMaxHistoryEntries);
return read_history(Shell::kHistoryFileName) == 0; return read_history(Shell::kHistoryFileName) == 0;
} }
@ -81,13 +82,25 @@ bool ReadLineEditor::Close() {
} }
i::SmartPointer<char> ReadLineEditor::Prompt(const char* prompt) { i::SmartArrayPointer<char> ReadLineEditor::Prompt(const char* prompt) {
char* result = readline(prompt); char* result = readline(prompt);
return i::SmartPointer<char>(result); return i::SmartArrayPointer<char>(result);
} }
void ReadLineEditor::AddHistory(const char* str) { void ReadLineEditor::AddHistory(const char* str) {
// Do not record empty input.
if (strlen(str) == 0) return;
// Remove duplicate history entry.
history_set_pos(history_length-1);
if (current_history()) {
do {
if (strcmp(current_history()->line, str) == 0) {
remove_history(where_history());
break;
}
} while (previous_history());
}
add_history(str); add_history(str);
} }
@ -105,7 +118,7 @@ char* ReadLineEditor::CompletionGenerator(const char* text, int state) {
static unsigned current_index; static unsigned current_index;
static Persistent<Array> current_completions; static Persistent<Array> current_completions;
if (state == 0) { if (state == 0) {
i::SmartPointer<char> full_text(i::StrNDup(rl_line_buffer, rl_point)); i::SmartArrayPointer<char> full_text(i::StrNDup(rl_line_buffer, rl_point));
HandleScope scope; HandleScope scope;
Handle<Array> completions = Handle<Array> completions =
Shell::GetCompletions(String::New(text), String::New(*full_text)); Shell::GetCompletions(String::New(text), String::New(*full_text));

162
deps/v8/src/d8.cc

@ -70,6 +70,7 @@ namespace v8 {
#ifndef V8_SHARED #ifndef V8_SHARED
LineEditor *LineEditor::first_ = NULL; LineEditor *LineEditor::first_ = NULL;
const char* Shell::kHistoryFileName = ".d8_history"; const char* Shell::kHistoryFileName = ".d8_history";
const int Shell::kMaxHistoryEntries = 1000;
LineEditor::LineEditor(Type type, const char* name) LineEditor::LineEditor(Type type, const char* name)
@ -95,19 +96,19 @@ LineEditor* LineEditor::Get() {
class DumbLineEditor: public LineEditor { class DumbLineEditor: public LineEditor {
public: public:
DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { } DumbLineEditor() : LineEditor(LineEditor::DUMB, "dumb") { }
virtual i::SmartPointer<char> Prompt(const char* prompt); virtual i::SmartArrayPointer<char> Prompt(const char* prompt);
}; };
static DumbLineEditor dumb_line_editor; static DumbLineEditor dumb_line_editor;
i::SmartPointer<char> DumbLineEditor::Prompt(const char* prompt) { i::SmartArrayPointer<char> DumbLineEditor::Prompt(const char* prompt) {
static const int kBufferSize = 256; static const int kBufferSize = 256;
char buffer[kBufferSize]; char buffer[kBufferSize];
printf("%s", prompt); printf("%s", prompt);
char* str = fgets(buffer, kBufferSize, stdin); char* str = fgets(buffer, kBufferSize, stdin);
return i::SmartPointer<char>(str ? i::StrDup(str) : str); return i::SmartArrayPointer<char>(str ? i::StrDup(str) : str);
} }
@ -117,6 +118,7 @@ CounterCollection Shell::local_counters_;
CounterCollection* Shell::counters_ = &local_counters_; CounterCollection* Shell::counters_ = &local_counters_;
i::Mutex* Shell::context_mutex_(i::OS::CreateMutex()); i::Mutex* Shell::context_mutex_(i::OS::CreateMutex());
Persistent<Context> Shell::utility_context_; Persistent<Context> Shell::utility_context_;
LineEditor* Shell::console = NULL;
#endif // V8_SHARED #endif // V8_SHARED
Persistent<Context> Shell::evaluation_context_; Persistent<Context> Shell::evaluation_context_;
@ -203,7 +205,7 @@ Handle<Value> Shell::Write(const Arguments& args) {
int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout)); int n = static_cast<int>(fwrite(*str, sizeof(**str), str.length(), stdout));
if (n != str.length()) { if (n != str.length()) {
printf("Error in fwrite\n"); printf("Error in fwrite\n");
exit(1); Exit(1);
} }
} }
return Undefined(); return Undefined();
@ -271,7 +273,7 @@ Handle<Value> Shell::Load(const Arguments& args) {
if (source.IsEmpty()) { if (source.IsEmpty()) {
return ThrowException(String::New("Error loading file")); return ThrowException(String::New("Error loading file"));
} }
if (!ExecuteString(source, String::New(*file), false, false)) { if (!ExecuteString(source, String::New(*file), false, true)) {
return ThrowException(String::New("Error executing file")); return ThrowException(String::New("Error executing file"));
} }
} }
@ -295,18 +297,20 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
size_t length = 0; size_t length = 0;
if (args[0]->IsUint32()) { if (args[0]->IsUint32()) {
length = args[0]->Uint32Value(); length = args[0]->Uint32Value();
} else if (args[0]->IsNumber()) { } else {
double raw_length = args[0]->NumberValue(); Local<Number> number = args[0]->ToNumber();
if (number.IsEmpty() || !number->IsNumber()) {
return ThrowException(String::New("Array length must be a number."));
}
int32_t raw_length = number->ToInt32()->Int32Value();
if (raw_length < 0) { if (raw_length < 0) {
return ThrowException(String::New("Array length must not be negative.")); return ThrowException(String::New("Array length must not be negative."));
} }
if (raw_length > kMaxLength) { if (raw_length > static_cast<int32_t>(kMaxLength)) {
return ThrowException( return ThrowException(
String::New("Array length exceeds maximum length.")); String::New("Array length exceeds maximum length."));
} }
length = static_cast<size_t>(raw_length); length = static_cast<size_t>(raw_length);
} else {
return ThrowException(String::New("Array length must be a number."));
} }
if (length > static_cast<size_t>(kMaxLength)) { if (length > static_cast<size_t>(kMaxLength)) {
return ThrowException(String::New("Array length exceeds maximum length.")); return ThrowException(String::New("Array length exceeds maximum length."));
@ -439,6 +443,7 @@ void Shell::ReportException(v8::TryCatch* try_catch) {
printf("%s\n", stack_trace_string); printf("%s\n", stack_trace_string);
} }
} }
printf("\n");
} }
@ -518,7 +523,7 @@ void Shell::MapCounters(const char* name) {
NULL : counters_file_->memory(); NULL : counters_file_->memory();
if (memory == NULL) { if (memory == NULL) {
printf("Could not map counters file %s\n", name); printf("Could not map counters file %s\n", name);
exit(1); Exit(1);
} }
counters_ = static_cast<CounterCollection*>(memory); counters_ = static_cast<CounterCollection*>(memory);
V8::SetCounterFunction(LookupCounter); V8::SetCounterFunction(LookupCounter);
@ -715,7 +720,7 @@ void Shell::Initialize() {
int bz2_result = startup_data_decompressor.Decompress(); int bz2_result = startup_data_decompressor.Decompress();
if (bz2_result != BZ_OK) { if (bz2_result != BZ_OK) {
fprintf(stderr, "bzip error code: %d\n", bz2_result); fprintf(stderr, "bzip error code: %d\n", bz2_result);
exit(1); Exit(1);
} }
#endif #endif
@ -777,8 +782,18 @@ Persistent<Context> Shell::CreateEvaluationContext() {
} }
void Shell::Exit(int exit_code) {
// Use _exit instead of exit to avoid races between isolate
// threads and static destructors.
fflush(stdout);
fflush(stderr);
_exit(exit_code);
}
#ifndef V8_SHARED #ifndef V8_SHARED
void Shell::OnExit() { void Shell::OnExit() {
if (console != NULL) console->Close();
if (i::FLAG_dump_counters) { if (i::FLAG_dump_counters) {
printf("+----------------------------------------+-------------+\n"); printf("+----------------------------------------+-------------+\n");
printf("| Name | Value |\n"); printf("| Name | Value |\n");
@ -883,20 +898,19 @@ void Shell::RunShell() {
HandleScope outer_scope; HandleScope outer_scope;
Handle<String> name = String::New("(d8)"); Handle<String> name = String::New("(d8)");
#ifndef V8_SHARED #ifndef V8_SHARED
LineEditor* editor = LineEditor::Get(); console = LineEditor::Get();
printf("V8 version %s [console: %s]\n", V8::GetVersion(), editor->name()); printf("V8 version %s [console: %s]\n", V8::GetVersion(), console->name());
if (i::FLAG_debugger) { if (i::FLAG_debugger) {
printf("JavaScript debugger enabled\n"); printf("JavaScript debugger enabled\n");
} }
editor->Open(); console->Open();
while (true) { while (true) {
i::SmartPointer<char> input = editor->Prompt(Shell::kPrompt); i::SmartArrayPointer<char> input = console->Prompt(Shell::kPrompt);
if (input.is_empty()) break; if (input.is_empty()) break;
editor->AddHistory(*input); console->AddHistory(*input);
HandleScope inner_scope; HandleScope inner_scope;
ExecuteString(String::New(*input), name, true, true); ExecuteString(String::New(*input), name, true, true);
} }
editor->Close();
#else #else
printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion()); printf("V8 version %s [D8 light using shared library]\n", V8::GetVersion());
static const int kBufferSize = 256; static const int kBufferSize = 256;
@ -915,18 +929,24 @@ void Shell::RunShell() {
#ifndef V8_SHARED #ifndef V8_SHARED
class ShellThread : public i::Thread { class ShellThread : public i::Thread {
public: public:
ShellThread(int no, i::Vector<const char> files) // Takes ownership of the underlying char array of |files|.
ShellThread(int no, char* files)
: Thread("d8:ShellThread"), : Thread("d8:ShellThread"),
no_(no), files_(files) { } no_(no), files_(files) { }
~ShellThread() {
delete[] files_;
}
virtual void Run(); virtual void Run();
private: private:
int no_; int no_;
i::Vector<const char> files_; char* files_;
}; };
void ShellThread::Run() { void ShellThread::Run() {
char* ptr = const_cast<char*>(files_.start()); char* ptr = files_;
while ((ptr != NULL) && (*ptr != '\0')) { while ((ptr != NULL) && (*ptr != '\0')) {
// For each newline-separated line. // For each newline-separated line.
char* next_line = ReadLine(ptr); char* next_line = ReadLine(ptr);
@ -939,23 +959,24 @@ void ShellThread::Run() {
// Prepare the context for this thread. // Prepare the context for this thread.
Locker locker; Locker locker;
HandleScope scope; HandleScope outer_scope;
Persistent<Context> thread_context = Shell::CreateEvaluationContext(); Persistent<Context> thread_context = Shell::CreateEvaluationContext();
Context::Scope context_scope(thread_context); Context::Scope context_scope(thread_context);
while ((ptr != NULL) && (*ptr != '\0')) { while ((ptr != NULL) && (*ptr != '\0')) {
HandleScope inner_scope;
char* filename = ptr; char* filename = ptr;
ptr = ReadWord(ptr); ptr = ReadWord(ptr);
// Skip empty strings. // Skip empty strings.
if (strlen(filename) == 0) { if (strlen(filename) == 0) {
break; continue;
} }
Handle<String> str = Shell::ReadFile(filename); Handle<String> str = Shell::ReadFile(filename);
if (str.IsEmpty()) { if (str.IsEmpty()) {
printf("WARNING: %s not found\n", filename); printf("File '%s' not found\n", filename);
break; Shell::Exit(1);
} }
Shell::ExecuteString(str, String::New(filename), false, false); Shell::ExecuteString(str, String::New(filename), false, false);
@ -968,12 +989,15 @@ void ShellThread::Run() {
#endif // V8_SHARED #endif // V8_SHARED
void SourceGroup::ExitShell(int exit_code) { SourceGroup::~SourceGroup() {
// Use _exit instead of exit to avoid races between isolate #ifndef V8_SHARED
// threads and static destructors. delete next_semaphore_;
fflush(stdout); next_semaphore_ = NULL;
fflush(stderr); delete done_semaphore_;
_exit(exit_code); done_semaphore_ = NULL;
delete thread_;
thread_ = NULL;
#endif // V8_SHARED
} }
@ -986,8 +1010,7 @@ void SourceGroup::Execute() {
Handle<String> file_name = String::New("unnamed"); Handle<String> file_name = String::New("unnamed");
Handle<String> source = String::New(argv_[i + 1]); Handle<String> source = String::New(argv_[i + 1]);
if (!Shell::ExecuteString(source, file_name, false, true)) { if (!Shell::ExecuteString(source, file_name, false, true)) {
ExitShell(1); Shell::Exit(1);
return;
} }
++i; ++i;
} else if (arg[0] == '-') { } else if (arg[0] == '-') {
@ -999,12 +1022,10 @@ void SourceGroup::Execute() {
Handle<String> source = ReadFile(arg); Handle<String> source = ReadFile(arg);
if (source.IsEmpty()) { if (source.IsEmpty()) {
printf("Error reading '%s'\n", arg); printf("Error reading '%s'\n", arg);
ExitShell(1); Shell::Exit(1);
return;
} }
if (!Shell::ExecuteString(source, file_name, false, true)) { if (!Shell::ExecuteString(source, file_name, false, true)) {
ExitShell(1); Shell::Exit(1);
return;
} }
} }
} }
@ -1037,7 +1058,7 @@ i::Thread::Options SourceGroup::GetThreadOptions() {
void SourceGroup::ExecuteInThread() { void SourceGroup::ExecuteInThread() {
Isolate* isolate = Isolate::New(); Isolate* isolate = Isolate::New();
do { do {
if (!next_semaphore_.is_empty()) next_semaphore_->Wait(); if (next_semaphore_ != NULL) next_semaphore_->Wait();
{ {
Isolate::Scope iscope(isolate); Isolate::Scope iscope(isolate);
Locker lock(isolate); Locker lock(isolate);
@ -1049,15 +1070,15 @@ void SourceGroup::ExecuteInThread() {
} }
context.Dispose(); context.Dispose();
} }
if (!done_semaphore_.is_empty()) done_semaphore_->Signal(); if (done_semaphore_ != NULL) done_semaphore_->Signal();
} while (!Shell::options.last_run); } while (!Shell::options.last_run);
isolate->Dispose(); isolate->Dispose();
} }
void SourceGroup::StartExecuteInThread() { void SourceGroup::StartExecuteInThread() {
if (thread_.is_empty()) { if (thread_ == NULL) {
thread_ = i::SmartPointer<i::Thread>(new IsolateThread(this)); thread_ = new IsolateThread(this);
thread_->Start(); thread_->Start();
} }
next_semaphore_->Signal(); next_semaphore_->Signal();
@ -1065,7 +1086,7 @@ void SourceGroup::StartExecuteInThread() {
void SourceGroup::WaitForThread() { void SourceGroup::WaitForThread() {
if (thread_.is_empty()) return; if (thread_ == NULL) return;
if (Shell::options.last_run) { if (Shell::options.last_run) {
thread_->Join(); thread_->Join();
} else { } else {
@ -1140,14 +1161,18 @@ bool Shell::SetOptions(int argc, char* argv[]) {
return false; return false;
#endif // V8_SHARED #endif // V8_SHARED
options.num_isolates++; options.num_isolates++;
} else if (strcmp(argv[i], "-p") == 0) {
#ifdef V8_SHARED
printf("D8 with shared library does not support multi-threading\n");
return false;
#else
options.num_parallel_files++;
#endif // V8_SHARED
} }
#ifdef V8_SHARED #ifdef V8_SHARED
else if (strcmp(argv[i], "--dump-counters") == 0) { else if (strcmp(argv[i], "--dump-counters") == 0) {
printf("D8 with shared library does not include counters\n"); printf("D8 with shared library does not include counters\n");
return false; return false;
} else if (strcmp(argv[i], "-p") == 0) {
printf("D8 with shared library does not support multi-threading\n");
return false;
} else if (strcmp(argv[i], "--debugger") == 0) { } else if (strcmp(argv[i], "--debugger") == 0) {
printf("Javascript debugger not included\n"); printf("Javascript debugger not included\n");
return false; return false;
@ -1157,6 +1182,8 @@ bool Shell::SetOptions(int argc, char* argv[]) {
#ifndef V8_SHARED #ifndef V8_SHARED
// Run parallel threads if we are not using --isolate // Run parallel threads if we are not using --isolate
options.parallel_files = new char*[options.num_parallel_files];
int parallel_files_set = 0;
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (argv[i] == NULL) continue; if (argv[i] == NULL) continue;
if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) { if (strcmp(argv[i], "-p") == 0 && i + 1 < argc) {
@ -1165,25 +1192,21 @@ bool Shell::SetOptions(int argc, char* argv[]) {
return false; return false;
} }
argv[i] = NULL; argv[i] = NULL;
if (options.parallel_files == NULL) { i++;
options.parallel_files = new i::List<i::Vector<const char> >(); options.parallel_files[parallel_files_set] = argv[i];
} parallel_files_set++;
int size = 0;
const char* files = ReadChars(argv[++i], &size);
if (files == NULL) {
printf("-p option incomplete\n");
return false;
}
argv[i] = NULL; argv[i] = NULL;
options.parallel_files->Add(i::Vector<const char>(files, size));
delete[] files;
} }
} }
if (parallel_files_set != options.num_parallel_files) {
printf("-p requires a file containing a list of files as parameter\n");
return false;
}
#endif // V8_SHARED #endif // V8_SHARED
v8::V8::SetFlagsFromCommandLine(&argc, argv, true); v8::V8::SetFlagsFromCommandLine(&argc, argv, true);
// set up isolated source groups // Set up isolated source groups.
options.isolate_sources = new SourceGroup[options.num_isolates]; options.isolate_sources = new SourceGroup[options.num_isolates];
SourceGroup* current = options.isolate_sources; SourceGroup* current = options.isolate_sources;
current->Begin(argv, 1); current->Begin(argv, 1);
@ -1206,14 +1229,22 @@ bool Shell::SetOptions(int argc, char* argv[]) {
int Shell::RunMain(int argc, char* argv[]) { int Shell::RunMain(int argc, char* argv[]) {
#ifndef V8_SHARED #ifndef V8_SHARED
i::List<i::Thread*> threads(1); i::List<i::Thread*> threads(1);
if (options.parallel_files != NULL) if (options.parallel_files != NULL) {
for (int i = 0; i < options.parallel_files->length(); i++) { for (int i = 0; i < options.num_parallel_files; i++) {
i::Vector<const char> files = options.parallel_files->at(i); char* files = NULL;
{ Locker lock(Isolate::GetCurrent());
int size = 0;
files = ReadChars(options.parallel_files[i], &size);
}
if (files == NULL) {
printf("File list '%s' not found\n", options.parallel_files[i]);
Exit(1);
}
ShellThread* thread = new ShellThread(threads.length(), files); ShellThread* thread = new ShellThread(threads.length(), files);
thread->Start(); thread->Start();
threads.Add(thread); threads.Add(thread);
} }
}
for (int i = 1; i < options.num_isolates; ++i) { for (int i = 1; i < options.num_isolates; ++i) {
options.isolate_sources[i].StartExecuteInThread(); options.isolate_sources[i].StartExecuteInThread();
} }
@ -1235,8 +1266,7 @@ int Shell::RunMain(int argc, char* argv[]) {
#ifndef V8_SHARED #ifndef V8_SHARED
// Start preemption if threads have been created and preemption is enabled. // Start preemption if threads have been created and preemption is enabled.
if (options.parallel_files != NULL if (threads.length() > 0
&& threads.length() > 0
&& options.use_preemption) { && options.use_preemption) {
Locker::StartPreemption(options.preemption_interval); Locker::StartPreemption(options.preemption_interval);
} }
@ -1248,12 +1278,16 @@ int Shell::RunMain(int argc, char* argv[]) {
options.isolate_sources[i].WaitForThread(); options.isolate_sources[i].WaitForThread();
} }
if (options.parallel_files != NULL)
for (int i = 0; i < threads.length(); i++) { for (int i = 0; i < threads.length(); i++) {
i::Thread* thread = threads[i]; i::Thread* thread = threads[i];
thread->Join(); thread->Join();
delete thread; delete thread;
} }
if (threads.length() > 0 && options.use_preemption) {
Locker lock;
Locker::StopPreemption();
}
#endif // V8_SHARED #endif // V8_SHARED
return 0; return 0;
} }

74
deps/v8/src/d8.h

@ -1,4 +1,4 @@
// Copyright 2009 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -31,7 +31,7 @@
#ifndef V8_SHARED #ifndef V8_SHARED
#include "allocation.h" #include "allocation.h"
#include "hashmap.h" #include "hashmap.h"
#include "smart-pointer.h" #include "smart-array-pointer.h"
#include "v8.h" #include "v8.h"
#else #else
#include "../include/v8.h" #include "../include/v8.h"
@ -116,17 +116,43 @@ class CounterMap {
#endif // V8_SHARED #endif // V8_SHARED
#ifndef V8_SHARED
class LineEditor {
public:
enum Type { DUMB = 0, READLINE = 1 };
LineEditor(Type type, const char* name);
virtual ~LineEditor() { }
virtual i::SmartArrayPointer<char> Prompt(const char* prompt) = 0;
virtual bool Open() { return true; }
virtual bool Close() { return true; }
virtual void AddHistory(const char* str) { }
const char* name() { return name_; }
static LineEditor* Get();
private:
Type type_;
const char* name_;
LineEditor* next_;
static LineEditor* first_;
};
#endif // V8_SHARED
class SourceGroup { class SourceGroup {
public: public:
SourceGroup() : SourceGroup() :
#ifndef V8_SHARED #ifndef V8_SHARED
next_semaphore_(v8::internal::OS::CreateSemaphore(0)), next_semaphore_(v8::internal::OS::CreateSemaphore(0)),
done_semaphore_(v8::internal::OS::CreateSemaphore(0)), done_semaphore_(v8::internal::OS::CreateSemaphore(0)),
thread_(NULL),
#endif // V8_SHARED #endif // V8_SHARED
argv_(NULL), argv_(NULL),
begin_offset_(0), begin_offset_(0),
end_offset_(0) {} end_offset_(0) {}
~SourceGroup();
void Begin(char** argv, int offset) { void Begin(char** argv, int offset) {
argv_ = const_cast<const char**>(argv); argv_ = const_cast<const char**>(argv);
begin_offset_ = offset; begin_offset_ = offset;
@ -157,9 +183,9 @@ class SourceGroup {
static i::Thread::Options GetThreadOptions(); static i::Thread::Options GetThreadOptions();
void ExecuteInThread(); void ExecuteInThread();
i::SmartPointer<i::Semaphore> next_semaphore_; i::Semaphore* next_semaphore_;
i::SmartPointer<i::Semaphore> done_semaphore_; i::Semaphore* done_semaphore_;
i::SmartPointer<i::Thread> thread_; i::Thread* thread_;
#endif // V8_SHARED #endif // V8_SHARED
void ExitShell(int exit_code); void ExitShell(int exit_code);
@ -177,6 +203,7 @@ class ShellOptions {
#ifndef V8_SHARED #ifndef V8_SHARED
use_preemption(true), use_preemption(true),
preemption_interval(10), preemption_interval(10),
num_parallel_files(0),
parallel_files(NULL), parallel_files(NULL),
#endif // V8_SHARED #endif // V8_SHARED
script_executed(false), script_executed(false),
@ -188,10 +215,18 @@ class ShellOptions {
num_isolates(1), num_isolates(1),
isolate_sources(NULL) { } isolate_sources(NULL) { }
~ShellOptions() {
#ifndef V8_SHARED
delete[] parallel_files;
#endif // V8_SHARED
delete[] isolate_sources;
}
#ifndef V8_SHARED #ifndef V8_SHARED
bool use_preemption; bool use_preemption;
int preemption_interval; int preemption_interval;
i::List< i::Vector<const char> >* parallel_files; int num_parallel_files;
char** parallel_files;
#endif // V8_SHARED #endif // V8_SHARED
bool script_executed; bool script_executed;
bool last_run; bool last_run;
@ -208,6 +243,7 @@ class Shell {
#else #else
class Shell : public i::AllStatic { class Shell : public i::AllStatic {
#endif // V8_SHARED #endif // V8_SHARED
public: public:
static bool ExecuteString(Handle<String> source, static bool ExecuteString(Handle<String> source,
Handle<Value> name, Handle<Value> name,
@ -219,6 +255,7 @@ class Shell : public i::AllStatic {
static Persistent<Context> CreateEvaluationContext(); static Persistent<Context> CreateEvaluationContext();
static int RunMain(int argc, char* argv[]); static int RunMain(int argc, char* argv[]);
static int Main(int argc, char* argv[]); static int Main(int argc, char* argv[]);
static void Exit(int exit_code);
#ifndef V8_SHARED #ifndef V8_SHARED
static Handle<Array> GetCompletions(Handle<String> text, static Handle<Array> GetCompletions(Handle<String> text,
@ -299,6 +336,8 @@ class Shell : public i::AllStatic {
static void AddOSMethods(Handle<ObjectTemplate> os_template); static void AddOSMethods(Handle<ObjectTemplate> os_template);
#ifndef V8_SHARED #ifndef V8_SHARED
static const char* kHistoryFileName; static const char* kHistoryFileName;
static const int kMaxHistoryEntries;
static LineEditor* console;
#endif // V8_SHARED #endif // V8_SHARED
static const char* kPrompt; static const char* kPrompt;
static ShellOptions options; static ShellOptions options;
@ -329,29 +368,6 @@ class Shell : public i::AllStatic {
}; };
#ifndef V8_SHARED
class LineEditor {
public:
enum Type { DUMB = 0, READLINE = 1 };
LineEditor(Type type, const char* name);
virtual ~LineEditor() { }
virtual i::SmartPointer<char> Prompt(const char* prompt) = 0;
virtual bool Open() { return true; }
virtual bool Close() { return true; }
virtual void AddHistory(const char* str) { }
const char* name() { return name_; }
static LineEditor* Get();
private:
Type type_;
const char* name_;
LineEditor* next_;
static LineEditor* first_;
};
#endif // V8_SHARED
} // namespace v8 } // namespace v8

4
deps/v8/src/dateparser.h

@ -36,7 +36,6 @@ namespace internal {
class DateParser : public AllStatic { class DateParser : public AllStatic {
public: public:
// Parse the string as a date. If parsing succeeds, return true after // Parse the string as a date. If parsing succeeds, return true after
// filling out the output array as follows (all integers are Smis): // filling out the output array as follows (all integers are Smis):
// [0]: year // [0]: year
@ -234,6 +233,7 @@ class DateParser : public AllStatic {
static DateToken Invalid() { static DateToken Invalid() {
return DateToken(kInvalidTokenTag, 0, -1); return DateToken(kInvalidTokenTag, 0, -1);
} }
private: private:
enum TagType { enum TagType {
kInvalidTokenTag = -6, kInvalidTokenTag = -6,
@ -275,6 +275,7 @@ class DateParser : public AllStatic {
} }
return false; return false;
} }
private: private:
DateToken Scan(); DateToken Scan();
@ -351,6 +352,7 @@ class DateParser : public AllStatic {
static bool IsMinute(int x) { return Between(x, 0, 59); } static bool IsMinute(int x) { return Between(x, 0, 59); }
static bool IsHour(int x) { return Between(x, 0, 23); } static bool IsHour(int x) { return Between(x, 0, 23); }
static bool IsSecond(int x) { return Between(x, 0, 59); } static bool IsSecond(int x) { return Between(x, 0, 59); }
private: private:
static bool IsHour12(int x) { return Between(x, 0, 12); } static bool IsHour12(int x) { return Between(x, 0, 12); }
static bool IsMillisecond(int x) { return Between(x, 0, 999); } static bool IsMillisecond(int x) { return Between(x, 0, 999); }

17
deps/v8/src/debug-agent.cc

@ -169,7 +169,8 @@ void DebuggerAgentSession::Run() {
while (true) { while (true) {
// Read data from the debugger front end. // Read data from the debugger front end.
SmartPointer<char> message = DebuggerAgentUtil::ReceiveMessage(client_); SmartArrayPointer<char> message =
DebuggerAgentUtil::ReceiveMessage(client_);
const char* msg = *message; const char* msg = *message;
bool is_closing_session = (msg == NULL); bool is_closing_session = (msg == NULL);
@ -232,7 +233,7 @@ const int DebuggerAgentUtil::kContentLengthSize =
StrLength(kContentLength); StrLength(kContentLength);
SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) { SmartArrayPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
int received; int received;
// Read header. // Read header.
@ -250,7 +251,7 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
received = conn->Receive(&c, 1); received = conn->Receive(&c, 1);
if (received <= 0) { if (received <= 0) {
PrintF("Error %d\n", Socket::LastError()); PrintF("Error %d\n", Socket::LastError());
return SmartPointer<char>(); return SmartArrayPointer<char>();
} }
// Add character to header buffer. // Add character to header buffer.
@ -287,12 +288,12 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
if (strcmp(key, kContentLength) == 0) { if (strcmp(key, kContentLength) == 0) {
// Get the content length value if present and within a sensible range. // Get the content length value if present and within a sensible range.
if (value == NULL || strlen(value) > 7) { if (value == NULL || strlen(value) > 7) {
return SmartPointer<char>(); return SmartArrayPointer<char>();
} }
for (int i = 0; value[i] != '\0'; i++) { for (int i = 0; value[i] != '\0'; i++) {
// Bail out if illegal data. // Bail out if illegal data.
if (value[i] < '0' || value[i] > '9') { if (value[i] < '0' || value[i] > '9') {
return SmartPointer<char>(); return SmartArrayPointer<char>();
} }
content_length = 10 * content_length + (value[i] - '0'); content_length = 10 * content_length + (value[i] - '0');
} }
@ -304,7 +305,7 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
// Return now if no body. // Return now if no body.
if (content_length == 0) { if (content_length == 0) {
return SmartPointer<char>(); return SmartArrayPointer<char>();
} }
// Read body. // Read body.
@ -312,11 +313,11 @@ SmartPointer<char> DebuggerAgentUtil::ReceiveMessage(const Socket* conn) {
received = ReceiveAll(conn, buffer, content_length); received = ReceiveAll(conn, buffer, content_length);
if (received < content_length) { if (received < content_length) {
PrintF("Error %d\n", Socket::LastError()); PrintF("Error %d\n", Socket::LastError());
return SmartPointer<char>(); return SmartArrayPointer<char>();
} }
buffer[content_length] = '\0'; buffer[content_length] = '\0';
return SmartPointer<char>(buffer); return SmartArrayPointer<char>(buffer);
} }

4
deps/v8/src/debug-agent.h

@ -72,7 +72,7 @@ class DebuggerAgent: public Thread {
void OnSessionClosed(DebuggerAgentSession* session); void OnSessionClosed(DebuggerAgentSession* session);
Isolate* isolate_; Isolate* isolate_;
SmartPointer<const char> name_; // Name of the embedding application. SmartArrayPointer<const char> name_; // Name of the embedding application.
int port_; // Port to use for the agent. int port_; // Port to use for the agent.
Socket* server_; // Server socket for listen/accept. Socket* server_; // Server socket for listen/accept.
bool terminate_; // Termination flag. bool terminate_; // Termination flag.
@ -117,7 +117,7 @@ class DebuggerAgentUtil {
static const char* const kContentLength; static const char* const kContentLength;
static const int kContentLengthSize; static const int kContentLengthSize;
static SmartPointer<char> ReceiveMessage(const Socket* conn); static SmartArrayPointer<char> ReceiveMessage(const Socket* conn);
static bool SendConnectMessage(const Socket* conn, static bool SendConnectMessage(const Socket* conn,
const char* embedding_host); const char* embedding_host);
static bool SendMessage(const Socket* conn, const Vector<uint16_t> message); static bool SendMessage(const Socket* conn, const Vector<uint16_t> message);

112
deps/v8/src/debug.cc

@ -40,6 +40,7 @@
#include "global-handles.h" #include "global-handles.h"
#include "ic.h" #include "ic.h"
#include "ic-inl.h" #include "ic-inl.h"
#include "list.h"
#include "messages.h" #include "messages.h"
#include "natives.h" #include "natives.h"
#include "stub-cache.h" #include "stub-cache.h"
@ -542,6 +543,7 @@ void Debug::ThreadInit() {
thread_local_.last_statement_position_ = RelocInfo::kNoPosition; thread_local_.last_statement_position_ = RelocInfo::kNoPosition;
thread_local_.step_count_ = 0; thread_local_.step_count_ = 0;
thread_local_.last_fp_ = 0; thread_local_.last_fp_ = 0;
thread_local_.queued_step_count_ = 0;
thread_local_.step_into_fp_ = 0; thread_local_.step_into_fp_ = 0;
thread_local_.step_out_fp_ = 0; thread_local_.step_out_fp_ = 0;
thread_local_.after_break_target_ = 0; thread_local_.after_break_target_ = 0;
@ -957,14 +959,49 @@ Object* Debug::Break(Arguments args) {
// Clear all current stepping setup. // Clear all current stepping setup.
ClearStepping(); ClearStepping();
if (thread_local_.queued_step_count_ > 0) {
// Perform queued steps
int step_count = thread_local_.queued_step_count_;
// Clear queue
thread_local_.queued_step_count_ = 0;
PrepareStep(StepNext, step_count);
} else {
// Notify the debug event listeners. // Notify the debug event listeners.
isolate_->debugger()->OnDebugBreak(break_points_hit, false); isolate_->debugger()->OnDebugBreak(break_points_hit, false);
}
} else if (thread_local_.last_step_action_ != StepNone) { } else if (thread_local_.last_step_action_ != StepNone) {
// Hold on to last step action as it is cleared by the call to // Hold on to last step action as it is cleared by the call to
// ClearStepping. // ClearStepping.
StepAction step_action = thread_local_.last_step_action_; StepAction step_action = thread_local_.last_step_action_;
int step_count = thread_local_.step_count_; int step_count = thread_local_.step_count_;
// If StepNext goes deeper in code, StepOut until original frame
// and keep step count queued up in the meantime.
if (step_action == StepNext && frame->fp() < thread_local_.last_fp_) {
// Count frames until target frame
int count = 0;
JavaScriptFrameIterator it(isolate_);
while (!it.done() && it.frame()->fp() != thread_local_.last_fp_) {
count++;
it.Advance();
}
// If we found original frame
if (it.frame()->fp() == thread_local_.last_fp_) {
if (step_count > 1) {
// Save old count and action to continue stepping after
// StepOut
thread_local_.queued_step_count_ = step_count - 1;
}
// Set up for StepOut to reach target frame
step_action = StepOut;
step_count = count;
}
}
// Clear all current stepping setup. // Clear all current stepping setup.
ClearStepping(); ClearStepping();
@ -1105,6 +1142,8 @@ void Debug::SetBreakPoint(Handle<SharedFunctionInfo> shared,
int* source_position) { int* source_position) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
PrepareForBreakPoints();
if (!EnsureDebugInfo(shared)) { if (!EnsureDebugInfo(shared)) {
// Return if retrieving debug info failed. // Return if retrieving debug info failed.
return; return;
@ -1178,6 +1217,7 @@ void Debug::ClearAllBreakPoints() {
void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) { void Debug::FloodWithOneShot(Handle<SharedFunctionInfo> shared) {
PrepareForBreakPoints();
// Make sure the function has setup the debug info. // Make sure the function has setup the debug info.
if (!EnsureDebugInfo(shared)) { if (!EnsureDebugInfo(shared)) {
// Return if we failed to retrieve the debug info. // Return if we failed to retrieve the debug info.
@ -1234,6 +1274,9 @@ bool Debug::IsBreakOnException(ExceptionBreakType type) {
void Debug::PrepareStep(StepAction step_action, int step_count) { void Debug::PrepareStep(StepAction step_action, int step_count) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
PrepareForBreakPoints();
ASSERT(Debug::InDebugger()); ASSERT(Debug::InDebugger());
// Remember this step action and count. // Remember this step action and count.
@ -1448,6 +1491,13 @@ void Debug::PrepareStep(StepAction step_action, int step_count) {
// steps before reporting break back to the debugger. // steps before reporting break back to the debugger.
bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator, bool Debug::StepNextContinue(BreakLocationIterator* break_location_iterator,
JavaScriptFrame* frame) { JavaScriptFrame* frame) {
// StepNext and StepOut shouldn't bring us deeper in code, so last frame
// shouldn't be a parent of current frame.
if (thread_local_.last_step_action_ == StepNext ||
thread_local_.last_step_action_ == StepOut) {
if (frame->fp() < thread_local_.last_fp_) return true;
}
// If the step last action was step next or step in make sure that a new // If the step last action was step next or step in make sure that a new
// statement is hit. // statement is hit.
if (thread_local_.last_step_action_ == StepNext || if (thread_local_.last_step_action_ == StepNext ||
@ -1676,20 +1726,64 @@ void Debug::ClearStepNext() {
} }
void Debug::PrepareForBreakPoints() {
// If preparing for the first break point make sure to deoptimize all
// functions as debugging does not work with optimized code.
if (!has_break_points_) {
Deoptimizer::DeoptimizeAll();
AssertNoAllocation no_allocation;
Builtins* builtins = isolate_->builtins();
Code* lazy_compile = builtins->builtin(Builtins::kLazyCompile);
// Find all non-optimized code functions with activation frames on
// the stack.
List<JSFunction*> active_functions(100);
for (JavaScriptFrameIterator it(isolate_); !it.done(); it.Advance()) {
JavaScriptFrame* frame = it.frame();
if (frame->function()->IsJSFunction()) {
JSFunction* function = JSFunction::cast(frame->function());
if (function->code()->kind() == Code::FUNCTION)
active_functions.Add(function);
}
}
active_functions.Sort();
// Scan the heap for all non-optimized functions which has no
// debug break slots.
HeapIterator iterator;
HeapObject* obj = NULL;
while (((obj = iterator.next()) != NULL)) {
if (obj->IsJSFunction()) {
JSFunction* function = JSFunction::cast(obj);
if (function->shared()->allows_lazy_compilation() &&
function->shared()->script()->IsScript() &&
function->code()->kind() == Code::FUNCTION &&
!function->code()->has_debug_break_slots()) {
bool has_activation =
SortedListBSearch<JSFunction*>(active_functions, function) != -1;
if (!has_activation) {
function->set_code(lazy_compile);
function->shared()->set_code(lazy_compile);
}
}
}
}
}
}
// Ensures the debug information is present for shared. // Ensures the debug information is present for shared.
bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) { bool Debug::EnsureDebugInfo(Handle<SharedFunctionInfo> shared) {
// Return if we already have the debug info for shared. // Return if we already have the debug info for shared.
if (HasDebugInfo(shared)) return true; if (HasDebugInfo(shared)) {
ASSERT(shared->is_compiled());
return true;
}
// Ensure shared in compiled. Return false if this failed. // Ensure shared in compiled. Return false if this failed.
if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false; if (!EnsureCompiled(shared, CLEAR_EXCEPTION)) return false;
// If preparing for the first break point make sure to deoptimize all
// functions as debugging does not work with optimized code.
if (!has_break_points_) {
Deoptimizer::DeoptimizeAll();
}
// Create the debug info object. // Create the debug info object.
Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared); Handle<DebugInfo> debug_info = FACTORY->NewDebugInfo(shared);
@ -1739,6 +1833,8 @@ void Debug::RemoveDebugInfo(Handle<DebugInfo> debug_info) {
void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) { void Debug::SetAfterBreakTarget(JavaScriptFrame* frame) {
HandleScope scope(isolate_); HandleScope scope(isolate_);
PrepareForBreakPoints();
// Get the executing function in which the debug break occurred. // Get the executing function in which the debug break occurred.
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());
@ -1829,6 +1925,8 @@ bool Debug::IsBreakAtReturn(JavaScriptFrame* frame) {
return false; return false;
} }
PrepareForBreakPoints();
// Get the executing function in which the debug break occurred. // Get the executing function in which the debug break occurred.
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared()); Handle<SharedFunctionInfo>(JSFunction::cast(frame->function())->shared());

6
deps/v8/src/debug.h

@ -247,6 +247,8 @@ class Debug {
static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared); static Handle<DebugInfo> GetDebugInfo(Handle<SharedFunctionInfo> shared);
static bool HasDebugInfo(Handle<SharedFunctionInfo> shared); static bool HasDebugInfo(Handle<SharedFunctionInfo> shared);
void PrepareForBreakPoints();
// Returns whether the operation succeeded. // Returns whether the operation succeeded.
bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared); bool EnsureDebugInfo(Handle<SharedFunctionInfo> shared);
@ -506,6 +508,9 @@ class Debug {
// Frame pointer from last step next action. // Frame pointer from last step next action.
Address last_fp_; Address last_fp_;
// Number of queued steps left to perform before debug event.
int queued_step_count_;
// Frame pointer for frame from which step in was performed. // Frame pointer for frame from which step in was performed.
Address step_into_fp_; Address step_into_fp_;
@ -1026,6 +1031,7 @@ class Debug_Address {
return NULL; return NULL;
} }
} }
private: private:
Debug::AddressId id_; Debug::AddressId id_;
}; };

5
deps/v8/src/disassembler.cc

@ -223,7 +223,7 @@ static int DecodeIt(FILE* f,
HeapStringAllocator allocator; HeapStringAllocator allocator;
StringStream accumulator(&allocator); StringStream accumulator(&allocator);
relocinfo.target_object()->ShortPrint(&accumulator); relocinfo.target_object()->ShortPrint(&accumulator);
SmartPointer<const char> obj_name = accumulator.ToCString(); SmartArrayPointer<const char> obj_name = accumulator.ToCString();
out.AddFormatted(" ;; object: %s", *obj_name); out.AddFormatted(" ;; object: %s", *obj_name);
} else if (rmode == RelocInfo::EXTERNAL_REFERENCE) { } else if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
const char* reference_name = const char* reference_name =
@ -247,9 +247,6 @@ static int DecodeIt(FILE* f,
PropertyType type = code->type(); PropertyType type = code->type();
out.AddFormatted(", %s", Code::PropertyType2String(type)); out.AddFormatted(", %s", Code::PropertyType2String(type));
} }
if (code->ic_in_loop() == IN_LOOP) {
out.AddFormatted(", in_loop");
}
if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) { if (kind == Code::CALL_IC || kind == Code::KEYED_CALL_IC) {
out.AddFormatted(", argc = %d", code->arguments_count()); out.AddFormatted(", argc = %d", code->arguments_count());
} }

24
deps/v8/src/elements.cc

@ -401,7 +401,7 @@ class DictionaryElementsAccessor
Heap* heap = isolate->heap(); Heap* heap = isolate->heap();
FixedArray* backing_store = FixedArray::cast(obj->elements()); FixedArray* backing_store = FixedArray::cast(obj->elements());
bool is_arguments = bool is_arguments =
(obj->GetElementsKind() == JSObject::NON_STRICT_ARGUMENTS_ELEMENTS); (obj->GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS);
if (is_arguments) { if (is_arguments) {
backing_store = FixedArray::cast(backing_store->get(1)); backing_store = FixedArray::cast(backing_store->get(1));
} }
@ -565,28 +565,28 @@ ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
switch (array->map()->instance_type()) { switch (array->map()->instance_type()) {
case FIXED_ARRAY_TYPE: case FIXED_ARRAY_TYPE:
if (array->IsDictionary()) { if (array->IsDictionary()) {
return elements_accessors_[JSObject::DICTIONARY_ELEMENTS]; return elements_accessors_[DICTIONARY_ELEMENTS];
} else { } else {
return elements_accessors_[JSObject::FAST_ELEMENTS]; return elements_accessors_[FAST_ELEMENTS];
} }
case EXTERNAL_BYTE_ARRAY_TYPE: case EXTERNAL_BYTE_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_BYTE_ELEMENTS]; return elements_accessors_[EXTERNAL_BYTE_ELEMENTS];
case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE: case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS]; return elements_accessors_[EXTERNAL_UNSIGNED_BYTE_ELEMENTS];
case EXTERNAL_SHORT_ARRAY_TYPE: case EXTERNAL_SHORT_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_SHORT_ELEMENTS]; return elements_accessors_[EXTERNAL_SHORT_ELEMENTS];
case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE: case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS]; return elements_accessors_[EXTERNAL_UNSIGNED_SHORT_ELEMENTS];
case EXTERNAL_INT_ARRAY_TYPE: case EXTERNAL_INT_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_INT_ELEMENTS]; return elements_accessors_[EXTERNAL_INT_ELEMENTS];
case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE: case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS]; return elements_accessors_[EXTERNAL_UNSIGNED_INT_ELEMENTS];
case EXTERNAL_FLOAT_ARRAY_TYPE: case EXTERNAL_FLOAT_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_FLOAT_ELEMENTS]; return elements_accessors_[EXTERNAL_FLOAT_ELEMENTS];
case EXTERNAL_DOUBLE_ARRAY_TYPE: case EXTERNAL_DOUBLE_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_DOUBLE_ELEMENTS]; return elements_accessors_[EXTERNAL_DOUBLE_ELEMENTS];
case EXTERNAL_PIXEL_ARRAY_TYPE: case EXTERNAL_PIXEL_ARRAY_TYPE:
return elements_accessors_[JSObject::EXTERNAL_PIXEL_ELEMENTS]; return elements_accessors_[EXTERNAL_PIXEL_ELEMENTS];
default: default:
UNREACHABLE(); UNREACHABLE();
return NULL; return NULL;

4
deps/v8/src/elements.h

@ -54,8 +54,8 @@ class ElementsAccessor {
Object* receiver) = 0; Object* receiver) = 0;
// Returns a shared ElementsAccessor for the specified ElementsKind. // Returns a shared ElementsAccessor for the specified ElementsKind.
static ElementsAccessor* ForKind(JSObject::ElementsKind elements_kind) { static ElementsAccessor* ForKind(ElementsKind elements_kind) {
ASSERT(elements_kind < JSObject::kElementsKindCount); ASSERT(elements_kind < kElementsKindCount);
return elements_accessors_[elements_kind]; return elements_accessors_[elements_kind];
} }

65
deps/v8/src/execution.cc

@ -149,12 +149,29 @@ Handle<Object> Execution::Call(Handle<Object> callable,
Handle<Object> receiver, Handle<Object> receiver,
int argc, int argc,
Object*** args, Object*** args,
bool* pending_exception) { bool* pending_exception,
bool convert_receiver) {
if (!callable->IsJSFunction()) { if (!callable->IsJSFunction()) {
callable = TryGetFunctionDelegate(callable, pending_exception); callable = TryGetFunctionDelegate(callable, pending_exception);
if (*pending_exception) return callable; if (*pending_exception) return callable;
} }
Handle<JSFunction> func = Handle<JSFunction>::cast(callable); Handle<JSFunction> func = Handle<JSFunction>::cast(callable);
// In non-strict mode, convert receiver.
if (convert_receiver && !receiver->IsJSReceiver() &&
!func->shared()->native() && !func->shared()->strict_mode()) {
if (receiver->IsUndefined() || receiver->IsNull()) {
Object* global = func->context()->global()->global_receiver();
// Under some circumstances, 'global' can be the JSBuiltinsObject
// In that case, don't rewrite.
// (FWIW, the same holds for GetIsolate()->global()->global_receiver().)
if (!global->IsJSBuiltinsObject()) receiver = Handle<Object>(global);
} else {
receiver = ToObject(receiver, pending_exception);
}
if (*pending_exception) return callable;
}
return Invoke(false, func, receiver, argc, args, pending_exception); return Invoke(false, func, receiver, argc, args, pending_exception);
} }
@ -210,10 +227,17 @@ Handle<Object> Execution::GetFunctionDelegate(Handle<Object> object) {
// If you return a function from here, it will be called when an // If you return a function from here, it will be called when an
// attempt is made to call the given object as a function. // attempt is made to call the given object as a function.
// If object is a function proxy, get its handler. Iterate if necessary.
Object* fun = *object;
while (fun->IsJSFunctionProxy()) {
fun = JSFunctionProxy::cast(fun)->call_trap();
}
if (fun->IsJSFunction()) return Handle<Object>(fun);
// Objects created through the API can have an instance-call handler // Objects created through the API can have an instance-call handler
// that should be used when calling the object as a function. // that should be used when calling the object as a function.
if (object->IsHeapObject() && if (fun->IsHeapObject() &&
HeapObject::cast(*object)->map()->has_instance_call_handler()) { HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>( return Handle<JSFunction>(
isolate->global_context()->call_as_function_delegate()); isolate->global_context()->call_as_function_delegate());
} }
@ -227,10 +251,17 @@ Handle<Object> Execution::TryGetFunctionDelegate(Handle<Object> object,
ASSERT(!object->IsJSFunction()); ASSERT(!object->IsJSFunction());
Isolate* isolate = Isolate::Current(); Isolate* isolate = Isolate::Current();
// If object is a function proxy, get its handler. Iterate if necessary.
Object* fun = *object;
while (fun->IsJSFunctionProxy()) {
fun = JSFunctionProxy::cast(fun)->call_trap();
}
if (fun->IsJSFunction()) return Handle<Object>(fun);
// Objects created through the API can have an instance-call handler // Objects created through the API can have an instance-call handler
// that should be used when calling the object as a function. // that should be used when calling the object as a function.
if (object->IsHeapObject() && if (fun->IsHeapObject() &&
HeapObject::cast(*object)->map()->has_instance_call_handler()) { HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>( return Handle<JSFunction>(
isolate->global_context()->call_as_function_delegate()); isolate->global_context()->call_as_function_delegate());
} }
@ -253,10 +284,17 @@ Handle<Object> Execution::GetConstructorDelegate(Handle<Object> object) {
// If you return a function from here, it will be called when an // If you return a function from here, it will be called when an
// attempt is made to call the given object as a constructor. // attempt is made to call the given object as a constructor.
// If object is a function proxies, get its handler. Iterate if necessary.
Object* fun = *object;
while (fun->IsJSFunctionProxy()) {
fun = JSFunctionProxy::cast(fun)->call_trap();
}
if (fun->IsJSFunction()) return Handle<Object>(fun);
// Objects created through the API can have an instance-call handler // Objects created through the API can have an instance-call handler
// that should be used when calling the object as a function. // that should be used when calling the object as a function.
if (object->IsHeapObject() && if (fun->IsHeapObject() &&
HeapObject::cast(*object)->map()->has_instance_call_handler()) { HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>( return Handle<JSFunction>(
isolate->global_context()->call_as_constructor_delegate()); isolate->global_context()->call_as_constructor_delegate());
} }
@ -274,10 +312,17 @@ Handle<Object> Execution::TryGetConstructorDelegate(
// If you return a function from here, it will be called when an // If you return a function from here, it will be called when an
// attempt is made to call the given object as a constructor. // attempt is made to call the given object as a constructor.
// If object is a function proxies, get its handler. Iterate if necessary.
Object* fun = *object;
while (fun->IsJSFunctionProxy()) {
fun = JSFunctionProxy::cast(fun)->call_trap();
}
if (fun->IsJSFunction()) return Handle<Object>(fun);
// Objects created through the API can have an instance-call handler // Objects created through the API can have an instance-call handler
// that should be used when calling the object as a function. // that should be used when calling the object as a function.
if (object->IsHeapObject() && if (fun->IsHeapObject() &&
HeapObject::cast(*object)->map()->has_instance_call_handler()) { HeapObject::cast(fun)->map()->has_instance_call_handler()) {
return Handle<JSFunction>( return Handle<JSFunction>(
isolate->global_context()->call_as_constructor_delegate()); isolate->global_context()->call_as_constructor_delegate());
} }
@ -553,7 +598,7 @@ Handle<Object> Execution::ToDetailString(Handle<Object> obj, bool* exc) {
Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) { Handle<Object> Execution::ToObject(Handle<Object> obj, bool* exc) {
if (obj->IsJSObject()) return obj; if (obj->IsSpecObject()) return obj;
RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc); RETURN_NATIVE_CALL(to_object, 1, { obj.location() }, exc);
} }

7
deps/v8/src/execution.h

@ -53,11 +53,16 @@ class Execution : public AllStatic {
// *pending_exception tells whether the invoke resulted in // *pending_exception tells whether the invoke resulted in
// a pending exception. // a pending exception.
// //
// When convert_receiver is set, and the receiver is not an object,
// and the function called is not in strict mode, receiver is converted to
// an object.
//
static Handle<Object> Call(Handle<Object> callable, static Handle<Object> Call(Handle<Object> callable,
Handle<Object> receiver, Handle<Object> receiver,
int argc, int argc,
Object*** args, Object*** args,
bool* pending_exception); bool* pending_exception,
bool convert_receiver = false);
// Construct object from function, the caller supplies an array of // Construct object from function, the caller supplies an array of
// arguments. Arguments are Object* type. After function returns, // arguments. Arguments are Object* type. After function returns,

19
deps/v8/src/factory.cc

@ -465,12 +465,12 @@ Handle<Map> Factory::GetSlowElementsMap(Handle<Map> src) {
} }
Handle<Map> Factory::GetExternalArrayElementsMap( Handle<Map> Factory::GetElementsTransitionMap(
Handle<Map> src, Handle<Map> src,
ExternalArrayType array_type, ElementsKind elements_kind,
bool safe_to_add_transition) { bool safe_to_add_transition) {
CALL_HEAP_FUNCTION(isolate(), CALL_HEAP_FUNCTION(isolate(),
src->GetExternalArrayElementsMap(array_type, src->GetElementsTransitionMap(elements_kind,
safe_to_add_transition), safe_to_add_transition),
Map); Map);
} }
@ -922,10 +922,19 @@ Handle<JSProxy> Factory::NewJSProxy(Handle<Object> handler,
} }
void Factory::BecomeJSObject(Handle<JSProxy> object) { void Factory::BecomeJSObject(Handle<JSReceiver> object) {
CALL_HEAP_FUNCTION_VOID(
isolate(),
isolate()->heap()->ReinitializeJSReceiver(
*object, JS_OBJECT_TYPE, JSObject::kHeaderSize));
}
void Factory::BecomeJSFunction(Handle<JSReceiver> object) {
CALL_HEAP_FUNCTION_VOID( CALL_HEAP_FUNCTION_VOID(
isolate(), isolate(),
isolate()->heap()->ReinitializeJSProxyAsJSObject(*object)); isolate()->heap()->ReinitializeJSReceiver(
*object, JS_FUNCTION_TYPE, JSFunction::kSize));
} }

9
deps/v8/src/factory.h

@ -219,8 +219,8 @@ class Factory {
Handle<Map> GetSlowElementsMap(Handle<Map> map); Handle<Map> GetSlowElementsMap(Handle<Map> map);
Handle<Map> GetExternalArrayElementsMap(Handle<Map> map, Handle<Map> GetElementsTransitionMap(Handle<Map> map,
ExternalArrayType array_type, ElementsKind elements_kind,
bool safe_to_add_transition); bool safe_to_add_transition);
Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array); Handle<FixedArray> CopyFixedArray(Handle<FixedArray> array);
@ -260,8 +260,9 @@ class Factory {
Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype); Handle<JSProxy> NewJSProxy(Handle<Object> handler, Handle<Object> prototype);
// Change the type of the argument into a regular JS object and reinitialize. // Change the type of the argument into a JS object/function and reinitialize.
void BecomeJSObject(Handle<JSProxy> object); void BecomeJSObject(Handle<JSReceiver> object);
void BecomeJSFunction(Handle<JSReceiver> object);
Handle<JSFunction> NewFunction(Handle<String> name, Handle<JSFunction> NewFunction(Handle<String> name,
Handle<Object> prototype); Handle<Object> prototype);

6
deps/v8/src/flags.cc

@ -31,7 +31,7 @@
#include "v8.h" #include "v8.h"
#include "platform.h" #include "platform.h"
#include "smart-pointer.h" #include "smart-array-pointer.h"
#include "string-stream.h" #include "string-stream.h"
@ -193,7 +193,7 @@ static const char* Type2String(Flag::FlagType type) {
} }
static SmartPointer<const char> ToString(Flag* flag) { static SmartArrayPointer<const char> ToString(Flag* flag) {
HeapStringAllocator string_allocator; HeapStringAllocator string_allocator;
StringStream buffer(&string_allocator); StringStream buffer(&string_allocator);
switch (flag->type()) { switch (flag->type()) {
@ -528,7 +528,7 @@ void FlagList::PrintHelp() {
printf("Options:\n"); printf("Options:\n");
for (size_t i = 0; i < num_flags; ++i) { for (size_t i = 0; i < num_flags; ++i) {
Flag* f = &flags[i]; Flag* f = &flags[i];
SmartPointer<const char> value = ToString(f); SmartArrayPointer<const char> value = ToString(f);
printf(" --%s (%s)\n type: %s default: %s\n", printf(" --%s (%s)\n type: %s default: %s\n",
f->name(), f->comment(), Type2String(f->type()), *value); f->name(), f->comment(), Type2String(f->type()), *value);
} }

1
deps/v8/src/frames.h

@ -579,6 +579,7 @@ class ArgumentsAdaptorFrame: public JavaScriptFrame {
virtual void Print(StringStream* accumulator, virtual void Print(StringStream* accumulator,
PrintMode mode, PrintMode mode,
int index) const; int index) const;
protected: protected:
explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator) explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator)
: JavaScriptFrame(iterator) { } : JavaScriptFrame(iterator) { }

4
deps/v8/src/full-codegen.cc

@ -286,11 +286,13 @@ bool FullCodeGenerator::MakeCode(CompilationInfo* info) {
} }
unsigned table_offset = cgen.EmitStackCheckTable(); unsigned table_offset = cgen.EmitStackCheckTable();
Code::Flags flags = Code::ComputeFlags(Code::FUNCTION, NOT_IN_LOOP); Code::Flags flags = Code::ComputeFlags(Code::FUNCTION);
Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info); Handle<Code> code = CodeGenerator::MakeCodeEpilogue(&masm, flags, info);
code->set_optimizable(info->IsOptimizable()); code->set_optimizable(info->IsOptimizable());
cgen.PopulateDeoptimizationData(code); cgen.PopulateDeoptimizationData(code);
code->set_has_deoptimization_support(info->HasDeoptimizationSupport()); code->set_has_deoptimization_support(info->HasDeoptimizationSupport());
code->set_has_debug_break_slots(
info->isolate()->debugger()->IsDebuggerActive());
code->set_allow_osr_at_loop_nesting_level(0); code->set_allow_osr_at_loop_nesting_level(0);
code->set_stack_check_table_offset(table_offset); code->set_stack_check_table_offset(table_offset);
CodeGenerator::PrintCode(code, info); CodeGenerator::PrintCode(code, info);

4
deps/v8/src/gdb-jit.cc

@ -993,7 +993,7 @@ class CodeDescription BASE_EMBEDDED {
} }
#endif #endif
SmartPointer<char> GetFilename() { SmartArrayPointer<char> GetFilename() {
return String::cast(script_->name())->ToCString(); return String::cast(script_->name())->ToCString();
} }
@ -1991,7 +1991,7 @@ void GDBJITInterface::AddCode(Handle<String> name,
GetScriptLineNumber(script, 0); GetScriptLineNumber(script, 0);
if (!name.is_null()) { if (!name.is_null()) {
SmartPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS); SmartArrayPointer<char> name_cstring = name->ToCString(DISALLOW_NULLS);
AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info); AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info);
} else { } else {
AddCode("", *code, GDBJITInterface::FUNCTION, *script, info); AddCode("", *code, GDBJITInterface::FUNCTION, *script, info);

17
deps/v8/src/handles.cc

@ -921,16 +921,13 @@ bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
} }
static bool CompileLazyFunction(Handle<JSFunction> function, bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag) {
ClearExceptionFlag flag,
InLoopFlag in_loop_flag) {
bool result = true; bool result = true;
if (function->shared()->is_compiled()) { if (function->shared()->is_compiled()) {
function->ReplaceCode(function->shared()->code()); function->ReplaceCode(function->shared()->code());
function->shared()->set_code_age(0); function->shared()->set_code_age(0);
} else { } else {
CompilationInfo info(function); CompilationInfo info(function);
if (in_loop_flag == IN_LOOP) info.MarkAsInLoop();
result = CompileLazyHelper(&info, flag); result = CompileLazyHelper(&info, flag);
ASSERT(!result || function->is_compiled()); ASSERT(!result || function->is_compiled());
} }
@ -938,18 +935,6 @@ static bool CompileLazyFunction(Handle<JSFunction> function,
} }
bool CompileLazy(Handle<JSFunction> function,
ClearExceptionFlag flag) {
return CompileLazyFunction(function, flag, NOT_IN_LOOP);
}
bool CompileLazyInLoop(Handle<JSFunction> function,
ClearExceptionFlag flag) {
return CompileLazyFunction(function, flag, IN_LOOP);
}
bool CompileOptimized(Handle<JSFunction> function, bool CompileOptimized(Handle<JSFunction> function,
int osr_ast_id, int osr_ast_id,
ClearExceptionFlag flag) { ClearExceptionFlag flag) {

2
deps/v8/src/handles.h

@ -363,8 +363,6 @@ bool CompileLazyShared(Handle<SharedFunctionInfo> shared,
bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag); bool CompileLazy(Handle<JSFunction> function, ClearExceptionFlag flag);
bool CompileLazyInLoop(Handle<JSFunction> function, ClearExceptionFlag flag);
bool CompileOptimized(Handle<JSFunction> function, bool CompileOptimized(Handle<JSFunction> function,
int osr_ast_id, int osr_ast_id,
ClearExceptionFlag flag); ClearExceptionFlag flag);

70
deps/v8/src/heap.cc

@ -1627,7 +1627,7 @@ MaybeObject* Heap::AllocateMap(InstanceType instance_type, int instance_size) {
map->set_unused_property_fields(0); map->set_unused_property_fields(0);
map->set_bit_field(0); map->set_bit_field(0);
map->set_bit_field2(1 << Map::kIsExtensible); map->set_bit_field2(1 << Map::kIsExtensible);
map->set_elements_kind(JSObject::FAST_ELEMENTS); map->set_elements_kind(FAST_ELEMENTS);
// If the map object is aligned fill the padding area with Smi 0 objects. // If the map object is aligned fill the padding area with Smi 0 objects.
if (Map::kPadStart < Map::kSize) { if (Map::kPadStart < Map::kSize) {
@ -3415,11 +3415,36 @@ MaybeObject* Heap::AllocateJSProxy(Object* handler, Object* prototype) {
map->set_prototype(prototype); map->set_prototype(prototype);
// Allocate the proxy object. // Allocate the proxy object.
Object* result; JSProxy* result;
MaybeObject* maybe_result = Allocate(map, NEW_SPACE); MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->ToObject(&result)) return maybe_result; if (!maybe_result->To<JSProxy>(&result)) return maybe_result;
JSProxy::cast(result)->set_handler(handler); result->InitializeBody(map->instance_size(), Smi::FromInt(0));
JSProxy::cast(result)->set_padding(Smi::FromInt(0)); result->set_handler(handler);
return result;
}
MaybeObject* Heap::AllocateJSFunctionProxy(Object* handler,
Object* call_trap,
Object* construct_trap,
Object* prototype) {
// Allocate map.
// TODO(rossberg): Once we optimize proxies, think about a scheme to share
// maps. Will probably depend on the identity of the handler object, too.
Map* map;
MaybeObject* maybe_map_obj =
AllocateMap(JS_FUNCTION_PROXY_TYPE, JSFunctionProxy::kSize);
if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
map->set_prototype(prototype);
// Allocate the proxy object.
JSFunctionProxy* result;
MaybeObject* maybe_result = Allocate(map, NEW_SPACE);
if (!maybe_result->To<JSFunctionProxy>(&result)) return maybe_result;
result->InitializeBody(map->instance_size(), Smi::FromInt(0));
result->set_handler(handler);
result->set_call_trap(call_trap);
result->set_construct_trap(construct_trap);
return result; return result;
} }
@ -3564,16 +3589,19 @@ MaybeObject* Heap::CopyJSObject(JSObject* source) {
} }
MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) { MaybeObject* Heap::ReinitializeJSReceiver(
JSReceiver* object, InstanceType type, int size) {
ASSERT(type >= FIRST_JS_RECEIVER_TYPE);
// Allocate fresh map. // Allocate fresh map.
// TODO(rossberg): Once we optimize proxies, cache these maps. // TODO(rossberg): Once we optimize proxies, cache these maps.
Map* map; Map* map;
MaybeObject* maybe_map_obj = MaybeObject* maybe_map_obj = AllocateMap(type, size);
AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj; if (!maybe_map_obj->To<Map>(&map)) return maybe_map_obj;
// Check that the receiver has the same size as a fresh object. // Check that the receiver has at least the size of the fresh object.
ASSERT(map->instance_size() == object->map()->instance_size()); int size_difference = object->map()->instance_size() - map->instance_size();
ASSERT(size_difference >= 0);
map->set_prototype(object->map()->prototype()); map->set_prototype(object->map()->prototype());
@ -3590,6 +3618,28 @@ MaybeObject* Heap::ReinitializeJSProxyAsJSObject(JSProxy* object) {
// Reinitialize the object from the constructor map. // Reinitialize the object from the constructor map.
InitializeJSObjectFromMap(JSObject::cast(object), InitializeJSObjectFromMap(JSObject::cast(object),
FixedArray::cast(properties), map); FixedArray::cast(properties), map);
// Functions require some minimal initialization.
if (type == JS_FUNCTION_TYPE) {
String* name;
MaybeObject* maybe_name = LookupAsciiSymbol("<freezing call trap>");
if (!maybe_name->To<String>(&name)) return maybe_name;
SharedFunctionInfo* shared;
MaybeObject* maybe_shared = AllocateSharedFunctionInfo(name);
if (!maybe_shared->To<SharedFunctionInfo>(&shared)) return maybe_shared;
JSFunction* func;
MaybeObject* maybe_func =
InitializeFunction(JSFunction::cast(object), shared, the_hole_value());
if (!maybe_func->To<JSFunction>(&func)) return maybe_func;
func->set_context(isolate()->context()->global_context());
}
// Put in filler if the new object is smaller than the old.
if (size_difference > 0) {
CreateFillerObjectAt(
object->address() + map->instance_size(), size_difference);
}
return object; return object;
} }

18
deps/v8/src/heap.h

@ -440,17 +440,25 @@ class Heap {
// Please note this does not perform a garbage collection. // Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateFunctionPrototype(JSFunction* function); MUST_USE_RESULT MaybeObject* AllocateFunctionPrototype(JSFunction* function);
// Allocates a Harmony Proxy. // Allocates a Harmony proxy or function proxy.
// Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation // Returns Failure::RetryAfterGC(requested_bytes, space) if the allocation
// failed. // failed.
// Please note this does not perform a garbage collection. // Please note this does not perform a garbage collection.
MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler, MUST_USE_RESULT MaybeObject* AllocateJSProxy(Object* handler,
Object* prototype); Object* prototype);
// Reinitialize a JSProxy into an (empty) JSObject. The receiver MUST_USE_RESULT MaybeObject* AllocateJSFunctionProxy(Object* handler,
// must have the same size as an empty object. The object is reinitialized Object* call_trap,
// and behaves as an object that has been freshly allocated. Object* construct_trap,
MUST_USE_RESULT MaybeObject* ReinitializeJSProxyAsJSObject(JSProxy* object); Object* prototype);
// Reinitialize a JSReceiver into an (empty) JS object of respective type and
// size, but keeping the original prototype. The receiver must have at least
// the size of the new object. The object is reinitialized and behaves as an
// object that has been freshly allocated.
MUST_USE_RESULT MaybeObject* ReinitializeJSReceiver(JSReceiver* object,
InstanceType type,
int size);
// Reinitialize an JSGlobalProxy based on a constructor. The object // Reinitialize an JSGlobalProxy based on a constructor. The object
// must have the same size as objects allocated using the // must have the same size as objects allocated using the

60
deps/v8/src/hydrogen-instructions.cc

@ -1133,7 +1133,7 @@ void HDeoptimize::PrintDataTo(StringStream* stream) {
void HEnterInlined::PrintDataTo(StringStream* stream) { void HEnterInlined::PrintDataTo(StringStream* stream) {
SmartPointer<char> name = function()->debug_name()->ToCString(); SmartArrayPointer<char> name = function()->debug_name()->ToCString();
stream->Add("%s, id=%d", *name, function()->id()); stream->Add("%s, id=%d", *name, function()->id());
} }
@ -1307,6 +1307,12 @@ void HCompareIDAndBranch::PrintDataTo(StringStream* stream) {
left()->PrintNameTo(stream); left()->PrintNameTo(stream);
stream->Add(" "); stream->Add(" ");
right()->PrintNameTo(stream); right()->PrintNameTo(stream);
HControlInstruction::PrintDataTo(stream);
}
void HGoto::PrintDataTo(StringStream* stream) {
stream->Add("B%d", SuccessorAt(0)->block_id());
} }
@ -1454,37 +1460,37 @@ void HLoadKeyedSpecializedArrayElement::PrintDataTo(
external_pointer()->PrintNameTo(stream); external_pointer()->PrintNameTo(stream);
stream->Add("."); stream->Add(".");
switch (elements_kind()) { switch (elements_kind()) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
stream->Add("byte"); stream->Add("byte");
break; break;
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
stream->Add("u_byte"); stream->Add("u_byte");
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
stream->Add("short"); stream->Add("short");
break; break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
stream->Add("u_short"); stream->Add("u_short");
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
stream->Add("int"); stream->Add("int");
break; break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
stream->Add("u_int"); stream->Add("u_int");
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
stream->Add("float"); stream->Add("float");
break; break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
stream->Add("double"); stream->Add("double");
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
stream->Add("pixel"); stream->Add("pixel");
break; break;
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -1549,37 +1555,37 @@ void HStoreKeyedSpecializedArrayElement::PrintDataTo(
external_pointer()->PrintNameTo(stream); external_pointer()->PrintNameTo(stream);
stream->Add("."); stream->Add(".");
switch (elements_kind()) { switch (elements_kind()) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
stream->Add("byte"); stream->Add("byte");
break; break;
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
stream->Add("u_byte"); stream->Add("u_byte");
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
stream->Add("short"); stream->Add("short");
break; break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
stream->Add("u_short"); stream->Add("u_short");
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
stream->Add("int"); stream->Add("int");
break; break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
stream->Add("u_int"); stream->Add("u_int");
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
stream->Add("float"); stream->Add("float");
break; break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
stream->Add("double"); stream->Add("double");
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
stream->Add("pixel"); stream->Add("pixel");
break; break;
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }

29
deps/v8/src/hydrogen-instructions.h

@ -915,6 +915,8 @@ class HGoto: public HTemplateControlInstruction<1, 0> {
return Representation::None(); return Representation::None();
} }
virtual void PrintDataTo(StringStream* stream);
DECLARE_CONCRETE_INSTRUCTION(Goto) DECLARE_CONCRETE_INSTRUCTION(Goto)
}; };
@ -2209,6 +2211,13 @@ class HPhi: public HValue {
is_convertible_to_integer_ = b; is_convertible_to_integer_ = b;
} }
bool AllOperandsConvertibleToInteger() {
for (int i = 0; i < OperandCount(); ++i) {
if (!OperandAt(i)->IsConvertibleToInteger()) return false;
}
return true;
}
protected: protected:
virtual void DeleteFromGraph(); virtual void DeleteFromGraph();
virtual void InternalSetOperandAt(int index, HValue* value) { virtual void InternalSetOperandAt(int index, HValue* value) {
@ -3555,12 +3564,12 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
public: public:
HLoadKeyedSpecializedArrayElement(HValue* external_elements, HLoadKeyedSpecializedArrayElement(HValue* external_elements,
HValue* key, HValue* key,
JSObject::ElementsKind elements_kind) ElementsKind elements_kind)
: elements_kind_(elements_kind) { : elements_kind_(elements_kind) {
SetOperandAt(0, external_elements); SetOperandAt(0, external_elements);
SetOperandAt(1, key); SetOperandAt(1, key);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
set_representation(Representation::Double()); set_representation(Representation::Double());
} else { } else {
set_representation(Representation::Integer32()); set_representation(Representation::Integer32());
@ -3583,7 +3592,7 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
HValue* external_pointer() { return OperandAt(0); } HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); } HValue* key() { return OperandAt(1); }
JSObject::ElementsKind elements_kind() const { return elements_kind_; } ElementsKind elements_kind() const { return elements_kind_; }
DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement) DECLARE_CONCRETE_INSTRUCTION(LoadKeyedSpecializedArrayElement)
@ -3596,7 +3605,7 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
} }
private: private:
JSObject::ElementsKind elements_kind_; ElementsKind elements_kind_;
}; };
@ -3776,7 +3785,7 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
HStoreKeyedSpecializedArrayElement(HValue* external_elements, HStoreKeyedSpecializedArrayElement(HValue* external_elements,
HValue* key, HValue* key,
HValue* val, HValue* val,
JSObject::ElementsKind elements_kind) ElementsKind elements_kind)
: elements_kind_(elements_kind) { : elements_kind_(elements_kind) {
SetFlag(kChangesSpecializedArrayElements); SetFlag(kChangesSpecializedArrayElements);
SetOperandAt(0, external_elements); SetOperandAt(0, external_elements);
@ -3791,8 +3800,8 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
return Representation::External(); return Representation::External();
} else { } else {
bool float_or_double_elements = bool float_or_double_elements =
elements_kind() == JSObject::EXTERNAL_FLOAT_ELEMENTS || elements_kind() == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind() == JSObject::EXTERNAL_DOUBLE_ELEMENTS; elements_kind() == EXTERNAL_DOUBLE_ELEMENTS;
if (index == 2 && float_or_double_elements) { if (index == 2 && float_or_double_elements) {
return Representation::Double(); return Representation::Double();
} else { } else {
@ -3804,12 +3813,12 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
HValue* external_pointer() { return OperandAt(0); } HValue* external_pointer() { return OperandAt(0); }
HValue* key() { return OperandAt(1); } HValue* key() { return OperandAt(1); }
HValue* value() { return OperandAt(2); } HValue* value() { return OperandAt(2); }
JSObject::ElementsKind elements_kind() const { return elements_kind_; } ElementsKind elements_kind() const { return elements_kind_; }
DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement) DECLARE_CONCRETE_INSTRUCTION(StoreKeyedSpecializedArrayElement)
private: private:
JSObject::ElementsKind elements_kind_; ElementsKind elements_kind_;
}; };

135
deps/v8/src/hydrogen.cc

@ -220,6 +220,17 @@ bool HBasicBlock::Dominates(HBasicBlock* other) const {
} }
int HBasicBlock::LoopNestingDepth() const {
const HBasicBlock* current = this;
int result = (current->IsLoopHeader()) ? 1 : 0;
while (current->parent_loop_header() != NULL) {
current = current->parent_loop_header();
result++;
}
return result;
}
void HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) { void HBasicBlock::PostProcessLoopHeader(IterationStatement* stmt) {
ASSERT(IsLoopHeader()); ASSERT(IsLoopHeader());
@ -638,8 +649,7 @@ Handle<Code> HGraph::Compile(CompilationInfo* info) {
PrintF("Crankshaft Compiler - "); PrintF("Crankshaft Compiler - ");
} }
CodeGenerator::MakeCodePrologue(info); CodeGenerator::MakeCodePrologue(info);
Code::Flags flags = Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION);
Code::ComputeFlags(Code::OPTIMIZED_FUNCTION, NOT_IN_LOOP);
Handle<Code> code = Handle<Code> code =
CodeGenerator::MakeCodeEpilogue(&assembler, flags, info); CodeGenerator::MakeCodeEpilogue(&assembler, flags, info);
generator.FinishCode(code); generator.FinishCode(code);
@ -1638,18 +1648,20 @@ Representation HInferRepresentation::TryChange(HValue* value) {
int non_tagged_count = double_count + int32_count; int non_tagged_count = double_count + int32_count;
// If a non-loop phi has tagged uses, don't convert it to untagged. // If a non-loop phi has tagged uses, don't convert it to untagged.
if (value->IsPhi() && !value->block()->IsLoopHeader()) { if (value->IsPhi() && !value->block()->IsLoopHeader() && tagged_count > 0) {
if (tagged_count > 0) return Representation::None(); return Representation::None();
} }
if (non_tagged_count >= tagged_count) { // Prefer unboxing over boxing, the latter is more expensive.
if (int32_count > 0) { if (tagged_count > non_tagged_count) Representation::None();
if (!value->IsPhi() || value->IsConvertibleToInteger()) {
// Prefer Integer32 over Double, if possible.
if (int32_count > 0 && value->IsConvertibleToInteger()) {
return Representation::Integer32(); return Representation::Integer32();
} }
}
if (double_count > 0) return Representation::Double(); if (double_count > 0) return Representation::Double();
}
return Representation::None(); return Representation::None();
} }
@ -1690,40 +1702,25 @@ void HInferRepresentation::Analyze() {
} }
} }
// (3) Sum up the non-phi use counts of all connected phis. Don't include // (3) Use the phi reachability information from step 2 to
// the non-phi uses of the phi itself. // (a) sum up the non-phi use counts of all connected phis.
// (b) push information about values which can't be converted to integer
// without deoptimization through the phi use-def chains, avoiding
// unnecessary deoptimizations later.
for (int i = 0; i < phi_count; ++i) { for (int i = 0; i < phi_count; ++i) {
HPhi* phi = phi_list->at(i); HPhi* phi = phi_list->at(i);
bool cti = phi->AllOperandsConvertibleToInteger();
for (BitVector::Iterator it(connected_phis.at(i)); for (BitVector::Iterator it(connected_phis.at(i));
!it.Done(); !it.Done();
it.Advance()) { it.Advance()) {
int index = it.Current(); int index = it.Current();
if (index != i) {
HPhi* it_use = phi_list->at(it.Current()); HPhi* it_use = phi_list->at(it.Current());
phi->AddNonPhiUsesFrom(it_use); if (index != i) phi->AddNonPhiUsesFrom(it_use); // Don't count twice!
} if (!cti) it_use->set_is_convertible_to_integer(false);
} }
} }
// (4) Compute phis that definitely can't be converted to integer // Initialize work list
// without deoptimization and mark them to avoid unnecessary deoptimization.
change = true;
while (change) {
change = false;
for (int i = 0; i < phi_count; ++i) {
HPhi* phi = phi_list->at(i);
for (int j = 0; j < phi->OperandCount(); ++j) {
if (phi->IsConvertibleToInteger() &&
!phi->OperandAt(j)->IsConvertibleToInteger()) {
phi->set_is_convertible_to_integer(false);
change = true;
break;
}
}
}
}
for (int i = 0; i < graph_->blocks()->length(); ++i) { for (int i = 0; i < graph_->blocks()->length(); ++i) {
HBasicBlock* block = graph_->blocks()->at(i); HBasicBlock* block = graph_->blocks()->at(i);
const ZoneList<HPhi*>* phis = block->phis(); const ZoneList<HPhi*>* phis = block->phis();
@ -1738,6 +1735,7 @@ void HInferRepresentation::Analyze() {
} }
} }
// Do a fixed point iteration, trying to improve representations
while (!worklist_.is_empty()) { while (!worklist_.is_empty()) {
HValue* current = worklist_.RemoveLast(); HValue* current = worklist_.RemoveLast();
in_worklist_.Remove(current->id()); in_worklist_.Remove(current->id());
@ -2203,7 +2201,8 @@ void TestContext::BuildBranch(HValue* value) {
void HGraphBuilder::Bailout(const char* reason) { void HGraphBuilder::Bailout(const char* reason) {
if (FLAG_trace_bailout) { if (FLAG_trace_bailout) {
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); SmartArrayPointer<char> name(
info()->shared_info()->DebugName()->ToCString());
PrintF("Bailout in HGraphBuilder: @\"%s\": %s\n", *name, reason); PrintF("Bailout in HGraphBuilder: @\"%s\": %s\n", *name, reason);
} }
SetStackOverflow(); SetStackOverflow();
@ -3904,35 +3903,35 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess(
HValue* external_elements, HValue* external_elements,
HValue* checked_key, HValue* checked_key,
HValue* val, HValue* val,
JSObject::ElementsKind elements_kind, ElementsKind elements_kind,
bool is_store) { bool is_store) {
if (is_store) { if (is_store) {
ASSERT(val != NULL); ASSERT(val != NULL);
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS: { case EXTERNAL_PIXEL_ELEMENTS: {
HClampToUint8* clamp = new(zone()) HClampToUint8(val); HClampToUint8* clamp = new(zone()) HClampToUint8(val);
AddInstruction(clamp); AddInstruction(clamp);
val = clamp; val = clamp;
break; break;
} }
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: { case EXTERNAL_UNSIGNED_INT_ELEMENTS: {
HToInt32* floor_val = new(zone()) HToInt32(val); HToInt32* floor_val = new(zone()) HToInt32(val);
AddInstruction(floor_val); AddInstruction(floor_val);
val = floor_val; val = floor_val;
break; break;
} }
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
break; break;
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -4016,7 +4015,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
SmallMapList* maps = prop->GetReceiverTypes(); SmallMapList* maps = prop->GetReceiverTypes();
bool todo_external_array = false; bool todo_external_array = false;
static const int kNumElementTypes = JSObject::kElementsKindCount; static const int kNumElementTypes = kElementsKindCount;
bool type_todo[kNumElementTypes]; bool type_todo[kNumElementTypes];
for (int i = 0; i < kNumElementTypes; ++i) { for (int i = 0; i < kNumElementTypes; ++i) {
type_todo[i] = false; type_todo[i] = false;
@ -4026,7 +4025,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
ASSERT(maps->at(i)->IsMap()); ASSERT(maps->at(i)->IsMap());
type_todo[maps->at(i)->elements_kind()] = true; type_todo[maps->at(i)->elements_kind()] = true;
if (maps->at(i)->elements_kind() if (maps->at(i)->elements_kind()
>= JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) { >= FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND) {
todo_external_array = true; todo_external_array = true;
} }
} }
@ -4041,16 +4040,16 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
HInstruction* checked_key = NULL; HInstruction* checked_key = NULL;
// FAST_ELEMENTS is assumed to be the first case. // FAST_ELEMENTS is assumed to be the first case.
STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); STATIC_ASSERT(FAST_ELEMENTS == 0);
for (JSObject::ElementsKind elements_kind = JSObject::FAST_ELEMENTS; for (ElementsKind elements_kind = FAST_ELEMENTS;
elements_kind <= JSObject::LAST_ELEMENTS_KIND; elements_kind <= LAST_ELEMENTS_KIND;
elements_kind = JSObject::ElementsKind(elements_kind + 1)) { elements_kind = ElementsKind(elements_kind + 1)) {
// After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we // After having handled FAST_ELEMENTS and DICTIONARY_ELEMENTS, we
// need to add some code that's executed for all external array cases. // need to add some code that's executed for all external array cases.
STATIC_ASSERT(JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND == STATIC_ASSERT(LAST_EXTERNAL_ARRAY_ELEMENTS_KIND ==
JSObject::LAST_ELEMENTS_KIND); LAST_ELEMENTS_KIND);
if (elements_kind == JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND if (elements_kind == FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND
&& todo_external_array) { && todo_external_array) {
HInstruction* length = HInstruction* length =
AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); AddInstruction(new(zone()) HFixedArrayBaseLength(elements));
@ -4069,11 +4068,11 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
set_current_block(if_true); set_current_block(if_true);
HInstruction* access; HInstruction* access;
if (elements_kind == JSObject::FAST_ELEMENTS || if (elements_kind == FAST_ELEMENTS ||
elements_kind == JSObject::FAST_DOUBLE_ELEMENTS) { elements_kind == FAST_DOUBLE_ELEMENTS) {
bool fast_double_elements = bool fast_double_elements =
elements_kind == JSObject::FAST_DOUBLE_ELEMENTS; elements_kind == FAST_DOUBLE_ELEMENTS;
if (is_store && elements_kind == JSObject::FAST_ELEMENTS) { if (is_store && elements_kind == FAST_ELEMENTS) {
AddInstruction(new(zone()) HCheckMap( AddInstruction(new(zone()) HCheckMap(
elements, isolate()->factory()->fixed_array_map(), elements, isolate()->factory()->fixed_array_map(),
elements_kind_branch)); elements_kind_branch));
@ -4138,7 +4137,7 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
new(zone()) HLoadKeyedFastElement(elements, checked_key)); new(zone()) HLoadKeyedFastElement(elements, checked_key));
} }
} }
} else if (elements_kind == JSObject::DICTIONARY_ELEMENTS) { } else if (elements_kind == DICTIONARY_ELEMENTS) {
if (is_store) { if (is_store) {
access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); access = AddInstruction(BuildStoreKeyedGeneric(object, key, val));
} else { } else {
@ -4433,8 +4432,10 @@ void HGraphBuilder::TraceInline(Handle<JSFunction> target,
Handle<JSFunction> caller, Handle<JSFunction> caller,
const char* reason) { const char* reason) {
if (FLAG_trace_inlining) { if (FLAG_trace_inlining) {
SmartPointer<char> target_name = target->shared()->DebugName()->ToCString(); SmartArrayPointer<char> target_name =
SmartPointer<char> caller_name = caller->shared()->DebugName()->ToCString(); target->shared()->DebugName()->ToCString();
SmartArrayPointer<char> caller_name =
caller->shared()->DebugName()->ToCString();
if (reason == NULL) { if (reason == NULL) {
PrintF("Inlined %s called from %s.\n", *target_name, *caller_name); PrintF("Inlined %s called from %s.\n", *target_name, *caller_name);
} else { } else {
@ -5913,7 +5914,9 @@ void HGraphBuilder::GenerateIsFunction(CallRuntime* call) {
CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
HValue* value = Pop(); HValue* value = Pop();
HHasInstanceTypeAndBranch* result = HHasInstanceTypeAndBranch* result =
new(zone()) HHasInstanceTypeAndBranch(value, JS_FUNCTION_TYPE); new(zone()) HHasInstanceTypeAndBranch(value,
JS_FUNCTION_TYPE,
JS_FUNCTION_PROXY_TYPE);
return ast_context()->ReturnControl(result, call->id()); return ast_context()->ReturnControl(result, call->id());
} }
@ -6567,6 +6570,8 @@ void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) {
PrintBlockProperty("dominator", current->dominator()->block_id()); PrintBlockProperty("dominator", current->dominator()->block_id());
} }
PrintIntProperty("loop_depth", current->LoopNestingDepth());
if (chunk != NULL) { if (chunk != NULL) {
int first_index = current->first_instruction_index(); int first_index = current->first_instruction_index();
int last_index = current->last_instruction_index(); int last_index = current->last_instruction_index();

3
deps/v8/src/hydrogen.h

@ -102,6 +102,7 @@ class HBasicBlock: public ZoneObject {
void RemovePhi(HPhi* phi); void RemovePhi(HPhi* phi);
void AddInstruction(HInstruction* instr); void AddInstruction(HInstruction* instr);
bool Dominates(HBasicBlock* other) const; bool Dominates(HBasicBlock* other) const;
int LoopNestingDepth() const;
void SetInitialEnvironment(HEnvironment* env); void SetInitialEnvironment(HEnvironment* env);
void ClearEnvironment() { last_environment_ = NULL; } void ClearEnvironment() { last_environment_ = NULL; }
@ -935,7 +936,7 @@ class HGraphBuilder: public AstVisitor {
HValue* external_elements, HValue* external_elements,
HValue* checked_key, HValue* checked_key,
HValue* val, HValue* val,
JSObject::ElementsKind elements_kind, ElementsKind elements_kind,
bool is_store); bool is_store);
HInstruction* BuildMonomorphicElementAccess(HValue* object, HInstruction* BuildMonomorphicElementAccess(HValue* object,

3
deps/v8/src/ia32/assembler-ia32.h

@ -465,6 +465,7 @@ class CpuFeatures : public AllStatic {
// Enable a specified feature within a scope. // Enable a specified feature within a scope.
class Scope BASE_EMBEDDED { class Scope BASE_EMBEDDED {
#ifdef DEBUG #ifdef DEBUG
public: public:
explicit Scope(CpuFeature f) { explicit Scope(CpuFeature f) {
uint64_t mask = static_cast<uint64_t>(1) << f; uint64_t mask = static_cast<uint64_t>(1) << f;
@ -484,10 +485,12 @@ class CpuFeatures : public AllStatic {
isolate_->set_enabled_cpu_features(old_enabled_); isolate_->set_enabled_cpu_features(old_enabled_);
} }
} }
private: private:
Isolate* isolate_; Isolate* isolate_;
uint64_t old_enabled_; uint64_t old_enabled_;
#else #else
public: public:
explicit Scope(CpuFeature f) {} explicit Scope(CpuFeature f) {}
#endif #endif

89
deps/v8/src/ia32/builtins-ia32.cc

@ -590,16 +590,17 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
// 2. Get the function to call (passed as receiver) from the stack, check // 2. Get the function to call (passed as receiver) from the stack, check
// if it is a function. // if it is a function.
Label non_function; Label slow, non_function;
// 1 ~ return address. // 1 ~ return address.
__ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize)); __ mov(edi, Operand(esp, eax, times_4, 1 * kPointerSize));
__ JumpIfSmi(edi, &non_function); __ JumpIfSmi(edi, &non_function);
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &non_function); __ j(not_equal, &slow);
// 3a. Patch the first argument if necessary when calling a function. // 3a. Patch the first argument if necessary when calling a function.
Label shift_arguments; Label shift_arguments;
__ Set(edx, Immediate(0)); // indicate regular JS_FUNCTION
{ Label convert_to_object, use_global_receiver, patch_receiver; { Label convert_to_object, use_global_receiver, patch_receiver;
// Change context eagerly in case we need the global receiver. // Change context eagerly in case we need the global receiver.
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
@ -637,6 +638,7 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ push(ebx); __ push(ebx);
__ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION); __ InvokeBuiltin(Builtins::TO_OBJECT, CALL_FUNCTION);
__ mov(ebx, eax); __ mov(ebx, eax);
__ Set(edx, Immediate(0)); // restore
__ pop(eax); __ pop(eax);
__ SmiUntag(eax); __ SmiUntag(eax);
@ -661,14 +663,19 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ jmp(&shift_arguments); __ jmp(&shift_arguments);
} }
// 3b. Patch the first argument when calling a non-function. The // 3b. Check for function proxy.
__ bind(&slow);
__ Set(edx, Immediate(1)); // indicate function proxy
__ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
__ j(equal, &shift_arguments);
__ bind(&non_function);
__ Set(edx, Immediate(2)); // indicate non-function
// 3c. Patch the first argument when calling a non-function. The
// CALL_NON_FUNCTION builtin expects the non-function callee as // CALL_NON_FUNCTION builtin expects the non-function callee as
// receiver, so overwrite the first argument which will ultimately // receiver, so overwrite the first argument which will ultimately
// become the receiver. // become the receiver.
__ bind(&non_function);
__ mov(Operand(esp, eax, times_4, 0), edi); __ mov(Operand(esp, eax, times_4, 0), edi);
// Clear edi to indicate a non-function being called.
__ Set(edi, Immediate(0));
// 4. Shift arguments and return address one slot down on the stack // 4. Shift arguments and return address one slot down on the stack
// (overwriting the original receiver). Adjust argument count to make // (overwriting the original receiver). Adjust argument count to make
@ -685,13 +692,26 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
__ dec(eax); // One fewer argument (first argument is new receiver). __ dec(eax); // One fewer argument (first argument is new receiver).
} }
// 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin. // 5a. Call non-function via tail call to CALL_NON_FUNCTION builtin,
{ Label function; // or a function proxy via CALL_FUNCTION_PROXY.
__ test(edi, Operand(edi)); { Label function, non_proxy;
__ j(not_zero, &function); __ test(edx, Operand(edx));
__ j(zero, &function);
__ Set(ebx, Immediate(0)); __ Set(ebx, Immediate(0));
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
__ SetCallKind(ecx, CALL_AS_METHOD); __ SetCallKind(ecx, CALL_AS_METHOD);
__ cmp(Operand(edx), Immediate(1));
__ j(not_equal, &non_proxy);
__ pop(edx); // return address
__ push(edi); // re-add proxy object as additional argument
__ push(edx);
__ inc(eax);
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
__ bind(&non_proxy);
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
__ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(), __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET); RelocInfo::CODE_TARGET);
__ bind(&function); __ bind(&function);
@ -717,13 +737,17 @@ void Builtins::Generate_FunctionCall(MacroAssembler* masm) {
void Builtins::Generate_FunctionApply(MacroAssembler* masm) { void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
static const int kArgumentsOffset = 2 * kPointerSize;
static const int kReceiverOffset = 3 * kPointerSize;
static const int kFunctionOffset = 4 * kPointerSize;
__ EnterInternalFrame(); __ EnterInternalFrame();
__ push(Operand(ebp, 4 * kPointerSize)); // push this __ push(Operand(ebp, kFunctionOffset)); // push this
__ push(Operand(ebp, 2 * kPointerSize)); // push arguments __ push(Operand(ebp, kArgumentsOffset)); // push arguments
__ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION); __ InvokeBuiltin(Builtins::APPLY_PREPARE, CALL_FUNCTION);
// Check the stack for overflow. We are not trying need to catch // Check the stack for overflow. We are not trying to catch
// interruptions (e.g. debug break and preemption) here, so the "real stack // interruptions (e.g. debug break and preemption) here, so the "real stack
// limit" is checked. // limit" is checked.
Label okay; Label okay;
@ -756,16 +780,21 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ push(eax); // limit __ push(eax); // limit
__ push(Immediate(0)); // index __ push(Immediate(0)); // index
// Change context eagerly to get the right global object if // Get the receiver.
// necessary. __ mov(ebx, Operand(ebp, kReceiverOffset));
__ mov(edi, Operand(ebp, 4 * kPointerSize));
// Check that the function is a JS function (otherwise it must be a proxy).
Label push_receiver;
__ mov(edi, Operand(ebp, kFunctionOffset));
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &push_receiver);
// Change context eagerly to get the right global object if necessary.
__ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
// Compute the receiver. // Compute the receiver.
Label call_to_object, use_global_receiver, push_receiver;
__ mov(ebx, Operand(ebp, 3 * kPointerSize));
// Do not transform the receiver for strict mode functions. // Do not transform the receiver for strict mode functions.
Label call_to_object, use_global_receiver;
__ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset)); __ mov(ecx, FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset));
__ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset), __ test_b(FieldOperand(ecx, SharedFunctionInfo::kStrictModeByteOffset),
1 << SharedFunctionInfo::kStrictModeBitWithinByte); 1 << SharedFunctionInfo::kStrictModeBitWithinByte);
@ -814,7 +843,7 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ mov(eax, Operand(ebp, kIndexOffset)); __ mov(eax, Operand(ebp, kIndexOffset));
__ jmp(&entry); __ jmp(&entry);
__ bind(&loop); __ bind(&loop);
__ mov(edx, Operand(ebp, 2 * kPointerSize)); // load arguments __ mov(edx, Operand(ebp, kArgumentsOffset)); // load arguments
// Use inline caching to speed up access to arguments. // Use inline caching to speed up access to arguments.
Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize(); Handle<Code> ic = masm->isolate()->builtins()->KeyedLoadIC_Initialize();
@ -837,14 +866,30 @@ void Builtins::Generate_FunctionApply(MacroAssembler* masm) {
__ j(not_equal, &loop); __ j(not_equal, &loop);
// Invoke the function. // Invoke the function.
Label call_proxy;
ParameterCount actual(eax); ParameterCount actual(eax);
__ SmiUntag(eax); __ SmiUntag(eax);
__ mov(edi, Operand(ebp, 4 * kPointerSize)); __ mov(edi, Operand(ebp, kFunctionOffset));
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &call_proxy);
__ InvokeFunction(edi, actual, CALL_FUNCTION, __ InvokeFunction(edi, actual, CALL_FUNCTION,
NullCallWrapper(), CALL_AS_METHOD); NullCallWrapper(), CALL_AS_METHOD);
__ LeaveInternalFrame(); __ LeaveInternalFrame();
__ ret(3 * kPointerSize); // remove this, receiver, and arguments __ ret(3 * kPointerSize); // remove this, receiver, and arguments
// Invoke the function proxy.
__ bind(&call_proxy);
__ push(edi); // add function proxy as last argument
__ inc(eax);
__ Set(ebx, Immediate(0));
__ SetCallKind(ecx, CALL_AS_METHOD);
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
__ call(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
__ LeaveInternalFrame();
__ ret(3 * kPointerSize); // remove this, receiver, and arguments
} }

35
deps/v8/src/ia32/code-stubs-ia32.cc

@ -3551,7 +3551,7 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
// stack overflow (on the backtrack stack) was detected in RegExp code but // stack overflow (on the backtrack stack) was detected in RegExp code but
// haven't created the exception yet. Handle that in the runtime system. // haven't created the exception yet. Handle that in the runtime system.
// TODO(592): Rerunning the RegExp to get the stack overflow exception. // TODO(592): Rerunning the RegExp to get the stack overflow exception.
ExternalReference pending_exception(Isolate::k_pending_exception_address, ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
masm->isolate()); masm->isolate());
__ mov(edx, __ mov(edx,
Operand::StaticVariable(ExternalReference::the_hole_value_location( Operand::StaticVariable(ExternalReference::the_hole_value_location(
@ -4199,7 +4199,7 @@ void StackCheckStub::Generate(MacroAssembler* masm) {
void CallFunctionStub::Generate(MacroAssembler* masm) { void CallFunctionStub::Generate(MacroAssembler* masm) {
Label slow; Label slow, non_function;
// The receiver might implicitly be the global object. This is // The receiver might implicitly be the global object. This is
// indicated by passing the hole as the receiver to the call // indicated by passing the hole as the receiver to the call
@ -4224,7 +4224,7 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
__ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize)); __ mov(edi, Operand(esp, (argc_ + 2) * kPointerSize));
// Check that the function really is a JavaScript function. // Check that the function really is a JavaScript function.
__ JumpIfSmi(edi, &slow); __ JumpIfSmi(edi, &non_function);
// Goto slow case if we do not have a function. // Goto slow case if we do not have a function.
__ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx); __ CmpObjectType(edi, JS_FUNCTION_TYPE, ecx);
__ j(not_equal, &slow); __ j(not_equal, &slow);
@ -4251,15 +4251,32 @@ void CallFunctionStub::Generate(MacroAssembler* masm) {
// Slow-case: Non-function called. // Slow-case: Non-function called.
__ bind(&slow); __ bind(&slow);
// Check for function proxy.
__ CmpInstanceType(ecx, JS_FUNCTION_PROXY_TYPE);
__ j(not_equal, &non_function);
__ pop(ecx);
__ push(edi); // put proxy as additional argument under return address
__ push(ecx);
__ Set(eax, Immediate(argc_ + 1));
__ Set(ebx, Immediate(0));
__ SetCallKind(ecx, CALL_AS_FUNCTION);
__ GetBuiltinEntry(edx, Builtins::CALL_FUNCTION_PROXY);
{
Handle<Code> adaptor =
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
__ jmp(adaptor, RelocInfo::CODE_TARGET);
}
// CALL_NON_FUNCTION expects the non-function callee as receiver (instead // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
// of the original receiver from the call site). // of the original receiver from the call site).
__ bind(&non_function);
__ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
__ Set(eax, Immediate(argc_)); __ Set(eax, Immediate(argc_));
__ Set(ebx, Immediate(0)); __ Set(ebx, Immediate(0));
__ SetCallKind(ecx, CALL_AS_METHOD);
__ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
Handle<Code> adaptor = Handle<Code> adaptor =
masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
__ SetCallKind(ecx, CALL_AS_METHOD);
__ jmp(adaptor, RelocInfo::CODE_TARGET); __ jmp(adaptor, RelocInfo::CODE_TARGET);
} }
@ -4341,7 +4358,7 @@ void CEntryStub::GenerateCore(MacroAssembler* masm,
__ j(zero, &failure_returned); __ j(zero, &failure_returned);
ExternalReference pending_exception_address( ExternalReference pending_exception_address(
Isolate::k_pending_exception_address, masm->isolate()); Isolate::kPendingExceptionAddress, masm->isolate());
// Check that there is no pending exception, otherwise we // Check that there is no pending exception, otherwise we
// should have returned some failure value. // should have returned some failure value.
@ -4482,11 +4499,11 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
__ push(ebx); __ push(ebx);
// Save copies of the top frame descriptor on the stack. // Save copies of the top frame descriptor on the stack.
ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); ExternalReference c_entry_fp(Isolate::kCEntryFPAddress, masm->isolate());
__ push(Operand::StaticVariable(c_entry_fp)); __ push(Operand::StaticVariable(c_entry_fp));
// If this is the outermost JS call, set js_entry_sp value. // If this is the outermost JS call, set js_entry_sp value.
ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, ExternalReference js_entry_sp(Isolate::kJSEntrySPAddress,
masm->isolate()); masm->isolate());
__ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0));
__ j(not_equal, &not_outermost_js, Label::kNear); __ j(not_equal, &not_outermost_js, Label::kNear);
@ -4503,7 +4520,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Caught exception: Store result (exception) in the pending // Caught exception: Store result (exception) in the pending
// exception field in the JSEnv and return a failure sentinel. // exception field in the JSEnv and return a failure sentinel.
ExternalReference pending_exception(Isolate::k_pending_exception_address, ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
masm->isolate()); masm->isolate());
__ mov(Operand::StaticVariable(pending_exception), eax); __ mov(Operand::StaticVariable(pending_exception), eax);
__ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception()));
@ -4554,7 +4571,7 @@ void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
// Restore the top frame descriptor from the stack. // Restore the top frame descriptor from the stack.
__ pop(Operand::StaticVariable(ExternalReference( __ pop(Operand::StaticVariable(ExternalReference(
Isolate::k_c_entry_fp_address, Isolate::kCEntryFPAddress,
masm->isolate()))); masm->isolate())));
// Restore callee-saved registers (C calling conventions). // Restore callee-saved registers (C calling conventions).

19
deps/v8/src/ia32/full-codegen-ia32.cc

@ -2013,9 +2013,8 @@ void FullCodeGenerator::EmitCallWithIC(Call* expr,
} }
// Record source position of the IC call. // Record source position of the IC call.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arg_count, in_loop, mode); isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
__ call(ic, mode, expr->id()); __ call(ic, mode, expr->id());
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
@ -2047,9 +2046,8 @@ void FullCodeGenerator::EmitKeyedCallWithIC(Call* expr,
} }
// Record source position of the IC call. // Record source position of the IC call.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; Handle<Code> ic =
Handle<Code> ic = isolate()->stub_cache()->ComputeKeyedCallInitialize( isolate()->stub_cache()->ComputeKeyedCallInitialize(arg_count);
arg_count, in_loop);
__ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key. __ mov(ecx, Operand(esp, (arg_count + 1) * kPointerSize)); // Key.
__ call(ic, RelocInfo::CODE_TARGET, expr->id()); __ call(ic, RelocInfo::CODE_TARGET, expr->id());
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
@ -2071,8 +2069,7 @@ void FullCodeGenerator::EmitCallWithStub(Call* expr, CallFunctionFlags flags) {
} }
// Record source position for debugger. // Record source position for debugger.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; CallFunctionStub stub(arg_count, flags);
CallFunctionStub stub(arg_count, in_loop, flags);
__ CallStub(&stub); __ CallStub(&stub);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
@ -2166,8 +2163,7 @@ void FullCodeGenerator::VisitCall(Call* expr) {
} }
// Record source position for debugger. // Record source position for debugger.
SetSourcePosition(expr->position()); SetSourcePosition(expr->position());
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP; CallFunctionStub stub(arg_count, RECEIVER_MIGHT_BE_IMPLICIT);
CallFunctionStub stub(arg_count, in_loop, RECEIVER_MIGHT_BE_IMPLICIT);
__ CallStub(&stub); __ CallStub(&stub);
RecordJSReturnSite(expr); RecordJSReturnSite(expr);
// Restore context register. // Restore context register.
@ -3582,10 +3578,9 @@ void FullCodeGenerator::VisitCallRuntime(CallRuntime* expr) {
if (expr->is_jsruntime()) { if (expr->is_jsruntime()) {
// Call the JS runtime function via a call IC. // Call the JS runtime function via a call IC.
__ Set(ecx, Immediate(expr->name())); __ Set(ecx, Immediate(expr->name()));
InLoopFlag in_loop = (loop_depth() > 0) ? IN_LOOP : NOT_IN_LOOP;
RelocInfo::Mode mode = RelocInfo::CODE_TARGET; RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic = isolate()->stub_cache()->ComputeCallInitialize( Handle<Code> ic =
arg_count, in_loop, mode); isolate()->stub_cache()->ComputeCallInitialize(arg_count, mode);
__ call(ic, mode, expr->id()); __ call(ic, mode, expr->id());
// Restore context register. // Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));

17
deps/v8/src/ia32/ic-ia32.cc

@ -144,7 +144,7 @@ static void GenerateDictionaryLoad(MacroAssembler* masm,
StringDictionary::kElementsStartIndex * kPointerSize; StringDictionary::kElementsStartIndex * kPointerSize;
const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
__ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
__ j(not_zero, miss_label); __ j(not_zero, miss_label);
// Get the value at the masked, scaled index. // Get the value at the masked, scaled index.
@ -198,8 +198,8 @@ static void GenerateDictionaryStore(MacroAssembler* masm,
StringDictionary::kHeaderSize + StringDictionary::kHeaderSize +
StringDictionary::kElementsStartIndex * kPointerSize; StringDictionary::kElementsStartIndex * kPointerSize;
const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize; const int kDetailsOffset = kElementsStartOffset + 2 * kPointerSize;
const int kTypeAndReadOnlyMask const int kTypeAndReadOnlyMask =
= (PropertyDetails::TypeField::mask() | (PropertyDetails::TypeField::kMask |
PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize; PropertyDetails::AttributesField::encode(READ_ONLY)) << kSmiTagSize;
__ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag), __ test(Operand(elements, r0, times_4, kDetailsOffset - kHeapObjectTag),
Immediate(kTypeAndReadOnlyMask)); Immediate(kTypeAndReadOnlyMask));
@ -832,7 +832,6 @@ static void GenerateMonomorphicCacheProbe(MacroAssembler* masm,
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(kind, Code::Flags flags = Code::ComputeFlags(kind,
NOT_IN_LOOP,
MONOMORPHIC, MONOMORPHIC,
extra_ic_state, extra_ic_state,
NORMAL, NORMAL,
@ -1237,9 +1236,7 @@ void LoadIC::GenerateMegamorphic(MacroAssembler* masm) {
// ----------------------------------- // -----------------------------------
// Probe the stub cache. // Probe the stub cache.
Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, Code::Flags flags = Code::ComputeFlags(Code::LOAD_IC, MONOMORPHIC);
NOT_IN_LOOP,
MONOMORPHIC);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, eax, ecx, ebx, Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, eax, ecx, ebx,
edx); edx);
@ -1339,10 +1336,8 @@ void StoreIC::GenerateMegamorphic(MacroAssembler* masm,
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
Code::Flags flags = Code::ComputeFlags(Code::STORE_IC, Code::Flags flags =
NOT_IN_LOOP, Code::ComputeFlags(Code::STORE_IC, MONOMORPHIC, strict_mode);
MONOMORPHIC,
strict_mode);
Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx, Isolate::Current()->stub_cache()->GenerateProbe(masm, flags, edx, ecx, ebx,
no_reg); no_reg);

93
deps/v8/src/ia32/lithium-codegen-ia32.cc

@ -88,7 +88,8 @@ void LCodeGen::FinishCode(Handle<Code> code) {
void LCodeGen::Abort(const char* format, ...) { void LCodeGen::Abort(const char* format, ...) {
if (FLAG_trace_bailout) { if (FLAG_trace_bailout) {
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); SmartArrayPointer<char> name(
info()->shared_info()->DebugName()->ToCString());
PrintF("Aborting LCodeGen in @\"%s\": ", *name); PrintF("Aborting LCodeGen in @\"%s\": ", *name);
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
@ -2219,11 +2220,11 @@ void LCodeGen::DoLoadElements(LLoadElements* instr) {
__ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset)); __ movzx_b(temp, FieldOperand(temp, Map::kBitField2Offset));
__ and_(temp, Map::kElementsKindMask); __ and_(temp, Map::kElementsKindMask);
__ shr(temp, Map::kElementsKindShift); __ shr(temp, Map::kElementsKindShift);
__ cmp(temp, JSObject::FAST_ELEMENTS); __ cmp(temp, FAST_ELEMENTS);
__ j(equal, &ok, Label::kNear); __ j(equal, &ok, Label::kNear);
__ cmp(temp, JSObject::FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND); __ cmp(temp, FIRST_EXTERNAL_ARRAY_ELEMENTS_KIND);
__ j(less, &fail, Label::kNear); __ j(less, &fail, Label::kNear);
__ cmp(temp, JSObject::LAST_EXTERNAL_ARRAY_ELEMENTS_KIND); __ cmp(temp, LAST_EXTERNAL_ARRAY_ELEMENTS_KIND);
__ j(less_equal, &ok, Label::kNear); __ j(less_equal, &ok, Label::kNear);
__ bind(&fail); __ bind(&fail);
__ Abort("Check for fast or external elements failed."); __ Abort("Check for fast or external elements failed.");
@ -2264,7 +2265,7 @@ void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
// Load the result. // Load the result.
__ mov(result, __ mov(result,
BuildFastArrayOperand(instr->elements(), instr->key(), BuildFastArrayOperand(instr->elements(), instr->key(),
JSObject::FAST_ELEMENTS, FAST_ELEMENTS,
FixedArray::kHeaderSize - kHeapObjectTag)); FixedArray::kHeaderSize - kHeapObjectTag));
// Check for the hole value. // Check for the hole value.
@ -2284,14 +2285,14 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
sizeof(kHoleNanLower32); sizeof(kHoleNanLower32);
Operand hole_check_operand = BuildFastArrayOperand( Operand hole_check_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), instr->elements(), instr->key(),
JSObject::FAST_DOUBLE_ELEMENTS, FAST_DOUBLE_ELEMENTS,
offset); offset);
__ cmp(hole_check_operand, Immediate(kHoleNanUpper32)); __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
DeoptimizeIf(equal, instr->environment()); DeoptimizeIf(equal, instr->environment());
} }
Operand double_load_operand = BuildFastArrayOperand( Operand double_load_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag); FixedDoubleArray::kHeaderSize - kHeapObjectTag);
__ movdbl(result, double_load_operand); __ movdbl(result, double_load_operand);
} }
@ -2300,7 +2301,7 @@ void LCodeGen::DoLoadKeyedFastDoubleElement(
Operand LCodeGen::BuildFastArrayOperand( Operand LCodeGen::BuildFastArrayOperand(
LOperand* elements_pointer, LOperand* elements_pointer,
LOperand* key, LOperand* key,
JSObject::ElementsKind elements_kind, ElementsKind elements_kind,
uint32_t offset) { uint32_t offset) {
Register elements_pointer_reg = ToRegister(elements_pointer); Register elements_pointer_reg = ToRegister(elements_pointer);
int shift_size = ElementsKindToShiftSize(elements_kind); int shift_size = ElementsKindToShiftSize(elements_kind);
@ -2320,35 +2321,35 @@ Operand LCodeGen::BuildFastArrayOperand(
void LCodeGen::DoLoadKeyedSpecializedArrayElement( void LCodeGen::DoLoadKeyedSpecializedArrayElement(
LLoadKeyedSpecializedArrayElement* instr) { LLoadKeyedSpecializedArrayElement* instr) {
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Operand operand(BuildFastArrayOperand(instr->external_pointer(), Operand operand(BuildFastArrayOperand(instr->external_pointer(),
instr->key(), elements_kind, 0)); instr->key(), elements_kind, 0));
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
XMMRegister result(ToDoubleRegister(instr->result())); XMMRegister result(ToDoubleRegister(instr->result()));
__ movss(result, operand); __ movss(result, operand);
__ cvtss2sd(result, result); __ cvtss2sd(result, result);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
__ movdbl(ToDoubleRegister(instr->result()), operand); __ movdbl(ToDoubleRegister(instr->result()), operand);
} else { } else {
Register result(ToRegister(instr->result())); Register result(ToRegister(instr->result()));
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
__ movsx_b(result, operand); __ movsx_b(result, operand);
break; break;
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ movzx_b(result, operand); __ movzx_b(result, operand);
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
__ movsx_w(result, operand); __ movsx_w(result, operand);
break; break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ movzx_w(result, operand); __ movzx_w(result, operand);
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
__ mov(result, operand); __ mov(result, operand);
break; break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ mov(result, operand); __ mov(result, operand);
__ test(result, Operand(result)); __ test(result, Operand(result));
// TODO(danno): we could be more clever here, perhaps having a special // TODO(danno): we could be more clever here, perhaps having a special
@ -2356,12 +2357,12 @@ void LCodeGen::DoLoadKeyedSpecializedArrayElement(
// happens, and generate code that returns a double rather than int. // happens, and generate code that returns a double rather than int.
DeoptimizeIf(negative, instr->environment()); DeoptimizeIf(negative, instr->environment());
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -2980,8 +2981,8 @@ void LCodeGen::DoCallKeyed(LCallKeyed* instr) {
ASSERT(ToRegister(instr->result()).is(eax)); ASSERT(ToRegister(instr->result()).is(eax));
int arity = instr->arity(); int arity = instr->arity();
Handle<Code> ic = isolate()->stub_cache()-> Handle<Code> ic =
ComputeKeyedCallInitialize(arity, NOT_IN_LOOP); isolate()->stub_cache()->ComputeKeyedCallInitialize(arity);
CallCode(ic, RelocInfo::CODE_TARGET, instr); CallCode(ic, RelocInfo::CODE_TARGET, instr);
} }
@ -2993,7 +2994,7 @@ void LCodeGen::DoCallNamed(LCallNamed* instr) {
int arity = instr->arity(); int arity = instr->arity();
RelocInfo::Mode mode = RelocInfo::CODE_TARGET; RelocInfo::Mode mode = RelocInfo::CODE_TARGET;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
__ mov(ecx, instr->name()); __ mov(ecx, instr->name());
CallCode(ic, mode, instr); CallCode(ic, mode, instr);
} }
@ -3004,7 +3005,7 @@ void LCodeGen::DoCallFunction(LCallFunction* instr) {
ASSERT(ToRegister(instr->result()).is(eax)); ASSERT(ToRegister(instr->result()).is(eax));
int arity = instr->arity(); int arity = instr->arity();
CallFunctionStub stub(arity, NOT_IN_LOOP, RECEIVER_MIGHT_BE_IMPLICIT); CallFunctionStub stub(arity, RECEIVER_MIGHT_BE_IMPLICIT);
CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
__ Drop(1); __ Drop(1);
} }
@ -3017,7 +3018,7 @@ void LCodeGen::DoCallGlobal(LCallGlobal* instr) {
int arity = instr->arity(); int arity = instr->arity();
RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT; RelocInfo::Mode mode = RelocInfo::CODE_TARGET_CONTEXT;
Handle<Code> ic = Handle<Code> ic =
isolate()->stub_cache()->ComputeCallInitialize(arity, NOT_IN_LOOP, mode); isolate()->stub_cache()->ComputeCallInitialize(arity, mode);
__ mov(ecx, instr->name()); __ mov(ecx, instr->name());
CallCode(ic, mode, instr); CallCode(ic, mode, instr);
} }
@ -3103,36 +3104,36 @@ void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
void LCodeGen::DoStoreKeyedSpecializedArrayElement( void LCodeGen::DoStoreKeyedSpecializedArrayElement(
LStoreKeyedSpecializedArrayElement* instr) { LStoreKeyedSpecializedArrayElement* instr) {
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Operand operand(BuildFastArrayOperand(instr->external_pointer(), Operand operand(BuildFastArrayOperand(instr->external_pointer(),
instr->key(), elements_kind, 0)); instr->key(), elements_kind, 0));
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
__ movss(operand, xmm0); __ movss(operand, xmm0);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
__ movdbl(operand, ToDoubleRegister(instr->value())); __ movdbl(operand, ToDoubleRegister(instr->value()));
} else { } else {
Register value = ToRegister(instr->value()); Register value = ToRegister(instr->value());
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
__ mov_b(operand, value); __ mov_b(operand, value);
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ mov_w(operand, value); __ mov_w(operand, value);
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ mov(operand, value); __ mov(operand, value);
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
UNREACHABLE(); UNREACHABLE();
break; break;
} }
@ -3186,7 +3187,7 @@ void LCodeGen::DoStoreKeyedFastDoubleElement(
__ bind(&have_value); __ bind(&have_value);
Operand double_store_operand = BuildFastArrayOperand( Operand double_store_operand = BuildFastArrayOperand(
instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, instr->elements(), instr->key(), FAST_DOUBLE_ELEMENTS,
FixedDoubleArray::kHeaderSize - kHeapObjectTag); FixedDoubleArray::kHeaderSize - kHeapObjectTag);
__ movdbl(double_store_operand, value); __ movdbl(double_store_operand, value);
} }

2
deps/v8/src/ia32/lithium-codegen-ia32.h

@ -224,7 +224,7 @@ class LCodeGen BASE_EMBEDDED {
int ToInteger32(LConstantOperand* op) const; int ToInteger32(LConstantOperand* op) const;
Operand BuildFastArrayOperand(LOperand* elements_pointer, Operand BuildFastArrayOperand(LOperand* elements_pointer,
LOperand* key, LOperand* key,
JSObject::ElementsKind elements_kind, ElementsKind elements_kind,
uint32_t offset); uint32_t offset);
// Specific math operations - used from DoUnaryMathOperation. // Specific math operations - used from DoUnaryMathOperation.

35
deps/v8/src/ia32/lithium-ia32.cc

@ -315,13 +315,13 @@ void LCallKeyed::PrintDataTo(StringStream* stream) {
void LCallNamed::PrintDataTo(StringStream* stream) { void LCallNamed::PrintDataTo(StringStream* stream) {
SmartPointer<char> name_string = name()->ToCString(); SmartArrayPointer<char> name_string = name()->ToCString();
stream->Add("%s #%d / ", *name_string, arity()); stream->Add("%s #%d / ", *name_string, arity());
} }
void LCallGlobal::PrintDataTo(StringStream* stream) { void LCallGlobal::PrintDataTo(StringStream* stream) {
SmartPointer<char> name_string = name()->ToCString(); SmartArrayPointer<char> name_string = name()->ToCString();
stream->Add("%s #%d / ", *name_string, arity()); stream->Add("%s #%d / ", *name_string, arity());
} }
@ -540,7 +540,8 @@ LChunk* LChunkBuilder::Build() {
void LChunkBuilder::Abort(const char* format, ...) { void LChunkBuilder::Abort(const char* format, ...) {
if (FLAG_trace_bailout) { if (FLAG_trace_bailout) {
SmartPointer<char> name(info()->shared_info()->DebugName()->ToCString()); SmartArrayPointer<char> name(
info()->shared_info()->DebugName()->ToCString());
PrintF("Aborting LChunk building in @\"%s\": ", *name); PrintF("Aborting LChunk building in @\"%s\": ", *name);
va_list arguments; va_list arguments;
va_start(arguments, format); va_start(arguments, format);
@ -1902,15 +1903,15 @@ LInstruction* LChunkBuilder::DoLoadKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
HLoadKeyedSpecializedArrayElement* instr) { HLoadKeyedSpecializedArrayElement* instr) {
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
Representation representation(instr->representation()); Representation representation(instr->representation());
ASSERT( ASSERT(
(representation.IsInteger32() && (representation.IsInteger32() &&
(elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (representation.IsDouble() &&
((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegisterOrConstant(instr->key()); LOperand* key = UseRegisterOrConstant(instr->key());
@ -1920,7 +1921,7 @@ LInstruction* LChunkBuilder::DoLoadKeyedSpecializedArrayElement(
LInstruction* load_instr = DefineAsRegister(result); LInstruction* load_instr = DefineAsRegister(result);
// An unsigned int array load might overflow and cause a deopt, make sure it // An unsigned int array load might overflow and cause a deopt, make sure it
// has an environment. // has an environment.
return (elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) return (elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS)
? AssignEnvironment(load_instr) ? AssignEnvironment(load_instr)
: load_instr; : load_instr;
} }
@ -1972,23 +1973,23 @@ LInstruction* LChunkBuilder::DoStoreKeyedFastDoubleElement(
LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement( LInstruction* LChunkBuilder::DoStoreKeyedSpecializedArrayElement(
HStoreKeyedSpecializedArrayElement* instr) { HStoreKeyedSpecializedArrayElement* instr) {
Representation representation(instr->value()->representation()); Representation representation(instr->value()->representation());
JSObject::ElementsKind elements_kind = instr->elements_kind(); ElementsKind elements_kind = instr->elements_kind();
ASSERT( ASSERT(
(representation.IsInteger32() && (representation.IsInteger32() &&
(elements_kind != JSObject::EXTERNAL_FLOAT_ELEMENTS) && (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
(elements_kind != JSObject::EXTERNAL_DOUBLE_ELEMENTS)) || (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
(representation.IsDouble() && (representation.IsDouble() &&
((elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) || ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
(elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS)))); (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
ASSERT(instr->external_pointer()->representation().IsExternal()); ASSERT(instr->external_pointer()->representation().IsExternal());
ASSERT(instr->key()->representation().IsInteger32()); ASSERT(instr->key()->representation().IsInteger32());
LOperand* external_pointer = UseRegister(instr->external_pointer()); LOperand* external_pointer = UseRegister(instr->external_pointer());
LOperand* key = UseRegisterOrConstant(instr->key()); LOperand* key = UseRegisterOrConstant(instr->key());
LOperand* val = NULL; LOperand* val = NULL;
if (elements_kind == JSObject::EXTERNAL_BYTE_ELEMENTS || if (elements_kind == EXTERNAL_BYTE_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS || elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
// We need a byte register in this case for the value. // We need a byte register in this case for the value.
val = UseFixed(instr->value(), eax); val = UseFixed(instr->value(), eax);
} else { } else {

4
deps/v8/src/ia32/lithium-ia32.h

@ -1184,7 +1184,7 @@ class LLoadKeyedSpecializedArrayElement: public LTemplateInstruction<1, 2, 0> {
LOperand* external_pointer() { return inputs_[0]; } LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
JSObject::ElementsKind elements_kind() const { ElementsKind elements_kind() const {
return hydrogen()->elements_kind(); return hydrogen()->elements_kind();
} }
}; };
@ -1699,7 +1699,7 @@ class LStoreKeyedSpecializedArrayElement: public LTemplateInstruction<0, 3, 0> {
LOperand* external_pointer() { return inputs_[0]; } LOperand* external_pointer() { return inputs_[0]; }
LOperand* key() { return inputs_[1]; } LOperand* key() { return inputs_[1]; }
LOperand* value() { return inputs_[2]; } LOperand* value() { return inputs_[2]; }
JSObject::ElementsKind elements_kind() const { ElementsKind elements_kind() const {
return hydrogen()->elements_kind(); return hydrogen()->elements_kind();
} }
}; };

26
deps/v8/src/ia32/macro-assembler-ia32.cc

@ -287,7 +287,7 @@ void MacroAssembler::CmpInstanceType(Register map, InstanceType type) {
void MacroAssembler::CheckFastElements(Register map, void MacroAssembler::CheckFastElements(Register map,
Label* fail, Label* fail,
Label::Distance distance) { Label::Distance distance) {
STATIC_ASSERT(JSObject::FAST_ELEMENTS == 0); STATIC_ASSERT(FAST_ELEMENTS == 0);
cmpb(FieldOperand(map, Map::kBitField2Offset), cmpb(FieldOperand(map, Map::kBitField2Offset),
Map::kMaximumBitField2FastElementValue); Map::kMaximumBitField2FastElementValue);
j(above, fail, distance); j(above, fail, distance);
@ -437,9 +437,9 @@ void MacroAssembler::EnterExitFramePrologue() {
push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot. push(Immediate(CodeObject())); // Accessed from ExitFrame::code_slot.
// Save the frame pointer and the context in top. // Save the frame pointer and the context in top.
ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress,
isolate()); isolate());
ExternalReference context_address(Isolate::k_context_address, ExternalReference context_address(Isolate::kContextAddress,
isolate()); isolate());
mov(Operand::StaticVariable(c_entry_fp_address), ebp); mov(Operand::StaticVariable(c_entry_fp_address), ebp);
mov(Operand::StaticVariable(context_address), esi); mov(Operand::StaticVariable(context_address), esi);
@ -518,14 +518,14 @@ void MacroAssembler::LeaveExitFrame(bool save_doubles) {
void MacroAssembler::LeaveExitFrameEpilogue() { void MacroAssembler::LeaveExitFrameEpilogue() {
// Restore current context from top and clear it in debug mode. // Restore current context from top and clear it in debug mode.
ExternalReference context_address(Isolate::k_context_address, isolate()); ExternalReference context_address(Isolate::kContextAddress, isolate());
mov(esi, Operand::StaticVariable(context_address)); mov(esi, Operand::StaticVariable(context_address));
#ifdef DEBUG #ifdef DEBUG
mov(Operand::StaticVariable(context_address), Immediate(0)); mov(Operand::StaticVariable(context_address), Immediate(0));
#endif #endif
// Clear the top frame. // Clear the top frame.
ExternalReference c_entry_fp_address(Isolate::k_c_entry_fp_address, ExternalReference c_entry_fp_address(Isolate::kCEntryFPAddress,
isolate()); isolate());
mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0)); mov(Operand::StaticVariable(c_entry_fp_address), Immediate(0));
} }
@ -567,10 +567,10 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
push(Immediate(Smi::FromInt(0))); // No context. push(Immediate(Smi::FromInt(0))); // No context.
} }
// Save the current handler as the next handler. // Save the current handler as the next handler.
push(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, push(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress,
isolate()))); isolate())));
// Link this handler as the new current one. // Link this handler as the new current one.
mov(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, mov(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress,
isolate())), isolate())),
esp); esp);
} }
@ -578,7 +578,7 @@ void MacroAssembler::PushTryHandler(CodeLocation try_location,
void MacroAssembler::PopTryHandler() { void MacroAssembler::PopTryHandler() {
STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0); STATIC_ASSERT(StackHandlerConstants::kNextOffset == 0);
pop(Operand::StaticVariable(ExternalReference(Isolate::k_handler_address, pop(Operand::StaticVariable(ExternalReference(Isolate::kHandlerAddress,
isolate()))); isolate())));
add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize)); add(Operand(esp), Immediate(StackHandlerConstants::kSize - kPointerSize));
} }
@ -598,7 +598,7 @@ void MacroAssembler::Throw(Register value) {
} }
// Drop the sp to the top of the handler. // Drop the sp to the top of the handler.
ExternalReference handler_address(Isolate::k_handler_address, ExternalReference handler_address(Isolate::kHandlerAddress,
isolate()); isolate());
mov(esp, Operand::StaticVariable(handler_address)); mov(esp, Operand::StaticVariable(handler_address));
@ -637,7 +637,7 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
} }
// Drop sp to the top stack handler. // Drop sp to the top stack handler.
ExternalReference handler_address(Isolate::k_handler_address, ExternalReference handler_address(Isolate::kHandlerAddress,
isolate()); isolate());
mov(esp, Operand::StaticVariable(handler_address)); mov(esp, Operand::StaticVariable(handler_address));
@ -660,13 +660,13 @@ void MacroAssembler::ThrowUncatchable(UncatchableExceptionType type,
if (type == OUT_OF_MEMORY) { if (type == OUT_OF_MEMORY) {
// Set external caught exception to false. // Set external caught exception to false.
ExternalReference external_caught( ExternalReference external_caught(
Isolate::k_external_caught_exception_address, Isolate::kExternalCaughtExceptionAddress,
isolate()); isolate());
mov(eax, false); mov(eax, false);
mov(Operand::StaticVariable(external_caught), eax); mov(Operand::StaticVariable(external_caught), eax);
// Set pending exception and eax to out of memory exception. // Set pending exception and eax to out of memory exception.
ExternalReference pending_exception(Isolate::k_pending_exception_address, ExternalReference pending_exception(Isolate::kPendingExceptionAddress,
isolate()); isolate());
mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException())); mov(eax, reinterpret_cast<int32_t>(Failure::OutOfMemoryException()));
mov(Operand::StaticVariable(pending_exception), eax); mov(Operand::StaticVariable(pending_exception), eax);
@ -840,7 +840,7 @@ void MacroAssembler::LoadFromNumberDictionary(Label* miss,
NumberDictionary::kElementsStartOffset + 2 * kPointerSize; NumberDictionary::kElementsStartOffset + 2 * kPointerSize;
ASSERT_EQ(NORMAL, 0); ASSERT_EQ(NORMAL, 0);
test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset), test(FieldOperand(elements, r2, times_pointer_size, kDetailsOffset),
Immediate(PropertyDetails::TypeField::mask() << kSmiTagSize)); Immediate(PropertyDetails::TypeField::kMask << kSmiTagSize));
j(not_zero, miss); j(not_zero, miss);
// Get the value at the masked, scaled index. // Get the value at the masked, scaled index.

86
deps/v8/src/ia32/stub-cache-ia32.cc

@ -2679,7 +2679,7 @@ MaybeObject* KeyedStoreStubCompiler::CompileStoreElement(Map* receiver_map) {
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
Code* stub; Code* stub;
JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); ElementsKind elements_kind = receiver_map->elements_kind();
bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE; bool is_jsarray = receiver_map->instance_type() == JS_ARRAY_TYPE;
MaybeObject* maybe_stub = MaybeObject* maybe_stub =
KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode(); KeyedStoreElementStub(is_jsarray, elements_kind).TryGetCode();
@ -3140,7 +3140,7 @@ MaybeObject* KeyedLoadStubCompiler::CompileLoadElement(Map* receiver_map) {
// -- esp[0] : return address // -- esp[0] : return address
// ----------------------------------- // -----------------------------------
Code* stub; Code* stub;
JSObject::ElementsKind elements_kind = receiver_map->elements_kind(); ElementsKind elements_kind = receiver_map->elements_kind();
MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode(); MaybeObject* maybe_stub = KeyedLoadElementStub(elements_kind).TryGetCode();
if (!maybe_stub->To(&stub)) return maybe_stub; if (!maybe_stub->To(&stub)) return maybe_stub;
__ DispatchMap(edx, __ DispatchMap(edx,
@ -3385,7 +3385,7 @@ void KeyedLoadStubCompiler::GenerateLoadDictionaryElement(
void KeyedLoadStubCompiler::GenerateLoadExternalArray( void KeyedLoadStubCompiler::GenerateLoadExternalArray(
MacroAssembler* masm, MacroAssembler* masm,
JSObject::ElementsKind elements_kind) { ElementsKind elements_kind) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- eax : key // -- eax : key
// -- edx : receiver // -- edx : receiver
@ -3407,29 +3407,29 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset)); __ mov(ebx, FieldOperand(ebx, ExternalArray::kExternalPointerOffset));
// ebx: base pointer of external storage // ebx: base pointer of external storage
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
__ SmiUntag(eax); // Untag the index. __ SmiUntag(eax); // Untag the index.
__ movsx_b(eax, Operand(ebx, eax, times_1, 0)); __ movsx_b(eax, Operand(ebx, eax, times_1, 0));
break; break;
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
__ SmiUntag(eax); // Untag the index. __ SmiUntag(eax); // Untag the index.
__ movzx_b(eax, Operand(ebx, eax, times_1, 0)); __ movzx_b(eax, Operand(ebx, eax, times_1, 0));
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
__ movsx_w(eax, Operand(ebx, eax, times_1, 0)); __ movsx_w(eax, Operand(ebx, eax, times_1, 0));
break; break;
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ movzx_w(eax, Operand(ebx, eax, times_1, 0)); __ movzx_w(eax, Operand(ebx, eax, times_1, 0));
break; break;
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
__ mov(ecx, Operand(ebx, eax, times_2, 0)); __ mov(ecx, Operand(ebx, eax, times_2, 0));
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
__ fld_s(Operand(ebx, eax, times_2, 0)); __ fld_s(Operand(ebx, eax, times_2, 0));
break; break;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
__ fld_d(Operand(ebx, eax, times_4, 0)); __ fld_d(Operand(ebx, eax, times_4, 0));
break; break;
default: default:
@ -3442,17 +3442,17 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// For floating-point array type: // For floating-point array type:
// FP(0): value // FP(0): value
if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS || if (elements_kind == EXTERNAL_INT_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) {
// For the Int and UnsignedInt array types, we need to see whether // For the Int and UnsignedInt array types, we need to see whether
// the value can be represented in a Smi. If not, we need to convert // the value can be represented in a Smi. If not, we need to convert
// it to a HeapNumber. // it to a HeapNumber.
Label box_int; Label box_int;
if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { if (elements_kind == EXTERNAL_INT_ELEMENTS) {
__ cmp(ecx, 0xC0000000); __ cmp(ecx, 0xC0000000);
__ j(sign, &box_int); __ j(sign, &box_int);
} else { } else {
ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
// The test is different for unsigned int values. Since we need // The test is different for unsigned int values. Since we need
// the value to be in the range of a positive smi, we can't // the value to be in the range of a positive smi, we can't
// handle either of the top two bits being set in the value. // handle either of the top two bits being set in the value.
@ -3468,12 +3468,12 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
// Allocate a HeapNumber for the int and perform int-to-double // Allocate a HeapNumber for the int and perform int-to-double
// conversion. // conversion.
if (elements_kind == JSObject::EXTERNAL_INT_ELEMENTS) { if (elements_kind == EXTERNAL_INT_ELEMENTS) {
__ push(ecx); __ push(ecx);
__ fild_s(Operand(esp, 0)); __ fild_s(Operand(esp, 0));
__ pop(ecx); __ pop(ecx);
} else { } else {
ASSERT_EQ(JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind); ASSERT_EQ(EXTERNAL_UNSIGNED_INT_ELEMENTS, elements_kind);
// Need to zero-extend the value. // Need to zero-extend the value.
// There's no fild variant for unsigned values, so zero-extend // There's no fild variant for unsigned values, so zero-extend
// to a 64-bit int manually. // to a 64-bit int manually.
@ -3489,8 +3489,8 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
__ mov(eax, ecx); __ mov(eax, ecx);
__ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fstp_d(FieldOperand(eax, HeapNumber::kValueOffset));
__ ret(0); __ ret(0);
} else if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS || } else if (elements_kind == EXTERNAL_FLOAT_ELEMENTS ||
elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
// For the floating-point array type, we need to always allocate a // For the floating-point array type, we need to always allocate a
// HeapNumber. // HeapNumber.
__ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation); __ AllocateHeapNumber(ecx, ebx, edi, &failed_allocation);
@ -3540,7 +3540,7 @@ void KeyedLoadStubCompiler::GenerateLoadExternalArray(
void KeyedStoreStubCompiler::GenerateStoreExternalArray( void KeyedStoreStubCompiler::GenerateStoreExternalArray(
MacroAssembler* masm, MacroAssembler* masm,
JSObject::ElementsKind elements_kind) { ElementsKind elements_kind) {
// ----------- S t a t e ------------- // ----------- S t a t e -------------
// -- eax : key // -- eax : key
// -- edx : receiver // -- edx : receiver
@ -3566,7 +3566,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// edx: receiver // edx: receiver
// ecx: key // ecx: key
// edi: elements array // edi: elements array
if (elements_kind == JSObject::EXTERNAL_PIXEL_ELEMENTS) { if (elements_kind == EXTERNAL_PIXEL_ELEMENTS) {
__ JumpIfNotSmi(eax, &slow); __ JumpIfNotSmi(eax, &slow);
} else { } else {
__ JumpIfNotSmi(eax, &check_heap_number); __ JumpIfNotSmi(eax, &check_heap_number);
@ -3578,33 +3578,33 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
// edi: base pointer of external storage // edi: base pointer of external storage
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
__ ClampUint8(ebx); __ ClampUint8(ebx);
__ SmiUntag(ecx); __ SmiUntag(ecx);
__ mov_b(Operand(edi, ecx, times_1, 0), ebx); __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
break; break;
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ SmiUntag(ecx); __ SmiUntag(ecx);
__ mov_b(Operand(edi, ecx, times_1, 0), ebx); __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ mov_w(Operand(edi, ecx, times_1, 0), ebx); __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
break; break;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
__ mov(Operand(edi, ecx, times_2, 0), ebx); __ mov(Operand(edi, ecx, times_2, 0), ebx);
break; break;
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
// Need to perform int-to-float conversion. // Need to perform int-to-float conversion.
__ push(ebx); __ push(ebx);
__ fild_s(Operand(esp, 0)); __ fild_s(Operand(esp, 0));
__ pop(ebx); __ pop(ebx);
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ fstp_s(Operand(edi, ecx, times_2, 0)); __ fstp_s(Operand(edi, ecx, times_2, 0));
} else { // elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS. } else { // elements_kind == EXTERNAL_DOUBLE_ELEMENTS.
__ fstp_d(Operand(edi, ecx, times_4, 0)); __ fstp_d(Operand(edi, ecx, times_4, 0));
} }
break; break;
@ -3615,7 +3615,7 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
__ ret(0); // Return the original value. __ ret(0); // Return the original value.
// TODO(danno): handle heap number -> pixel array conversion // TODO(danno): handle heap number -> pixel array conversion
if (elements_kind != JSObject::EXTERNAL_PIXEL_ELEMENTS) { if (elements_kind != EXTERNAL_PIXEL_ELEMENTS) {
__ bind(&check_heap_number); __ bind(&check_heap_number);
// eax: value // eax: value
// edx: receiver // edx: receiver
@ -3630,11 +3630,11 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// reproducible behavior, convert these to zero. // reproducible behavior, convert these to zero.
__ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset)); __ mov(edi, FieldOperand(edi, ExternalArray::kExternalPointerOffset));
// edi: base pointer of external storage // edi: base pointer of external storage
if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) {
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
__ fstp_s(Operand(edi, ecx, times_2, 0)); __ fstp_s(Operand(edi, ecx, times_2, 0));
__ ret(0); __ ret(0);
} else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) {
__ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
__ fstp_d(Operand(edi, ecx, times_4, 0)); __ fstp_d(Operand(edi, ecx, times_4, 0));
__ ret(0); __ ret(0);
@ -3647,23 +3647,23 @@ void KeyedStoreStubCompiler::GenerateStoreExternalArray(
// (code-stubs-ia32.cc) is roughly what is needed here though the // (code-stubs-ia32.cc) is roughly what is needed here though the
// conversion failure case does not need to be handled. // conversion failure case does not need to be handled.
if (CpuFeatures::IsSupported(SSE2)) { if (CpuFeatures::IsSupported(SSE2)) {
if (elements_kind != JSObject::EXTERNAL_INT_ELEMENTS && if (elements_kind != EXTERNAL_INT_ELEMENTS &&
elements_kind != JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS) { elements_kind != EXTERNAL_UNSIGNED_INT_ELEMENTS) {
ASSERT(CpuFeatures::IsSupported(SSE2)); ASSERT(CpuFeatures::IsSupported(SSE2));
CpuFeatures::Scope scope(SSE2); CpuFeatures::Scope scope(SSE2);
__ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset)); __ cvttsd2si(ebx, FieldOperand(eax, HeapNumber::kValueOffset));
// ecx: untagged integer value // ecx: untagged integer value
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
__ ClampUint8(ebx); __ ClampUint8(ebx);
// Fall through. // Fall through.
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
__ SmiUntag(ecx); __ SmiUntag(ecx);
__ mov_b(Operand(edi, ecx, times_1, 0), ebx); __ mov_b(Operand(edi, ecx, times_1, 0), ebx);
break; break;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
__ mov_w(Operand(edi, ecx, times_1, 0), ebx); __ mov_w(Operand(edi, ecx, times_1, 0), ebx);
break; break;
default: default:

50
deps/v8/src/ic.cc

@ -61,8 +61,7 @@ static char TransitionMarkFromState(IC::State state) {
void IC::TraceIC(const char* type, void IC::TraceIC(const char* type,
Handle<Object> name, Handle<Object> name,
State old_state, State old_state,
Code* new_target, Code* new_target) {
const char* extra_info) {
if (FLAG_trace_ic) { if (FLAG_trace_ic) {
State new_state = StateFrom(new_target, State new_state = StateFrom(new_target,
HEAP->undefined_value(), HEAP->undefined_value(),
@ -94,10 +93,9 @@ void IC::TraceIC(const char* type,
} else { } else {
PrintF("<unknown>"); PrintF("<unknown>");
} }
PrintF(" (%c->%c)%s", PrintF(" (%c->%c)",
TransitionMarkFromState(old_state), TransitionMarkFromState(old_state),
TransitionMarkFromState(new_state), TransitionMarkFromState(new_state));
extra_info);
name->Print(); name->Print();
PrintF("]\n"); PrintF("]\n");
} }
@ -326,7 +324,6 @@ void CallICBase::Clear(Address address, Code* target) {
Code* code = Code* code =
Isolate::Current()->stub_cache()->FindCallInitialize( Isolate::Current()->stub_cache()->FindCallInitialize(
target->arguments_count(), target->arguments_count(),
target->ic_in_loop(),
contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET, contextual ? RelocInfo::CODE_TARGET_CONTEXT : RelocInfo::CODE_TARGET,
target->kind()); target->kind());
SetTargetAtAddress(address, code); SetTargetAtAddress(address, code);
@ -604,13 +601,11 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
Handle<Object> object, Handle<Object> object,
Handle<String> name) { Handle<String> name) {
int argc = target()->arguments_count(); int argc = target()->arguments_count();
InLoopFlag in_loop = target()->ic_in_loop();
MaybeObject* maybe_code = NULL; MaybeObject* maybe_code = NULL;
switch (lookup->type()) { switch (lookup->type()) {
case FIELD: { case FIELD: {
int index = lookup->GetFieldIndex(); int index = lookup->GetFieldIndex();
maybe_code = isolate()->stub_cache()->ComputeCallField(argc, maybe_code = isolate()->stub_cache()->ComputeCallField(argc,
in_loop,
kind_, kind_,
extra_ic_state, extra_ic_state,
*name, *name,
@ -626,7 +621,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
JSFunction* function = lookup->GetConstantFunction(); JSFunction* function = lookup->GetConstantFunction();
maybe_code = maybe_code =
isolate()->stub_cache()->ComputeCallConstant(argc, isolate()->stub_cache()->ComputeCallConstant(argc,
in_loop,
kind_, kind_,
extra_ic_state, extra_ic_state,
*name, *name,
@ -646,7 +640,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
if (!cell->value()->IsJSFunction()) return NULL; if (!cell->value()->IsJSFunction()) return NULL;
JSFunction* function = JSFunction::cast(cell->value()); JSFunction* function = JSFunction::cast(cell->value());
maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc, maybe_code = isolate()->stub_cache()->ComputeCallGlobal(argc,
in_loop,
kind_, kind_,
extra_ic_state, extra_ic_state,
*name, *name,
@ -661,7 +654,6 @@ MaybeObject* CallICBase::ComputeMonomorphicStub(
// applicable. // applicable.
if (lookup->holder() != *receiver) return NULL; if (lookup->holder() != *receiver) return NULL;
maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc, maybe_code = isolate()->stub_cache()->ComputeCallNormal(argc,
in_loop,
kind_, kind_,
extra_ic_state, extra_ic_state,
*name, *name,
@ -706,7 +698,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// Compute the number of arguments. // Compute the number of arguments.
int argc = target()->arguments_count(); int argc = target()->arguments_count();
InLoopFlag in_loop = target()->ic_in_loop();
MaybeObject* maybe_code = NULL; MaybeObject* maybe_code = NULL;
bool had_proto_failure = false; bool had_proto_failure = false;
if (state == UNINITIALIZED) { if (state == UNINITIALIZED) {
@ -715,7 +706,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
// setting the monomorphic state. // setting the monomorphic state.
maybe_code = maybe_code =
isolate()->stub_cache()->ComputeCallPreMonomorphic(argc, isolate()->stub_cache()->ComputeCallPreMonomorphic(argc,
in_loop,
kind_, kind_,
extra_ic_state); extra_ic_state);
} else if (state == MONOMORPHIC) { } else if (state == MONOMORPHIC) {
@ -739,7 +729,6 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
} else { } else {
maybe_code = maybe_code =
isolate()->stub_cache()->ComputeCallMegamorphic(argc, isolate()->stub_cache()->ComputeCallMegamorphic(argc,
in_loop,
kind_, kind_,
extra_ic_state); extra_ic_state);
} }
@ -776,7 +765,7 @@ void CallICBase::UpdateCaches(LookupResult* lookup,
#ifdef DEBUG #ifdef DEBUG
if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE; if (had_proto_failure) state = MONOMORPHIC_PROTOTYPE_FAILURE;
TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC", TraceIC(kind_ == Code::CALL_IC ? "CallIC" : "KeyedCallIC",
name, state, target(), in_loop ? " (in-loop)" : ""); name, state, target());
#endif #endif
} }
@ -797,31 +786,28 @@ MaybeObject* KeyedCallIC::LoadFunction(State state,
if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) { if (FLAG_use_ic && state != MEGAMORPHIC && object->IsHeapObject()) {
int argc = target()->arguments_count(); int argc = target()->arguments_count();
InLoopFlag in_loop = target()->ic_in_loop();
Heap* heap = Handle<HeapObject>::cast(object)->GetHeap(); Heap* heap = Handle<HeapObject>::cast(object)->GetHeap();
Map* map = heap->non_strict_arguments_elements_map(); Map* map = heap->non_strict_arguments_elements_map();
if (object->IsJSObject() && if (object->IsJSObject() &&
Handle<JSObject>::cast(object)->elements()->map() == map) { Handle<JSObject>::cast(object)->elements()->map() == map) {
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments( MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallArguments(
argc, in_loop, Code::KEYED_CALL_IC); argc, Code::KEYED_CALL_IC);
Object* code; Object* code;
if (maybe_code->ToObject(&code)) { if (maybe_code->ToObject(&code)) {
set_target(Code::cast(code)); set_target(Code::cast(code));
#ifdef DEBUG #ifdef DEBUG
TraceIC( TraceIC("KeyedCallIC", key, state, target());
"KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
#endif #endif
} }
} else if (FLAG_use_ic && state != MEGAMORPHIC && } else if (FLAG_use_ic && state != MEGAMORPHIC &&
!object->IsAccessCheckNeeded()) { !object->IsAccessCheckNeeded()) {
MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic( MaybeObject* maybe_code = isolate()->stub_cache()->ComputeCallMegamorphic(
argc, in_loop, Code::KEYED_CALL_IC, Code::kNoExtraICState); argc, Code::KEYED_CALL_IC, Code::kNoExtraICState);
Object* code; Object* code;
if (maybe_code->ToObject(&code)) { if (maybe_code->ToObject(&code)) {
set_target(Code::cast(code)); set_target(Code::cast(code));
#ifdef DEBUG #ifdef DEBUG
TraceIC( TraceIC("KeyedCallIC", key, state, target());
"KeyedCallIC", key, state, target(), in_loop ? " (in-loop)" : "");
#endif #endif
} }
} }
@ -1093,7 +1079,7 @@ void LoadIC::UpdateCaches(LookupResult* lookup,
MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck( MaybeObject* KeyedLoadIC::GetElementStubWithoutMapCheck(
bool is_js_array, bool is_js_array,
JSObject::ElementsKind elements_kind) { ElementsKind elements_kind) {
return KeyedLoadElementStub(elements_kind).TryGetCode(); return KeyedLoadElementStub(elements_kind).TryGetCode();
} }
@ -1650,7 +1636,6 @@ MaybeObject* KeyedIC::ComputeStub(JSObject* receiver,
PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache(); PolymorphicCodeCache* cache = isolate()->heap()->polymorphic_code_cache();
Code::Flags flags = Code::ComputeFlags(this->kind(), Code::Flags flags = Code::ComputeFlags(this->kind(),
NOT_IN_LOOP,
MEGAMORPHIC, MEGAMORPHIC,
strict_mode); strict_mode);
Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags); Object* maybe_cached_stub = cache->Lookup(&target_receiver_maps, flags);
@ -1721,7 +1706,7 @@ MaybeObject* KeyedIC::ComputeMonomorphicStub(JSObject* receiver,
MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck( MaybeObject* KeyedStoreIC::GetElementStubWithoutMapCheck(
bool is_js_array, bool is_js_array,
JSObject::ElementsKind elements_kind) { ElementsKind elements_kind) {
return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode(); return KeyedStoreElementStub(is_js_array, elements_kind).TryGetCode();
} }
@ -1905,16 +1890,11 @@ void KeyedStoreIC::UpdateCaches(LookupResult* lookup,
// //
static JSFunction* CompileFunction(Isolate* isolate, static JSFunction* CompileFunction(Isolate* isolate,
JSFunction* function, JSFunction* function) {
InLoopFlag in_loop) {
// Compile now with optimization. // Compile now with optimization.
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<JSFunction> function_handle(function, isolate); Handle<JSFunction> function_handle(function, isolate);
if (in_loop == IN_LOOP) {
CompileLazyInLoop(function_handle, CLEAR_EXCEPTION);
} else {
CompileLazy(function_handle, CLEAR_EXCEPTION); CompileLazy(function_handle, CLEAR_EXCEPTION);
}
return *function_handle; return *function_handle;
} }
@ -1943,9 +1923,7 @@ RUNTIME_FUNCTION(MaybeObject*, CallIC_Miss) {
if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
return result; return result;
} }
return CompileFunction(isolate, return CompileFunction(isolate, JSFunction::cast(result));
JSFunction::cast(result),
ic.target()->ic_in_loop());
} }
@ -1964,9 +1942,7 @@ RUNTIME_FUNCTION(MaybeObject*, KeyedCallIC_Miss) {
if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) { if (!result->IsJSFunction() || JSFunction::cast(result)->is_compiled()) {
return result; return result;
} }
return CompileFunction(isolate, return CompileFunction(isolate, JSFunction::cast(result));
JSFunction::cast(result),
ic.target()->ic_in_loop());
} }

9
deps/v8/src/ic.h

@ -149,8 +149,7 @@ class IC {
void TraceIC(const char* type, void TraceIC(const char* type,
Handle<Object> name, Handle<Object> name,
State old_state, State old_state,
Code* new_target, Code* new_target);
const char* extra_info = "");
#endif #endif
Failure* TypeError(const char* type, Failure* TypeError(const char* type,
@ -348,7 +347,7 @@ class KeyedIC: public IC {
virtual MaybeObject* GetElementStubWithoutMapCheck( virtual MaybeObject* GetElementStubWithoutMapCheck(
bool is_js_array, bool is_js_array,
JSObject::ElementsKind elements_kind) = 0; ElementsKind elements_kind) = 0;
protected: protected:
virtual Code* string_stub() { virtual Code* string_stub() {
@ -415,7 +414,7 @@ class KeyedLoadIC: public KeyedIC {
virtual MaybeObject* GetElementStubWithoutMapCheck( virtual MaybeObject* GetElementStubWithoutMapCheck(
bool is_js_array, bool is_js_array,
JSObject::ElementsKind elements_kind); ElementsKind elements_kind);
protected: protected:
virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; } virtual Code::Kind kind() const { return Code::KEYED_LOAD_IC; }
@ -566,7 +565,7 @@ class KeyedStoreIC: public KeyedIC {
virtual MaybeObject* GetElementStubWithoutMapCheck( virtual MaybeObject* GetElementStubWithoutMapCheck(
bool is_js_array, bool is_js_array,
JSObject::ElementsKind elements_kind); ElementsKind elements_kind);
protected: protected:
virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; } virtual Code::Kind kind() const { return Code::KEYED_STORE_IC; }

2
deps/v8/src/inspector.h

@ -41,7 +41,6 @@ namespace internal {
class Inspector { class Inspector {
public: public:
static void DumpObjectType(FILE* out, Object *obj, bool print_more); static void DumpObjectType(FILE* out, Object *obj, bool print_more);
static void DumpObjectType(FILE* out, Object *obj) { static void DumpObjectType(FILE* out, Object *obj) {
DumpObjectType(out, obj, false); DumpObjectType(out, obj, false);
@ -59,4 +58,3 @@ class Inspector {
#endif // INSPECTOR #endif // INSPECTOR
#endif // V8_INSPECTOR_H_ #endif // V8_INSPECTOR_H_

9
deps/v8/src/isolate.cc

@ -1414,7 +1414,7 @@ Isolate::Isolate()
TRACE_ISOLATE(constructor); TRACE_ISOLATE(constructor);
memset(isolate_addresses_, 0, memset(isolate_addresses_, 0,
sizeof(isolate_addresses_[0]) * (k_isolate_address_count + 1)); sizeof(isolate_addresses_[0]) * (kIsolateAddressCount + 1));
heap_.isolate_ = this; heap_.isolate_ = this;
zone_.isolate_ = this; zone_.isolate_ = this;
@ -1686,9 +1686,10 @@ bool Isolate::Init(Deserializer* des) {
// ensuring that Isolate::Current() == this. // ensuring that Isolate::Current() == this.
heap_.SetStackLimits(); heap_.SetStackLimits();
#define C(name) isolate_addresses_[Isolate::k_##name] = \ #define ASSIGN_ELEMENT(CamelName, hacker_name) \
reinterpret_cast<Address>(name()); isolate_addresses_[Isolate::k##CamelName##Address] = \
ISOLATE_ADDRESS_LIST(C) reinterpret_cast<Address>(hacker_name##_address());
FOR_EACH_ISOLATE_ADDRESS_NAME(ASSIGN_ELEMENT)
#undef C #undef C
string_tracker_ = new StringTracker(); string_tracker_ = new StringTracker();

22
deps/v8/src/isolate.h

@ -119,13 +119,13 @@ typedef ZoneList<Handle<Object> > ZoneObjectList;
#define RETURN_IF_EMPTY_HANDLE(isolate, call) \ #define RETURN_IF_EMPTY_HANDLE(isolate, call) \
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception()) RETURN_IF_EMPTY_HANDLE_VALUE(isolate, call, Failure::Exception())
#define ISOLATE_ADDRESS_LIST(C) \ #define FOR_EACH_ISOLATE_ADDRESS_NAME(C) \
C(handler_address) \ C(Handler, handler) \
C(c_entry_fp_address) \ C(CEntryFP, c_entry_fp) \
C(context_address) \ C(Context, context) \
C(pending_exception_address) \ C(PendingException, pending_exception) \
C(external_caught_exception_address) \ C(ExternalCaughtException, external_caught_exception) \
C(js_entry_sp_address) C(JSEntrySP, js_entry_sp)
// Platform-independent, reliable thread identifier. // Platform-independent, reliable thread identifier.
@ -423,10 +423,10 @@ class Isolate {
enum AddressId { enum AddressId {
#define C(name) k_##name, #define DECLARE_ENUM(CamelName, hacker_name) k##CamelName##Address,
ISOLATE_ADDRESS_LIST(C) FOR_EACH_ISOLATE_ADDRESS_NAME(DECLARE_ENUM)
#undef C #undef C
k_isolate_address_count kIsolateAddressCount
}; };
// Returns the PerIsolateThreadData for the current thread (or NULL if one is // Returns the PerIsolateThreadData for the current thread (or NULL if one is
@ -1097,7 +1097,7 @@ class Isolate {
StringStream* incomplete_message_; StringStream* incomplete_message_;
// The preallocated memory thread singleton. // The preallocated memory thread singleton.
PreallocatedMemoryThread* preallocated_memory_thread_; PreallocatedMemoryThread* preallocated_memory_thread_;
Address isolate_addresses_[k_isolate_address_count + 1]; // NOLINT Address isolate_addresses_[kIsolateAddressCount + 1]; // NOLINT
NoAllocationStringAllocator* preallocated_message_space_; NoAllocationStringAllocator* preallocated_message_space_;
Bootstrapper* bootstrapper_; Bootstrapper* bootstrapper_;

8
deps/v8/src/json.js

@ -54,7 +54,7 @@ function Revive(holder, name, reviver) {
function JSONParse(text, reviver) { function JSONParse(text, reviver) {
var unfiltered = %ParseJson(TO_STRING_INLINE(text)); var unfiltered = %ParseJson(TO_STRING_INLINE(text));
if (IS_FUNCTION(reviver)) { if (IS_SPEC_FUNCTION(reviver)) {
return Revive({'': unfiltered}, '', reviver); return Revive({'': unfiltered}, '', reviver);
} else { } else {
return unfiltered; return unfiltered;
@ -143,11 +143,11 @@ function JSONSerialize(key, holder, replacer, stack, indent, gap) {
var value = holder[key]; var value = holder[key];
if (IS_SPEC_OBJECT(value)) { if (IS_SPEC_OBJECT(value)) {
var toJSON = value.toJSON; var toJSON = value.toJSON;
if (IS_FUNCTION(toJSON)) { if (IS_SPEC_FUNCTION(toJSON)) {
value = %_CallFunction(value, key, toJSON); value = %_CallFunction(value, key, toJSON);
} }
} }
if (IS_FUNCTION(replacer)) { if (IS_SPEC_FUNCTION(replacer)) {
value = %_CallFunction(holder, key, value, replacer); value = %_CallFunction(holder, key, value, replacer);
} }
if (IS_STRING(value)) { if (IS_STRING(value)) {
@ -273,7 +273,7 @@ function BasicSerializeObject(value, stack, builder) {
function BasicJSONSerialize(key, value, stack, builder) { function BasicJSONSerialize(key, value, stack, builder) {
if (IS_SPEC_OBJECT(value)) { if (IS_SPEC_OBJECT(value)) {
var toJSON = value.toJSON; var toJSON = value.toJSON;
if (IS_FUNCTION(toJSON)) { if (IS_SPEC_FUNCTION(toJSON)) {
value = %_CallFunction(value, ToString(key), toJSON); value = %_CallFunction(value, ToString(key), toJSON);
} }
} }

8
deps/v8/src/jsregexp.h

@ -255,6 +255,7 @@ class SetRelation BASE_EMBEDDED {
return (bits_ == (kInFirst | kInSecond | kInBoth)); return (bits_ == (kInFirst | kInSecond | kInBoth));
} }
int value() { return bits_; } int value() { return bits_; }
private: private:
int bits_; int bits_;
}; };
@ -404,6 +405,7 @@ class DispatchTable : public ZoneObject {
template <typename Callback> template <typename Callback>
void ForEach(Callback* callback) { return tree()->ForEach(callback); } void ForEach(Callback* callback) { return tree()->ForEach(callback); }
private: private:
// There can't be a static empty set since it allocates its // There can't be a static empty set since it allocates its
// successors in a zone and caches them. // successors in a zone and caches them.
@ -793,6 +795,7 @@ class ActionNode: public SeqRegExpNode {
virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; } virtual int GreedyLoopTextLength() { return kNodeIsTooComplexForGreedyLoops; }
virtual ActionNode* Clone() { return new ActionNode(*this); } virtual ActionNode* Clone() { return new ActionNode(*this); }
virtual int ComputeFirstCharacterSet(int budget); virtual int ComputeFirstCharacterSet(int budget);
private: private:
union { union {
struct { struct {
@ -861,6 +864,7 @@ class TextNode: public SeqRegExpNode {
} }
void CalculateOffsets(); void CalculateOffsets();
virtual int ComputeFirstCharacterSet(int budget); virtual int ComputeFirstCharacterSet(int budget);
private: private:
enum TextEmitPassType { enum TextEmitPassType {
NON_ASCII_MATCH, // Check for characters that can't match. NON_ASCII_MATCH, // Check for characters that can't match.
@ -925,6 +929,7 @@ class AssertionNode: public SeqRegExpNode {
virtual AssertionNode* Clone() { return new AssertionNode(*this); } virtual AssertionNode* Clone() { return new AssertionNode(*this); }
AssertionNodeType type() { return type_; } AssertionNodeType type() { return type_; }
void set_type(AssertionNodeType type) { type_ = type; } void set_type(AssertionNodeType type) { type_ = type; }
private: private:
AssertionNode(AssertionNodeType t, RegExpNode* on_success) AssertionNode(AssertionNodeType t, RegExpNode* on_success)
: SeqRegExpNode(on_success), type_(t) { } : SeqRegExpNode(on_success), type_(t) { }
@ -955,6 +960,7 @@ class BackReferenceNode: public SeqRegExpNode {
} }
virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); } virtual BackReferenceNode* Clone() { return new BackReferenceNode(*this); }
virtual int ComputeFirstCharacterSet(int budget); virtual int ComputeFirstCharacterSet(int budget);
private: private:
int start_reg_; int start_reg_;
int end_reg_; int end_reg_;
@ -1301,6 +1307,7 @@ class Trace {
} }
void InvalidateCurrentCharacter(); void InvalidateCurrentCharacter();
void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler); void AdvanceCurrentPositionInTrace(int by, RegExpCompiler* compiler);
private: private:
int FindAffectedRegisters(OutSet* affected_registers); int FindAffectedRegisters(OutSet* affected_registers);
void PerformDeferredActions(RegExpMacroAssembler* macro, void PerformDeferredActions(RegExpMacroAssembler* macro,
@ -1402,6 +1409,7 @@ FOR_EACH_NODE_TYPE(DECLARE_VISIT)
void fail(const char* error_message) { void fail(const char* error_message) {
error_message_ = error_message; error_message_ = error_message;
} }
private: private:
bool ignore_case_; bool ignore_case_;
bool is_ascii_; bool is_ascii_;

29
deps/v8/src/list-inl.h

@ -207,6 +207,35 @@ void List<T, P>::Initialize(int capacity) {
} }
template <typename T>
int SortedListBSearch(
const List<T>& list, T elem, int (*cmp)(const T* x, const T* y)) {
int low = 0;
int high = list.length() - 1;
while (low <= high) {
int mid = (low + high) / 2;
T mid_elem = list[mid];
if (mid_elem > elem) {
high = mid - 1;
continue;
}
if (mid_elem < elem) {
low = mid + 1;
continue;
}
// Found the elememt.
return mid;
}
return -1;
}
template <typename T>
int SortedListBSearch(const List<T>& list, T elem) {
return SortedListBSearch<T>(list, elem, PointerValueCompare<T>);
}
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_LIST_INL_H_ #endif // V8_LIST_INL_H_

10
deps/v8/src/list.h

@ -49,7 +49,6 @@ namespace internal {
template <typename T, class P> template <typename T, class P>
class List { class List {
public: public:
List() { Initialize(0); } List() { Initialize(0); }
INLINE(explicit List(int capacity)) { Initialize(capacity); } INLINE(explicit List(int capacity)) { Initialize(capacity); }
INLINE(~List()) { DeleteData(data_); } INLINE(~List()) { DeleteData(data_); }
@ -169,6 +168,15 @@ class Code;
typedef List<Map*> MapList; typedef List<Map*> MapList;
typedef List<Code*> CodeList; typedef List<Code*> CodeList;
// Perform binary search for an element in an already sorted
// list. Returns the index of the element of -1 if it was not found.
template <typename T>
int SortedListBSearch(
const List<T>& list, T elem, int (*cmp)(const T* x, const T* y));
template <typename T>
int SortedListBSearch(const List<T>& list, T elem);
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_LIST_H_ #endif // V8_LIST_H_

28
deps/v8/src/lithium.cc

@ -166,25 +166,25 @@ void LPointerMap::PrintTo(StringStream* stream) {
} }
int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind) { int ElementsKindToShiftSize(ElementsKind elements_kind) {
switch (elements_kind) { switch (elements_kind) {
case JSObject::EXTERNAL_BYTE_ELEMENTS: case EXTERNAL_BYTE_ELEMENTS:
case JSObject::EXTERNAL_PIXEL_ELEMENTS: case EXTERNAL_PIXEL_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
return 0; return 0;
case JSObject::EXTERNAL_SHORT_ELEMENTS: case EXTERNAL_SHORT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_SHORT_ELEMENTS: case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
return 1; return 1;
case JSObject::EXTERNAL_INT_ELEMENTS: case EXTERNAL_INT_ELEMENTS:
case JSObject::EXTERNAL_UNSIGNED_INT_ELEMENTS: case EXTERNAL_UNSIGNED_INT_ELEMENTS:
case JSObject::EXTERNAL_FLOAT_ELEMENTS: case EXTERNAL_FLOAT_ELEMENTS:
return 2; return 2;
case JSObject::EXTERNAL_DOUBLE_ELEMENTS: case EXTERNAL_DOUBLE_ELEMENTS:
case JSObject::FAST_DOUBLE_ELEMENTS: case FAST_DOUBLE_ELEMENTS:
return 3; return 3;
case JSObject::FAST_ELEMENTS: case FAST_ELEMENTS:
case JSObject::DICTIONARY_ELEMENTS: case DICTIONARY_ELEMENTS:
case JSObject::NON_STRICT_ARGUMENTS_ELEMENTS: case NON_STRICT_ARGUMENTS_ELEMENTS:
return kPointerSizeLog2; return kPointerSizeLog2;
} }
UNREACHABLE(); UNREACHABLE();

8
deps/v8/src/lithium.h

@ -165,8 +165,7 @@ class LUnallocated: public LOperand {
} }
Policy policy() const { return PolicyField::decode(value_); } Policy policy() const { return PolicyField::decode(value_); }
void set_policy(Policy policy) { void set_policy(Policy policy) {
value_ &= ~PolicyField::mask(); value_ = PolicyField::update(value_, policy);
value_ |= PolicyField::encode(policy);
} }
int fixed_index() const { int fixed_index() const {
return static_cast<int>(value_) >> kFixedIndexShift; return static_cast<int>(value_) >> kFixedIndexShift;
@ -177,8 +176,7 @@ class LUnallocated: public LOperand {
} }
void set_virtual_register(unsigned id) { void set_virtual_register(unsigned id) {
value_ &= ~VirtualRegisterField::mask(); value_ = VirtualRegisterField::update(value_, id);
value_ |= VirtualRegisterField::encode(id);
} }
LUnallocated* CopyUnconstrained() { LUnallocated* CopyUnconstrained() {
@ -586,7 +584,7 @@ class DeepIterator BASE_EMBEDDED {
}; };
int ElementsKindToShiftSize(JSObject::ElementsKind elements_kind); int ElementsKindToShiftSize(ElementsKind elements_kind);
} } // namespace v8::internal } } // namespace v8::internal

2
deps/v8/src/liveedit.cc

@ -1450,7 +1450,7 @@ static bool FixTryCatchHandler(StackFrame* top_frame,
StackFrame* bottom_frame) { StackFrame* bottom_frame) {
Address* pointer_address = Address* pointer_address =
&Memory::Address_at(Isolate::Current()->get_address_from_id( &Memory::Address_at(Isolate::Current()->get_address_from_id(
Isolate::k_handler_address)); Isolate::kHandlerAddress));
while (*pointer_address < top_frame->sp()) { while (*pointer_address < top_frame->sp()) {
pointer_address = &Memory::Address_at(*pointer_address); pointer_address = &Memory::Address_at(*pointer_address);

12
deps/v8/src/liveobjectlist.cc

@ -184,7 +184,7 @@ bool IsOfType(LiveObjectType type, HeapObject *obj) {
const AllocationSpace kInvalidSpace = static_cast<AllocationSpace>(-1); const AllocationSpace kInvalidSpace = static_cast<AllocationSpace>(-1);
static AllocationSpace FindSpaceFor(String* space_str) { static AllocationSpace FindSpaceFor(String* space_str) {
SmartPointer<char> s = SmartArrayPointer<char> s =
space_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); space_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
const char* key_str = *s; const char* key_str = *s;
@ -236,7 +236,7 @@ static bool InSpace(AllocationSpace space, HeapObject *heap_obj) {
static LiveObjectType FindTypeFor(String* type_str) { static LiveObjectType FindTypeFor(String* type_str) {
SmartPointer<char> s = SmartArrayPointer<char> s =
type_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); type_str->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
#define CHECK_OBJECT_TYPE(type_, name) { \ #define CHECK_OBJECT_TYPE(type_, name) { \
@ -503,7 +503,7 @@ static void GenerateObjectDesc(HeapObject* obj,
// We'll only dump 80 of them after we compact them. // We'll only dump 80 of them after we compact them.
const int kMaxCharToDump = 80; const int kMaxCharToDump = 80;
const int kMaxBufferSize = kMaxCharToDump * 2; const int kMaxBufferSize = kMaxCharToDump * 2;
SmartPointer<char> str_sp = str->ToCString(DISALLOW_NULLS, SmartArrayPointer<char> str_sp = str->ToCString(DISALLOW_NULLS,
ROBUST_STRING_TRAVERSAL, ROBUST_STRING_TRAVERSAL,
0, 0,
kMaxBufferSize); kMaxBufferSize);
@ -526,14 +526,14 @@ static void GenerateObjectDesc(HeapObject* obj,
} }
String* name = sinfo->DebugName(); String* name = sinfo->DebugName();
SmartPointer<char> name_sp = SmartArrayPointer<char> name_sp =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
char* name_cstr = *name_sp; char* name_cstr = *name_sp;
HeapStringAllocator string_allocator; HeapStringAllocator string_allocator;
StringStream stream(&string_allocator); StringStream stream(&string_allocator);
sinfo->SourceCodePrint(&stream, 50); sinfo->SourceCodePrint(&stream, 50);
SmartPointer<const char> source_sp = stream.ToCString(); SmartArrayPointer<const char> source_sp = stream.ToCString();
const char* source_cstr = *source_sp; const char* source_cstr = *source_sp;
OS::SNPrintF(buffer_v, OS::SNPrintF(buffer_v,
@ -1656,7 +1656,7 @@ int LiveObjectList::GetObjId(Object* obj) {
// Gets the obj id for the specified address if valid. // Gets the obj id for the specified address if valid.
Object* LiveObjectList::GetObjId(Handle<String> address) { Object* LiveObjectList::GetObjId(Handle<String> address) {
SmartPointer<char> addr_str = SmartArrayPointer<char> addr_str =
address->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); address->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
Isolate* isolate = Isolate::Current(); Isolate* isolate = Isolate::Current();

3
deps/v8/src/liveobjectlist.h

@ -114,7 +114,6 @@ class LiveObjectList {
static Object* PrintObj(int obj_id); static Object* PrintObj(int obj_id);
private: private:
struct Element { struct Element {
int id_; int id_;
HeapObject* obj_; HeapObject* obj_;
@ -224,7 +223,6 @@ class LiveObjectList {
// Helper class for updating the LiveObjectList HeapObject pointers. // Helper class for updating the LiveObjectList HeapObject pointers.
class UpdateLiveObjectListVisitor: public ObjectVisitor { class UpdateLiveObjectListVisitor: public ObjectVisitor {
public: public:
void VisitPointer(Object** p) { UpdatePointer(p); } void VisitPointer(Object** p) { UpdatePointer(p); }
void VisitPointers(Object** start, Object** end) { void VisitPointers(Object** start, Object** end) {
@ -319,4 +317,3 @@ class LiveObjectList {
} } // namespace v8::internal } } // namespace v8::internal
#endif // V8_LIVEOBJECTLIST_H_ #endif // V8_LIVEOBJECTLIST_H_

2
deps/v8/src/log-utils.cc

@ -125,7 +125,7 @@ void Log::Initialize() {
stream.Put(*p); stream.Put(*p);
} }
} }
SmartPointer<const char> expanded = stream.ToCString(); SmartArrayPointer<const char> expanded = stream.ToCString();
OpenFile(*expanded); OpenFile(*expanded);
} else { } else {
OpenFile(FLAG_logfile); OpenFile(FLAG_logfile);

1
deps/v8/src/log-utils.h

@ -141,7 +141,6 @@ class LogMessageBuilder BASE_EMBEDDED {
void WriteToLogFile(); void WriteToLogFile();
private: private:
Log* log_; Log* log_;
ScopedLock sl; ScopedLock sl;
int pos_; int pos_;

64
deps/v8/src/log.cc

@ -617,7 +617,7 @@ void Logger::ApiEvent(const char* format, ...) {
void Logger::ApiNamedSecurityCheck(Object* key) { void Logger::ApiNamedSecurityCheck(Object* key) {
if (!log_->IsEnabled() || !FLAG_log_api) return; if (!log_->IsEnabled() || !FLAG_log_api) return;
if (key->IsString()) { if (key->IsString()) {
SmartPointer<char> str = SmartArrayPointer<char> str =
String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,check-security,\"%s\"\n", *str); ApiEvent("api,check-security,\"%s\"\n", *str);
} else if (key->IsUndefined()) { } else if (key->IsUndefined()) {
@ -762,9 +762,9 @@ void Logger::ApiNamedPropertyAccess(const char* tag,
ASSERT(name->IsString()); ASSERT(name->IsString());
if (!log_->IsEnabled() || !FLAG_log_api) return; if (!log_->IsEnabled() || !FLAG_log_api) return;
String* class_name_obj = holder->class_name(); String* class_name_obj = holder->class_name();
SmartPointer<char> class_name = SmartArrayPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
SmartPointer<char> property_name = SmartArrayPointer<char> property_name =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name); ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
} }
@ -774,7 +774,7 @@ void Logger::ApiIndexedPropertyAccess(const char* tag,
uint32_t index) { uint32_t index) {
if (!log_->IsEnabled() || !FLAG_log_api) return; if (!log_->IsEnabled() || !FLAG_log_api) return;
String* class_name_obj = holder->class_name(); String* class_name_obj = holder->class_name();
SmartPointer<char> class_name = SmartArrayPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index); ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
} }
@ -782,7 +782,7 @@ void Logger::ApiIndexedPropertyAccess(const char* tag,
void Logger::ApiObjectAccess(const char* tag, JSObject* object) { void Logger::ApiObjectAccess(const char* tag, JSObject* object) {
if (!log_->IsEnabled() || !FLAG_log_api) return; if (!log_->IsEnabled() || !FLAG_log_api) return;
String* class_name_obj = object->class_name(); String* class_name_obj = object->class_name();
SmartPointer<char> class_name = SmartArrayPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\"\n", tag, *class_name); ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
} }
@ -836,7 +836,7 @@ void Logger::CallbackEventInternal(const char* prefix, const char* name,
void Logger::CallbackEvent(String* name, Address entry_point) { void Logger::CallbackEvent(String* name, Address entry_point) {
if (!log_->IsEnabled() || !FLAG_log_code) return; if (!log_->IsEnabled() || !FLAG_log_code) return;
SmartPointer<char> str = SmartArrayPointer<char> str =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
CallbackEventInternal("", *str, entry_point); CallbackEventInternal("", *str, entry_point);
} }
@ -844,7 +844,7 @@ void Logger::CallbackEvent(String* name, Address entry_point) {
void Logger::GetterCallbackEvent(String* name, Address entry_point) { void Logger::GetterCallbackEvent(String* name, Address entry_point) {
if (!log_->IsEnabled() || !FLAG_log_code) return; if (!log_->IsEnabled() || !FLAG_log_code) return;
SmartPointer<char> str = SmartArrayPointer<char> str =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
CallbackEventInternal("get ", *str, entry_point); CallbackEventInternal("get ", *str, entry_point);
} }
@ -852,7 +852,7 @@ void Logger::GetterCallbackEvent(String* name, Address entry_point) {
void Logger::SetterCallbackEvent(String* name, Address entry_point) { void Logger::SetterCallbackEvent(String* name, Address entry_point) {
if (!log_->IsEnabled() || !FLAG_log_code) return; if (!log_->IsEnabled() || !FLAG_log_code) return;
SmartPointer<char> str = SmartArrayPointer<char> str =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
CallbackEventInternal("set ", *str, entry_point); CallbackEventInternal("set ", *str, entry_point);
} }
@ -957,7 +957,7 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
return; return;
LogMessageBuilder msg(this); LogMessageBuilder msg(this);
SmartPointer<char> str = SmartArrayPointer<char> str =
name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); name->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append("%s,%s,", msg.Append("%s,%s,",
kLogEventsNames[CODE_CREATION_EVENT], kLogEventsNames[CODE_CREATION_EVENT],
@ -998,9 +998,9 @@ void Logger::CodeCreateEvent(LogEventsAndTags tag,
} }
if (!FLAG_log_code) return; if (!FLAG_log_code) return;
LogMessageBuilder msg(this); LogMessageBuilder msg(this);
SmartPointer<char> name = SmartArrayPointer<char> name =
shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
SmartPointer<char> sourcestr = SmartArrayPointer<char> sourcestr =
source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL); source->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
msg.Append("%s,%s,", msg.Append("%s,%s,",
kLogEventsNames[CODE_CREATION_EVENT], kLogEventsNames[CODE_CREATION_EVENT],
@ -1527,20 +1527,8 @@ void Logger::LogCodeObjects() {
} }
void Logger::LogCompiledFunctions() { void Logger::LogExistingFunction(Handle<SharedFunctionInfo> shared,
HandleScope scope; Handle<Code> code) {
const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL);
ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
ScopedVector< Handle<Code> > code_objects(compiled_funcs_count);
EnumerateCompiledFunctions(sfis.start(), code_objects.start());
// During iteration, there can be heap allocation due to
// GetScriptLineNumber call.
for (int i = 0; i < compiled_funcs_count; ++i) {
if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
Builtins::kLazyCompile))
continue;
Handle<SharedFunctionInfo> shared = sfis[i];
Handle<String> func_name(shared->DebugName()); Handle<String> func_name(shared->DebugName());
if (shared->script()->IsScript()) { if (shared->script()->IsScript()) {
Handle<Script> script(Script::cast(shared->script())); Handle<Script> script(Script::cast(shared->script()));
@ -1551,20 +1539,20 @@ void Logger::LogCompiledFunctions() {
PROFILE(ISOLATE, PROFILE(ISOLATE,
CodeCreateEvent( CodeCreateEvent(
Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
*code_objects[i], *shared, *code, *shared,
*script_name, line_num + 1)); *script_name, line_num + 1));
} else { } else {
// Can't distinguish eval and script here, so always use Script. // Can't distinguish eval and script here, so always use Script.
PROFILE(ISOLATE, PROFILE(ISOLATE,
CodeCreateEvent( CodeCreateEvent(
Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script), Logger::ToNativeByScript(Logger::SCRIPT_TAG, *script),
*code_objects[i], *shared, *script_name)); *code, *shared, *script_name));
} }
} else { } else {
PROFILE(ISOLATE, PROFILE(ISOLATE,
CodeCreateEvent( CodeCreateEvent(
Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script), Logger::ToNativeByScript(Logger::LAZY_COMPILE_TAG, *script),
*code_objects[i], *shared, *func_name)); *code, *shared, *func_name));
} }
} else if (shared->IsApiFunction()) { } else if (shared->IsApiFunction()) {
// API function. // API function.
@ -1579,9 +1567,25 @@ void Logger::LogCompiledFunctions() {
} else { } else {
PROFILE(ISOLATE, PROFILE(ISOLATE,
CodeCreateEvent( CodeCreateEvent(
Logger::LAZY_COMPILE_TAG, *code_objects[i], Logger::LAZY_COMPILE_TAG, *code, *shared, *func_name));
*shared, *func_name));
} }
}
void Logger::LogCompiledFunctions() {
HandleScope scope;
const int compiled_funcs_count = EnumerateCompiledFunctions(NULL, NULL);
ScopedVector< Handle<SharedFunctionInfo> > sfis(compiled_funcs_count);
ScopedVector< Handle<Code> > code_objects(compiled_funcs_count);
EnumerateCompiledFunctions(sfis.start(), code_objects.start());
// During iteration, there can be heap allocation due to
// GetScriptLineNumber call.
for (int i = 0; i < compiled_funcs_count; ++i) {
if (*code_objects[i] == Isolate::Current()->builtins()->builtin(
Builtins::kLazyCompile))
continue;
LogExistingFunction(sfis[i], code_objects[i]);
} }
} }

2
deps/v8/src/log.h

@ -281,6 +281,8 @@ class Logger {
void ResumeProfiler(); void ResumeProfiler();
bool IsProfilerPaused(); bool IsProfilerPaused();
void LogExistingFunction(Handle<SharedFunctionInfo> shared,
Handle<Code> code);
// Logs all compiled functions found in the heap. // Logs all compiled functions found in the heap.
void LogCompiledFunctions(); void LogCompiledFunctions();
// Logs all accessor callbacks found in the heap. // Logs all accessor callbacks found in the heap.

10
deps/v8/src/macros.py

@ -116,10 +116,18 @@ macro FLOOR(arg) = $floor(arg);
# Macro for ECMAScript 5 queries of the type: # Macro for ECMAScript 5 queries of the type:
# "Type(O) is object." # "Type(O) is object."
# This is the same as being either a function or an object in V8 terminology. # This is the same as being either a function or an object in V8 terminology
# (including proxies).
# In addition, an undetectable object is also included by this. # In addition, an undetectable object is also included by this.
macro IS_SPEC_OBJECT(arg) = (%_IsSpecObject(arg)); macro IS_SPEC_OBJECT(arg) = (%_IsSpecObject(arg));
# Macro for ECMAScript 5 queries of the type:
# "IsCallable(O)"
# We assume here that this is the same as being either a function or a function
# proxy. That ignores host objects with [[Call]] methods, but in most situations
# we cannot handle those anyway.
macro IS_SPEC_FUNCTION(arg) = (%_ClassOf(arg) === 'Function');
# Inline macros. Use %IS_VAR to make sure arg is evaluated only once. # Inline macros. Use %IS_VAR to make sure arg is evaluated only once.
macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg)); macro NUMBER_IS_NAN(arg) = (!%_IsSmi(%IS_VAR(arg)) && !(arg == arg));
macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 1/0) && (arg != -1/0))); macro NUMBER_IS_FINITE(arg) = (%_IsSmi(%IS_VAR(arg)) || ((arg == arg) && (arg != 1/0) && (arg != -1/0)));

7
deps/v8/src/messages.cc

@ -41,13 +41,13 @@ namespace internal {
// by default. // by default.
void MessageHandler::DefaultMessageReport(const MessageLocation* loc, void MessageHandler::DefaultMessageReport(const MessageLocation* loc,
Handle<Object> message_obj) { Handle<Object> message_obj) {
SmartPointer<char> str = GetLocalizedMessage(message_obj); SmartArrayPointer<char> str = GetLocalizedMessage(message_obj);
if (loc == NULL) { if (loc == NULL) {
PrintF("%s\n", *str); PrintF("%s\n", *str);
} else { } else {
HandleScope scope; HandleScope scope;
Handle<Object> data(loc->script()->name()); Handle<Object> data(loc->script()->name());
SmartPointer<char> data_str; SmartArrayPointer<char> data_str;
if (data->IsString()) if (data->IsString())
data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS); data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS);
PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>", PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>",
@ -170,7 +170,8 @@ Handle<String> MessageHandler::GetMessage(Handle<Object> data) {
} }
SmartPointer<char> MessageHandler::GetLocalizedMessage(Handle<Object> data) { SmartArrayPointer<char> MessageHandler::GetLocalizedMessage(
Handle<Object> data) {
HandleScope scope; HandleScope scope;
return GetMessage(data)->ToCString(DISALLOW_NULLS); return GetMessage(data)->ToCString(DISALLOW_NULLS);
} }

2
deps/v8/src/messages.h

@ -105,7 +105,7 @@ class MessageHandler {
static void DefaultMessageReport(const MessageLocation* loc, static void DefaultMessageReport(const MessageLocation* loc,
Handle<Object> message_obj); Handle<Object> message_obj);
static Handle<String> GetMessage(Handle<Object> data); static Handle<String> GetMessage(Handle<Object> data);
static SmartPointer<char> GetLocalizedMessage(Handle<Object> data); static SmartArrayPointer<char> GetLocalizedMessage(Handle<Object> data);
}; };
} } // namespace v8::internal } } // namespace v8::internal

3
deps/v8/src/messages.js

@ -185,6 +185,7 @@ function FormatMessage(message) {
"define_disallowed", ["Cannot define property:", "%0", ", object is not extensible."], "define_disallowed", ["Cannot define property:", "%0", ", object is not extensible."],
"non_extensible_proto", ["%0", " is not extensible"], "non_extensible_proto", ["%0", " is not extensible"],
"handler_non_object", ["Proxy.", "%0", " called with non-object as handler"], "handler_non_object", ["Proxy.", "%0", " called with non-object as handler"],
"trap_function_expected", ["Proxy.", "%0", " called with non-function for ", "%1", " trap"],
"handler_trap_missing", ["Proxy handler ", "%0", " has no '", "%1", "' trap"], "handler_trap_missing", ["Proxy handler ", "%0", " has no '", "%1", "' trap"],
"handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"], "handler_trap_must_be_callable", ["Proxy handler ", "%0", " has non-callable '", "%1", "' trap"],
"handler_returned_false", ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"], "handler_returned_false", ["Proxy handler ", "%0", " returned false for '", "%1", "' trap"],
@ -239,6 +240,8 @@ function FormatMessage(message) {
"strict_poison_pill", ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"], "strict_poison_pill", ["'caller', 'callee', and 'arguments' properties may not be accessed on strict mode functions or the arguments objects for calls to them"],
"strict_caller", ["Illegal access to a strict mode caller function."], "strict_caller", ["Illegal access to a strict mode caller function."],
"unprotected_let", ["Illegal let declaration in unprotected statement context."], "unprotected_let", ["Illegal let declaration in unprotected statement context."],
"cant_prevent_ext_external_array_elements", ["Cannot prevent extension of an object with external array elements"],
"redef_external_array_element", ["Cannot redefine a property of an object with external array elements"],
]; ];
var messages = { __proto__ : null }; var messages = { __proto__ : null };
var desc = new PropertyDescriptor(); var desc = new PropertyDescriptor();

13
deps/v8/src/mips/assembler-mips-inl.h

@ -83,6 +83,14 @@ bool Operand::is_reg() const {
// RelocInfo. // RelocInfo.
void RelocInfo::apply(intptr_t delta) { void RelocInfo::apply(intptr_t delta) {
if (IsCodeTarget(rmode_)) {
uint32_t scope1 = (uint32_t) target_address() & ~kImm28Mask;
uint32_t scope2 = reinterpret_cast<uint32_t>(pc_) & ~kImm28Mask;
if (scope1 != scope2) {
Assembler::JumpLabelToJumpRegister(pc_);
}
}
if (IsInternalReference(rmode_)) { if (IsInternalReference(rmode_)) {
// Absolute code pointer inside code object moves with the code object. // Absolute code pointer inside code object moves with the code object.
byte* p = reinterpret_cast<byte*>(pc_); byte* p = reinterpret_cast<byte*>(pc_);
@ -218,8 +226,9 @@ bool RelocInfo::IsPatchedReturnSequence() {
Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize); Instr instr2 = Assembler::instr_at(pc_ + 2 * Assembler::kInstrSize);
bool patched_return = ((instr0 & kOpcodeMask) == LUI && bool patched_return = ((instr0 & kOpcodeMask) == LUI &&
(instr1 & kOpcodeMask) == ORI && (instr1 & kOpcodeMask) == ORI &&
(instr2 & kOpcodeMask) == SPECIAL && ((instr2 & kOpcodeMask) == JAL ||
(instr2 & kFunctionFieldMask) == JALR); ((instr2 & kOpcodeMask) == SPECIAL &&
(instr2 & kFunctionFieldMask) == JALR)));
return patched_return; return patched_return;
} }

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save