Version 3.21.5
Fixed compilation with recent MinGW64 versions. (issue 2300)
Added RemovePrototype to FunctionTemplate. (Chromium issue 272440)
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@16383 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 37763eb..16b5126 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2013-08-28: Version 3.21.5
+
+ Fixed compilation with recent MinGW64 versions. (issue 2300)
+
+ Added RemovePrototype to FunctionTemplate. (Chromium issue 272440)
+
+ Performance and stability improvements on all platforms.
+
+
2013-08-26: Version 3.21.4
Lowered kInitialMaxFastElementArray constant to 95K (issue 2790).
diff --git a/include/v8-debug.h b/include/v8-debug.h
index bacccb6..a7d2198 100755
--- a/include/v8-debug.h
+++ b/include/v8-debug.h
@@ -150,21 +150,6 @@
virtual ~EventDetails() {}
};
-
- /**
- * Debug event callback function.
- *
- * \param event the type of the debug event that triggered the callback
- * (enum DebugEvent)
- * \param exec_state execution state (JavaScript object)
- * \param event_data event specific data (JavaScript object)
- * \param data value passed by the user to SetDebugEventListener
- */
- typedef void (*EventCallback)(DebugEvent event,
- Handle<Object> exec_state,
- Handle<Object> event_data,
- Handle<Value> data);
-
/**
* Debug event callback function.
*
@@ -179,23 +164,8 @@
* Debug message callback function.
*
* \param message the debug message handler message object
- * \param length length of the message
- * \param client_data the data value passed when registering the message handler
-
- * A MessageHandler does not take possession of the message string,
- * and must not rely on the data persisting after the handler returns.
*
- * This message handler is deprecated. Use MessageHandler2 instead.
- */
- typedef void (*MessageHandler)(const uint16_t* message, int length,
- ClientData* client_data);
-
- /**
- * Debug message callback function.
- *
- * \param message the debug message handler message object
- *
- * A MessageHandler does not take possession of the message data,
+ * A MessageHandler2 does not take possession of the message data,
* and must not rely on the data persisting after the handler returns.
*/
typedef void (*MessageHandler2)(const Message& message);
@@ -210,10 +180,6 @@
*/
typedef void (*DebugMessageDispatchHandler)();
- // Set a C debug event listener.
- V8_DEPRECATED(static bool SetDebugEventListener(
- EventCallback that,
- Handle<Value> data = Handle<Value>()));
static bool SetDebugEventListener2(EventCallback2 that,
Handle<Value> data = Handle<Value>());
@@ -234,16 +200,12 @@
// Break execution of JavaScript in the given isolate (this method
// can be invoked from a non-VM thread) for further client command
// execution on a VM thread. Client data is then passed in
- // EventDetails to EventCallback at the moment when the VM actually
+ // EventDetails to EventCallback2 at the moment when the VM actually
// stops. If no isolate is provided the default isolate is used.
static void DebugBreakForCommand(ClientData* data = NULL,
Isolate* isolate = NULL);
- // Message based interface. The message protocol is JSON. NOTE the message
- // handler thread is not supported any more parameter must be false.
- V8_DEPRECATED(static void SetMessageHandler(
- MessageHandler handler,
- bool message_handler_thread = false));
+ // Message based interface. The message protocol is JSON.
static void SetMessageHandler2(MessageHandler2 handler);
// If no isolate is provided the default isolate is
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 936ea59..1932fb8 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -57,21 +57,6 @@
*/
int GetLineNumber() const;
- /**
- * Returns total (self + children) execution time of the function,
- * in milliseconds, estimated by samples count.
- */
- V8_DEPRECATED(double GetTotalTime() const);
-
- /**
- * Returns self execution time of the function, in milliseconds,
- * estimated by samples count.
- */
- V8_DEPRECATED(double GetSelfTime() const);
-
- /** Returns the count of samples where function exists. */
- V8_DEPRECATED(double GetTotalSamplesCount() const);
-
/** DEPRECATED. Please use GetHitCount instead.
* Returns the count of samples where function was currently executing.
*/
diff --git a/include/v8.h b/include/v8.h
index dbf2b08..c29bba6 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -83,7 +83,6 @@
*/
namespace v8 {
-class AccessorInfo;
class AccessorSignature;
class Array;
class Boolean;
@@ -125,7 +124,6 @@
class FunctionTemplate;
class ObjectTemplate;
class Data;
-class AccessorInfo;
template<typename T> class PropertyCallbackInfo;
class StackTrace;
class StackFrame;
@@ -351,11 +349,9 @@
friend class Utils;
template<class F> friend class Persistent;
template<class F> friend class Local;
- friend class Arguments;
template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo;
template<class F> friend class internal::CustomArguments;
- friend class AccessorInfo;
friend Handle<Primitive> Undefined(Isolate* isolate);
friend Handle<Primitive> Null(Isolate* isolate);
friend Handle<Boolean> True(Isolate* isolate);
@@ -439,12 +435,10 @@
template<class F> friend class Eternal;
template<class F> friend class Persistent;
template<class F> friend class Handle;
- friend class Arguments;
template<class F> friend class FunctionCallbackInfo;
template<class F> friend class PropertyCallbackInfo;
friend class String;
friend class Object;
- friend class AccessorInfo;
friend class Context;
template<class F> friend class internal::CustomArguments;
friend class HandleScope;
@@ -2035,16 +2029,11 @@
* setting|getting a particular property. See Object and ObjectTemplate's
* method SetAccessor.
*/
-typedef Handle<Value> (*AccessorGetter)(Local<String> property,
- const AccessorInfo& info);
typedef void (*AccessorGetterCallback)(
Local<String> property,
const PropertyCallbackInfo<Value>& info);
-typedef void (*AccessorSetter)(Local<String> property,
- Local<Value> value,
- const AccessorInfo& info);
typedef void (*AccessorSetterCallback)(
Local<String> property,
Local<Value> value,
@@ -2118,12 +2107,6 @@
bool Delete(uint32_t index);
- V8_DEPRECATED(bool SetAccessor(Handle<String> name,
- AccessorGetter getter,
- AccessorSetter setter = 0,
- Handle<Value> data = Handle<Value>(),
- AccessControl settings = DEFAULT,
- PropertyAttribute attribute = None));
bool SetAccessor(Handle<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter = 0,
@@ -3072,15 +3055,6 @@
};
-class V8_EXPORT Arguments : public FunctionCallbackInfo<Value> {
- private:
- friend class internal::FunctionCallbackArguments;
- V8_INLINE(Arguments(internal::Object** implicit_args,
- internal::Object** values,
- int length,
- bool is_construct_call));
-};
-
/**
* The information passed to a property callback about the context
* of the property access.
@@ -3113,23 +3087,12 @@
};
-class V8_EXPORT AccessorInfo : public PropertyCallbackInfo<Value> {
- private:
- friend class internal::PropertyCallbackArguments;
- V8_INLINE(AccessorInfo(internal::Object** args))
- : PropertyCallbackInfo<Value>(args) { }
-};
-
-
-typedef Handle<Value> (*InvocationCallback)(const Arguments& args);
typedef void (*FunctionCallback)(const FunctionCallbackInfo<Value>& info);
/**
* NamedProperty[Getter|Setter] are used as interceptors on object.
* See ObjectTemplate::SetNamedPropertyHandler.
*/
-typedef Handle<Value> (*NamedPropertyGetter)(Local<String> property,
- const AccessorInfo& info);
typedef void (*NamedPropertyGetterCallback)(
Local<String> property,
const PropertyCallbackInfo<Value>& info);
@@ -3139,9 +3102,6 @@
* Returns the value if the setter intercepts the request.
* Otherwise, returns an empty handle.
*/
-typedef Handle<Value> (*NamedPropertySetter)(Local<String> property,
- Local<Value> value,
- const AccessorInfo& info);
typedef void (*NamedPropertySetterCallback)(
Local<String> property,
Local<Value> value,
@@ -3153,8 +3113,6 @@
* The result is an integer encoding property attributes (like v8::None,
* v8::DontEnum, etc.)
*/
-typedef Handle<Integer> (*NamedPropertyQuery)(Local<String> property,
- const AccessorInfo& info);
typedef void (*NamedPropertyQueryCallback)(
Local<String> property,
const PropertyCallbackInfo<Integer>& info);
@@ -3165,8 +3123,6 @@
* The return value is true if the property could be deleted and false
* otherwise.
*/
-typedef Handle<Boolean> (*NamedPropertyDeleter)(Local<String> property,
- const AccessorInfo& info);
typedef void (*NamedPropertyDeleterCallback)(
Local<String> property,
const PropertyCallbackInfo<Boolean>& info);
@@ -3176,7 +3132,6 @@
* Returns an array containing the names of the properties the named
* property getter intercepts.
*/
-typedef Handle<Array> (*NamedPropertyEnumerator)(const AccessorInfo& info);
typedef void (*NamedPropertyEnumeratorCallback)(
const PropertyCallbackInfo<Array>& info);
@@ -3185,8 +3140,6 @@
* Returns the value of the property if the getter intercepts the
* request. Otherwise, returns an empty handle.
*/
-typedef Handle<Value> (*IndexedPropertyGetter)(uint32_t index,
- const AccessorInfo& info);
typedef void (*IndexedPropertyGetterCallback)(
uint32_t index,
const PropertyCallbackInfo<Value>& info);
@@ -3196,9 +3149,6 @@
* Returns the value if the setter intercepts the request.
* Otherwise, returns an empty handle.
*/
-typedef Handle<Value> (*IndexedPropertySetter)(uint32_t index,
- Local<Value> value,
- const AccessorInfo& info);
typedef void (*IndexedPropertySetterCallback)(
uint32_t index,
Local<Value> value,
@@ -3209,8 +3159,6 @@
* Returns a non-empty handle if the interceptor intercepts the request.
* The result is an integer encoding property attributes.
*/
-typedef Handle<Integer> (*IndexedPropertyQuery)(uint32_t index,
- const AccessorInfo& info);
typedef void (*IndexedPropertyQueryCallback)(
uint32_t index,
const PropertyCallbackInfo<Integer>& info);
@@ -3221,8 +3169,6 @@
* The return value is true if the property could be deleted and false
* otherwise.
*/
-typedef Handle<Boolean> (*IndexedPropertyDeleter)(uint32_t index,
- const AccessorInfo& info);
typedef void (*IndexedPropertyDeleterCallback)(
uint32_t index,
const PropertyCallbackInfo<Boolean>& info);
@@ -3232,7 +3178,6 @@
* Returns an array containing the indices of the properties the
* indexed property getter intercepts.
*/
-typedef Handle<Array> (*IndexedPropertyEnumerator)(const AccessorInfo& info);
typedef void (*IndexedPropertyEnumeratorCallback)(
const PropertyCallbackInfo<Array>& info);
@@ -3364,11 +3309,6 @@
class V8_EXPORT FunctionTemplate : public Template {
public:
/** Creates a function template.*/
- V8_DEPRECATED(static Local<FunctionTemplate> New(
- InvocationCallback callback,
- Handle<Value> data = Handle<Value>(),
- Handle<Signature> signature = Handle<Signature>(),
- int length = 0));
static Local<FunctionTemplate> New(
FunctionCallback callback = 0,
Handle<Value> data = Handle<Value>(),
@@ -3383,8 +3323,6 @@
* callback is called whenever the function created from this
* FunctionTemplate is called.
*/
- V8_DEPRECATED(void SetCallHandler(InvocationCallback callback,
- Handle<Value> data = Handle<Value>()));
void SetCallHandler(FunctionCallback callback,
Handle<Value> data = Handle<Value>());
@@ -3431,6 +3369,12 @@
void ReadOnlyPrototype();
/**
+ * Removes the prototype property from functions created from this
+ * FunctionTemplate.
+ */
+ void RemovePrototype();
+
+ /**
* Returns true if the given object is an instance of this function
* template.
*/
@@ -3438,9 +3382,6 @@
private:
FunctionTemplate();
- // TODO(dcarney): Remove with SetCallHandler.
- friend class v8::CallHandlerHelper;
- void SetCallHandlerInternal(InvocationCallback callback, Handle<Value> data);
friend class Context;
friend class ObjectTemplate;
};
@@ -3489,14 +3430,6 @@
* defined by FunctionTemplate::HasInstance()), an implicit TypeError is
* thrown and no callback is invoked.
*/
- V8_DEPRECATED(void SetAccessor(Handle<String> name,
- AccessorGetter getter,
- AccessorSetter setter = 0,
- Handle<Value> data = Handle<Value>(),
- AccessControl settings = DEFAULT,
- PropertyAttribute attribute = None,
- Handle<AccessorSignature> signature =
- Handle<AccessorSignature>()));
void SetAccessor(Handle<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter = 0,
@@ -3531,13 +3464,6 @@
* \param data A piece of data that will be passed to the callbacks
* whenever they are invoked.
*/
- V8_DEPRECATED(void SetNamedPropertyHandler(
- NamedPropertyGetter getter,
- NamedPropertySetter setter = 0,
- NamedPropertyQuery query = 0,
- NamedPropertyDeleter deleter = 0,
- NamedPropertyEnumerator enumerator = 0,
- Handle<Value> data = Handle<Value>()));
void SetNamedPropertyHandler(
NamedPropertyGetterCallback getter,
NamedPropertySetterCallback setter = 0,
@@ -3562,13 +3488,6 @@
* \param data A piece of data that will be passed to the callbacks
* whenever they are invoked.
*/
- V8_DEPRECATED(void SetIndexedPropertyHandler(
- IndexedPropertyGetter getter,
- IndexedPropertySetter setter = 0,
- IndexedPropertyQuery query = 0,
- IndexedPropertyDeleter deleter = 0,
- IndexedPropertyEnumerator enumerator = 0,
- Handle<Value> data = Handle<Value>()));
void SetIndexedPropertyHandler(
IndexedPropertyGetterCallback getter,
IndexedPropertySetterCallback setter = 0,
@@ -3583,9 +3502,6 @@
* behave like normal JavaScript objects that cannot be called as a
* function.
*/
- V8_DEPRECATED(void SetCallAsFunctionHandler(
- InvocationCallback callback,
- Handle<Value> data = Handle<Value>()));
void SetCallAsFunctionHandler(FunctionCallback callback,
Handle<Value> data = Handle<Value>());
@@ -5467,6 +5383,8 @@
typedef SmiTagging<kApiPointerSize> PlatformSmiTagging;
const int kSmiShiftSize = PlatformSmiTagging::kSmiShiftSize;
const int kSmiValueSize = PlatformSmiTagging::kSmiValueSize;
+V8_INLINE(static bool SmiValuesAre31Bits()) { return kSmiValueSize == 31; }
+V8_INLINE(static bool SmiValuesAre32Bits()) { return kSmiValueSize == 32; }
/**
* This class exports constants and functionality from within v8 that
@@ -6007,13 +5925,6 @@
is_construct_call_(is_construct_call) { }
-Arguments::Arguments(internal::Object** args,
- internal::Object** values,
- int length,
- bool is_construct_call)
- : FunctionCallbackInfo<Value>(args, values, length, is_construct_call) { }
-
-
template<typename T>
Local<Value> FunctionCallbackInfo<T>::operator[](int i) const {
if (i < 0 || length_ <= i) return Local<Value>(*Undefined());
diff --git a/include/v8config.h b/include/v8config.h
index 25eb480..2bf3b9d 100644
--- a/include/v8config.h
+++ b/include/v8config.h
@@ -91,7 +91,10 @@
//
// V8_CC_CLANG - Clang
// V8_CC_GNU - GNU C++
+// V8_CC_INTEL - Intel C++
// V8_CC_MINGW - Minimalist GNU for Windows
+// V8_CC_MINGW32 - Minimalist GNU for Windows (mingw32)
+// V8_CC_MINGW64 - Minimalist GNU for Windows (mingw-w64)
// V8_CC_MSVC - Microsoft Visual C/C++
//
// C++11 feature detection
@@ -105,18 +108,29 @@
//
// Compiler-specific feature detection
//
-// V8_HAS___ALIGNOF - __alignof(type) operator supported
-// V8_HAS___ALIGNOF__ - __alignof__(type) operator supported
-// V8_HAS_ATTRIBUTE_ALIGNED - __attribute__((aligned(n))) supported
-// V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline)) supported
-// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported
-// V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported
-// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
-// V8_HAS_DECLSPEC_ALIGN - __declspec(align(n)) supported
-// V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported
-// V8_HAS___FINAL - __final supported in non-C++11 mode
-// V8_HAS___FORCEINLINE - __forceinline supported
-// V8_HAS_SEALED - MSVC style sealed marker supported
+// V8_HAS___ALIGNOF - __alignof(type) operator supported
+// V8_HAS___ALIGNOF__ - __alignof__(type) operator supported
+// V8_HAS_ATTRIBUTE_ALIGNED - __attribute__((aligned(n))) supported
+// V8_HAS_ATTRIBUTE_ALWAYS_INLINE - __attribute__((always_inline))
+// supported
+// V8_HAS_ATTRIBUTE_DEPRECATED - __attribute__((deprecated)) supported
+// V8_HAS_ATTRIBUTE_NOINLINE - __attribute__((noinline)) supported
+// V8_HAS_ATTRIBUTE_VISIBILITY - __attribute__((visibility)) supported
+// V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT - __attribute__((warn_unused_result))
+// supported
+// V8_HAS_BUILTIN_EXPECT - __builtin_expect() supported
+// V8_HAS_DECLSPEC_ALIGN - __declspec(align(n)) supported
+// V8_HAS_DECLSPEC_DEPRECATED - __declspec(deprecated) supported
+// V8_HAS_DECLSPEC_NOINLINE - __declspec(noinline) supported
+// V8_HAS___FINAL - __final supported in non-C++11 mode
+// V8_HAS___FORCEINLINE - __forceinline supported
+// V8_HAS_SEALED - MSVC style sealed marker supported
+//
+// Note that testing for compilers and/or features must be done using #if
+// not #ifdef. For example, to test for Intel C++ Compiler, use:
+// #if V8_CC_INTEL
+// ...
+// #endif
#if defined(__clang__)
@@ -132,7 +146,10 @@
# define V8_HAS_ATTRIBUTE_ALIGNED (__has_attribute(aligned))
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (__has_attribute(always_inline))
# define V8_HAS_ATTRIBUTE_DEPRECATED (__has_attribute(deprecated))
+# define V8_HAS_ATTRIBUTE_NOINLINE (__has_attribute(noinline))
# define V8_HAS_ATTRIBUTE_VISIBILITY (__has_attribute(visibility))
+# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
+ (__has_attribute(warn_unused_result))
# define V8_HAS_BUILTIN_EXPECT (__has_builtin(__builtin_expect))
@@ -149,9 +166,11 @@
((major) * 10000 + (minor) * 100 + (patchlevel)))
# define V8_CC_GNU 1
-# if defined(__MINGW32__)
-# define V8_CC_MINGW 1
-# endif
+// Intel C++ also masquerades as GCC 3.2.0
+# define V8_CC_INTEL (defined(__INTEL_COMPILER))
+# define V8_CC_MINGW32 (defined(__MINGW32__))
+# define V8_CC_MINGW64 (defined(__MINGW64__))
+# define V8_CC_MINGW (V8_CC_MINGW32 || V8_CC_MINGW64)
# define V8_HAS___ALIGNOF__ (V8_GNUC_PREREQ(4, 3, 0))
@@ -161,7 +180,10 @@
// older compilers.
# define V8_HAS_ATTRIBUTE_ALWAYS_INLINE (V8_GNUC_PREREQ(4, 4, 0))
# define V8_HAS_ATTRIBUTE_DEPRECATED (V8_GNUC_PREREQ(3, 4, 0))
+# define V8_HAS_ATTRIBUTE_NOINLINE (V8_GNUC_PREREQ(3, 4, 0))
# define V8_HAS_ATTRIBUTE_VISIBILITY (V8_GNUC_PREREQ(4, 3, 0))
+# define V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT \
+ (!V8_CC_INTEL && V8_GNUC_PREREQ(4, 1, 0))
# define V8_HAS_BUILTIN_EXPECT (V8_GNUC_PREREQ(2, 96, 0))
@@ -199,6 +221,7 @@
# define V8_HAS_DECLSPEC_ALIGN 1
# define V8_HAS_DECLSPEC_DEPRECATED (_MSC_VER >= 1300)
+# define V8_HAS_DECLSPEC_NOINLINE 1
# define V8_HAS___FORCEINLINE 1
@@ -218,6 +241,17 @@
#endif
+// A macro used to tell the compiler to never inline a particular function.
+// Don't bother for debug builds.
+#if !defined(DEBUG) && V8_HAS_ATTRIBUTE_NOINLINE
+# define V8_NOINLINE(declarator) __attribute__((noinline)) declarator
+#elif !defined(DEBUG) && V8_HAS_DECLSPEC_NOINLINE
+# define V8_NOINLINE(declarator) __declspec(noinline) declarator
+#else
+# define V8_NOINLINE(declarator) declarator
+#endif
+
+
// A macro to mark classes or functions as deprecated.
#if !V8_DISABLE_DEPRECATIONS && V8_HAS_ATTRIBUTE_DEPRECATED
# define V8_DEPRECATED(declarator) declarator __attribute__((deprecated))
@@ -228,6 +262,16 @@
#endif
+// Annotate a function indicating the caller must examine the return value.
+// Use like:
+// int foo() V8_WARN_UNUSED_RESULT;
+#if V8_HAS_ATTRIBUTE_WARN_UNUSED_RESULT
+# define V8_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define V8_WARN_UNUSED_RESULT /* NOT SUPPORTED */
+#endif
+
+
// A macro to provide the compiler with branch prediction information.
#if V8_HAS_BUILTIN_EXPECT
# define V8_UNLIKELY(condition) (__builtin_expect(!!(condition), 0))
diff --git a/src/api.cc b/src/api.cc
index 61cc520..9c0ac7b 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1049,25 +1049,8 @@
}
-// TODO(dcarney): Remove this abstraction when old callbacks are removed.
-class CallHandlerHelper {
- public:
- static inline void Set(Local<FunctionTemplate> function_template,
- InvocationCallback callback,
- v8::Handle<Value> data) {
- function_template->SetCallHandlerInternal(callback, data);
- }
- static inline void Set(Local<FunctionTemplate> function_template,
- FunctionCallback callback,
- v8::Handle<Value> data) {
- function_template->SetCallHandler(callback, data);
- }
-};
-
-
-template<typename Callback>
-static Local<FunctionTemplate> FunctionTemplateNew(
- Callback callback,
+Local<FunctionTemplate> FunctionTemplate::New(
+ FunctionCallback callback,
v8::Handle<Value> data,
v8::Handle<Signature> signature,
int length) {
@@ -1085,7 +1068,7 @@
obj->set_serial_number(i::Smi::FromInt(next_serial_number));
if (callback != 0) {
if (data.IsEmpty()) data = v8::Undefined();
- CallHandlerHelper::Set(Utils::ToLocal(obj), callback, data);
+ Utils::ToLocal(obj)->SetCallHandler(callback, data);
}
obj->set_length(length);
obj->set_undetectable(false);
@@ -1097,24 +1080,6 @@
}
-Local<FunctionTemplate> FunctionTemplate::New(
- InvocationCallback callback,
- v8::Handle<Value> data,
- v8::Handle<Signature> signature,
- int length) {
- return FunctionTemplateNew(callback, data, signature, length);
-}
-
-
-Local<FunctionTemplate> FunctionTemplate::New(
- FunctionCallback callback,
- v8::Handle<Value> data,
- v8::Handle<Signature> signature,
- int length) {
- return FunctionTemplateNew(callback, data, signature, length);
-}
-
-
Local<Signature> Signature::New(Handle<FunctionTemplate> receiver,
int argc, Handle<FunctionTemplate> argv[]) {
i::Isolate* isolate = i::Isolate::Current();
@@ -1304,11 +1269,9 @@
} while (false)
-template<typename Callback>
-static void FunctionTemplateSetCallHandler(FunctionTemplate* function_template,
- Callback callback_in,
- v8::Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(function_template)->GetIsolate();
+void FunctionTemplate::SetCallHandler(FunctionCallback callback,
+ v8::Handle<Value> data) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate, "v8::FunctionTemplate::SetCallHandler()")) return;
ENTER_V8(isolate);
i::HandleScope scope(isolate);
@@ -1316,28 +1279,12 @@
isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
i::Handle<i::CallHandlerInfo> obj =
i::Handle<i::CallHandlerInfo>::cast(struct_obj);
- FunctionCallback callback =
- i::CallbackTable::Register(isolate, callback_in);
SET_FIELD_WRAPPED(obj, set_callback, callback);
if (data.IsEmpty()) data = v8::Undefined();
obj->set_data(*Utils::OpenHandle(*data));
- Utils::OpenHandle(function_template)->set_call_code(*obj);
+ Utils::OpenHandle(this)->set_call_code(*obj);
}
-void FunctionTemplate::SetCallHandler(InvocationCallback callback,
- v8::Handle<Value> data) {
- FunctionTemplateSetCallHandler(this, callback, data);
-}
-
-void FunctionTemplate::SetCallHandlerInternal(InvocationCallback callback,
- v8::Handle<Value> data) {
- FunctionTemplateSetCallHandler(this, callback, data);
-}
-
-void FunctionTemplate::SetCallHandler(FunctionCallback callback,
- v8::Handle<Value> data) {
- FunctionTemplateSetCallHandler(this, callback, data);
-}
static i::Handle<i::AccessorInfo> SetAccessorInfoProperties(
i::Handle<i::AccessorInfo> obj,
@@ -1360,8 +1307,8 @@
template<typename Getter, typename Setter>
static i::Handle<i::AccessorInfo> MakeAccessorInfo(
v8::Handle<String> name,
- Getter getter_in,
- Setter setter_in,
+ Getter getter,
+ Setter setter,
v8::Handle<Value> data,
v8::AccessControl settings,
v8::PropertyAttribute attributes,
@@ -1369,11 +1316,7 @@
i::Isolate* isolate = Utils::OpenHandle(*name)->GetIsolate();
i::Handle<i::ExecutableAccessorInfo> obj =
isolate->factory()->NewExecutableAccessorInfo();
- AccessorGetterCallback getter =
- i::CallbackTable::Register(isolate, getter_in);
SET_FIELD_WRAPPED(obj, set_getter, getter);
- AccessorSetterCallback setter =
- i::CallbackTable::Register(isolate, setter_in);
SET_FIELD_WRAPPED(obj, set_setter, setter);
if (data.IsEmpty()) data = v8::Undefined();
obj->set_data(*Utils::OpenHandle(*data));
@@ -1451,124 +1394,14 @@
Utils::OpenHandle(this)->set_read_only_prototype(true);
}
-template<
- typename Getter,
- typename Setter,
- typename Query,
- typename Deleter,
- typename Enumerator>
-static void SetNamedInstancePropertyHandler(
- i::Handle<i::FunctionTemplateInfo> function_template,
- Getter getter_in,
- Setter setter_in,
- Query query_in,
- Deleter remover_in,
- Enumerator enumerator_in,
- Handle<Value> data) {
- i::Isolate* isolate = function_template->GetIsolate();
- if (IsDeadCheck(isolate,
- "v8::FunctionTemplate::SetNamedInstancePropertyHandler()")) {
+
+void FunctionTemplate::RemovePrototype() {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ if (IsDeadCheck(isolate, "v8::FunctionTemplate::RemovePrototype()")) {
return;
}
ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
- i::Handle<i::InterceptorInfo> obj =
- i::Handle<i::InterceptorInfo>::cast(struct_obj);
-
- NamedPropertyGetterCallback getter =
- i::CallbackTable::Register(isolate, getter_in);
- if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
- NamedPropertySetterCallback setter =
- i::CallbackTable::Register(isolate, setter_in);
- if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
- NamedPropertyQueryCallback query =
- i::CallbackTable::Register(isolate, query_in);
- if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
- NamedPropertyDeleterCallback remover =
- i::CallbackTable::Register(isolate, remover_in);
- if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
- NamedPropertyEnumeratorCallback enumerator =
- i::CallbackTable::Register(isolate, enumerator_in);
- if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
-
- if (data.IsEmpty()) data = v8::Undefined();
- obj->set_data(*Utils::OpenHandle(*data));
- function_template->set_named_property_handler(*obj);
-}
-
-
-template<
- typename Getter,
- typename Setter,
- typename Query,
- typename Deleter,
- typename Enumerator>
-static void SetIndexedInstancePropertyHandler(
- i::Handle<i::FunctionTemplateInfo> function_template,
- Getter getter_in,
- Setter setter_in,
- Query query_in,
- Deleter remover_in,
- Enumerator enumerator_in,
- Handle<Value> data) {
- i::Isolate* isolate = function_template->GetIsolate();
- if (IsDeadCheck(isolate,
- "v8::FunctionTemplate::SetIndexedInstancePropertyHandler()")) {
- return;
- }
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
- i::Handle<i::InterceptorInfo> obj =
- i::Handle<i::InterceptorInfo>::cast(struct_obj);
-
- IndexedPropertyGetterCallback getter =
- i::CallbackTable::Register(isolate, getter_in);
- if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
- IndexedPropertySetterCallback setter =
- i::CallbackTable::Register(isolate, setter_in);
- if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
- IndexedPropertyQueryCallback query =
- i::CallbackTable::Register(isolate, query_in);
- if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
- IndexedPropertyDeleterCallback remover =
- i::CallbackTable::Register(isolate, remover_in);
- if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
- IndexedPropertyEnumeratorCallback enumerator =
- i::CallbackTable::Register(isolate, enumerator_in);
- if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
-
- if (data.IsEmpty()) data = v8::Undefined();
- obj->set_data(*Utils::OpenHandle(*data));
- function_template->set_indexed_property_handler(*obj);
-}
-
-
-template<typename Callback>
-static void SetInstanceCallAsFunctionHandler(
- i::Handle<i::FunctionTemplateInfo> function_template,
- Callback callback_in,
- Handle<Value> data) {
- i::Isolate* isolate = function_template->GetIsolate();
- if (IsDeadCheck(isolate,
- "v8::FunctionTemplate::SetInstanceCallAsFunctionHandler()")) {
- return;
- }
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- i::Handle<i::Struct> struct_obj =
- isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
- i::Handle<i::CallHandlerInfo> obj =
- i::Handle<i::CallHandlerInfo>::cast(struct_obj);
- FunctionCallback callback =
- i::CallbackTable::Register(isolate, callback_in);
- SET_FIELD_WRAPPED(obj, set_callback, callback);
- if (data.IsEmpty()) data = v8::Undefined();
- obj->set_data(*Utils::OpenHandle(*data));
- function_template->set_instance_call_handler(*obj);
+ Utils::OpenHandle(this)->set_remove_prototype(true);
}
@@ -1653,18 +1486,6 @@
void ObjectTemplate::SetAccessor(v8::Handle<String> name,
- AccessorGetter getter,
- AccessorSetter setter,
- v8::Handle<Value> data,
- AccessControl settings,
- PropertyAttribute attribute,
- v8::Handle<AccessorSignature> signature) {
- ObjectTemplateSetAccessor(
- this, name, getter, setter, data, settings, attribute, signature);
-}
-
-
-void ObjectTemplate::SetAccessor(v8::Handle<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter,
v8::Handle<Value> data,
@@ -1687,52 +1508,6 @@
}
-template<
- typename Getter,
- typename Setter,
- typename Query,
- typename Deleter,
- typename Enumerator>
-static void ObjectTemplateSetNamedPropertyHandler(
- ObjectTemplate* object_template,
- Getter getter,
- Setter setter,
- Query query,
- Deleter remover,
- Enumerator enumerator,
- Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(object_template)->GetIsolate();
- if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
- return;
- }
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- EnsureConstructor(object_template);
- i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
- Utils::OpenHandle(object_template)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
- SetNamedInstancePropertyHandler(cons,
- getter,
- setter,
- query,
- remover,
- enumerator,
- data);
-}
-
-
-void ObjectTemplate::SetNamedPropertyHandler(
- NamedPropertyGetter getter,
- NamedPropertySetter setter,
- NamedPropertyQuery query,
- NamedPropertyDeleter remover,
- NamedPropertyEnumerator enumerator,
- Handle<Value> data) {
- ObjectTemplateSetNamedPropertyHandler(
- this, getter, setter, query, remover, enumerator, data);
-}
-
-
void ObjectTemplate::SetNamedPropertyHandler(
NamedPropertyGetterCallback getter,
NamedPropertySetterCallback setter,
@@ -1740,8 +1515,30 @@
NamedPropertyDeleterCallback remover,
NamedPropertyEnumeratorCallback enumerator,
Handle<Value> data) {
- ObjectTemplateSetNamedPropertyHandler(
- this, getter, setter, query, remover, enumerator, data);
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetNamedPropertyHandler()")) {
+ return;
+ }
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ EnsureConstructor(this);
+ i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
+ Utils::OpenHandle(this)->constructor());
+ i::Handle<i::FunctionTemplateInfo> cons(constructor);
+ i::Handle<i::Struct> struct_obj =
+ isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
+ i::Handle<i::InterceptorInfo> obj =
+ i::Handle<i::InterceptorInfo>::cast(struct_obj);
+
+ if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
+ if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
+ if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
+ if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
+ if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+
+ if (data.IsEmpty()) data = v8::Undefined();
+ obj->set_data(*Utils::OpenHandle(*data));
+ cons->set_named_property_handler(*obj);
}
@@ -1790,52 +1587,6 @@
}
-template<
- typename Getter,
- typename Setter,
- typename Query,
- typename Deleter,
- typename Enumerator>
-void ObjectTemplateSetIndexedPropertyHandler(
- ObjectTemplate* object_template,
- Getter getter,
- Setter setter,
- Query query,
- Deleter remover,
- Enumerator enumerator,
- Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(object_template)->GetIsolate();
- if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
- return;
- }
- ENTER_V8(isolate);
- i::HandleScope scope(isolate);
- EnsureConstructor(object_template);
- i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
- Utils::OpenHandle(object_template)->constructor());
- i::Handle<i::FunctionTemplateInfo> cons(constructor);
- SetIndexedInstancePropertyHandler(cons,
- getter,
- setter,
- query,
- remover,
- enumerator,
- data);
-}
-
-
-void ObjectTemplate::SetIndexedPropertyHandler(
- IndexedPropertyGetter getter,
- IndexedPropertySetter setter,
- IndexedPropertyQuery query,
- IndexedPropertyDeleter remover,
- IndexedPropertyEnumerator enumerator,
- Handle<Value> data) {
- ObjectTemplateSetIndexedPropertyHandler(
- this, getter, setter, query, remover, enumerator, data);
-}
-
-
void ObjectTemplate::SetIndexedPropertyHandler(
IndexedPropertyGetterCallback getter,
IndexedPropertySetterCallback setter,
@@ -1843,40 +1594,54 @@
IndexedPropertyDeleterCallback remover,
IndexedPropertyEnumeratorCallback enumerator,
Handle<Value> data) {
- ObjectTemplateSetIndexedPropertyHandler(
- this, getter, setter, query, remover, enumerator, data);
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
+ if (IsDeadCheck(isolate, "v8::ObjectTemplate::SetIndexedPropertyHandler()")) {
+ return;
+ }
+ ENTER_V8(isolate);
+ i::HandleScope scope(isolate);
+ EnsureConstructor(this);
+ i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
+ Utils::OpenHandle(this)->constructor());
+ i::Handle<i::FunctionTemplateInfo> cons(constructor);
+ i::Handle<i::Struct> struct_obj =
+ isolate->factory()->NewStruct(i::INTERCEPTOR_INFO_TYPE);
+ i::Handle<i::InterceptorInfo> obj =
+ i::Handle<i::InterceptorInfo>::cast(struct_obj);
+
+ if (getter != 0) SET_FIELD_WRAPPED(obj, set_getter, getter);
+ if (setter != 0) SET_FIELD_WRAPPED(obj, set_setter, setter);
+ if (query != 0) SET_FIELD_WRAPPED(obj, set_query, query);
+ if (remover != 0) SET_FIELD_WRAPPED(obj, set_deleter, remover);
+ if (enumerator != 0) SET_FIELD_WRAPPED(obj, set_enumerator, enumerator);
+
+ if (data.IsEmpty()) data = v8::Undefined();
+ obj->set_data(*Utils::OpenHandle(*data));
+ cons->set_indexed_property_handler(*obj);
}
-template<typename Callback>
-static void ObjectTemplateSetCallAsFunctionHandler(
- ObjectTemplate* object_template,
- Callback callback,
- Handle<Value> data) {
- i::Isolate* isolate = Utils::OpenHandle(object_template)->GetIsolate();
+void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
+ Handle<Value> data) {
+ i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
if (IsDeadCheck(isolate,
"v8::ObjectTemplate::SetCallAsFunctionHandler()")) {
return;
}
ENTER_V8(isolate);
i::HandleScope scope(isolate);
- EnsureConstructor(object_template);
+ EnsureConstructor(this);
i::FunctionTemplateInfo* constructor = i::FunctionTemplateInfo::cast(
- Utils::OpenHandle(object_template)->constructor());
+ Utils::OpenHandle(this)->constructor());
i::Handle<i::FunctionTemplateInfo> cons(constructor);
- SetInstanceCallAsFunctionHandler(cons, callback, data);
-}
-
-
-void ObjectTemplate::SetCallAsFunctionHandler(InvocationCallback callback,
- Handle<Value> data) {
- return ObjectTemplateSetCallAsFunctionHandler(this, callback, data);
-}
-
-
-void ObjectTemplate::SetCallAsFunctionHandler(FunctionCallback callback,
- Handle<Value> data) {
- return ObjectTemplateSetCallAsFunctionHandler(this, callback, data);
+ i::Handle<i::Struct> struct_obj =
+ isolate->factory()->NewStruct(i::CALL_HANDLER_INFO_TYPE);
+ i::Handle<i::CallHandlerInfo> obj =
+ i::Handle<i::CallHandlerInfo>::cast(struct_obj);
+ SET_FIELD_WRAPPED(obj, set_callback, callback);
+ if (data.IsEmpty()) data = v8::Undefined();
+ obj->set_data(*Utils::OpenHandle(*data));
+ cons->set_instance_call_handler(*obj);
}
@@ -3843,17 +3608,6 @@
bool Object::SetAccessor(Handle<String> name,
- AccessorGetter getter,
- AccessorSetter setter,
- v8::Handle<Value> data,
- AccessControl settings,
- PropertyAttribute attributes) {
- return ObjectSetAccessor(
- this, name, getter, setter, data, settings, attributes);
-}
-
-
-bool Object::SetAccessor(Handle<String> name,
AccessorGetterCallback getter,
AccessorSetterCallback setter,
v8::Handle<Value> data,
@@ -7255,37 +7009,6 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
-static void EventCallbackWrapper(const v8::Debug::EventDetails& event_details) {
- i::Isolate* isolate = i::Isolate::Current();
- if (isolate->debug_event_callback() != NULL) {
- isolate->debug_event_callback()(event_details.GetEvent(),
- event_details.GetExecutionState(),
- event_details.GetEventData(),
- event_details.GetCallbackData());
- }
-}
-
-
-bool Debug::SetDebugEventListener(EventCallback that, Handle<Value> data) {
- i::Isolate* isolate = i::Isolate::Current();
- EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener()");
- ON_BAILOUT(isolate, "v8::Debug::SetDebugEventListener()", return false);
- ENTER_V8(isolate);
-
- isolate->set_debug_event_callback(that);
-
- i::HandleScope scope(isolate);
- i::Handle<i::Object> foreign = isolate->factory()->undefined_value();
- if (that != NULL) {
- foreign =
- isolate->factory()->NewForeign(FUNCTION_ADDR(EventCallbackWrapper));
- }
- isolate->debugger()->SetEventListener(foreign,
- Utils::OpenHandle(*data, true));
- return true;
-}
-
-
bool Debug::SetDebugEventListener2(EventCallback2 that, Handle<Value> data) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::SetDebugEventListener2()");
@@ -7345,35 +7068,6 @@
}
-static void MessageHandlerWrapper(const v8::Debug::Message& message) {
- i::Isolate* isolate = i::Isolate::Current();
- if (isolate->message_handler()) {
- v8::String::Value json(message.GetJSON());
- (isolate->message_handler())(*json, json.length(), message.GetClientData());
- }
-}
-
-
-void Debug::SetMessageHandler(v8::Debug::MessageHandler handler,
- bool message_handler_thread) {
- i::Isolate* isolate = i::Isolate::Current();
- EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
- ENTER_V8(isolate);
-
- // Message handler thread not supported any more. Parameter temporally left in
- // the API for client compatibility reasons.
- CHECK(!message_handler_thread);
-
- // TODO(sgjesse) support the old message handler API through a simple wrapper.
- isolate->set_message_handler(handler);
- if (handler != NULL) {
- isolate->debugger()->SetMessageHandler(MessageHandlerWrapper);
- } else {
- isolate->debugger()->SetMessageHandler(NULL);
- }
-}
-
-
void Debug::SetMessageHandler2(v8::Debug::MessageHandler2 handler) {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "v8::Debug::SetMessageHandler");
@@ -7541,27 +7235,6 @@
}
-double CpuProfileNode::GetTotalTime() const {
- i::Isolate* isolate = i::Isolate::Current();
- IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalTime");
- return reinterpret_cast<const i::ProfileNode*>(this)->GetTotalMillis();
-}
-
-
-double CpuProfileNode::GetSelfTime() const {
- i::Isolate* isolate = i::Isolate::Current();
- IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfTime");
- return reinterpret_cast<const i::ProfileNode*>(this)->GetSelfMillis();
-}
-
-
-double CpuProfileNode::GetTotalSamplesCount() const {
- i::Isolate* isolate = i::Isolate::Current();
- IsDeadCheck(isolate, "v8::CpuProfileNode::GetTotalSamplesCount");
- return reinterpret_cast<const i::ProfileNode*>(this)->total_ticks();
-}
-
-
double CpuProfileNode::GetSelfSamplesCount() const {
i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::CpuProfileNode::GetSelfSamplesCount");
@@ -8172,20 +7845,6 @@
}
-v8::Handle<v8::Value> InvokeAccessorGetter(
- v8::Local<v8::String> property,
- const v8::AccessorInfo& info,
- v8::AccessorGetter getter) {
- Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
- Address getter_address = reinterpret_cast<Address>(reinterpret_cast<intptr_t>(
- getter));
- // Leaving JavaScript.
- VMState<EXTERNAL> state(isolate);
- ExternalCallbackScope call_scope(isolate, getter_address);
- return getter(property, info);
-}
-
-
void InvokeAccessorGetterCallback(
v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info,
@@ -8200,18 +7859,6 @@
}
-v8::Handle<v8::Value> InvokeInvocationCallback(
- const v8::Arguments& args,
- v8::InvocationCallback callback) {
- Isolate* isolate = reinterpret_cast<Isolate*>(args.GetIsolate());
- Address callback_address =
- reinterpret_cast<Address>(reinterpret_cast<intptr_t>(callback));
- VMState<EXTERNAL> state(isolate);
- ExternalCallbackScope call_scope(isolate, callback_address);
- return callback(args);
-}
-
-
void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
v8::FunctionCallback callback) {
Isolate* isolate = reinterpret_cast<Isolate*>(info.GetIsolate());
diff --git a/src/api.h b/src/api.h
index 0f33bc8..63a29e4 100644
--- a/src/api.h
+++ b/src/api.h
@@ -690,19 +690,11 @@
// Interceptor functions called from generated inline caches to notify
// CPU profiler that external callbacks are invoked.
-v8::Handle<v8::Value> InvokeAccessorGetter(
- v8::Local<v8::String> property,
- const v8::AccessorInfo& info,
- v8::AccessorGetter getter);
-
-
void InvokeAccessorGetterCallback(
v8::Local<v8::String> property,
const v8::PropertyCallbackInfo<v8::Value>& info,
v8::AccessorGetterCallback getter);
-v8::Handle<v8::Value> InvokeInvocationCallback(const v8::Arguments& args,
- v8::InvocationCallback callback);
void InvokeFunctionCallback(const v8::FunctionCallbackInfo<v8::Value>& info,
v8::FunctionCallback callback);
diff --git a/src/apinatives.js b/src/apinatives.js
index ace882b..7adeb7e 100644
--- a/src/apinatives.js
+++ b/src/apinatives.js
@@ -75,22 +75,26 @@
var fun = %CreateApiFunction(data);
if (name) %FunctionSetName(fun, name);
cache[serialNumber] = fun;
- var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
var flags = %GetTemplateField(data, kApiFlagOffset);
- // Note: Do not directly use an object template as a condition, our
- // internal ToBoolean doesn't handle that!
- fun.prototype = typeof prototype === 'undefined' ?
- {} : Instantiate(prototype);
- if (flags & (1 << kReadOnlyPrototypeBit)) {
- %FunctionSetReadOnlyPrototype(fun);
- }
- %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
- var parent = %GetTemplateField(data, kApiParentTemplateOffset);
- // Note: Do not directly use a function template as a condition, our
- // internal ToBoolean doesn't handle that!
- if (!(typeof parent === 'undefined')) {
- var parent_fun = Instantiate(parent);
- %SetPrototype(fun.prototype, parent_fun.prototype);
+ if (flags & (1 << kRemovePrototypeBit)) {
+ %FunctionRemovePrototype(fun);
+ } else {
+ var prototype = %GetTemplateField(data, kApiPrototypeTemplateOffset);
+ // Note: Do not directly use an object template as a condition, our
+ // internal ToBoolean doesn't handle that!
+ fun.prototype = typeof prototype === 'undefined' ?
+ {} : Instantiate(prototype);
+ if (flags & (1 << kReadOnlyPrototypeBit)) {
+ %FunctionSetReadOnlyPrototype(fun);
+ }
+ %SetProperty(fun.prototype, "constructor", fun, DONT_ENUM);
+ var parent = %GetTemplateField(data, kApiParentTemplateOffset);
+ // Note: Do not directly use a function template as a condition, our
+ // internal ToBoolean doesn't handle that!
+ if (!(typeof parent === 'undefined')) {
+ var parent_fun = Instantiate(parent);
+ %SetPrototype(fun.prototype, parent_fun.prototype);
+ }
}
ConfigureTemplateInstance(fun, data);
} catch (e) {
diff --git a/src/arguments.cc b/src/arguments.cc
index 11d9279..2878057 100644
--- a/src/arguments.cc
+++ b/src/arguments.cc
@@ -34,49 +34,6 @@
namespace internal {
-static bool Match(void* a, void* b) {
- return a == b;
-}
-
-
-static uint32_t Hash(void* function) {
- uintptr_t as_int = reinterpret_cast<uintptr_t>(function);
- if (sizeof(function) == 4) return static_cast<uint32_t>(as_int);
- uint64_t as_64 = static_cast<uint64_t>(as_int);
- return
- static_cast<uint32_t>(as_64 >> 32) ^
- static_cast<uint32_t>(as_64);
-}
-
-
-CallbackTable::CallbackTable(): map_(Match, 64) {}
-
-
-bool CallbackTable::Contains(void* function) {
- ASSERT(function != NULL);
- return map_.Lookup(function, Hash(function), false) != NULL;
-}
-
-
-void CallbackTable::InsertCallback(Isolate* isolate,
- void* function,
- bool returns_void) {
- if (function == NULL) return;
- // Don't store for performance.
- if (kStoreVoidFunctions != returns_void) return;
- CallbackTable* table = isolate->callback_table();
- if (table == NULL) {
- table = new CallbackTable();
- isolate->set_callback_table(table);
- }
- typedef HashMap::Entry Entry;
- Entry* entry = table->map_.Lookup(function, Hash(function), true);
- ASSERT(entry != NULL);
- ASSERT(entry->value == NULL || entry->value == function);
- entry->value = function;
-}
-
-
template<typename T>
template<typename V>
v8::Handle<V> CustomArguments<T>::GetReturnValue(Isolate* isolate) {
@@ -88,110 +45,67 @@
}
-v8::Handle<v8::Value> FunctionCallbackArguments::Call(InvocationCallback f) {
+v8::Handle<v8::Value> FunctionCallbackArguments::Call(FunctionCallback f) {
Isolate* isolate = this->isolate();
- void* f_as_void = CallbackTable::FunctionToVoidPtr(f);
- bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void);
VMState<EXTERNAL> state(isolate);
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f));
- if (new_style) {
- FunctionCallback c = reinterpret_cast<FunctionCallback>(f);
- FunctionCallbackInfo<v8::Value> info(end(),
- argv_,
- argc_,
- is_construct_call_);
- c(info);
- } else {
- v8::Arguments args(end(),
- argv_,
- argc_,
- is_construct_call_);
- v8::Handle<v8::Value> return_value = f(args);
- if (!return_value.IsEmpty()) return return_value;
- }
+ FunctionCallbackInfo<v8::Value> info(end(),
+ argv_,
+ argc_,
+ is_construct_call_);
+ f(info);
return GetReturnValue<v8::Value>(isolate);
}
-#define WRITE_CALL_0(OldFunction, NewFunction, ReturnValue) \
-v8::Handle<ReturnValue> PropertyCallbackArguments::Call(OldFunction f) { \
+#define WRITE_CALL_0(Function, ReturnValue) \
+v8::Handle<ReturnValue> PropertyCallbackArguments::Call(Function f) { \
Isolate* isolate = this->isolate(); \
- void* f_as_void = CallbackTable::FunctionToVoidPtr(f); \
- bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
- if (new_style) { \
- NewFunction c = reinterpret_cast<NewFunction>(f); \
- PropertyCallbackInfo<ReturnValue> info(end()); \
- c(info); \
- } else { \
- v8::AccessorInfo info(end()); \
- v8::Handle<ReturnValue> return_value = f(info); \
- if (!return_value.IsEmpty()) return return_value; \
- } \
+ PropertyCallbackInfo<ReturnValue> info(end()); \
+ f(info); \
return GetReturnValue<ReturnValue>(isolate); \
}
-#define WRITE_CALL_1(OldFunction, NewFunction, ReturnValue, Arg1) \
-v8::Handle<ReturnValue> PropertyCallbackArguments::Call(OldFunction f, \
+
+#define WRITE_CALL_1(Function, ReturnValue, Arg1) \
+v8::Handle<ReturnValue> PropertyCallbackArguments::Call(Function f, \
Arg1 arg1) { \
Isolate* isolate = this->isolate(); \
- void* f_as_void = CallbackTable::FunctionToVoidPtr(f); \
- bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
- if (new_style) { \
- NewFunction c = reinterpret_cast<NewFunction>(f); \
- PropertyCallbackInfo<ReturnValue> info(end()); \
- c(arg1, info); \
- } else { \
- v8::AccessorInfo info(end()); \
- v8::Handle<ReturnValue> return_value = f(arg1, info); \
- if (!return_value.IsEmpty()) return return_value; \
- } \
+ PropertyCallbackInfo<ReturnValue> info(end()); \
+ f(arg1, info); \
return GetReturnValue<ReturnValue>(isolate); \
}
-#define WRITE_CALL_2(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
-v8::Handle<ReturnValue> PropertyCallbackArguments::Call(OldFunction f, \
+
+#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2) \
+v8::Handle<ReturnValue> PropertyCallbackArguments::Call(Function f, \
Arg1 arg1, \
Arg2 arg2) { \
Isolate* isolate = this->isolate(); \
- void* f_as_void = CallbackTable::FunctionToVoidPtr(f); \
- bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
- if (new_style) { \
- NewFunction c = reinterpret_cast<NewFunction>(f); \
- PropertyCallbackInfo<ReturnValue> info(end()); \
- c(arg1, arg2, info); \
- } else { \
- v8::AccessorInfo info(end()); \
- v8::Handle<ReturnValue> return_value = f(arg1, arg2, info); \
- if (!return_value.IsEmpty()) return return_value; \
- } \
+ PropertyCallbackInfo<ReturnValue> info(end()); \
+ f(arg1, arg2, info); \
return GetReturnValue<ReturnValue>(isolate); \
}
-#define WRITE_CALL_2_VOID(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
-void PropertyCallbackArguments::Call(OldFunction f, \
+
+#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \
+void PropertyCallbackArguments::Call(Function f, \
Arg1 arg1, \
Arg2 arg2) { \
Isolate* isolate = this->isolate(); \
- void* f_as_void = CallbackTable::FunctionToVoidPtr(f); \
- bool new_style = CallbackTable::ReturnsVoid(isolate, f_as_void); \
VMState<EXTERNAL> state(isolate); \
ExternalCallbackScope call_scope(isolate, FUNCTION_ADDR(f)); \
- if (new_style) { \
- NewFunction c = reinterpret_cast<NewFunction>(f); \
- PropertyCallbackInfo<ReturnValue> info(end()); \
- c(arg1, arg2, info); \
- } else { \
- v8::AccessorInfo info(end()); \
- f(arg1, arg2, info); \
- } \
+ PropertyCallbackInfo<ReturnValue> info(end()); \
+ f(arg1, arg2, info); \
}
+
FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
FOR_EACH_CALLBACK_TABLE_MAPPING_2(WRITE_CALL_2)
diff --git a/src/arguments.h b/src/arguments.h
index f9dca11..169528b 100644
--- a/src/arguments.h
+++ b/src/arguments.h
@@ -83,116 +83,49 @@
};
-// mappings from old property callbacks to new ones
-// F(old name, new name, return value, parameters...)
-//
+// For each type of callback, we have a list of arguments
+// They are used to generate the Call() functions below
// These aren't included in the list as they have duplicate signatures
-// F(NamedPropertyEnumerator, NamedPropertyEnumeratorCallback, ...)
-// F(NamedPropertyGetter, NamedPropertyGetterCallback, ...)
+// F(NamedPropertyEnumeratorCallback, ...)
+// F(NamedPropertyGetterCallback, ...)
#define FOR_EACH_CALLBACK_TABLE_MAPPING_0(F) \
- F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback, v8::Array) \
+ F(IndexedPropertyEnumeratorCallback, v8::Array) \
#define FOR_EACH_CALLBACK_TABLE_MAPPING_1(F) \
- F(AccessorGetter, AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
- F(NamedPropertyQuery, \
- NamedPropertyQueryCallback, \
+ F(AccessorGetterCallback, v8::Value, v8::Local<v8::String>) \
+ F(NamedPropertyQueryCallback, \
v8::Integer, \
v8::Local<v8::String>) \
- F(NamedPropertyDeleter, \
- NamedPropertyDeleterCallback, \
+ F(NamedPropertyDeleterCallback, \
v8::Boolean, \
v8::Local<v8::String>) \
- F(IndexedPropertyGetter, \
- IndexedPropertyGetterCallback, \
+ F(IndexedPropertyGetterCallback, \
v8::Value, \
uint32_t) \
- F(IndexedPropertyQuery, \
- IndexedPropertyQueryCallback, \
+ F(IndexedPropertyQueryCallback, \
v8::Integer, \
uint32_t) \
- F(IndexedPropertyDeleter, \
- IndexedPropertyDeleterCallback, \
+ F(IndexedPropertyDeleterCallback, \
v8::Boolean, \
uint32_t) \
#define FOR_EACH_CALLBACK_TABLE_MAPPING_2(F) \
- F(NamedPropertySetter, \
- NamedPropertySetterCallback, \
+ F(NamedPropertySetterCallback, \
v8::Value, \
v8::Local<v8::String>, \
v8::Local<v8::Value>) \
- F(IndexedPropertySetter, \
- IndexedPropertySetterCallback, \
+ F(IndexedPropertySetterCallback, \
v8::Value, \
uint32_t, \
v8::Local<v8::Value>) \
#define FOR_EACH_CALLBACK_TABLE_MAPPING_2_VOID_RETURN(F) \
- F(AccessorSetter, \
- AccessorSetterCallback, \
+ F(AccessorSetterCallback, \
void, \
v8::Local<v8::String>, \
v8::Local<v8::Value>) \
-// All property callbacks as well as invocation callbacks
-#define FOR_EACH_CALLBACK_TABLE_MAPPING(F) \
- F(InvocationCallback, FunctionCallback) \
- F(AccessorGetter, AccessorGetterCallback) \
- F(AccessorSetter, AccessorSetterCallback) \
- F(NamedPropertySetter, NamedPropertySetterCallback) \
- F(NamedPropertyQuery, NamedPropertyQueryCallback) \
- F(NamedPropertyDeleter, NamedPropertyDeleterCallback) \
- F(IndexedPropertyGetter, IndexedPropertyGetterCallback) \
- F(IndexedPropertySetter, IndexedPropertySetterCallback) \
- F(IndexedPropertyQuery, IndexedPropertyQueryCallback) \
- F(IndexedPropertyDeleter, IndexedPropertyDeleterCallback) \
- F(IndexedPropertyEnumerator, IndexedPropertyEnumeratorCallback) \
-
-
-// TODO(dcarney): Remove this class when old callbacks are gone.
-class CallbackTable {
- public:
- static const bool kStoreVoidFunctions = false;
- static inline bool ReturnsVoid(Isolate* isolate, void* function) {
- CallbackTable* table = isolate->callback_table();
- bool contains =
- table != NULL &&
- table->map_.occupancy() != 0 &&
- table->Contains(function);
- return contains == kStoreVoidFunctions;
- }
-
- STATIC_ASSERT(sizeof(intptr_t) == sizeof(AccessorGetterCallback));
-
- template<typename F>
- static inline void* FunctionToVoidPtr(F function) {
- return reinterpret_cast<void*>(reinterpret_cast<intptr_t>(function));
- }
-
-#define WRITE_REGISTER(OldFunction, NewFunction) \
- static NewFunction Register(Isolate* isolate, OldFunction f) { \
- InsertCallback(isolate, FunctionToVoidPtr(f), false); \
- return reinterpret_cast<NewFunction>(f); \
- } \
- \
- static NewFunction Register(Isolate* isolate, NewFunction f) { \
- InsertCallback(isolate, FunctionToVoidPtr(f), true); \
- return f; \
- }
- FOR_EACH_CALLBACK_TABLE_MAPPING(WRITE_REGISTER)
-#undef WRITE_REGISTER
-
- private:
- CallbackTable();
- bool Contains(void* function);
- static void InsertCallback(Isolate* isolate,
- void* function,
- bool returns_void);
- HashMap map_;
- DISALLOW_COPY_AND_ASSIGN(CallbackTable);
-};
-
// Custom arguments replicate a small segment of stack that can be
// accessed through an Arguments object the same way the actual stack
@@ -218,7 +151,6 @@
typedef CustomArgumentsBase<T::kArgsLength> Super;
~CustomArguments() {
- // TODO(dcarney): create a new zap value for this.
this->end()[kReturnValueOffset] =
reinterpret_cast<Object*>(kHandleZapValue);
}
@@ -271,17 +203,17 @@
* and used if it's been set to anything inside the callback.
* New style callbacks always use the return value.
*/
-#define WRITE_CALL_0(OldFunction, NewFunction, ReturnValue) \
- v8::Handle<ReturnValue> Call(OldFunction f); \
+#define WRITE_CALL_0(Function, ReturnValue) \
+ v8::Handle<ReturnValue> Call(Function f); \
-#define WRITE_CALL_1(OldFunction, NewFunction, ReturnValue, Arg1) \
- v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1); \
+#define WRITE_CALL_1(Function, ReturnValue, Arg1) \
+ v8::Handle<ReturnValue> Call(Function f, Arg1 arg1); \
-#define WRITE_CALL_2(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
- v8::Handle<ReturnValue> Call(OldFunction f, Arg1 arg1, Arg2 arg2); \
+#define WRITE_CALL_2(Function, ReturnValue, Arg1, Arg2) \
+ v8::Handle<ReturnValue> Call(Function f, Arg1 arg1, Arg2 arg2); \
-#define WRITE_CALL_2_VOID(OldFunction, NewFunction, ReturnValue, Arg1, Arg2) \
- void Call(OldFunction f, Arg1 arg1, Arg2 arg2); \
+#define WRITE_CALL_2_VOID(Function, ReturnValue, Arg1, Arg2) \
+ void Call(Function f, Arg1 arg1, Arg2 arg2); \
FOR_EACH_CALLBACK_TABLE_MAPPING_0(WRITE_CALL_0)
FOR_EACH_CALLBACK_TABLE_MAPPING_1(WRITE_CALL_1)
@@ -336,7 +268,7 @@
* and used if it's been set to anything inside the callback.
* New style callbacks always use the return value.
*/
- v8::Handle<v8::Value> Call(InvocationCallback f);
+ v8::Handle<v8::Value> Call(FunctionCallback f);
private:
internal::Object** argv_;
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 3dbdb2f..9a4d6e5 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -38,6 +38,17 @@
namespace internal {
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { r2 };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
void ToNumberStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
@@ -309,134 +320,6 @@
}
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
- // Create a new closure from the given function info in new
- // space. Set the context to the current context in cp.
- Counters* counters = masm->isolate()->counters();
-
- Label gc;
-
- // Pop the function info from the stack.
- __ pop(r3);
-
- // Attempt to allocate new JSFunction in new space.
- __ Allocate(JSFunction::kSize, r0, r1, r2, &gc, TAG_OBJECT);
-
- __ IncrementCounter(counters->fast_new_closure_total(), 1, r6, r7);
-
- int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
- // Compute the function map in the current native context and set that
- // as the map of the allocated object.
- __ ldr(r2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
- __ ldr(r2, FieldMemOperand(r2, GlobalObject::kNativeContextOffset));
- __ ldr(r5, MemOperand(r2, Context::SlotOffset(map_index)));
- __ str(r5, FieldMemOperand(r0, HeapObject::kMapOffset));
-
- // Initialize the rest of the function. We don't have to update the
- // write barrier because the allocated object is in new space.
- __ LoadRoot(r1, Heap::kEmptyFixedArrayRootIndex);
- __ LoadRoot(r5, Heap::kTheHoleValueRootIndex);
- __ str(r1, FieldMemOperand(r0, JSObject::kPropertiesOffset));
- __ str(r1, FieldMemOperand(r0, JSObject::kElementsOffset));
- __ str(r5, FieldMemOperand(r0, JSFunction::kPrototypeOrInitialMapOffset));
- __ str(r3, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
- __ str(cp, FieldMemOperand(r0, JSFunction::kContextOffset));
- __ str(r1, FieldMemOperand(r0, JSFunction::kLiteralsOffset));
-
- // Initialize the code pointer in the function to be the one
- // found in the shared function info object.
- // But first check if there is an optimized version for our context.
- Label check_optimized;
- Label install_unoptimized;
- if (FLAG_cache_optimized_code) {
- __ ldr(r1,
- FieldMemOperand(r3, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ tst(r1, r1);
- __ b(ne, &check_optimized);
- }
- __ bind(&install_unoptimized);
- __ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
- __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
- __ ldr(r3, FieldMemOperand(r3, SharedFunctionInfo::kCodeOffset));
- __ add(r3, r3, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ str(r3, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
-
- // Return result. The argument function info has been popped already.
- __ Ret();
-
- __ bind(&check_optimized);
-
- __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, r6, r7);
-
- // r2 holds native context, r1 points to fixed array of 3-element entries
- // (native context, optimized code, literals).
- // The optimized code map must never be empty, so check the first elements.
- Label install_optimized;
- // Speculatively move code object into r4.
- __ ldr(r4, FieldMemOperand(r1, SharedFunctionInfo::kFirstCodeSlot));
- __ ldr(r5, FieldMemOperand(r1, SharedFunctionInfo::kFirstContextSlot));
- __ cmp(r2, r5);
- __ b(eq, &install_optimized);
-
- // Iterate through the rest of map backwards. r4 holds an index as a Smi.
- Label loop;
- __ ldr(r4, FieldMemOperand(r1, FixedArray::kLengthOffset));
- __ bind(&loop);
- // Do not double check first entry.
- __ cmp(r4, Operand(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
- __ b(eq, &install_unoptimized);
- __ sub(r4, r4, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ add(r5, r5, Operand::PointerOffsetFromSmiKey(r4));
- __ ldr(r5, MemOperand(r5));
- __ cmp(r2, r5);
- __ b(ne, &loop);
- // Hit: fetch the optimized code.
- __ add(r5, r1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ add(r5, r5, Operand::PointerOffsetFromSmiKey(r4));
- __ add(r5, r5, Operand(kPointerSize));
- __ ldr(r4, MemOperand(r5));
-
- __ bind(&install_optimized);
- __ IncrementCounter(counters->fast_new_closure_install_optimized(),
- 1, r6, r7);
-
- // TODO(fschneider): Idea: store proper code pointers in the map and either
- // unmangle them on marking or do nothing as the whole map is discarded on
- // major GC anyway.
- __ add(r4, r4, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ str(r4, FieldMemOperand(r0, JSFunction::kCodeEntryOffset));
-
- // Now link a function into a list of optimized functions.
- __ ldr(r4, ContextOperand(r2, Context::OPTIMIZED_FUNCTIONS_LIST));
-
- __ str(r4, FieldMemOperand(r0, JSFunction::kNextFunctionLinkOffset));
- // No need for write barrier as JSFunction (eax) is in the new space.
-
- __ str(r0, ContextOperand(r2, Context::OPTIMIZED_FUNCTIONS_LIST));
- // Store JSFunction (eax) into edx before issuing write barrier as
- // it clobbers all the registers passed.
- __ mov(r4, r0);
- __ RecordWriteContextSlot(
- r2,
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
- r4,
- r1,
- kLRHasNotBeenSaved,
- kDontSaveFPRegs);
-
- // Return result. The argument function info has been popped already.
- __ Ret();
-
- // Create a new closure through the slower runtime call.
- __ bind(&gc);
- __ LoadRoot(r4, Heap::kFalseValueRootIndex);
- __ Push(cp, r3, r4);
- __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
void FastNewContextStub::Generate(MacroAssembler* masm) {
// Try to allocate the context in new space.
Label gc;
@@ -4530,6 +4413,7 @@
{
FrameScope scope(masm, StackFrame::INTERNAL);
+ __ SmiTag(r0);
__ push(r0);
__ push(r1);
__ push(r2);
@@ -4540,6 +4424,7 @@
__ pop(r2);
__ pop(r1);
__ pop(r0);
+ __ SmiUntag(r0);
}
__ b(&done);
diff --git a/src/arm/disasm-arm.cc b/src/arm/disasm-arm.cc
index ecdf638..acffaa3 100644
--- a/src/arm/disasm-arm.cc
+++ b/src/arm/disasm-arm.cc
@@ -50,9 +50,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
-#ifndef WIN32
-#include <stdint.h>
-#endif
#include "v8.h"
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 2243296..3400248 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -1330,8 +1330,7 @@
scope()->is_function_scope() &&
info->num_literals() == 0) {
FastNewClosureStub stub(info->language_mode(), info->is_generator());
- __ mov(r0, Operand(info));
- __ push(r0);
+ __ mov(r2, Operand(info));
__ CallStub(&stub);
} else {
__ mov(r0, Operand(info));
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 7c02a62..5978fad 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -260,6 +260,14 @@
}
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+ stream->Add(" = ");
+ function()->PrintTo(stream);
+ stream->Add(".code_entry = ");
+ code_object()->PrintTo(stream);
+}
+
+
void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
@@ -1079,6 +1087,14 @@
}
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+ HStoreCodeEntry* store_code_entry) {
+ LOperand* function = UseRegister(store_code_entry->function());
+ LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+ return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
HInnerAllocatedObject* inner_object) {
LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1909,11 +1925,12 @@
ASSERT(to.IsInteger32());
LOperand* value = NULL;
LInstruction* res = NULL;
- if (instr->value()->type().IsSmi()) {
- value = UseRegisterAtStart(instr->value());
+ HValue* val = instr->value();
+ if (val->type().IsSmi() || val->representation().IsSmi()) {
+ value = UseRegisterAtStart(val);
res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else {
- value = UseRegister(instr->value());
+ value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = FixedTemp(d11);
res = DefineSameAsFirst(new(zone()) LTaggedToI(value,
@@ -2435,8 +2452,7 @@
LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
- HEnvironment* env = current_block_->last_environment();
- instr->ReplayEnvironment(env);
+ instr->ReplayEnvironment(current_block_->last_environment());
// There are no real uses of a captured object.
return NULL;
@@ -2484,20 +2500,7 @@
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
- HEnvironment* env = current_block_->last_environment();
- ASSERT(env != NULL);
-
- env->set_ast_id(instr->ast_id());
-
- env->Drop(instr->pop_count());
- for (int i = instr->values()->length() - 1; i >= 0; --i) {
- HValue* value = instr->values()->at(i);
- if (instr->HasAssignedIndexAt(i)) {
- env->Bind(instr->GetAssignedIndexAt(i), value);
- } else {
- env->Push(value);
- }
- }
+ instr->ReplayEnvironment(current_block_->last_environment());
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index 316df7d..90fb117 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -162,6 +162,7 @@
V(SmiTag) \
V(SmiUntag) \
V(StackCheck) \
+ V(StoreCodeEntry) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
V(StoreGlobalGeneric) \
@@ -1753,7 +1754,24 @@
};
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+ LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+ inputs_[0] = function;
+ temps_[0] = code_object;
+ }
+
+ LOperand* function() { return inputs_[0]; }
+ LOperand* code_object() { return temps_[0]; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+ DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
public:
explicit LInnerAllocatedObject(LOperand* base_object) {
inputs_[0] = base_object;
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index f3f8b50..e34e15b 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -431,7 +431,7 @@
} else if (r.IsDouble()) {
Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
} else {
- ASSERT(r.IsTagged());
+ ASSERT(r.IsSmiOrTagged());
__ LoadObject(scratch, literal);
}
return scratch;
@@ -1584,10 +1584,7 @@
instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
if (right_op->IsConstantOperand() && !can_overflow) {
- // Use optimized code for specific constants.
- int32_t constant = ToRepresentation(
- LConstantOperand::cast(right_op),
- instr->hydrogen()->right()->representation());
+ int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
if (bailout_on_minus_zero && (constant < 0)) {
// The case of a null constant will be handled separately.
@@ -4146,6 +4143,15 @@
}
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+ Register function = ToRegister(instr->function());
+ Register code_object = ToRegister(instr->code_object());
+ __ add(code_object, code_object, Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ str(code_object,
+ FieldMemOperand(function, JSFunction::kCodeEntryOffset));
+}
+
+
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
@@ -5417,8 +5423,7 @@
if (!pretenure && instr->hydrogen()->has_no_literals()) {
FastNewClosureStub stub(instr->hydrogen()->language_mode(),
instr->hydrogen()->is_generator());
- __ mov(r1, Operand(instr->hydrogen()->shared_info()));
- __ push(r1);
+ __ mov(r2, Operand(instr->hydrogen()->shared_info()));
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
} else {
__ mov(r2, Operand(instr->hydrogen()->shared_info()));
diff --git a/src/arm/macro-assembler-arm.cc b/src/arm/macro-assembler-arm.cc
index 16ba89c..7628f23 100644
--- a/src/arm/macro-assembler-arm.cc
+++ b/src/arm/macro-assembler-arm.cc
@@ -2285,7 +2285,6 @@
ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset) {
ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate());
@@ -2354,15 +2353,6 @@
Label leave_exit_frame;
Label return_value_loaded;
- if (returns_handle) {
- Label load_return_value;
- cmp(r0, Operand::Zero());
- b(eq, &load_return_value);
- // derefernce returned value
- ldr(r0, MemOperand(r0));
- b(&return_value_loaded);
- bind(&load_return_value);
- }
// load value from ReturnValue
ldr(r0, MemOperand(fp, return_value_offset*kPointerSize));
bind(&return_value_loaded);
diff --git a/src/arm/macro-assembler-arm.h b/src/arm/macro-assembler-arm.h
index f3716c2..cff9ac7 100644
--- a/src/arm/macro-assembler-arm.h
+++ b/src/arm/macro-assembler-arm.h
@@ -1111,7 +1111,6 @@
ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset_from_fp);
// Jump to a runtime routine.
diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc
index c9e3616..def1818 100644
--- a/src/arm/simulator-arm.cc
+++ b/src/arm/simulator-arm.cc
@@ -1686,20 +1686,12 @@
// This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h).
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
-typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
- int32_t arg0, int32_t arg1);
-typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback.
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
- int32_t arg1);
-typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
- int32_t arg1);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
- int32_t arg0, int32_t arg1, int32_t arg2);
-typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
+typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingGetterCall)(
int32_t arg0, int32_t arg1, int32_t arg2);
// Software interrupt instructions are used by the simulator to call into the
@@ -1839,9 +1831,7 @@
break;
}
}
- } else if (
- redirection->type() == ExternalReference::DIRECT_API_CALL ||
- redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) {
+ } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF("Call to host function at %p args %08x",
reinterpret_cast<void*>(external), arg0);
@@ -1851,22 +1841,11 @@
PrintF("\n");
}
CHECK(stack_aligned);
- if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
- SimulatorRuntimeDirectApiCall target =
- reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
- v8::Handle<v8::Value> result = target(arg0);
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }
- set_register(r0, reinterpret_cast<int32_t>(*result));
- } else {
- SimulatorRuntimeDirectApiCallNew target =
- reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
- target(arg0);
- }
+ SimulatorRuntimeDirectApiCall target =
+ reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
+ target(arg0);
} else if (
- redirection->type() == ExternalReference::PROFILING_API_CALL ||
- redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
+ redirection->type() == ExternalReference::PROFILING_API_CALL) {
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF("Call to host function at %p args %08x %08x",
reinterpret_cast<void*>(external), arg0, arg1);
@@ -1876,22 +1855,11 @@
PrintF("\n");
}
CHECK(stack_aligned);
- if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
- SimulatorRuntimeProfilingApiCall target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
- v8::Handle<v8::Value> result = target(arg0, arg1);
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }
- set_register(r0, reinterpret_cast<int32_t>(*result));
- } else {
- SimulatorRuntimeProfilingApiCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
- target(arg0, arg1);
- }
+ SimulatorRuntimeProfilingApiCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+ target(arg0, arg1);
} else if (
- redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
- redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
+ redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF("Call to host function at %p args %08x %08x",
reinterpret_cast<void*>(external), arg0, arg1);
@@ -1901,22 +1869,11 @@
PrintF("\n");
}
CHECK(stack_aligned);
- if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
- SimulatorRuntimeDirectGetterCall target =
- reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
- v8::Handle<v8::Value> result = target(arg0, arg1);
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }
- set_register(r0, reinterpret_cast<int32_t>(*result));
- } else {
- SimulatorRuntimeDirectGetterCallNew target =
- reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
- target(arg0, arg1);
- }
+ SimulatorRuntimeDirectGetterCall target =
+ reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
+ target(arg0, arg1);
} else if (
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
+ redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
if (::v8::internal::FLAG_trace_sim || !stack_aligned) {
PrintF("Call to host function at %p args %08x %08x %08x",
reinterpret_cast<void*>(external), arg0, arg1, arg2);
@@ -1926,20 +1883,10 @@
PrintF("\n");
}
CHECK(stack_aligned);
- if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
- SimulatorRuntimeProfilingGetterCall target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
- v8::Handle<v8::Value> result = target(arg0, arg1, arg2);
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Returned %p\n", reinterpret_cast<void *>(*result));
- }
- set_register(r0, reinterpret_cast<int32_t>(*result));
- } else {
- SimulatorRuntimeProfilingGetterCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(
- external);
- target(arg0, arg1, arg2);
- }
+ SimulatorRuntimeProfilingGetterCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(
+ external);
+ target(arg0, arg1, arg2);
} else {
// builtin call.
ASSERT(redirection->type() == ExternalReference::BUILTIN_CALL);
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index ea28a34..7605525 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -903,23 +903,13 @@
const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
Address function_address = v8::ToCData<Address>(api_call_info->callback());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
ApiFunction fun(function_address);
- ExternalReference::Type type =
- returns_handle ?
- ExternalReference::DIRECT_API_CALL :
- ExternalReference::DIRECT_API_CALL_NEW;
+ ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
ExternalReference ref = ExternalReference(&fun,
type,
masm->isolate());
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_API_CALL :
- ExternalReference::PROFILING_API_CALL_NEW;
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
masm->isolate());
@@ -930,7 +920,6 @@
thunk_ref,
r1,
kStackUnwindSpace,
- returns_handle,
kFastApiCallArguments + 1);
}
@@ -1424,23 +1413,14 @@
const int kStackUnwindSpace = kFastApiCallArguments + 1;
Address getter_address = v8::ToCData<Address>(callback->getter());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(isolate(), getter_address);
ApiFunction fun(getter_address);
- ExternalReference::Type type =
- returns_handle ?
- ExternalReference::DIRECT_GETTER_CALL :
- ExternalReference::DIRECT_GETTER_CALL_NEW;
+ ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
ExternalReference ref = ExternalReference(&fun, type, isolate());
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_GETTER_CALL :
- ExternalReference::PROFILING_GETTER_CALL_NEW;
+ ExternalReference::PROFILING_GETTER_CALL;
ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
isolate());
@@ -1449,7 +1429,6 @@
thunk_ref,
r2,
kStackUnwindSpace,
- returns_handle,
5);
}
diff --git a/src/assembler.h b/src/assembler.h
index d70d5aa..b358136 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -644,38 +644,21 @@
BUILTIN_FP_INT_CALL,
// Direct call to API function callback.
- // Handle<Value> f(v8::Arguments&)
+ // void f(v8::FunctionCallbackInfo&)
DIRECT_API_CALL,
- // Call to invocation callback via InvokeInvocationCallback.
- // Handle<Value> f(v8::Arguments&, v8::InvocationCallback)
+ // Call to function callback via InvokeFunctionCallback.
+ // void f(v8::FunctionCallbackInfo&, v8::FunctionCallback)
PROFILING_API_CALL,
- // Direct call to API function callback.
- // void f(v8::Arguments&)
- DIRECT_API_CALL_NEW,
-
- // Call to function callback via InvokeFunctionCallback.
- // void f(v8::Arguments&, v8::FunctionCallback)
- PROFILING_API_CALL_NEW,
-
// Direct call to accessor getter callback.
- // Handle<value> f(Local<String> property, AccessorInfo& info)
+ // void f(Local<String> property, PropertyCallbackInfo& info)
DIRECT_GETTER_CALL,
- // Call to accessor getter callback via InvokeAccessorGetter.
- // Handle<value> f(Local<String> property, AccessorInfo& info,
- // AccessorGetter getter)
- PROFILING_GETTER_CALL,
-
- // Direct call to accessor getter callback.
- // void f(Local<String> property, AccessorInfo& info)
- DIRECT_GETTER_CALL_NEW,
-
// Call to accessor getter callback via InvokeAccessorGetterCallback.
- // void f(Local<String> property, AccessorInfo& info,
+ // void f(Local<String> property, PropertyCallbackInfo& info,
// AccessorGetterCallback callback)
- PROFILING_GETTER_CALL_NEW
+ PROFILING_GETTER_CALL
};
static void SetUp();
diff --git a/src/ast.h b/src/ast.h
index f61f495..bf76cfa 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -123,10 +123,6 @@
STATEMENT_NODE_LIST(V) \
EXPRESSION_NODE_LIST(V)
-#ifdef WIN32
-#undef Yield
-#endif
-
// Forward declarations
class AstConstructionVisitor;
template<class> class AstNodeFactory;
@@ -1963,7 +1959,7 @@
Expression* expression() const { return expression_; }
virtual int position() const V8_OVERRIDE { return pos_; }
- void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* znoe);
+ void RecordTypeFeedback(TypeFeedbackOracle* oracle, Zone* zone);
virtual bool IsMonomorphic() V8_OVERRIDE { return is_monomorphic_; }
virtual SmallMapList* GetReceiverTypes() V8_OVERRIDE {
return &receiver_types_;
diff --git a/src/builtins.cc b/src/builtins.cc
index 4a5cd03..1bc0a72 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -1253,8 +1253,8 @@
if (!raw_call_data->IsUndefined()) {
CallHandlerInfo* call_data = CallHandlerInfo::cast(raw_call_data);
Object* callback_obj = call_data->callback();
- v8::InvocationCallback callback =
- v8::ToCData<v8::InvocationCallback>(callback_obj);
+ v8::FunctionCallback callback =
+ v8::ToCData<v8::FunctionCallback>(callback_obj);
Object* data_obj = call_data->data();
Object* result;
@@ -1322,8 +1322,8 @@
ASSERT(!handler->IsUndefined());
CallHandlerInfo* call_data = CallHandlerInfo::cast(handler);
Object* callback_obj = call_data->callback();
- v8::InvocationCallback callback =
- v8::ToCData<v8::InvocationCallback>(callback_obj);
+ v8::FunctionCallback callback =
+ v8::ToCData<v8::FunctionCallback>(callback_obj);
// Get the data for the call and perform the callback.
Object* result;
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 3e18138..35927f4 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -112,6 +112,13 @@
HValue* BuildInternalArrayConstructor(ElementsKind kind,
ArgumentClass argument_class);
+ void BuildInstallOptimizedCode(HValue* js_function, HValue* native_context,
+ HValue* code_object);
+ void BuildInstallCode(HValue* js_function, HValue* shared_info);
+ void BuildInstallFromOptimizedCodeMap(HValue* js_function,
+ HValue* shared_info,
+ HValue* native_context);
+
private:
HValue* BuildArraySingleArgumentConstructor(JSArrayBuilder* builder);
HValue* BuildArrayNArgumentsConstructor(JSArrayBuilder* builder,
@@ -904,4 +911,194 @@
}
+void CodeStubGraphBuilderBase::BuildInstallOptimizedCode(
+ HValue* js_function,
+ HValue* native_context,
+ HValue* code_object) {
+ Counters* counters = isolate()->counters();
+ AddIncrementCounter(counters->fast_new_closure_install_optimized(),
+ context());
+
+ // TODO(fschneider): Idea: store proper code pointers in the optimized code
+ // map and either unmangle them on marking or do nothing as the whole map is
+ // discarded on major GC anyway.
+ Add<HStoreCodeEntry>(js_function, code_object);
+
+ // Now link a function into a list of optimized functions.
+ HValue* optimized_functions_list = Add<HLoadNamedField>(native_context,
+ HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST));
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForNextFunctionLinkPointer(),
+ optimized_functions_list);
+
+ // This store is the only one that should have a write barrier.
+ Add<HStoreNamedField>(native_context,
+ HObjectAccess::ForContextSlot(Context::OPTIMIZED_FUNCTIONS_LIST),
+ js_function);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallCode(HValue* js_function,
+ HValue* shared_info) {
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForNextFunctionLinkPointer(),
+ graph()->GetConstantUndefined());
+ HValue* code_object = Add<HLoadNamedField>(shared_info,
+ HObjectAccess::ForCodeOffset());
+ Add<HStoreCodeEntry>(js_function, code_object);
+}
+
+
+void CodeStubGraphBuilderBase::BuildInstallFromOptimizedCodeMap(
+ HValue* js_function,
+ HValue* shared_info,
+ HValue* native_context) {
+ Counters* counters = isolate()->counters();
+ IfBuilder is_optimized(this);
+ HInstruction* optimized_map = Add<HLoadNamedField>(shared_info,
+ HObjectAccess::ForOptimizedCodeMap());
+ HValue* null_constant = Add<HConstant>(0);
+ is_optimized.If<HCompareObjectEqAndBranch>(optimized_map, null_constant);
+ is_optimized.Then();
+ {
+ BuildInstallCode(js_function, shared_info);
+ }
+ is_optimized.Else();
+ {
+ AddIncrementCounter(counters->fast_new_closure_try_optimized(), context());
+ // optimized_map points to fixed array of 3-element entries
+ // (native context, optimized code, literals).
+ // Map must never be empty, so check the first elements.
+ Label install_optimized;
+ HValue* first_context_slot = Add<HLoadNamedField>(optimized_map,
+ HObjectAccess::ForFirstContextSlot());
+ IfBuilder already_in(this);
+ already_in.If<HCompareObjectEqAndBranch>(native_context,
+ first_context_slot);
+ already_in.Then();
+ {
+ HValue* code_object = Add<HLoadNamedField>(optimized_map,
+ HObjectAccess::ForFirstCodeSlot());
+ BuildInstallOptimizedCode(js_function, native_context, code_object);
+ }
+ already_in.Else();
+ {
+ HValue* shared_function_entry_length =
+ Add<HConstant>(SharedFunctionInfo::kEntryLength);
+ LoopBuilder loop_builder(this,
+ context(),
+ LoopBuilder::kPostDecrement,
+ shared_function_entry_length);
+ HValue* array_length = Add<HLoadNamedField>(optimized_map,
+ HObjectAccess::ForFixedArrayLength());
+ HValue* key = loop_builder.BeginBody(array_length,
+ graph()->GetConstant0(),
+ Token::GT);
+ {
+ // Iterate through the rest of map backwards.
+ // Do not double check first entry.
+ HValue* second_entry_index =
+ Add<HConstant>(SharedFunctionInfo::kSecondEntryIndex);
+ IfBuilder restore_check(this);
+ restore_check.If<HCompareNumericAndBranch>(key, second_entry_index,
+ Token::EQ);
+ restore_check.Then();
+ {
+ // Store the unoptimized code
+ BuildInstallCode(js_function, shared_info);
+ loop_builder.Break();
+ }
+ restore_check.Else();
+ {
+ HValue* keyed_minus = AddInstruction(HSub::New(zone(), context(), key,
+ shared_function_entry_length));
+ HInstruction* keyed_lookup = Add<HLoadKeyed>(optimized_map,
+ keyed_minus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+ IfBuilder done_check(this);
+ done_check.If<HCompareObjectEqAndBranch>(native_context,
+ keyed_lookup);
+ done_check.Then();
+ {
+ // Hit: fetch the optimized code.
+ HValue* keyed_plus = AddInstruction(HAdd::New(zone(), context(),
+ keyed_minus, graph()->GetConstant1()));
+ HValue* code_object = Add<HLoadKeyed>(optimized_map,
+ keyed_plus, static_cast<HValue*>(NULL), FAST_ELEMENTS);
+ BuildInstallOptimizedCode(js_function, native_context, code_object);
+
+ // Fall out of the loop
+ loop_builder.Break();
+ }
+ done_check.Else();
+ done_check.End();
+ }
+ restore_check.End();
+ }
+ loop_builder.EndBody();
+ }
+ already_in.End();
+ }
+ is_optimized.End();
+}
+
+
+template<>
+HValue* CodeStubGraphBuilder<FastNewClosureStub>::BuildCodeStub() {
+ Counters* counters = isolate()->counters();
+ Factory* factory = isolate()->factory();
+ HInstruction* empty_fixed_array =
+ Add<HConstant>(factory->empty_fixed_array());
+ HValue* shared_info = GetParameter(0);
+
+ // Create a new closure from the given function info in new space
+ HValue* size = Add<HConstant>(JSFunction::kSize);
+ HInstruction* js_function = Add<HAllocate>(size, HType::JSObject(),
+ NOT_TENURED, JS_FUNCTION_TYPE);
+ AddIncrementCounter(counters->fast_new_closure_total(), context());
+
+ int map_index = Context::FunctionMapIndex(casted_stub()->language_mode(),
+ casted_stub()->is_generator());
+
+ // Compute the function map in the current native context and set that
+ // as the map of the allocated object.
+ HInstruction* native_context = BuildGetNativeContext();
+ HInstruction* map_slot_value = Add<HLoadNamedField>(native_context,
+ HObjectAccess::ForContextSlot(map_index));
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForMap(), map_slot_value);
+
+ // Initialize the rest of the function.
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForPropertiesPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForElementsPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForLiteralsPointer(),
+ empty_fixed_array);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForPrototypeOrInitialMap(),
+ graph()->GetConstantHole());
+ Add<HStoreNamedField>(js_function,
+ HObjectAccess::ForSharedFunctionInfoPointer(),
+ shared_info);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
+ shared_info);
+ Add<HStoreNamedField>(js_function, HObjectAccess::ForFunctionContextPointer(),
+ context());
+
+ // Initialize the code pointer in the function to be the one
+ // found in the shared function info object.
+ // But first check if there is an optimized version for our context.
+ if (FLAG_cache_optimized_code) {
+ BuildInstallFromOptimizedCodeMap(js_function, shared_info, native_context);
+ } else {
+ BuildInstallCode(js_function, shared_info);
+ }
+
+ return js_function;
+}
+
+
+Handle<Code> FastNewClosureStub::GenerateCode() {
+ return DoGenerateCode(this);
+}
+
+
} } // namespace v8::internal
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index dd70127..01456ee 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -759,6 +759,12 @@
}
+void FastNewClosureStub::InstallDescriptors(Isolate* isolate) {
+ FastNewClosureStub stub(STRICT_MODE, false);
+ InstallDescriptor(isolate, &stub);
+}
+
+
ArrayConstructorStub::ArrayConstructorStub(Isolate* isolate)
: argument_count_(ANY) {
ArrayConstructorStubBase::GenerateStubsAheadOfTime(isolate);
diff --git a/src/code-stubs.h b/src/code-stubs.h
index 4be914d..ccd2caf 100644
--- a/src/code-stubs.h
+++ b/src/code-stubs.h
@@ -489,20 +489,29 @@
};
-class FastNewClosureStub : public PlatformCodeStub {
+class FastNewClosureStub : public HydrogenCodeStub {
public:
explicit FastNewClosureStub(LanguageMode language_mode, bool is_generator)
: language_mode_(language_mode),
is_generator_(is_generator) { }
- void Generate(MacroAssembler* masm);
+ virtual Handle<Code> GenerateCode();
+
+ virtual void InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor);
+
+ static void InstallDescriptors(Isolate* isolate);
+
+ LanguageMode language_mode() const { return language_mode_; }
+ bool is_generator() const { return is_generator_; }
private:
class StrictModeBits: public BitField<bool, 0, 1> {};
class IsGeneratorBits: public BitField<bool, 1, 1> {};
Major MajorKey() { return FastNewClosure; }
- int MinorKey() {
+ int NotMissMinorKey() {
return StrictModeBits::encode(language_mode_ != CLASSIC_MODE) |
IsGeneratorBits::encode(is_generator_);
}
diff --git a/src/compiler.cc b/src/compiler.cc
index c14234f..6c2bdce 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -1262,6 +1262,7 @@
bool CompilationPhase::ShouldProduceTraceOutput() const {
// Trace if the appropriate trace flag is set and the phase name's first
// character is in the FLAG_trace_phase command line parameter.
+ AllowHandleDereference allow_deref;
bool tracing_on = info()->IsStub()
? FLAG_trace_hydrogen_stubs
: (FLAG_trace_hydrogen &&
diff --git a/src/cpu.cc b/src/cpu.cc
index d7c32dd..1bae001 100644
--- a/src/cpu.cc
+++ b/src/cpu.cc
@@ -58,7 +58,7 @@
#else // !V8_CC_MSVC || (!defined(__i386__) && !defined(__pic__))
-static void V8_INLINE(__cpuid(int cpu_info[4], int info_type)) {
+static V8_INLINE(void __cpuid(int cpu_info[4], int info_type)) {
__asm__ volatile (
"cpuid \n\t"
: "=a"(cpu_info[0]), "=b"(cpu_info[1]), "=c"(cpu_info[2]), "=d"(cpu_info[3])
diff --git a/src/d8.h b/src/d8.h
index 3b06985..6008d35 100644
--- a/src/d8.h
+++ b/src/d8.h
@@ -400,8 +400,8 @@
static void RunShell(Isolate* isolate);
static bool SetOptions(int argc, char* argv[]);
static Handle<ObjectTemplate> CreateGlobalTemplate(Isolate* isolate);
- static Handle<FunctionTemplate> CreateArrayBufferTemplate(InvocationCallback);
- static Handle<FunctionTemplate> CreateArrayTemplate(InvocationCallback);
+ static Handle<FunctionTemplate> CreateArrayBufferTemplate(FunctionCallback);
+ static Handle<FunctionTemplate> CreateArrayTemplate(FunctionCallback);
static Handle<Value> CreateExternalArrayBuffer(Isolate* isolate,
Handle<Object> buffer,
int32_t size);
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index 2d6863b..0ea5a32 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -620,7 +620,7 @@
DEFINE_float(testing_float_flag, 2.5, "float-flag")
DEFINE_string(testing_string_flag, "Hello, world!", "string-flag")
DEFINE_int(testing_prng_seed, 42, "Seed used for threading test randomness")
-#ifdef WIN32
+#ifdef _WIN32
DEFINE_string(testing_serialization_file, "C:\\Windows\\Temp\\serdes",
"file in which to testing_serialize heap")
#else
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index 74db807..664673f 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -1872,7 +1872,7 @@
static void RegisterCodeEntry(JITCodeEntry* entry,
bool dump_if_enabled,
const char* name_hint) {
-#if defined(DEBUG) && !defined(WIN32)
+#if defined(DEBUG) && !V8_OS_WIN
static int file_num = 0;
if (FLAG_gdbjit_dump && dump_if_enabled) {
static const int kMaxFileNameSize = 64;
diff --git a/src/globals.h b/src/globals.h
index 2d072a0..d0a57a4 100644
--- a/src/globals.h
+++ b/src/globals.h
@@ -171,27 +171,32 @@
// Define our own macros for writing 64-bit constants. This is less fragile
// than defining __STDC_CONSTANT_MACROS before including <stdint.h>, and it
// works on compilers that don't have it (like MSVC).
-#if V8_HOST_ARCH_64_BIT
-#if defined(_MSC_VER)
-#define V8_UINT64_C(x) (x ## UI64)
-#define V8_INT64_C(x) (x ## I64)
-#define V8_INTPTR_C(x) (x ## I64)
-#define V8_PTR_PREFIX "ll"
-#elif defined(__MINGW64__)
-#define V8_UINT64_C(x) (x ## ULL)
-#define V8_INT64_C(x) (x ## LL)
-#define V8_INTPTR_C(x) (x ## LL)
-#define V8_PTR_PREFIX "I64"
+#if V8_CC_MSVC
+# define V8_UINT64_C(x) (x ## UI64)
+# define V8_INT64_C(x) (x ## I64)
+# if V8_HOST_ARCH_64_BIT
+# define V8_INTPTR_C(x) (x ## I64)
+# define V8_PTR_PREFIX "ll"
+# else
+# define V8_INTPTR_C(x) (x)
+# define V8_PTR_PREFIX ""
+# endif // V8_HOST_ARCH_64_BIT
+#elif V8_CC_MINGW64
+# define V8_UINT64_C(x) (x ## ULL)
+# define V8_INT64_C(x) (x ## LL)
+# define V8_INTPTR_C(x) (x ## LL)
+# define V8_PTR_PREFIX "I64"
+#elif V8_HOST_ARCH_64_BIT
+# define V8_UINT64_C(x) (x ## UL)
+# define V8_INT64_C(x) (x ## L)
+# define V8_INTPTR_C(x) (x ## L)
+# define V8_PTR_PREFIX "l"
#else
-#define V8_UINT64_C(x) (x ## UL)
-#define V8_INT64_C(x) (x ## L)
-#define V8_INTPTR_C(x) (x ## L)
-#define V8_PTR_PREFIX "l"
+# define V8_UINT64_C(x) (x ## ULL)
+# define V8_INT64_C(x) (x ## LL)
+# define V8_INTPTR_C(x) (x)
+# define V8_PTR_PREFIX ""
#endif
-#else // V8_HOST_ARCH_64_BIT
-#define V8_INTPTR_C(x) (x)
-#define V8_PTR_PREFIX ""
-#endif // V8_HOST_ARCH_64_BIT
// The following macro works on both 32 and 64-bit platforms.
// Usage: instead of writing 0x1234567890123456
@@ -337,31 +342,13 @@
DISALLOW_COPY_AND_ASSIGN(TypeName)
-// Define used for helping GCC to make better inlining. Don't bother for debug
-// builds. On GCC 3.4.5 using __attribute__((always_inline)) causes compilation
-// errors in debug build.
-#if defined(__GNUC__) && !defined(DEBUG)
-#if (__GNUC__ >= 4)
-#define INLINE(header) inline header __attribute__((always_inline))
-#define NO_INLINE(header) header __attribute__((noinline))
-#else
-#define INLINE(header) inline __attribute__((always_inline)) header
-#define NO_INLINE(header) __attribute__((noinline)) header
-#endif
-#elif defined(_MSC_VER) && !defined(DEBUG)
-#define INLINE(header) __forceinline header
-#define NO_INLINE(header) header
-#else
-#define INLINE(header) inline header
-#define NO_INLINE(header) header
-#endif
+// Newly written code should use V8_INLINE() and V8_NOINLINE() directly.
+#define INLINE(declarator) V8_INLINE(declarator)
+#define NO_INLINE(declarator) V8_NOINLINE(declarator)
-#if defined(__GNUC__) && __GNUC__ >= 4
-#define MUST_USE_RESULT __attribute__ ((warn_unused_result))
-#else
-#define MUST_USE_RESULT
-#endif
+// Newly written code should use V8_WARN_UNUSED_RESULT.
+#define MUST_USE_RESULT V8_WARN_UNUSED_RESULT
// Define DISABLE_ASAN macros.
diff --git a/src/handles.cc b/src/handles.cc
index b173edc..9d47690 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -532,8 +532,9 @@
args(isolate, interceptor->data(), *receiver, *object);
v8::Handle<v8::Array> result;
if (!interceptor->enumerator()->IsUndefined()) {
- v8::NamedPropertyEnumerator enum_fun =
- v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator());
+ v8::NamedPropertyEnumeratorCallback enum_fun =
+ v8::ToCData<v8::NamedPropertyEnumeratorCallback>(
+ interceptor->enumerator());
LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object));
result = args.Call(enum_fun);
}
@@ -554,8 +555,9 @@
args(isolate, interceptor->data(), *receiver, *object);
v8::Handle<v8::Array> result;
if (!interceptor->enumerator()->IsUndefined()) {
- v8::IndexedPropertyEnumerator enum_fun =
- v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator());
+ v8::IndexedPropertyEnumeratorCallback enum_fun =
+ v8::ToCData<v8::IndexedPropertyEnumeratorCallback>(
+ interceptor->enumerator());
LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object));
result = args.Call(enum_fun);
#if ENABLE_EXTRA_CHECKS
diff --git a/src/heap.cc b/src/heap.cc
index ad352bc..b1096b3 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -4971,7 +4971,7 @@
int object_size = map->instance_size();
Object* clone;
- ASSERT(map->CanTrackAllocationSite());
+ ASSERT(AllocationSite::CanTrack(map->instance_type()));
ASSERT(map->instance_type() == JS_ARRAY_TYPE);
WriteBarrierMode wb_mode = UPDATE_WRITE_BARRIER;
diff --git a/src/hydrogen-bch.cc b/src/hydrogen-bch.cc
index 137d629..a0a0fee 100644
--- a/src/hydrogen-bch.cc
+++ b/src/hydrogen-bch.cc
@@ -102,10 +102,11 @@
int current_dominated_block_;
};
- HGraph* graph() { return graph_; }
- HBasicBlock* loop_header() { return loop_header_; }
- Element* at(int index) { return &(elements_.at(index)); }
- Element* at(HBasicBlock* block) { return at(block->block_id()); }
+ HGraph* graph() const { return graph_; }
+ Counters* counters() const { return graph()->isolate()->counters(); }
+ HBasicBlock* loop_header() const { return loop_header_; }
+ Element* at(int index) const { return &(elements_.at(index)); }
+ Element* at(HBasicBlock* block) const { return at(block->block_id()); }
void AddCheckAt(HBasicBlock* block) {
at(block->block_id())->set_has_check();
@@ -258,23 +259,17 @@
// all checks are done on constants: if all check are done against the same
// constant limit we will use that instead of the induction limit.
bool has_upper_constant_limit = true;
- InductionVariableData::InductionVariableCheck* current_check = check;
int32_t upper_constant_limit =
- current_check != NULL && current_check->HasUpperLimit() ?
- current_check->upper_limit() : 0;
- while (current_check != NULL) {
- if (check->HasUpperLimit()) {
- if (check->upper_limit() != upper_constant_limit) {
- has_upper_constant_limit = false;
- }
- } else {
- has_upper_constant_limit = false;
- }
-
- current_check->check()->block()->graph()->isolate()->counters()->
- bounds_checks_eliminated()->Increment();
+ check != NULL && check->HasUpperLimit() ? check->upper_limit() : 0;
+ for (InductionVariableData::InductionVariableCheck* current_check = check;
+ current_check != NULL;
+ current_check = current_check->next()) {
+ has_upper_constant_limit =
+ has_upper_constant_limit &&
+ check->HasUpperLimit() &&
+ check->upper_limit() == upper_constant_limit;
+ counters()->bounds_checks_eliminated()->Increment();
current_check->check()->set_skip_check();
- current_check = current_check->next();
}
// Choose the appropriate limit.
@@ -303,8 +298,7 @@
zone, context, limit, check->check()->length());
hoisted_check->InsertBefore(pre_header->end());
hoisted_check->set_allow_equality(true);
- hoisted_check->block()->graph()->isolate()->counters()->
- bounds_checks_hoisted()->Increment();
+ counters()->bounds_checks_hoisted()->Increment();
}
void CollectInductionVariableData(HBasicBlock* bb) {
@@ -341,8 +335,7 @@
// TODO(mmassi): skip OSR values for check->length().
if (check->length() == data->limit() ||
check->length() == data->additional_upper_limit()) {
- check->block()->graph()->isolate()->counters()->
- bounds_checks_eliminated()->Increment();
+ counters()->bounds_checks_eliminated()->Increment();
check->set_skip_check();
continue;
}
@@ -407,4 +400,3 @@
}
} } // namespace v8::internal
-
diff --git a/src/hydrogen-canonicalize.cc b/src/hydrogen-canonicalize.cc
index 6432343..4d96415 100644
--- a/src/hydrogen-canonicalize.cc
+++ b/src/hydrogen-canonicalize.cc
@@ -48,6 +48,10 @@
if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
HInstruction::kTruncatingToSmi)) {
instr->SetFlag(HInstruction::kAllUsesTruncatingToSmi);
+ } else if (instr->HasAtLeastOneUseWithFlagAndNoneWithout(
+ HInstruction::kTruncatingToInt32)) {
+ // Avoid redundant minus zero check
+ instr->SetFlag(HInstruction::kAllUsesTruncatingToInt32);
}
}
}
diff --git a/src/hydrogen-infer-representation.cc b/src/hydrogen-infer-representation.cc
index 95c3412..1b3ab6f 100644
--- a/src/hydrogen-infer-representation.cc
+++ b/src/hydrogen-infer-representation.cc
@@ -82,24 +82,36 @@
if (done.Contains(i)) continue;
// Check if all uses of all connected phis in this group are truncating.
- bool all_uses_everywhere_truncating = true;
+ bool all_uses_everywhere_truncating_int32 = true;
+ bool all_uses_everywhere_truncating_smi = true;
for (BitVector::Iterator it(connected_phis[i]);
!it.Done();
it.Advance()) {
int index = it.Current();
- all_uses_everywhere_truncating &=
+ all_uses_everywhere_truncating_int32 &=
phi_list->at(index)->CheckFlag(HInstruction::kTruncatingToInt32);
+ all_uses_everywhere_truncating_smi &=
+ phi_list->at(index)->CheckFlag(HInstruction::kTruncatingToSmi);
done.Add(index);
}
- if (all_uses_everywhere_truncating) {
- continue; // Great, nothing to do.
+
+ if (!all_uses_everywhere_truncating_int32) {
+ // Clear truncation flag of this group of connected phis.
+ for (BitVector::Iterator it(connected_phis[i]);
+ !it.Done();
+ it.Advance()) {
+ int index = it.Current();
+ phi_list->at(index)->ClearFlag(HInstruction::kTruncatingToInt32);
+ }
}
- // Clear truncation flag of this group of connected phis.
- for (BitVector::Iterator it(connected_phis[i]);
- !it.Done();
- it.Advance()) {
- int index = it.Current();
- phi_list->at(index)->ClearFlag(HInstruction::kTruncatingToInt32);
+ if (!all_uses_everywhere_truncating_smi) {
+ // Clear truncation flag of this group of connected phis.
+ for (BitVector::Iterator it(connected_phis[i]);
+ !it.Done();
+ it.Advance()) {
+ int index = it.Current();
+ phi_list->at(index)->ClearFlag(HInstruction::kTruncatingToSmi);
+ }
}
}
}
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 90cf017..0bd7b79 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -397,6 +397,18 @@
}
+bool HValue::CheckUsesForFlag(Flag f, HValue** value) const {
+ for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
+ if (it.value()->IsSimulate()) continue;
+ if (!it.value()->CheckFlag(f)) {
+ *value = it.value();
+ return false;
+ }
+ }
+ return true;
+}
+
+
bool HValue::HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const {
bool return_value = false;
for (HUseIterator it(uses()); !it.Done(); it.Advance()) {
@@ -1231,6 +1243,7 @@
HValue* HDiv::Canonicalize() {
+ if (IsIdentityOperation(left(), right(), 1)) return left();
return this;
}
@@ -2289,6 +2302,21 @@
}
+void HSimulate::ReplayEnvironment(HEnvironment* env) {
+ ASSERT(env != NULL);
+ env->set_ast_id(ast_id());
+ env->Drop(pop_count());
+ for (int i = values()->length() - 1; i >= 0; --i) {
+ HValue* value = values()->at(i);
+ if (HasAssignedIndexAt(i)) {
+ env->Bind(GetAssignedIndexAt(i), value);
+ } else {
+ env->Push(value);
+ }
+ }
+}
+
+
// Replay captured objects by replacing all captured objects with the
// same capture id in the current and all outer environments.
void HCapturedObject::ReplayEnvironment(HEnvironment* env) {
@@ -2468,7 +2496,7 @@
void HConstant::Initialize(Representation r) {
if (r.IsNone()) {
- if (has_smi_value_ && kSmiValueSize == 31) {
+ if (has_smi_value_ && SmiValuesAre31Bits()) {
r = Representation::Smi();
} else if (has_int32_value_) {
r = Representation::Integer32();
@@ -3255,8 +3283,9 @@
// First update the size of the dominator allocate instruction.
dominator_size = dominator_allocate->size();
- int32_t dominator_size_constant =
+ int32_t original_object_size =
HConstant::cast(dominator_size)->GetInteger32Constant();
+ int32_t dominator_size_constant = original_object_size;
int32_t current_size_constant =
HConstant::cast(current_size)->GetInteger32Constant();
int32_t new_dominator_size = dominator_size_constant + current_size_constant;
@@ -3291,9 +3320,19 @@
#ifdef VERIFY_HEAP
if (FLAG_verify_heap && dominator_allocate->IsNewSpaceAllocation()) {
dominator_allocate->MakePrefillWithFiller();
+ } else {
+ // TODO(hpayer): This is a short-term hack to make allocation mementos
+ // work again in new space.
+ ClearNextMapWord(original_object_size);
}
+#else
+ // TODO(hpayer): This is a short-term hack to make allocation mementos
+ // work again in new space.
+ ClearNextMapWord(original_object_size);
#endif
+ dominator_allocate->clear_next_map_word_ = clear_next_map_word_;
+
// After that replace the dominated allocate instruction.
HInstruction* dominated_allocate_instr =
HInnerAllocatedObject::New(zone,
@@ -3429,6 +3468,19 @@
}
+void HAllocate::ClearNextMapWord(int offset) {
+ if (clear_next_map_word_) {
+ Zone* zone = block()->zone();
+ HObjectAccess access = HObjectAccess::ForJSObjectOffset(offset);
+ HStoreNamedField* clear_next_map =
+ HStoreNamedField::New(zone, context(), this, access,
+ block()->graph()->GetConstantNull());
+ clear_next_map->ClearAllSideEffects();
+ clear_next_map->InsertAfter(this);
+ }
+}
+
+
void HAllocate::PrintDataTo(StringStream* stream) {
size()->PrintNameTo(stream);
stream->Add(" (");
@@ -4030,6 +4082,15 @@
}
+HObjectAccess HObjectAccess::ForContextSlot(int index) {
+ ASSERT(index >= 0);
+ Portion portion = kInobject;
+ int offset = Context::kHeaderSize + index * kPointerSize;
+ ASSERT_EQ(offset, Context::SlotOffset(index) + kHeapObjectTag);
+ return HObjectAccess(portion, offset, Representation::Tagged());
+}
+
+
HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
ASSERT(offset >= 0);
Portion portion = kInobject;
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 5dee185..8f79edf 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -164,6 +164,7 @@
V(Shr) \
V(Simulate) \
V(StackCheck) \
+ V(StoreCodeEntry) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
V(StoreGlobalGeneric) \
@@ -806,6 +807,8 @@
// Returns true if the flag specified is set for all uses, false otherwise.
bool CheckUsesForFlag(Flag f) const;
+ // Same as before and the first one without the flag is returned in value.
+ bool CheckUsesForFlag(Flag f, HValue** value) const;
// Returns true if the flag specified is set for all uses, and this set
// of uses is non-empty.
bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
@@ -1544,7 +1547,10 @@
ASSERT(!value->representation().Equals(to));
set_representation(to);
SetFlag(kUseGVN);
- if (is_truncating_to_smi) SetFlag(kTruncatingToSmi);
+ if (is_truncating_to_smi) {
+ SetFlag(kTruncatingToSmi);
+ SetFlag(kTruncatingToInt32);
+ }
if (is_truncating_to_int32) SetFlag(kTruncatingToInt32);
if (value->representation().IsSmi() || value->type().IsSmi()) {
set_type(HType::Smi());
@@ -1676,6 +1682,9 @@
void MergeWith(ZoneList<HSimulate*>* list);
bool is_candidate_for_removal() { return removable_ == REMOVABLE_SIMULATE; }
+ // Replay effects of this instruction on the given environment.
+ void ReplayEnvironment(HEnvironment* env);
+
DECLARE_CONCRETE_INSTRUCTION(Simulate)
#ifdef DEBUG
@@ -3326,7 +3335,7 @@
}
virtual Representation KnownOptimalRepresentation() V8_OVERRIDE {
- if (HasSmiValue() && kSmiValueSize == 31) return Representation::Smi();
+ if (HasSmiValue() && SmiValuesAre31Bits()) return Representation::Smi();
if (HasInteger32Value()) return Representation::Integer32();
if (HasNumberValue()) return Representation::Double();
if (HasExternalReferenceValue()) return Representation::External();
@@ -4510,7 +4519,6 @@
virtual void UpdateRepresentation(Representation new_rep,
HInferRepresentationPhase* h_infer,
const char* reason) V8_OVERRIDE {
- if (new_rep.IsSmi()) new_rep = Representation::Integer32();
HArithmeticBinaryOperation::UpdateRepresentation(new_rep, h_infer, reason);
}
@@ -4720,6 +4728,7 @@
right->representation().IsSmi() &&
HConstant::cast(right)->Integer32Value() >= 0))) {
SetFlag(kTruncatingToSmi);
+ SetFlag(kTruncatingToInt32);
// BIT_OR with a smi-range negative value will always set the entire
// sign-extension of the smi-sign.
} else if (op == Token::BIT_OR &&
@@ -4730,6 +4739,7 @@
right->representation().IsSmi() &&
HConstant::cast(right)->Integer32Value() < 0))) {
SetFlag(kTruncatingToSmi);
+ SetFlag(kTruncatingToInt32);
}
}
@@ -5156,7 +5166,8 @@
InstanceType instance_type)
: HTemplateInstruction<2>(type),
dominating_allocate_(NULL),
- filler_free_space_size_(NULL) {
+ filler_free_space_size_(NULL),
+ clear_next_map_word_(false) {
SetOperandAt(0, context);
SetOperandAt(1, size);
set_representation(Representation::Tagged());
@@ -5168,9 +5179,18 @@
? ALLOCATE_IN_OLD_POINTER_SPACE : ALLOCATE_IN_OLD_DATA_SPACE)
: ALLOCATE_IN_NEW_SPACE;
if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
- flags_ = static_cast<HAllocate::Flags>(flags_ |
- ALLOCATE_DOUBLE_ALIGNED);
+ flags_ = static_cast<HAllocate::Flags>(flags_ | ALLOCATE_DOUBLE_ALIGNED);
}
+ // We have to fill the allocated object with one word fillers if we do
+ // not use allocation folding since some allocations may depend on each
+ // other, i.e., have a pointer to each other. A GC in between these
+ // allocations may leave such objects behind in a not completely initialized
+ // state.
+ if (!FLAG_use_gvn || !FLAG_use_allocation_folding) {
+ flags_ = static_cast<HAllocate::Flags>(flags_ | PREFILL_WITH_FILLER);
+ }
+ clear_next_map_word_ = pretenure_flag == NOT_TENURED &&
+ AllocationSite::CanTrack(instance_type);
}
void UpdateSize(HValue* size) {
@@ -5190,14 +5210,43 @@
allocate->IsOldPointerSpaceAllocation());
}
+ void ClearNextMapWord(int offset);
+
Flags flags_;
Handle<Map> known_initial_map_;
HAllocate* dominating_allocate_;
HStoreNamedField* filler_free_space_size_;
+ bool clear_next_map_word_;
};
-class HInnerAllocatedObject V8_FINAL : public HTemplateInstruction<1> {
+class HStoreCodeEntry V8_FINAL: public HTemplateInstruction<2> {
+ public:
+ static HStoreCodeEntry* New(Zone* zone,
+ HValue* context,
+ HValue* function,
+ HValue* code) {
+ return new(zone) HStoreCodeEntry(function, code);
+ }
+
+ virtual Representation RequiredInputRepresentation(int index) {
+ return Representation::Tagged();
+ }
+
+ HValue* function() { return OperandAt(0); }
+ HValue* code_object() { return OperandAt(1); }
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry)
+
+ private:
+ HStoreCodeEntry(HValue* function, HValue* code) {
+ SetOperandAt(0, function);
+ SetOperandAt(1, code);
+ }
+};
+
+
+class HInnerAllocatedObject V8_FINAL: public HTemplateInstruction<1> {
public:
static HInnerAllocatedObject* New(Zone* zone,
HValue* context,
@@ -5506,6 +5555,14 @@
return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
}
+ static HObjectAccess ForLiteralsPointer() {
+ return HObjectAccess(kInobject, JSFunction::kLiteralsOffset);
+ }
+
+ static HObjectAccess ForNextFunctionLinkPointer() {
+ return HObjectAccess(kInobject, JSFunction::kNextFunctionLinkOffset);
+ }
+
static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
return HObjectAccess(
kArrayLengths,
@@ -5550,6 +5607,35 @@
return HObjectAccess(kInobject, JSFunction::kPrototypeOrInitialMapOffset);
}
+ static HObjectAccess ForSharedFunctionInfoPointer() {
+ return HObjectAccess(kInobject, JSFunction::kSharedFunctionInfoOffset);
+ }
+
+ static HObjectAccess ForCodeEntryPointer() {
+ return HObjectAccess(kInobject, JSFunction::kCodeEntryOffset);
+ }
+
+ static HObjectAccess ForCodeOffset() {
+ return HObjectAccess(kInobject, SharedFunctionInfo::kCodeOffset);
+ }
+
+ static HObjectAccess ForFirstCodeSlot() {
+ return HObjectAccess(kInobject, SharedFunctionInfo::kFirstCodeSlot);
+ }
+
+ static HObjectAccess ForFirstContextSlot() {
+ return HObjectAccess(kInobject, SharedFunctionInfo::kFirstContextSlot);
+ }
+
+ static HObjectAccess ForOptimizedCodeMap() {
+ return HObjectAccess(kInobject,
+ SharedFunctionInfo::kOptimizedCodeMapOffset);
+ }
+
+ static HObjectAccess ForFunctionContextPointer() {
+ return HObjectAccess(kInobject, JSFunction::kContextOffset);
+ }
+
static HObjectAccess ForMap() {
return HObjectAccess(kMaps, JSObject::kMapOffset);
}
@@ -5580,6 +5666,8 @@
// Create an access to an in-object property in a JSArray.
static HObjectAccess ForJSArrayOffset(int offset);
+ static HObjectAccess ForContextSlot(int index);
+
// Create an access to the backing store of an object.
static HObjectAccess ForBackingStoreOffset(int offset,
Representation representation = Representation::Tagged());
@@ -5759,7 +5847,7 @@
virtual ~ArrayInstructionInterface() { };
static Representation KeyedAccessIndexRequirement(Representation r) {
- return r.IsInteger32() || kSmiValueSize != 31
+ return r.IsInteger32() || SmiValuesAre32Bits()
? Representation::Integer32() : Representation::Smi();
}
};
diff --git a/src/hydrogen-representation-changes.cc b/src/hydrogen-representation-changes.cc
index 862457d..9601137 100644
--- a/src/hydrogen-representation-changes.cc
+++ b/src/hydrogen-representation-changes.cc
@@ -99,7 +99,8 @@
// int32-phis allow truncation and iteratively remove the ones that
// are used in an operation that does not allow a truncating
// conversion.
- ZoneList<HPhi*> worklist(8, zone());
+ ZoneList<HPhi*> int_worklist(8, zone());
+ ZoneList<HPhi*> smi_worklist(8, zone());
const ZoneList<HPhi*>* phi_list(graph()->phi_list());
for (int i = 0; i < phi_list->length(); i++) {
@@ -108,51 +109,64 @@
phi->SetFlag(HValue::kTruncatingToInt32);
} else if (phi->representation().IsSmi()) {
phi->SetFlag(HValue::kTruncatingToSmi);
+ phi->SetFlag(HValue::kTruncatingToInt32);
}
}
for (int i = 0; i < phi_list->length(); i++) {
HPhi* phi = phi_list->at(i);
- for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) {
- // If a Phi is used as a non-truncating int32 or as a double,
- // clear its "truncating" flag.
- HValue* use = it.value();
- Representation input_representation =
- use->RequiredInputRepresentation(it.index());
- if ((phi->representation().IsInteger32() &&
- !(input_representation.IsInteger32() &&
- use->CheckFlag(HValue::kTruncatingToInt32))) ||
- (phi->representation().IsSmi() &&
- !(input_representation.IsSmi() &&
- use->CheckFlag(HValue::kTruncatingToSmi)))) {
- if (FLAG_trace_representation) {
- PrintF("#%d Phi is not truncating because of #%d %s\n",
- phi->id(), it.value()->id(), it.value()->Mnemonic());
- }
- phi->ClearFlag(HValue::kTruncatingToInt32);
- phi->ClearFlag(HValue::kTruncatingToSmi);
- worklist.Add(phi, zone());
- break;
+ HValue* value = NULL;
+ if (phi->representation().IsSmiOrInteger32() &&
+ !phi->CheckUsesForFlag(HValue::kTruncatingToInt32, &value)) {
+ int_worklist.Add(phi, zone());
+ phi->ClearFlag(HValue::kTruncatingToInt32);
+ if (FLAG_trace_representation) {
+ PrintF("#%d Phi is not truncating Int32 because of #%d %s\n",
+ phi->id(), value->id(), value->Mnemonic());
+ }
+ }
+
+ if (phi->representation().IsSmi() &&
+ !phi->CheckUsesForFlag(HValue::kTruncatingToSmi, &value)) {
+ smi_worklist.Add(phi, zone());
+ phi->ClearFlag(HValue::kTruncatingToSmi);
+ if (FLAG_trace_representation) {
+ PrintF("#%d Phi is not truncating Smi because of #%d %s\n",
+ phi->id(), value->id(), value->Mnemonic());
}
}
}
- while (!worklist.is_empty()) {
- HPhi* current = worklist.RemoveLast();
+ while (!int_worklist.is_empty()) {
+ HPhi* current = int_worklist.RemoveLast();
for (int i = 0; i < current->OperandCount(); ++i) {
HValue* input = current->OperandAt(i);
if (input->IsPhi() &&
- ((input->representation().IsInteger32() &&
- input->CheckFlag(HValue::kTruncatingToInt32)) ||
- (input->representation().IsSmi() &&
- input->CheckFlag(HValue::kTruncatingToSmi)))) {
+ input->representation().IsSmiOrInteger32() &&
+ input->CheckFlag(HValue::kTruncatingToInt32)) {
if (FLAG_trace_representation) {
- PrintF("#%d Phi is not truncating because of #%d %s\n",
+ PrintF("#%d Phi is not truncating Int32 because of #%d %s\n",
input->id(), current->id(), current->Mnemonic());
}
input->ClearFlag(HValue::kTruncatingToInt32);
+ int_worklist.Add(HPhi::cast(input), zone());
+ }
+ }
+ }
+
+ while (!smi_worklist.is_empty()) {
+ HPhi* current = smi_worklist.RemoveLast();
+ for (int i = 0; i < current->OperandCount(); ++i) {
+ HValue* input = current->OperandAt(i);
+ if (input->IsPhi() &&
+ input->representation().IsSmi() &&
+ input->CheckFlag(HValue::kTruncatingToSmi)) {
+ if (FLAG_trace_representation) {
+ PrintF("#%d Phi is not truncating Smi because of #%d %s\n",
+ input->id(), current->id(), current->Mnemonic());
+ }
input->ClearFlag(HValue::kTruncatingToSmi);
- worklist.Add(HPhi::cast(input), zone());
+ smi_worklist.Add(HPhi::cast(input), zone());
}
}
}
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 95090d5..4847f1a 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -828,7 +828,6 @@
ASSERT(!captured_);
ASSERT(!finished_);
last_true_block_ = builder_->current_block();
- ASSERT(first_true_block_ == NULL || !last_true_block_->IsFinished());
builder_->set_current_block(first_false_block_);
did_else_ = true;
}
@@ -864,9 +863,11 @@
if (!did_else_) {
last_true_block_ = builder_->current_block();
}
- if (first_true_block_ == NULL) {
+ if (last_true_block_ == NULL || last_true_block_->IsFinished()) {
+ ASSERT(did_else_);
// Return on true. Nothing to do, just continue the false block.
- } else if (first_false_block_ == NULL) {
+ } else if (first_false_block_ == NULL ||
+ (did_else_ && builder_->current_block()->IsFinished())) {
// Deopt on false. Nothing to do except switching to the true block.
builder_->set_current_block(last_true_block_);
} else {
@@ -906,6 +907,24 @@
header_block_ = builder->CreateLoopHeaderBlock();
body_block_ = NULL;
exit_block_ = NULL;
+ exit_trampoline_block_ = NULL;
+ increment_amount_ = builder_->graph()->GetConstant1();
+}
+
+
+HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
+ HValue* context,
+ LoopBuilder::Direction direction,
+ HValue* increment_amount)
+ : builder_(builder),
+ context_(context),
+ direction_(direction),
+ finished_(false) {
+ header_block_ = builder->CreateLoopHeaderBlock();
+ body_block_ = NULL;
+ exit_block_ = NULL;
+ exit_trampoline_block_ = NULL;
+ increment_amount_ = increment_amount;
}
@@ -921,12 +940,14 @@
HEnvironment* body_env = env->Copy();
HEnvironment* exit_env = env->Copy();
- body_block_ = builder_->CreateBasicBlock(body_env);
- exit_block_ = builder_->CreateBasicBlock(exit_env);
// Remove the phi from the expression stack
body_env->Pop();
+ exit_env->Pop();
+ body_block_ = builder_->CreateBasicBlock(body_env);
+ exit_block_ = builder_->CreateBasicBlock(exit_env);
builder_->set_current_block(header_block_);
+ env->Pop();
HCompareNumericAndBranch* compare =
new(zone()) HCompareNumericAndBranch(phi_, terminating, token);
compare->SetSuccessorAt(0, body_block_);
@@ -950,15 +971,26 @@
}
+void HGraphBuilder::LoopBuilder::Break() {
+ if (exit_trampoline_block_ == NULL) {
+ // Its the first time we saw a break.
+ HEnvironment* env = exit_block_->last_environment()->Copy();
+ exit_trampoline_block_ = builder_->CreateBasicBlock(env);
+ exit_block_->GotoNoSimulate(exit_trampoline_block_);
+ }
+
+ builder_->current_block()->GotoNoSimulate(exit_trampoline_block_);
+}
+
+
void HGraphBuilder::LoopBuilder::EndBody() {
ASSERT(!finished_);
if (direction_ == kPostIncrement || direction_ == kPostDecrement) {
- HValue* one = builder_->graph()->GetConstant1();
if (direction_ == kPostIncrement) {
- increment_ = HAdd::New(zone(), context_, phi_, one);
+ increment_ = HAdd::New(zone(), context_, phi_, increment_amount_);
} else {
- increment_ = HSub::New(zone(), context_, phi_, one);
+ increment_ = HSub::New(zone(), context_, phi_, increment_amount_);
}
increment_->ClearFlag(HValue::kCanOverflow);
builder_->AddInstruction(increment_);
@@ -970,9 +1002,11 @@
last_block->GotoNoSimulate(header_block_);
header_block_->loop_information()->RegisterBackEdge(last_block);
- builder_->set_current_block(exit_block_);
- // Pop the phi from the expression stack
- builder_->environment()->Pop();
+ if (exit_trampoline_block_ != NULL) {
+ builder_->set_current_block(exit_trampoline_block_);
+ } else {
+ builder_->set_current_block(exit_block_);
+ }
finished_ = true;
}
@@ -1674,22 +1708,12 @@
if (mode == TRACK_ALLOCATION_SITE) {
size += AllocationMemento::kSize;
}
- int elems_offset = size;
- InstanceType instance_type = IsFastDoubleElementsKind(kind) ?
- FIXED_DOUBLE_ARRAY_TYPE : FIXED_ARRAY_TYPE;
- if (length > 0) {
- size += IsFastDoubleElementsKind(kind)
- ? FixedDoubleArray::SizeFor(length)
- : FixedArray::SizeFor(length);
- }
- // Allocate both the JS array and the elements array in one big
- // allocation. This avoids multiple limit checks.
HValue* size_in_bytes = Add<HConstant>(size);
HInstruction* object = Add<HAllocate>(size_in_bytes,
HType::JSObject(),
NOT_TENURED,
- instance_type);
+ JS_OBJECT_TYPE);
// Copy the JS array part.
for (int i = 0; i < JSArray::kSize; i += kPointerSize) {
@@ -1706,10 +1730,17 @@
}
if (length > 0) {
- // Get hold of the elements array of the boilerplate and setup the
- // elements pointer in the resulting object.
HValue* boilerplate_elements = AddLoadElements(boilerplate);
- HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
+ HValue* object_elements;
+ if (IsFastDoubleElementsKind(kind)) {
+ HValue* elems_size = Add<HConstant>(FixedDoubleArray::SizeFor(length));
+ object_elements = Add<HAllocate>(elems_size, HType::JSArray(),
+ NOT_TENURED, FIXED_DOUBLE_ARRAY_TYPE);
+ } else {
+ HValue* elems_size = Add<HConstant>(FixedArray::SizeFor(length));
+ object_elements = Add<HAllocate>(elems_size, HType::JSArray(),
+ NOT_TENURED, FIXED_ARRAY_TYPE);
+ }
Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
object_elements);
@@ -7494,7 +7525,12 @@
HConstant* delta = (expr->op() == Token::INC)
? graph()->GetConstant1()
: graph()->GetConstantMinus1();
- HInstruction* instr = Add<HAdd>(Top(), delta);
+ HInstruction* instr = AddUncasted<HAdd>(Top(), delta);
+ if (instr->IsAdd()) {
+ HAdd* add = HAdd::cast(instr);
+ add->set_observed_input_representation(1, rep);
+ add->set_observed_input_representation(2, Representation::Smi());
+ }
instr->SetFlag(HInstruction::kCannotBeTagged);
instr->ClearAllSideEffects();
return instr;
@@ -8293,7 +8329,7 @@
int* data_offset,
AllocationSiteMode mode) {
bool create_allocation_site_info = mode == TRACK_ALLOCATION_SITE &&
- boilerplate_object->map()->CanTrackAllocationSite();
+ AllocationSite::CanTrack(boilerplate_object->map()->instance_type());
// If using allocation sites, then the payload on the site should already
// be filled in as a valid (boilerplate) array.
@@ -8349,7 +8385,7 @@
// Create allocation site info.
if (mode == TRACK_ALLOCATION_SITE &&
- boilerplate_object->map()->CanTrackAllocationSite()) {
+ AllocationSite::CanTrack(boilerplate_object->map()->instance_type())) {
elements_offset += AllocationMemento::kSize;
*offset += AllocationMemento::kSize;
BuildCreateAllocationMemento(target, JSArray::kSize, allocation_site);
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 2b9fd96..22bffd1 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1058,7 +1058,7 @@
template<class I, class P1, class P2>
I* Add(P1 p1, P2 p2) {
- return static_cast<I*>(AddUncasted<I>(p1, p2));
+ return I::cast(AddUncasted<I>(p1, p2));
}
template<class I, class P1, class P2, class P3>
@@ -1412,6 +1412,11 @@
LoopBuilder(HGraphBuilder* builder,
HValue* context,
Direction direction);
+ LoopBuilder(HGraphBuilder* builder,
+ HValue* context,
+ Direction direction,
+ HValue* increment_amount);
+
~LoopBuilder() {
ASSERT(finished_);
}
@@ -1420,6 +1425,9 @@
HValue* initial,
HValue* terminating,
Token::Value token);
+
+ void Break();
+
void EndBody();
private:
@@ -1427,11 +1435,13 @@
HGraphBuilder* builder_;
HValue* context_;
+ HValue* increment_amount_;
HInstruction* increment_;
HPhi* phi_;
HBasicBlock* header_block_;
HBasicBlock* body_block_;
HBasicBlock* exit_block_;
+ HBasicBlock* exit_trampoline_block_;
Direction direction_;
bool finished_;
};
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index db50616..64f36b3 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -43,6 +43,17 @@
namespace internal {
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { ebx };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
void ToNumberStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
@@ -299,133 +310,6 @@
}
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
- // Create a new closure from the given function info in new
- // space. Set the context to the current context in esi.
- Counters* counters = masm->isolate()->counters();
-
- Label gc;
- __ Allocate(JSFunction::kSize, eax, ebx, ecx, &gc, TAG_OBJECT);
-
- __ IncrementCounter(counters->fast_new_closure_total(), 1);
-
- // Get the function info from the stack.
- __ mov(edx, Operand(esp, 1 * kPointerSize));
-
- int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
- // Compute the function map in the current native context and set that
- // as the map of the allocated object.
- __ mov(ecx, Operand(esi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
- __ mov(ecx, FieldOperand(ecx, GlobalObject::kNativeContextOffset));
- __ mov(ebx, Operand(ecx, Context::SlotOffset(map_index)));
- __ mov(FieldOperand(eax, JSObject::kMapOffset), ebx);
-
- // Initialize the rest of the function. We don't have to update the
- // write barrier because the allocated object is in new space.
- Factory* factory = masm->isolate()->factory();
- __ mov(ebx, Immediate(factory->empty_fixed_array()));
- __ mov(FieldOperand(eax, JSObject::kPropertiesOffset), ebx);
- __ mov(FieldOperand(eax, JSObject::kElementsOffset), ebx);
- __ mov(FieldOperand(eax, JSFunction::kPrototypeOrInitialMapOffset),
- Immediate(factory->the_hole_value()));
- __ mov(FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset), edx);
- __ mov(FieldOperand(eax, JSFunction::kContextOffset), esi);
- __ mov(FieldOperand(eax, JSFunction::kLiteralsOffset), ebx);
-
- // Initialize the code pointer in the function to be the one
- // found in the shared function info object.
- // But first check if there is an optimized version for our context.
- Label check_optimized;
- Label install_unoptimized;
- if (FLAG_cache_optimized_code) {
- __ mov(ebx, FieldOperand(edx, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ test(ebx, ebx);
- __ j(not_zero, &check_optimized, Label::kNear);
- }
- __ bind(&install_unoptimized);
- __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset),
- Immediate(factory->undefined_value()));
- __ mov(edx, FieldOperand(edx, SharedFunctionInfo::kCodeOffset));
- __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
- __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
-
- // Return and remove the on-stack parameter.
- __ ret(1 * kPointerSize);
-
- __ bind(&check_optimized);
-
- __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1);
-
- // ecx holds native context, ebx points to fixed array of 3-element entries
- // (native context, optimized code, literals).
- // Map must never be empty, so check the first elements.
- Label install_optimized;
- // Speculatively move code object into edx.
- __ mov(edx, FieldOperand(ebx, SharedFunctionInfo::kFirstCodeSlot));
- __ cmp(ecx, FieldOperand(ebx, SharedFunctionInfo::kFirstContextSlot));
- __ j(equal, &install_optimized);
-
- // Iterate through the rest of map backwards. edx holds an index as a Smi.
- Label loop;
- Label restore;
- __ mov(edx, FieldOperand(ebx, FixedArray::kLengthOffset));
- __ bind(&loop);
- // Do not double check first entry.
- __ cmp(edx, Immediate(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
- __ j(equal, &restore);
- __ sub(edx, Immediate(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ cmp(ecx, CodeGenerator::FixedArrayElementOperand(ebx, edx, 0));
- __ j(not_equal, &loop, Label::kNear);
- // Hit: fetch the optimized code.
- __ mov(edx, CodeGenerator::FixedArrayElementOperand(ebx, edx, 1));
-
- __ bind(&install_optimized);
- __ IncrementCounter(counters->fast_new_closure_install_optimized(), 1);
-
- // TODO(fschneider): Idea: store proper code pointers in the optimized code
- // map and either unmangle them on marking or do nothing as the whole map is
- // discarded on major GC anyway.
- __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
- __ mov(FieldOperand(eax, JSFunction::kCodeEntryOffset), edx);
-
- // Now link a function into a list of optimized functions.
- __ mov(edx, ContextOperand(ecx, Context::OPTIMIZED_FUNCTIONS_LIST));
-
- __ mov(FieldOperand(eax, JSFunction::kNextFunctionLinkOffset), edx);
- // No need for write barrier as JSFunction (eax) is in the new space.
-
- __ mov(ContextOperand(ecx, Context::OPTIMIZED_FUNCTIONS_LIST), eax);
- // Store JSFunction (eax) into edx before issuing write barrier as
- // it clobbers all the registers passed.
- __ mov(edx, eax);
- __ RecordWriteContextSlot(
- ecx,
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
- edx,
- ebx,
- kDontSaveFPRegs);
-
- // Return and remove the on-stack parameter.
- __ ret(1 * kPointerSize);
-
- __ bind(&restore);
- // Restore SharedFunctionInfo into edx.
- __ mov(edx, Operand(esp, 1 * kPointerSize));
- __ jmp(&install_unoptimized);
-
- // Create a new closure through the slower runtime call.
- __ bind(&gc);
- __ pop(ecx); // Temporarily remove return address.
- __ pop(edx);
- __ push(esi);
- __ push(edx);
- __ push(Immediate(factory->false_value()));
- __ push(ecx); // Restore return address.
- __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
void FastNewContextStub::Generate(MacroAssembler* masm) {
// Try to allocate the context in new space.
Label gc;
@@ -4419,6 +4303,7 @@
{
FrameScope scope(masm, StackFrame::INTERNAL);
+ __ SmiTag(eax);
__ push(eax);
__ push(edi);
__ push(ebx);
@@ -4429,6 +4314,7 @@
__ pop(ebx);
__ pop(edi);
__ pop(eax);
+ __ SmiUntag(eax);
}
__ jmp(&done);
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index bfe1f22..775a168 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -1268,7 +1268,7 @@
scope()->is_function_scope() &&
info->num_literals() == 0) {
FastNewClosureStub stub(info->language_mode(), info->is_generator());
- __ push(Immediate(info));
+ __ mov(ebx, Immediate(info));
__ CallStub(&stub);
} else {
__ push(esi);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 81c22e2..ccd623c 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4349,6 +4349,14 @@
}
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+ Register function = ToRegister(instr->function());
+ Register code_object = ToRegister(instr->code_object());
+ __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize));
+ __ mov(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object);
+}
+
+
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
@@ -6209,7 +6217,7 @@
if (!pretenure && instr->hydrogen()->has_no_literals()) {
FastNewClosureStub stub(instr->hydrogen()->language_mode(),
instr->hydrogen()->is_generator());
- __ push(Immediate(instr->hydrogen()->shared_info()));
+ __ mov(ebx, Immediate(instr->hydrogen()->shared_info()));
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
} else {
__ push(esi);
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 2fdbb98..7ec1258 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -290,6 +290,14 @@
}
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+ stream->Add(" = ");
+ function()->PrintTo(stream);
+ stream->Add(".code_entry = ");
+ code_object()->PrintTo(stream);
+}
+
+
void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
@@ -1150,6 +1158,14 @@
}
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+ HStoreCodeEntry* store_code_entry) {
+ LOperand* function = UseRegister(store_code_entry->function());
+ LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+ return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
HInnerAllocatedObject* inner_object) {
LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1929,13 +1945,14 @@
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- if (instr->value()->type().IsSmi()) {
- LOperand* value = UseRegister(instr->value());
+ HValue* val = instr->value();
+ if (val->type().IsSmi() || val->representation().IsSmi()) {
+ LOperand* value = UseRegister(val);
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
} else {
bool truncating = instr->CanTruncateToInt32();
if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
- LOperand* value = UseRegister(instr->value());
+ LOperand* value = UseRegister(val);
LOperand* xmm_temp =
(truncating && CpuFeatures::IsSupported(SSE3))
? NULL
@@ -1943,7 +1960,7 @@
LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp);
return AssignEnvironment(DefineSameAsFirst(res));
} else {
- LOperand* value = UseFixed(instr->value(), ecx);
+ LOperand* value = UseFixed(val, ecx);
LTaggedToINoSSE2* res =
new(zone()) LTaggedToINoSSE2(value, TempRegister(),
TempRegister(), TempRegister());
@@ -2564,8 +2581,7 @@
LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
- HEnvironment* env = current_block_->last_environment();
- instr->ReplayEnvironment(env);
+ instr->ReplayEnvironment(current_block_->last_environment());
// There are no real uses of a captured object.
return NULL;
@@ -2615,20 +2631,7 @@
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
- HEnvironment* env = current_block_->last_environment();
- ASSERT(env != NULL);
-
- env->set_ast_id(instr->ast_id());
-
- env->Drop(instr->pop_count());
- for (int i = instr->values()->length() - 1; i >= 0; --i) {
- HValue* value = instr->values()->at(i);
- if (instr->HasAssignedIndexAt(i)) {
- env->Bind(instr->GetAssignedIndexAt(i), value);
- } else {
- env->Push(value);
- }
- }
+ instr->ReplayEnvironment(current_block_->last_environment());
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index a6a2526..e8a3baf 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -161,6 +161,7 @@
V(SmiTag) \
V(SmiUntag) \
V(StackCheck) \
+ V(StoreCodeEntry) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
V(StoreGlobalGeneric) \
@@ -1777,7 +1778,24 @@
};
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+ LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+ inputs_[0] = function;
+ temps_[0] = code_object;
+ }
+
+ LOperand* function() { return inputs_[0]; }
+ LOperand* code_object() { return temps_[0]; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+ DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
public:
explicit LInnerAllocatedObject(LOperand* base_object) {
inputs_[0] = base_object;
diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc
index bf785df..aaacbd9 100644
--- a/src/ia32/macro-assembler-ia32.cc
+++ b/src/ia32/macro-assembler-ia32.cc
@@ -1977,50 +1977,15 @@
}
-// If true, a Handle<T> returned by value from a function with cdecl calling
-// convention will be returned directly as a value of location_ field in a
-// register eax.
-// If false, it is returned as a pointer to a preallocated by caller memory
-// region. Pointer to this region should be passed to a function as an
-// implicit first argument.
-#if defined(USING_BSD_ABI) || defined(__MINGW32__) || defined(__CYGWIN__)
-static const bool kReturnHandlesDirectly = true;
-#else
-static const bool kReturnHandlesDirectly = false;
-#endif
-
-
-Operand ApiParameterOperand(int index, bool returns_handle) {
- int offset = (index +(kReturnHandlesDirectly || !returns_handle ? 0 : 1));
- return Operand(esp, offset * kPointerSize);
+Operand ApiParameterOperand(int index) {
+ return Operand(esp, index * kPointerSize);
}
-void MacroAssembler::PrepareCallApiFunction(int argc, bool returns_handle) {
- if (kReturnHandlesDirectly || !returns_handle) {
- EnterApiExitFrame(argc);
- // When handles are returned directly we don't have to allocate extra
- // space for and pass an out parameter.
- if (emit_debug_code()) {
- mov(esi, Immediate(BitCast<int32_t>(kZapValue)));
- }
- } else {
- // We allocate two additional slots: return value and pointer to it.
- EnterApiExitFrame(argc + 2);
-
- // The argument slots are filled as follows:
- //
- // n + 1: output slot
- // n: arg n
- // ...
- // 1: arg1
- // 0: pointer to the output slot
-
- lea(esi, Operand(esp, (argc + 1) * kPointerSize));
- mov(Operand(esp, 0 * kPointerSize), esi);
- if (emit_debug_code()) {
- mov(Operand(esi, 0), Immediate(0));
- }
+void MacroAssembler::PrepareCallApiFunction(int argc) {
+ EnterApiExitFrame(argc);
+ if (emit_debug_code()) {
+ mov(esi, Immediate(BitCast<int32_t>(kZapValue)));
}
}
@@ -2029,7 +1994,6 @@
Address thunk_address,
Operand thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset) {
ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate());
@@ -2085,21 +2049,6 @@
}
Label prologue;
- if (returns_handle) {
- if (!kReturnHandlesDirectly) {
- // PrepareCallApiFunction saved pointer to the output slot into
- // callee-save register esi.
- mov(eax, Operand(esi, 0));
- }
- Label empty_handle;
- // Check if the result handle holds 0.
- test(eax, eax);
- j(zero, &empty_handle);
- // It was non-zero. Dereference to get the result value.
- mov(eax, Operand(eax, 0));
- jmp(&prologue);
- bind(&empty_handle);
- }
// Load the value from ReturnValue
mov(eax, Operand(ebp, return_value_offset * kPointerSize));
diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h
index d537b0b..4d9ebad 100644
--- a/src/ia32/macro-assembler-ia32.h
+++ b/src/ia32/macro-assembler-ia32.h
@@ -782,7 +782,7 @@
// Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1)
// etc. Saves context (esi). If space was reserved for return value then
// stores the pointer to the reserved slot into esi.
- void PrepareCallApiFunction(int argc, bool returns_handle);
+ void PrepareCallApiFunction(int argc);
// Calls an API function. Allocates HandleScope, extracts returned value
// from handle and propagates exceptions. Clobbers ebx, edi and
@@ -792,7 +792,6 @@
Address thunk_address,
Operand thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset_from_ebp);
// Jump to a runtime routine.
@@ -1039,7 +1038,7 @@
// Generates an Operand for saving parameters after PrepareCallApiFunction.
-Operand ApiParameterOperand(int index, bool returns_handle);
+Operand ApiParameterOperand(int index);
#ifdef GENERATED_CODE_COVERAGE
diff --git a/src/ia32/regexp-macro-assembler-ia32.cc b/src/ia32/regexp-macro-assembler-ia32.cc
index dfcc869..7d9e2f7 100644
--- a/src/ia32/regexp-macro-assembler-ia32.cc
+++ b/src/ia32/regexp-macro-assembler-ia32.cc
@@ -711,7 +711,7 @@
// position registers.
__ mov(Operand(ebp, kInputStartMinusOne), eax);
-#ifdef WIN32
+#if V8_OS_WIN
// Ensure that we write to each stack page, in order. Skipping a page
// on Windows can cause segmentation faults. Assuming page size is 4k.
const int kPageSize = 4096;
@@ -721,7 +721,7 @@
i += kRegistersPerPage) {
__ mov(register_location(i), eax); // One write every page.
}
-#endif // WIN32
+#endif // V8_OS_WIN
Label load_char_start_regexp, start_regexp;
// Load newline if index is at start, previous character otherwise.
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index 93293a9..9aa7bae 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -516,34 +516,28 @@
// Function address is a foreign pointer outside V8's heap.
Address function_address = v8::ToCData<Address>(api_call_info->callback());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(masm->isolate(),
- reinterpret_cast<void*>(function_address));
- __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, returns_handle);
+ __ PrepareCallApiFunction(kApiArgc + kApiStackSpace);
// v8::Arguments::implicit_args_.
- __ mov(ApiParameterOperand(2, returns_handle), eax);
+ __ mov(ApiParameterOperand(2), eax);
__ add(eax, Immediate(argc * kPointerSize));
// v8::Arguments::values_.
- __ mov(ApiParameterOperand(3, returns_handle), eax);
+ __ mov(ApiParameterOperand(3), eax);
// v8::Arguments::length_.
- __ Set(ApiParameterOperand(4, returns_handle), Immediate(argc));
+ __ Set(ApiParameterOperand(4), Immediate(argc));
// v8::Arguments::is_construct_call_.
- __ Set(ApiParameterOperand(5, returns_handle), Immediate(0));
+ __ Set(ApiParameterOperand(5), Immediate(0));
// v8::InvocationCallback's argument.
- __ lea(eax, ApiParameterOperand(2, returns_handle));
- __ mov(ApiParameterOperand(0, returns_handle), eax);
+ __ lea(eax, ApiParameterOperand(2));
+ __ mov(ApiParameterOperand(0), eax);
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
__ CallApiFunctionAndReturn(function_address,
thunk_address,
- ApiParameterOperand(1, returns_handle),
+ ApiParameterOperand(1),
argc + kFastApiCallArguments + 1,
- returns_handle,
kFastApiCallArguments + 1);
}
@@ -1400,28 +1394,22 @@
const int kApiArgc = 2 + 1;
Address getter_address = v8::ToCData<Address>(callback->getter());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(isolate(),
- reinterpret_cast<void*>(getter_address));
- __ PrepareCallApiFunction(kApiArgc, returns_handle);
- __ mov(ApiParameterOperand(0, returns_handle), ebx); // name.
+ __ PrepareCallApiFunction(kApiArgc);
+ __ mov(ApiParameterOperand(0), ebx); // name.
__ add(ebx, Immediate(kPointerSize));
- __ mov(ApiParameterOperand(1, returns_handle), ebx); // arguments pointer.
+ __ mov(ApiParameterOperand(1), ebx); // arguments pointer.
// Emitting a stub call may try to allocate (if the code is not
// already generated). Do not allow the assembler to perform a
// garbage collection but instead return the allocation failure
// object.
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
__ CallApiFunctionAndReturn(getter_address,
thunk_address,
- ApiParameterOperand(2, returns_handle),
+ ApiParameterOperand(2),
kStackSpace,
- returns_handle,
6);
}
diff --git a/src/ic.cc b/src/ic.cc
index a8d3527..2a1f83d 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -2581,7 +2581,7 @@
v8::internal::TypeInfo type = v8::internal::TypeInfo::FromValue(value);
if (type.IsSmi()) return BinaryOpIC::SMI;
if (type.IsInteger32()) {
- if (kSmiValueSize == 32) return BinaryOpIC::SMI;
+ if (SmiValuesAre32Bits()) return BinaryOpIC::SMI;
return BinaryOpIC::INT32;
}
if (type.IsNumber()) return BinaryOpIC::NUMBER;
@@ -2593,7 +2593,7 @@
op == Token::SAR ||
op == Token::SHL ||
op == Token::SHR) {
- if (kSmiValueSize == 32) return BinaryOpIC::SMI;
+ if (SmiValuesAre32Bits()) return BinaryOpIC::SMI;
return BinaryOpIC::INT32;
}
return BinaryOpIC::ODDBALL;
@@ -2671,7 +2671,7 @@
if (op == Token::DIV ||
op == Token::MUL ||
op == Token::SHR ||
- kSmiValueSize == 32) {
+ SmiValuesAre32Bits()) {
// Arithmetic on two Smi inputs has yielded a heap number.
// That is the only way to get here from the Smi stub.
// With 32-bit Smis, all overflows give heap numbers, but with
diff --git a/src/isolate.cc b/src/isolate.cc
index b70dd68..774ad5c 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1793,7 +1793,6 @@
optimizing_compiler_thread_(this),
marking_thread_(NULL),
sweeper_thread_(NULL),
- callback_table_(NULL),
stress_deopt_count_(0) {
id_ = NoBarrier_AtomicIncrement(&isolate_counter_, 1);
TRACE_ISOLATE(constructor);
@@ -2063,9 +2062,6 @@
delete external_reference_table_;
external_reference_table_ = NULL;
- delete callback_table_;
- callback_table_ = NULL;
-
#ifdef ENABLE_DEBUGGER_SUPPORT
delete debugger_;
debugger_ = NULL;
@@ -2329,6 +2325,7 @@
ToBooleanStub::InitializeForIsolate(this);
ArrayConstructorStubBase::InstallDescriptors(this);
InternalArrayConstructorStubBase::InstallDescriptors(this);
+ FastNewClosureStub::InstallDescriptors(this);
}
if (FLAG_concurrent_recompilation) optimizing_compiler_thread_.Start();
diff --git a/src/isolate.h b/src/isolate.h
index 401505a..3d42cad 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -52,7 +52,6 @@
namespace internal {
class Bootstrapper;
-class CallbackTable;
class CodeGenerator;
class CodeRange;
struct CodeStubInterfaceDescriptor;
@@ -321,7 +320,6 @@
#ifdef ENABLE_DEBUGGER_SUPPORT
#define ISOLATE_DEBUGGER_INIT_LIST(V) \
- V(v8::Debug::EventCallback, debug_event_callback, NULL) \
V(DebuggerAgent*, debugger_agent_instance, NULL)
#else
@@ -361,7 +359,6 @@
V(byte*, assembler_spare_buffer, NULL) \
V(FatalErrorCallback, exception_behavior, NULL) \
V(AllowCodeGenerationFromStringsCallback, allow_code_gen_callback, NULL) \
- V(v8::Debug::MessageHandler, message_handler, NULL) \
/* To distinguish the function templates, so that we can find them in the */ \
/* function cache of the native context. */ \
V(int, next_serial_number, 0) \
@@ -1111,13 +1108,6 @@
return sweeper_thread_;
}
- CallbackTable* callback_table() {
- return callback_table_;
- }
- void set_callback_table(CallbackTable* callback_table) {
- callback_table_ = callback_table;
- }
-
int id() const { return static_cast<int>(id_); }
HStatistics* GetHStatistics();
@@ -1363,7 +1353,6 @@
OptimizingCompilerThread optimizing_compiler_thread_;
MarkingThread** marking_thread_;
SweeperThread** sweeper_thread_;
- CallbackTable* callback_table_;
// Counts deopt points if deopt_every_n_times is enabled.
unsigned int stress_deopt_count_;
diff --git a/src/macros.py b/src/macros.py
index d50231d..f1a2130 100644
--- a/src/macros.py
+++ b/src/macros.py
@@ -67,7 +67,8 @@
# For apinatives.js
const kUninitialized = -1;
-const kReadOnlyPrototypeBit = 3; # For FunctionTemplateInfo, matches objects.h
+const kReadOnlyPrototypeBit = 3;
+const kRemovePrototypeBit = 4; # For FunctionTemplateInfo, matches objects.h
# Note: kDayZeroInJulianDay = ToJulianDay(1970, 0, 1).
const kInvalidDate = 'Invalid Date';
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 8a03a9a..2c42001 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -39,6 +39,17 @@
namespace internal {
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { a2 };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
void ToNumberStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
@@ -310,134 +321,6 @@
}
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
- // Create a new closure from the given function info in new
- // space. Set the context to the current context in cp.
- Counters* counters = masm->isolate()->counters();
-
- Label gc;
-
- // Pop the function info from the stack.
- __ pop(a3);
-
- // Attempt to allocate new JSFunction in new space.
- __ Allocate(JSFunction::kSize, v0, a1, a2, &gc, TAG_OBJECT);
-
- __ IncrementCounter(counters->fast_new_closure_total(), 1, t2, t3);
-
- int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
- // Compute the function map in the current native context and set that
- // as the map of the allocated object.
- __ lw(a2, MemOperand(cp, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
- __ lw(a2, FieldMemOperand(a2, GlobalObject::kNativeContextOffset));
- __ lw(t1, MemOperand(a2, Context::SlotOffset(map_index)));
- __ sw(t1, FieldMemOperand(v0, HeapObject::kMapOffset));
-
- // Initialize the rest of the function. We don't have to update the
- // write barrier because the allocated object is in new space.
- __ LoadRoot(a1, Heap::kEmptyFixedArrayRootIndex);
- __ LoadRoot(t1, Heap::kTheHoleValueRootIndex);
- __ sw(a1, FieldMemOperand(v0, JSObject::kPropertiesOffset));
- __ sw(a1, FieldMemOperand(v0, JSObject::kElementsOffset));
- __ sw(t1, FieldMemOperand(v0, JSFunction::kPrototypeOrInitialMapOffset));
- __ sw(a3, FieldMemOperand(v0, JSFunction::kSharedFunctionInfoOffset));
- __ sw(cp, FieldMemOperand(v0, JSFunction::kContextOffset));
- __ sw(a1, FieldMemOperand(v0, JSFunction::kLiteralsOffset));
-
- // Initialize the code pointer in the function to be the one
- // found in the shared function info object.
- // But first check if there is an optimized version for our context.
- Label check_optimized;
- Label install_unoptimized;
- if (FLAG_cache_optimized_code) {
- __ lw(a1,
- FieldMemOperand(a3, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ And(at, a1, a1);
- __ Branch(&check_optimized, ne, at, Operand(zero_reg));
- }
- __ bind(&install_unoptimized);
- __ LoadRoot(t0, Heap::kUndefinedValueRootIndex);
- __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
- __ lw(a3, FieldMemOperand(a3, SharedFunctionInfo::kCodeOffset));
- __ Addu(a3, a3, Operand(Code::kHeaderSize - kHeapObjectTag));
-
- // Return result. The argument function info has been popped already.
- __ Ret(USE_DELAY_SLOT);
- __ sw(a3, FieldMemOperand(v0, JSFunction::kCodeEntryOffset));
-
- __ bind(&check_optimized);
-
- __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1, t2, t3);
-
- // a2 holds native context, a1 points to fixed array of 3-element entries
- // (native context, optimized code, literals).
- // The optimized code map must never be empty, so check the first elements.
- Label install_optimized;
- // Speculatively move code object into t0.
- __ lw(t0, FieldMemOperand(a1, SharedFunctionInfo::kFirstCodeSlot));
- __ lw(t1, FieldMemOperand(a1, SharedFunctionInfo::kFirstContextSlot));
- __ Branch(&install_optimized, eq, a2, Operand(t1));
-
- // Iterate through the rest of map backwards. t0 holds an index as a Smi.
- Label loop;
- __ lw(t0, FieldMemOperand(a1, FixedArray::kLengthOffset));
- __ bind(&loop);
- // Do not double check first entry.
- __ Branch(&install_unoptimized, eq, t0,
- Operand(Smi::FromInt(SharedFunctionInfo::kSecondEntryIndex)));
- __ Subu(t0, t0, Operand(Smi::FromInt(SharedFunctionInfo::kEntryLength)));
- __ Addu(t1, a1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ sll(at, t0, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(t1, t1, Operand(at));
- __ lw(t1, MemOperand(t1));
- __ Branch(&loop, ne, a2, Operand(t1));
- // Hit: fetch the optimized code.
- __ Addu(t1, a1, Operand(FixedArray::kHeaderSize - kHeapObjectTag));
- __ sll(at, t0, kPointerSizeLog2 - kSmiTagSize);
- __ Addu(t1, t1, Operand(at));
- __ Addu(t1, t1, Operand(kPointerSize));
- __ lw(t0, MemOperand(t1));
-
- __ bind(&install_optimized);
- __ IncrementCounter(counters->fast_new_closure_install_optimized(),
- 1, t2, t3);
-
- // TODO(fschneider): Idea: store proper code pointers in the map and either
- // unmangle them on marking or do nothing as the whole map is discarded on
- // major GC anyway.
- __ Addu(t0, t0, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ sw(t0, FieldMemOperand(v0, JSFunction::kCodeEntryOffset));
-
- // Now link a function into a list of optimized functions.
- __ lw(t0, ContextOperand(a2, Context::OPTIMIZED_FUNCTIONS_LIST));
-
- __ sw(t0, FieldMemOperand(v0, JSFunction::kNextFunctionLinkOffset));
- // No need for write barrier as JSFunction (eax) is in the new space.
-
- __ sw(v0, ContextOperand(a2, Context::OPTIMIZED_FUNCTIONS_LIST));
- // Store JSFunction (eax) into edx before issuing write barrier as
- // it clobbers all the registers passed.
- __ mov(t0, v0);
- __ RecordWriteContextSlot(
- a2,
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
- t0,
- a1,
- kRAHasNotBeenSaved,
- kDontSaveFPRegs);
-
- // Return result. The argument function info has been popped already.
- __ Ret();
-
- // Create a new closure through the slower runtime call.
- __ bind(&gc);
- __ LoadRoot(t0, Heap::kFalseValueRootIndex);
- __ Push(cp, a3, t0);
- __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
void FastNewContextStub::Generate(MacroAssembler* masm) {
// Try to allocate the context in new space.
Label gc;
@@ -4808,12 +4691,14 @@
1 << 5 | // a1
1 << 6; // a2
+ __ SmiTag(a0);
__ MultiPush(kSavedRegs);
CreateAllocationSiteStub create_stub;
__ CallStub(&create_stub);
__ MultiPop(kSavedRegs);
+ __ SmiUntag(a0);
}
__ Branch(&done);
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index 708df39..691df94 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -50,9 +50,6 @@
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
-#ifndef WIN32
-#include <stdint.h>
-#endif
#include "v8.h"
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 9da8e54..d59820f 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -1333,8 +1333,7 @@
scope()->is_function_scope() &&
info->num_literals() == 0) {
FastNewClosureStub stub(info->language_mode(), info->is_generator());
- __ li(a0, Operand(info));
- __ push(a0);
+ __ li(a2, Operand(info));
__ CallStub(&stub);
} else {
__ li(a0, Operand(info));
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index aa56d72..80794c8 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -409,7 +409,7 @@
} else if (r.IsDouble()) {
Abort(kEmitLoadRegisterUnsupportedDoubleImmediate);
} else {
- ASSERT(r.IsTagged());
+ ASSERT(r.IsSmiOrTagged());
__ LoadObject(scratch, literal);
}
return scratch;
@@ -1398,10 +1398,7 @@
instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
if (right_op->IsConstantOperand() && !can_overflow) {
- // Use optimized code for specific constants.
- int32_t constant = ToRepresentation(
- LConstantOperand::cast(right_op),
- instr->hydrogen()->right()->representation());
+ int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
if (bailout_on_minus_zero && (constant < 0)) {
// The case of a null constant will be handled separately.
@@ -4067,6 +4064,16 @@
}
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+ Register function = ToRegister(instr->function());
+ Register code_object = ToRegister(instr->code_object());
+ __ Addu(code_object, code_object,
+ Operand(Code::kHeaderSize - kHeapObjectTag));
+ __ sw(code_object,
+ FieldMemOperand(function, JSFunction::kCodeEntryOffset));
+}
+
+
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
@@ -5407,8 +5414,7 @@
if (!pretenure && instr->hydrogen()->has_no_literals()) {
FastNewClosureStub stub(instr->hydrogen()->language_mode(),
instr->hydrogen()->is_generator());
- __ li(a1, Operand(instr->hydrogen()->shared_info()));
- __ push(a1);
+ __ li(a2, Operand(instr->hydrogen()->shared_info()));
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
} else {
__ li(a2, Operand(instr->hydrogen()->shared_info()));
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 8025d8e..b11c9c2 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -265,6 +265,14 @@
}
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+ stream->Add(" = ");
+ function()->PrintTo(stream);
+ stream->Add(".code_entry = ");
+ code_object()->PrintTo(stream);
+}
+
+
void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
@@ -1079,6 +1087,14 @@
}
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+ HStoreCodeEntry* store_code_entry) {
+ LOperand* function = UseRegister(store_code_entry->function());
+ LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+ return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
HInnerAllocatedObject* inner_object) {
LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1828,11 +1844,12 @@
ASSERT(to.IsInteger32());
LOperand* value = NULL;
LInstruction* res = NULL;
- if (instr->value()->type().IsSmi()) {
- value = UseRegisterAtStart(instr->value());
+ HValue* val = instr->value();
+ if (val->type().IsSmi() || val->representation().IsSmi()) {
+ value = UseRegisterAtStart(val);
res = DefineAsRegister(new(zone()) LSmiUntag(value, false));
} else {
- value = UseRegister(instr->value());
+ value = UseRegister(val);
LOperand* temp1 = TempRegister();
LOperand* temp2 = instr->CanTruncateToInt32() ? TempRegister()
: NULL;
@@ -2361,8 +2378,7 @@
LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
- HEnvironment* env = current_block_->last_environment();
- instr->ReplayEnvironment(env);
+ instr->ReplayEnvironment(current_block_->last_environment());
// There are no real uses of a captured object.
return NULL;
@@ -2410,20 +2426,7 @@
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
- HEnvironment* env = current_block_->last_environment();
- ASSERT(env != NULL);
-
- env->set_ast_id(instr->ast_id());
-
- env->Drop(instr->pop_count());
- for (int i = instr->values()->length() - 1; i >= 0; --i) {
- HValue* value = instr->values()->at(i);
- if (instr->HasAssignedIndexAt(i)) {
- env->Bind(instr->GetAssignedIndexAt(i), value);
- } else {
- env->Push(value);
- }
- }
+ instr->ReplayEnvironment(current_block_->last_environment());
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index 479f75a..6498943 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -161,6 +161,7 @@
V(SmiTag) \
V(SmiUntag) \
V(StackCheck) \
+ V(StoreCodeEntry) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
V(StoreGlobalGeneric) \
@@ -1731,7 +1732,24 @@
};
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+ LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+ inputs_[0] = function;
+ temps_[0] = code_object;
+ }
+
+ LOperand* function() { return inputs_[0]; }
+ LOperand* code_object() { return temps_[0]; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+ DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
public:
explicit LInnerAllocatedObject(LOperand* base_object) {
inputs_[0] = base_object;
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index 5becf7c..ace7323 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -3963,7 +3963,6 @@
ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset_from_fp) {
ExternalReference next_address =
ExternalReference::handle_scope_next_address(isolate());
@@ -3992,14 +3991,6 @@
PopSafepointRegisters();
}
- // The O32 ABI requires us to pass a pointer in a0 where the returned struct
- // (4 bytes) will be placed. This is also built into the Simulator.
- // Set up the pointer to the returned value (a0). It was allocated in
- // EnterExitFrame.
- if (returns_handle) {
- addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset);
- }
-
Label profiler_disabled;
Label end_profiler_check;
bool* is_profiling_flag =
@@ -4039,19 +4030,6 @@
Label leave_exit_frame;
Label return_value_loaded;
- if (returns_handle) {
- Label load_return_value;
-
- // As mentioned above, on MIPS a pointer is returned - we need to
- // dereference it to get the actual return value (which is also a pointer).
- lw(v0, MemOperand(v0));
-
- Branch(&load_return_value, eq, v0, Operand(zero_reg));
- // Dereference returned value.
- lw(v0, MemOperand(v0));
- Branch(&return_value_loaded);
- bind(&load_return_value);
- }
// Load value from ReturnValue.
lw(v0, MemOperand(fp, return_value_offset_from_fp*kPointerSize));
bind(&return_value_loaded);
@@ -4477,6 +4455,11 @@
RecordComment("Abort message: ");
RecordComment(msg);
}
+
+ if (FLAG_trap_on_abort) {
+ stop(msg);
+ return;
+ }
#endif
li(a0, Operand(p0));
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 3b3cfdb..9605038 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -1233,7 +1233,6 @@
ExternalReference thunk_ref,
Register thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset_from_fp);
// Jump to the builtin routine.
diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc
index 914a758..ea8b659 100644
--- a/src/mips/simulator-mips.cc
+++ b/src/mips/simulator-mips.cc
@@ -1387,27 +1387,12 @@
// This signature supports direct call in to API function native callback
// (refer to InvocationCallback in v8.h).
-// NOTE: the O32 abi requires a0 to hold a special pointer when returning a
-// struct from the function (which is currently the case). This means we pass
-// the first argument in a1 instead of a0.
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
-// Here, we pass the first argument in a0, because this function
-// does not return a struct.
-typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingApiCall)(
- int32_t arg0, int32_t arg1);
-typedef void (*SimulatorRuntimeProfilingApiCallNew)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeDirectApiCall)(int32_t arg0);
+typedef void (*SimulatorRuntimeProfilingApiCall)(int32_t arg0, int32_t arg1);
// This signature supports direct call to accessor getter callback.
-// See comment at SimulatorRuntimeDirectApiCall.
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeDirectGetterCall)(int32_t arg0,
- int32_t arg1);
-// See comment at SimulatorRuntimeDirectApiCallNew.
-typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0,
- int32_t arg1);
-typedef v8::Handle<v8::Value> (*SimulatorRuntimeProfilingGetterCall)(
- int32_t arg0, int32_t arg1, int32_t arg2);
-typedef void (*SimulatorRuntimeProfilingGetterCallNew)(
+typedef void (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1);
+typedef void (*SimulatorRuntimeProfilingGetterCall)(
int32_t arg0, int32_t arg1, int32_t arg2);
// Software interrupt instructions are used by the simulator to call into the
@@ -1553,102 +1538,41 @@
break;
}
}
- } else if (
- redirection->type() == ExternalReference::DIRECT_API_CALL ||
- redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) {
- if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
- // See comment at type definition of SimulatorRuntimeDirectApiCall
- // for explanation of register usage.
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x\n",
- reinterpret_cast<void*>(external), arg1);
- }
- SimulatorRuntimeDirectApiCall target =
- reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
- v8::Handle<v8::Value> result = target(arg1);
- *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
- set_register(v0, arg0);
- } else {
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x\n",
- reinterpret_cast<void*>(external), arg0);
- }
- SimulatorRuntimeDirectApiCallNew target =
- reinterpret_cast<SimulatorRuntimeDirectApiCallNew>(external);
- target(arg0);
+ } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) {
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x\n",
+ reinterpret_cast<void*>(external), arg0);
}
+ SimulatorRuntimeDirectApiCall target =
+ reinterpret_cast<SimulatorRuntimeDirectApiCall>(external);
+ target(arg0);
} else if (
- redirection->type() == ExternalReference::PROFILING_API_CALL ||
- redirection->type() == ExternalReference::PROFILING_API_CALL_NEW) {
- if (redirection->type() == ExternalReference::PROFILING_API_CALL) {
- // See comment at type definition of SimulatorRuntimeDirectApiCall
- // for explanation of register usage.
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x\n",
- reinterpret_cast<void*>(external), arg1, arg2);
- }
- SimulatorRuntimeProfilingApiCall target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
- v8::Handle<v8::Value> result = target(arg1, arg2);
- *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
- set_register(v0, arg0);
- } else {
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x\n",
- reinterpret_cast<void*>(external), arg0, arg1);
- }
- SimulatorRuntimeProfilingApiCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingApiCallNew>(external);
- target(arg0, arg1);
+ redirection->type() == ExternalReference::PROFILING_API_CALL) {
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x\n",
+ reinterpret_cast<void*>(external), arg0, arg1);
}
+ SimulatorRuntimeProfilingApiCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingApiCall>(external);
+ target(arg0, arg1);
} else if (
- redirection->type() == ExternalReference::DIRECT_GETTER_CALL ||
- redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) {
- if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
- // See comment at type definition of SimulatorRuntimeDirectGetterCall
- // for explanation of register usage.
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x\n",
- reinterpret_cast<void*>(external), arg1, arg2);
- }
- SimulatorRuntimeDirectGetterCall target =
- reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
- v8::Handle<v8::Value> result = target(arg1, arg2);
- *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
- set_register(v0, arg0);
- } else {
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x\n",
- reinterpret_cast<void*>(external), arg0, arg1);
- }
- SimulatorRuntimeDirectGetterCallNew target =
- reinterpret_cast<SimulatorRuntimeDirectGetterCallNew>(external);
- target(arg0, arg1);
+ redirection->type() == ExternalReference::DIRECT_GETTER_CALL) {
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x\n",
+ reinterpret_cast<void*>(external), arg0, arg1);
}
+ SimulatorRuntimeDirectGetterCall target =
+ reinterpret_cast<SimulatorRuntimeDirectGetterCall>(external);
+ target(arg0, arg1);
} else if (
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL ||
- redirection->type() == ExternalReference::PROFILING_GETTER_CALL_NEW) {
- if (redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
- // See comment at type definition of SimulatorRuntimeProfilingGetterCall
- // for explanation of register usage.
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x %08x\n",
- reinterpret_cast<void*>(external), arg1, arg2, arg3);
- }
- SimulatorRuntimeProfilingGetterCall target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
- v8::Handle<v8::Value> result = target(arg1, arg2, arg3);
- *(reinterpret_cast<int*>(arg0)) = reinterpret_cast<int32_t>(*result);
- set_register(v0, arg0);
- } else {
- if (::v8::internal::FLAG_trace_sim) {
- PrintF("Call to host function at %p args %08x %08x %08x\n",
- reinterpret_cast<void*>(external), arg0, arg1, arg2);
- }
- SimulatorRuntimeProfilingGetterCallNew target =
- reinterpret_cast<SimulatorRuntimeProfilingGetterCallNew>(external);
- target(arg0, arg1, arg2);
+ redirection->type() == ExternalReference::PROFILING_GETTER_CALL) {
+ if (::v8::internal::FLAG_trace_sim) {
+ PrintF("Call to host function at %p args %08x %08x %08x\n",
+ reinterpret_cast<void*>(external), arg0, arg1, arg2);
}
+ SimulatorRuntimeProfilingGetterCall target =
+ reinterpret_cast<SimulatorRuntimeProfilingGetterCall>(external);
+ target(arg0, arg1, arg2);
} else {
SimulatorRuntimeCall target =
reinterpret_cast<SimulatorRuntimeCall>(external);
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index b84aca7..ccbe86a 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -879,51 +879,31 @@
FrameScope frame_scope(masm, StackFrame::MANUAL);
__ EnterExitFrame(false, kApiStackSpace);
- // NOTE: the O32 abi requires a0 to hold a special pointer when returning a
- // struct from the function (which is currently the case). This means we pass
- // the first argument in a1 instead of a0, if returns_handle is true.
- // CallApiFunctionAndReturn will set up a0.
-
- Address function_address = v8::ToCData<Address>(api_call_info->callback());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
-
- Register first_arg = returns_handle ? a1 : a0;
- Register second_arg = returns_handle ? a2 : a1;
-
- // first_arg = v8::Arguments&
+ // a0 = v8::Arguments&
// Arguments is built at sp + 1 (sp is a reserved spot for ra).
- __ Addu(first_arg, sp, kPointerSize);
+ __ Addu(a0, sp, kPointerSize);
// v8::Arguments::implicit_args_
- __ sw(a2, MemOperand(first_arg, 0 * kPointerSize));
+ __ sw(a2, MemOperand(a0, 0 * kPointerSize));
// v8::Arguments::values_
__ Addu(t0, a2, Operand(argc * kPointerSize));
- __ sw(t0, MemOperand(first_arg, 1 * kPointerSize));
+ __ sw(t0, MemOperand(a0, 1 * kPointerSize));
// v8::Arguments::length_ = argc
__ li(t0, Operand(argc));
- __ sw(t0, MemOperand(first_arg, 2 * kPointerSize));
+ __ sw(t0, MemOperand(a0, 2 * kPointerSize));
// v8::Arguments::is_construct_call = 0
- __ sw(zero_reg, MemOperand(first_arg, 3 * kPointerSize));
+ __ sw(zero_reg, MemOperand(a0, 3 * kPointerSize));
const int kStackUnwindSpace = argc + kFastApiCallArguments + 1;
+ Address function_address = v8::ToCData<Address>(api_call_info->callback());
ApiFunction fun(function_address);
- ExternalReference::Type type =
- returns_handle ?
- ExternalReference::DIRECT_API_CALL :
- ExternalReference::DIRECT_API_CALL_NEW;
+ ExternalReference::Type type = ExternalReference::DIRECT_API_CALL;
ExternalReference ref =
ExternalReference(&fun,
type,
masm->isolate());
-
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
- ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_API_CALL :
- ExternalReference::PROFILING_API_CALL_NEW;
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
+ ExternalReference::Type thunk_type = ExternalReference::PROFILING_API_CALL;
ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
masm->isolate());
@@ -932,9 +912,8 @@
__ CallApiFunctionAndReturn(ref,
function_address,
thunk_ref,
- second_arg,
+ a1,
kStackUnwindSpace,
- returns_handle,
kFastApiCallArguments + 1);
}
@@ -1419,21 +1398,8 @@
__ sw(scratch4(), MemOperand(sp, 1 * kPointerSize));
__ sw(name(), MemOperand(sp, 0 * kPointerSize));
- Address getter_address = v8::ToCData<Address>(callback->getter());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(isolate(), getter_address);
-
- Register first_arg = returns_handle ? a1 : a0;
- Register second_arg = returns_handle ? a2 : a1;
- Register third_arg = returns_handle ? a3 : a2;
-
__ mov(a2, scratch2()); // Saved in case scratch2 == a1.
- __ mov(first_arg, sp); // (first argument - see note below) = Handle<Name>
-
- // NOTE: the O32 abi requires a0 to hold a special pointer when returning a
- // struct from the function (which is currently the case). This means we pass
- // the arguments in a1-a2 instead of a0-a1, if returns_handle is true.
- // CallApiFunctionAndReturn will set up a0.
+ __ mov(a0, sp); // (first argument - a0) = Handle<Name>
const int kApiStackSpace = 1;
FrameScope frame_scope(masm(), StackFrame::MANUAL);
@@ -1442,34 +1408,26 @@
// Create AccessorInfo instance on the stack above the exit frame with
// scratch2 (internal::Object** args_) as the data.
__ sw(a2, MemOperand(sp, kPointerSize));
- // (second argument - see note above) = AccessorInfo&
- __ Addu(second_arg, sp, kPointerSize);
+ // (second argument - a1) = AccessorInfo&
+ __ Addu(a1, sp, kPointerSize);
const int kStackUnwindSpace = kFastApiCallArguments + 1;
-
+ Address getter_address = v8::ToCData<Address>(callback->getter());
ApiFunction fun(getter_address);
- ExternalReference::Type type =
- returns_handle ?
- ExternalReference::DIRECT_GETTER_CALL :
- ExternalReference::DIRECT_GETTER_CALL_NEW;
+ ExternalReference::Type type = ExternalReference::DIRECT_GETTER_CALL;
ExternalReference ref = ExternalReference(&fun, type, isolate());
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
ExternalReference::Type thunk_type =
- returns_handle ?
- ExternalReference::PROFILING_GETTER_CALL :
- ExternalReference::PROFILING_GETTER_CALL_NEW;
+ ExternalReference::PROFILING_GETTER_CALL;
ApiFunction thunk_fun(thunk_address);
ExternalReference thunk_ref = ExternalReference(&thunk_fun, thunk_type,
isolate());
__ CallApiFunctionAndReturn(ref,
getter_address,
thunk_ref,
- third_arg,
+ a2,
kStackUnwindSpace,
- returns_handle,
5);
}
@@ -1803,25 +1761,25 @@
&call_builtin,
DONT_DO_SMI_CHECK);
- // Get the array's length into r0 and calculate new length.
- __ lw(a0, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ // Get the array's length into v0 and calculate new length.
+ __ lw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
STATIC_ASSERT(kSmiTagSize == 1);
STATIC_ASSERT(kSmiTag == 0);
- __ Addu(a0, a0, Operand(Smi::FromInt(argc)));
+ __ Addu(v0, v0, Operand(Smi::FromInt(argc)));
// Get the elements' length.
__ lw(t0, FieldMemOperand(elements, FixedArray::kLengthOffset));
// Check if we could survive without allocation.
- __ Branch(&call_builtin, gt, a0, Operand(t0));
+ __ Branch(&call_builtin, gt, v0, Operand(t0));
__ lw(t0, MemOperand(sp, (argc - 1) * kPointerSize));
__ StoreNumberToDoubleElements(
- t0, a0, elements, a3, t1, a2, t5,
+ t0, v0, elements, a3, t1, a2, t5,
&call_builtin, argc * kDoubleSize);
// Save new length.
- __ sw(a0, FieldMemOperand(receiver, JSArray::kLengthOffset));
+ __ sw(v0, FieldMemOperand(receiver, JSArray::kLengthOffset));
// Check for a smi.
__ DropAndRet(argc + 1);
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 22d1ac3..b165ad4 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -1312,7 +1312,7 @@
bool JSObject::ShouldTrackAllocationInfo() {
- if (map()->CanTrackAllocationSite()) {
+ if (AllocationSite::CanTrack(map()->instance_type())) {
if (!IsJSArray()) {
return true;
}
@@ -1349,6 +1349,11 @@
}
+inline bool AllocationSite::CanTrack(InstanceType type) {
+ return type == JS_ARRAY_TYPE;
+}
+
+
MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
ValidateElements();
ElementsKind elements_kind = map()->elements_kind();
@@ -3593,11 +3598,6 @@
}
-inline bool Map::CanTrackAllocationSite() {
- return instance_type() == JS_ARRAY_TYPE;
-}
-
-
void Map::set_owns_descriptors(bool is_shared) {
set_bit_field3(OwnsDescriptors::update(bit_field3(), is_shared));
}
@@ -4576,6 +4576,8 @@
kNeedsAccessCheckBit)
BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
kReadOnlyPrototypeBit)
+BOOL_ACCESSORS(FunctionTemplateInfo, flag, remove_prototype,
+ kRemovePrototypeBit)
BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
kIsExpressionBit)
BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
diff --git a/src/objects.cc b/src/objects.cc
index d8a05eb..3e4601a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -368,7 +368,8 @@
}
ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(structure);
Object* fun_obj = data->getter();
- v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
+ v8::AccessorGetterCallback call_fun =
+ v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
if (call_fun == NULL) return isolate->heap()->undefined_value();
HandleScope scope(isolate);
JSObject* self = JSObject::cast(receiver);
@@ -2772,8 +2773,8 @@
if (!interceptor->setter()->IsUndefined()) {
LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name));
PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
- v8::NamedPropertySetter setter =
- v8::ToCData<v8::NamedPropertySetter>(interceptor->setter());
+ v8::NamedPropertySetterCallback setter =
+ v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter());
Handle<Object> value_unhole(value->IsTheHole() ?
isolate->heap()->undefined_value() :
value,
@@ -2874,7 +2875,8 @@
// TODO(rossberg): Support symbols in the API.
if (name->IsSymbol()) return value;
Object* call_obj = data->setter();
- v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);
+ v8::AccessorSetterCallback call_fun =
+ v8::ToCData<v8::AccessorSetterCallback>(call_obj);
if (call_fun == NULL) return value;
Handle<String> key(String::cast(name));
LOG(isolate, ApiNamedPropertyAccess("store", this, name));
@@ -4230,8 +4232,8 @@
Handle<String> name_handle(String::cast(name));
PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
if (!interceptor->query()->IsUndefined()) {
- v8::NamedPropertyQuery query =
- v8::ToCData<v8::NamedPropertyQuery>(interceptor->query());
+ v8::NamedPropertyQueryCallback query =
+ v8::ToCData<v8::NamedPropertyQueryCallback>(interceptor->query());
LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name));
v8::Handle<v8::Integer> result =
@@ -4241,8 +4243,8 @@
return static_cast<PropertyAttributes>(result->Int32Value());
}
} else if (!interceptor->getter()->IsUndefined()) {
- v8::NamedPropertyGetter getter =
- v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
+ v8::NamedPropertyGetterCallback getter =
+ v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-get-has", this, name));
v8::Handle<v8::Value> result =
@@ -4362,16 +4364,16 @@
Handle<JSObject> holder(this);
PropertyCallbackArguments args(isolate, interceptor->data(), receiver, this);
if (!interceptor->query()->IsUndefined()) {
- v8::IndexedPropertyQuery query =
- v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query());
+ v8::IndexedPropertyQueryCallback query =
+ v8::ToCData<v8::IndexedPropertyQueryCallback>(interceptor->query());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-has", this, index));
v8::Handle<v8::Integer> result = args.Call(query, index);
if (!result.IsEmpty())
return static_cast<PropertyAttributes>(result->Int32Value());
} else if (!interceptor->getter()->IsUndefined()) {
- v8::IndexedPropertyGetter getter =
- v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
+ v8::IndexedPropertyGetterCallback getter =
+ v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-get-has", this, index));
v8::Handle<v8::Value> result = args.Call(getter, index);
@@ -5038,8 +5040,8 @@
Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor());
if (!interceptor->deleter()->IsUndefined()) {
- v8::NamedPropertyDeleter deleter =
- v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter());
+ v8::NamedPropertyDeleterCallback deleter =
+ v8::ToCData<v8::NamedPropertyDeleterCallback>(interceptor->deleter());
LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-delete", *object, *name));
PropertyCallbackArguments args(
@@ -5071,8 +5073,8 @@
HandleScope scope(isolate);
Handle<InterceptorInfo> interceptor(GetIndexedInterceptor());
if (interceptor->deleter()->IsUndefined()) return heap->false_value();
- v8::IndexedPropertyDeleter deleter =
- v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter());
+ v8::IndexedPropertyDeleterCallback deleter =
+ v8::ToCData<v8::IndexedPropertyDeleterCallback>(interceptor->deleter());
Handle<JSObject> this_handle(this);
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index));
@@ -11577,8 +11579,8 @@
Handle<JSObject> this_handle(this);
Handle<Object> value_handle(value, isolate);
if (!interceptor->setter()->IsUndefined()) {
- v8::IndexedPropertySetter setter =
- v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter());
+ v8::IndexedPropertySetterCallback setter =
+ v8::ToCData<v8::IndexedPropertySetterCallback>(interceptor->setter());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-set", this, index));
PropertyCallbackArguments args(isolate, interceptor->data(), this, this);
@@ -11611,7 +11613,8 @@
Handle<ExecutableAccessorInfo> data(
ExecutableAccessorInfo::cast(structure));
Object* fun_obj = data->getter();
- v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj);
+ v8::AccessorGetterCallback call_fun =
+ v8::ToCData<v8::AccessorGetterCallback>(fun_obj);
if (call_fun == NULL) return isolate->heap()->undefined_value();
HandleScope scope(isolate);
Handle<JSObject> self(JSObject::cast(receiver));
@@ -11676,7 +11679,8 @@
Handle<ExecutableAccessorInfo> data(
ExecutableAccessorInfo::cast(structure));
Object* call_obj = data->setter();
- v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj);
+ v8::AccessorSetterCallback call_fun =
+ v8::ToCData<v8::AccessorSetterCallback>(call_obj);
if (call_fun == NULL) return value;
Handle<Object> number = isolate->factory()->NewNumberFromUint(index);
Handle<String> key(isolate->factory()->NumberToString(number));
@@ -12585,8 +12589,8 @@
Handle<Object> this_handle(receiver, isolate);
Handle<JSObject> holder_handle(this, isolate);
if (!interceptor->getter()->IsUndefined()) {
- v8::IndexedPropertyGetter getter =
- v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
+ v8::IndexedPropertyGetterCallback getter =
+ v8::ToCData<v8::IndexedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
ApiIndexedPropertyAccess("interceptor-indexed-get", this, index));
PropertyCallbackArguments
@@ -12890,8 +12894,8 @@
Handle<String> name_handle(String::cast(name));
if (!interceptor->getter()->IsUndefined()) {
- v8::NamedPropertyGetter getter =
- v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter());
+ v8::NamedPropertyGetterCallback getter =
+ v8::ToCData<v8::NamedPropertyGetterCallback>(interceptor->getter());
LOG(isolate,
ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name));
PropertyCallbackArguments
diff --git a/src/objects.h b/src/objects.h
index 411908c..988f1ab 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -5776,7 +5776,6 @@
set_bit_field3(EnumLengthBits::update(bit_field3(), length));
}
- inline bool CanTrackAllocationSite();
inline bool owns_descriptors();
inline void set_owns_descriptors(bool is_shared);
inline bool is_observed();
@@ -7845,6 +7844,7 @@
static inline AllocationSiteMode GetMode(
ElementsKind boilerplate_elements_kind);
static inline AllocationSiteMode GetMode(ElementsKind from, ElementsKind to);
+ static inline bool CanTrack(InstanceType type);
static const int kTransitionInfoOffset = HeapObject::kHeaderSize;
static const int kWeakNextOffset = kTransitionInfoOffset + kPointerSize;
@@ -9874,6 +9874,7 @@
// requires access check.
DECL_BOOLEAN_ACCESSORS(needs_access_check)
DECL_BOOLEAN_ACCESSORS(read_only_prototype)
+ DECL_BOOLEAN_ACCESSORS(remove_prototype)
static inline FunctionTemplateInfo* cast(Object* obj);
@@ -9909,6 +9910,7 @@
static const int kUndetectableBit = 1;
static const int kNeedsAccessCheckBit = 2;
static const int kReadOnlyPrototypeBit = 3;
+ static const int kRemovePrototypeBit = 4;
DISALLOW_IMPLICIT_CONSTRUCTORS(FunctionTemplateInfo);
};
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
deleted file mode 100644
index dc7adb6..0000000
--- a/src/platform-nullos.cc
+++ /dev/null
@@ -1,558 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Platform specific code for NULLOS goes here
-
-// Minimal include to get access to abort, fprintf and friends for bootstrapping
-// messages.
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "v8.h"
-
-#include "platform.h"
-#include "vm-state-inl.h"
-
-
-namespace v8 {
-namespace internal {
-
-// Give V8 the opportunity to override the default ceil behaviour.
-double ceiling(double x) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-// Give V8 the opportunity to override the default fmod behavior.
-double modulo(double x, double y) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-double fast_sin(double x) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-double fast_cos(double x) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-double fast_tan(double x) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-double fast_log(double x) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-// Initialize OS class early in the V8 startup.
-void OS::SetUp() {
- // Seed the random number generator.
- UNIMPLEMENTED();
-}
-
-
-void OS::PostSetUp() {
- UNIMPLEMENTED();
-}
-
-
-void OS::TearDown() {
- UNIMPLEMENTED();
-}
-
-
-// Returns the accumulated user time for thread.
-int OS::GetUserTime(uint32_t* secs, uint32_t* usecs) {
- UNIMPLEMENTED();
- *secs = 0;
- *usecs = 0;
- return 0;
-}
-
-
-// Returns current time as the number of milliseconds since
-// 00:00:00 UTC, January 1, 1970.
-double OS::TimeCurrentMillis() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-// Returns ticks in microsecond resolution.
-int64_t OS::Ticks() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-// Returns a string identifying the current timezone taking into
-// account daylight saving.
-const char* OS::LocalTimezone(double time) {
- UNIMPLEMENTED();
- return "<none>";
-}
-
-
-// Returns the daylight savings offset in milliseconds for the given time.
-double OS::DaylightSavingsOffset(double time) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-int OS::GetLastError() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-// Returns the local time offset in milliseconds east of UTC without
-// taking daylight savings time into account.
-double OS::LocalTimeOffset() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-// Print (debug) message to console.
-void OS::Print(const char* format, ...) {
- UNIMPLEMENTED();
-}
-
-
-// Print (debug) message to console.
-void OS::VPrint(const char* format, va_list args) {
- // Minimalistic implementation for bootstrapping.
- vfprintf(stdout, format, args);
-}
-
-
-void OS::FPrint(FILE* out, const char* format, ...) {
- va_list args;
- va_start(args, format);
- VFPrint(out, format, args);
- va_end(args);
-}
-
-
-void OS::VFPrint(FILE* out, const char* format, va_list args) {
- vfprintf(out, format, args);
-}
-
-
-// Print error message to console.
-void OS::PrintError(const char* format, ...) {
- // Minimalistic implementation for bootstrapping.
- va_list args;
- va_start(args, format);
- VPrintError(format, args);
- va_end(args);
-}
-
-
-// Print error message to console.
-void OS::VPrintError(const char* format, va_list args) {
- // Minimalistic implementation for bootstrapping.
- vfprintf(stderr, format, args);
-}
-
-
-int OS::SNPrintF(char* str, size_t size, const char* format, ...) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-int OS::VSNPrintF(char* str, size_t size, const char* format, va_list args) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-uint64_t OS::CpuFeaturesImpliedByPlatform() {
- return 0;
-}
-
-
-double OS::nan_value() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-bool OS::ArmUsingHardFloat() {
- UNIMPLEMENTED();
-}
-
-
-bool OS::IsOutsideAllocatedSpace(void* address) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-size_t OS::AllocateAlignment() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-void* OS::Allocate(const size_t requested,
- size_t* allocated,
- bool executable) {
- UNIMPLEMENTED();
- return NULL;
-}
-
-
-void OS::Free(void* buf, const size_t length) {
- // TODO(1240712): potential system call return value which is ignored here.
- UNIMPLEMENTED();
-}
-
-
-void OS::Guard(void* address, const size_t size) {
- UNIMPLEMENTED();
-}
-
-
-void OS::Sleep(int milliseconds) {
- UNIMPLEMENTED();
-}
-
-
-int OS::NumberOfCores() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-void OS::Abort() {
- // Minimalistic implementation for bootstrapping.
- abort();
-}
-
-
-void OS::DebugBreak() {
- UNIMPLEMENTED();
-}
-
-
-void OS::DumpBacktrace() {
- // Currently unsupported.
-}
-
-
-OS::MemoryMappedFile* OS::MemoryMappedFile::open(const char* name) {
- UNIMPLEMENTED();
- return NULL;
-}
-
-
-OS::MemoryMappedFile* OS::MemoryMappedFile::create(const char* name, int size,
- void* initial) {
- UNIMPLEMENTED();
- return NULL;
-}
-
-
-void OS::LogSharedLibraryAddresses() {
- UNIMPLEMENTED();
-}
-
-
-void OS::SignalCodeMovingGC() {
- UNIMPLEMENTED();
-}
-
-
-int OS::StackWalk(Vector<OS::StackFrame> frames) {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-VirtualMemory::VirtualMemory() {
- UNIMPLEMENTED();
-}
-
-
-VirtualMemory::VirtualMemory(size_t size) {
- UNIMPLEMENTED();
-}
-
-
-VirtualMemory::VirtualMemory(size_t size, void* address_hint) {
- UNIMPLEMENTED();
-}
-
-
-VirtualMemory::~VirtualMemory() {
- UNIMPLEMENTED();
-}
-
-
-bool VirtualMemory::IsReserved() {
- UNIMPLEMENTED();
- return false;
-}
-
-
-void VirtualMemory::Reset() {
- UNIMPLEMENTED();
-}
-
-
-bool VirtualMemory::Commit(void* address, size_t size, bool executable) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-bool VirtualMemory::Uncommit(void* address, size_t size) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-bool VirtualMemory::Guard(void* address) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-void* VirtualMemory::ReserveRegion(size_t size) {
- UNIMPLEMENTED();
- return NULL;
-}
-
-
-bool VirtualMemory::CommitRegion(void* base, size_t size, bool is_executable) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-bool VirtualMemory::UncommitRegion(void* base, size_t size) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-bool VirtualMemory::ReleaseRegion(void* base, size_t size) {
- UNIMPLEMENTED();
- return false;
-}
-
-
-bool VirtualMemory::HasLazyCommits() {
- // TODO(alph): implement for the platform.
- return false;
-}
-
-
-class Thread::PlatformData : public Malloced {
- public:
- PlatformData() {
- UNIMPLEMENTED();
- }
-
- void* pd_data_;
-};
-
-
-Thread::Thread(const Options& options)
- : data_(new PlatformData()),
- stack_size_(options.stack_size),
- start_semaphore_(NULL) {
- set_name(options.name);
- UNIMPLEMENTED();
-}
-
-
-Thread::Thread(const char* name)
- : data_(new PlatformData()),
- stack_size_(0) {
- set_name(name);
- UNIMPLEMENTED();
-}
-
-
-Thread::~Thread() {
- delete data_;
- UNIMPLEMENTED();
-}
-
-
-void Thread::set_name(const char* name) {
- strncpy(name_, name, sizeof(name_));
- name_[sizeof(name_) - 1] = '\0';
-}
-
-
-void Thread::Start() {
- UNIMPLEMENTED();
-}
-
-
-void Thread::Join() {
- UNIMPLEMENTED();
-}
-
-
-Thread::LocalStorageKey Thread::CreateThreadLocalKey() {
- UNIMPLEMENTED();
- return static_cast<LocalStorageKey>(0);
-}
-
-
-void Thread::DeleteThreadLocalKey(LocalStorageKey key) {
- UNIMPLEMENTED();
-}
-
-
-void* Thread::GetThreadLocal(LocalStorageKey key) {
- UNIMPLEMENTED();
- return NULL;
-}
-
-
-void Thread::SetThreadLocal(LocalStorageKey key, void* value) {
- UNIMPLEMENTED();
-}
-
-
-void Thread::YieldCPU() {
- UNIMPLEMENTED();
-}
-
-
-class NullMutex : public Mutex {
- public:
- NullMutex() : data_(NULL) {
- UNIMPLEMENTED();
- }
-
- virtual ~NullMutex() {
- UNIMPLEMENTED();
- }
-
- virtual int Lock() {
- UNIMPLEMENTED();
- return 0;
- }
-
- virtual int Unlock() {
- UNIMPLEMENTED();
- return 0;
- }
-
- private:
- void* data_;
-};
-
-
-Mutex* OS::CreateMutex() {
- UNIMPLEMENTED();
- return new NullMutex();
-}
-
-
-class NullSemaphore : public Semaphore {
- public:
- explicit NullSemaphore(int count) : data_(NULL) {
- UNIMPLEMENTED();
- }
-
- virtual ~NullSemaphore() {
- UNIMPLEMENTED();
- }
-
- virtual void Wait() {
- UNIMPLEMENTED();
- }
-
- virtual void Signal() {
- UNIMPLEMENTED();
- }
- private:
- void* data_;
-};
-
-
-Semaphore* OS::CreateSemaphore(int count) {
- UNIMPLEMENTED();
- return new NullSemaphore(count);
-}
-
-
-class ProfileSampler::PlatformData : public Malloced {
- public:
- PlatformData() {
- UNIMPLEMENTED();
- }
-};
-
-
-ProfileSampler::ProfileSampler(int interval) {
- UNIMPLEMENTED();
- // Shared setup follows.
- data_ = new PlatformData();
- interval_ = interval;
- active_ = false;
-}
-
-
-ProfileSampler::~ProfileSampler() {
- UNIMPLEMENTED();
- // Shared tear down follows.
- delete data_;
-}
-
-
-void ProfileSampler::Start() {
- UNIMPLEMENTED();
-}
-
-
-void ProfileSampler::Stop() {
- UNIMPLEMENTED();
-}
-
-
-} } // namespace v8::internal
diff --git a/src/platform.h b/src/platform.h
index 384ae15..10a7e2c 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -44,6 +44,12 @@
#ifndef V8_PLATFORM_H_
#define V8_PLATFORM_H_
+#include <cstdarg>
+
+#include "lazy-instance.h"
+#include "utils.h"
+#include "v8globals.h"
+
#ifdef __sun
# ifndef signbit
namespace std {
@@ -55,19 +61,12 @@
// GCC specific stuff
#ifdef __GNUC__
-// Needed for va_list on at least MinGW and Android.
-#include <stdarg.h>
-
#define __GNUC_VERSION__ (__GNUC__ * 10000 + __GNUC_MINOR__ * 100)
#endif // __GNUC__
-
-// Windows specific stuff.
-#ifdef WIN32
-
// Microsoft Visual C++ specific stuff.
-#ifdef _MSC_VER
+#if V8_CC_MSVC
#include "win32-headers.h"
#include "win32-math.h"
@@ -76,7 +75,7 @@
inline int lrint(double flt) {
int intgr;
-#if defined(V8_TARGET_ARCH_IA32)
+#if V8_TARGET_ARCH_IA32
__asm {
fld flt
fistp intgr
@@ -91,18 +90,12 @@
return intgr;
}
-#endif // _MSC_VER
+#endif // V8_CC_MSVC
-#ifndef __CYGWIN__
// Random is missing on both Visual Studio and MinGW.
+#if V8_CC_MSVC || V8_CC_MINGW
int random();
-#endif
-
-#endif // WIN32
-
-#include "lazy-instance.h"
-#include "utils.h"
-#include "v8globals.h"
+#endif // V8_CC_MSVC || V8_CC_MINGW
namespace v8 {
namespace internal {
diff --git a/src/preparser.h b/src/preparser.h
index faddecc..9358d6b 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -104,11 +104,6 @@
};
-#ifdef WIN32
-#undef Yield
-#endif
-
-
class PreParser {
public:
enum PreParseResult {
diff --git a/src/profile-generator-inl.h b/src/profile-generator-inl.h
index 6791c88..5a984e5 100644
--- a/src/profile-generator-inl.h
+++ b/src/profile-generator-inl.h
@@ -73,7 +73,6 @@
ProfileNode::ProfileNode(ProfileTree* tree, CodeEntry* entry)
: tree_(tree),
entry_(entry),
- total_ticks_(0),
self_ticks_(0),
children_(CodeEntriesMatch),
id_(tree->next_node_id()) {
diff --git a/src/profile-generator.cc b/src/profile-generator.cc
index 86bd17b..b1dadc1 100644
--- a/src/profile-generator.cc
+++ b/src/profile-generator.cc
@@ -209,19 +209,9 @@
}
-double ProfileNode::GetSelfMillis() const {
- return tree_->TicksToMillis(self_ticks_);
-}
-
-
-double ProfileNode::GetTotalMillis() const {
- return tree_->TicksToMillis(total_ticks_);
-}
-
-
void ProfileNode::Print(int indent) {
- OS::Print("%5u %5u %*c %s%s %d #%d",
- total_ticks_, self_ticks_,
+ OS::Print("%5u %*c %s%s %d #%d",
+ self_ticks_,
indent, ' ',
entry_->name_prefix(),
entry_->name(),
@@ -298,11 +288,6 @@
};
-void ProfileTree::SetTickRatePerMs(double ticks_per_ms) {
- ms_to_ticks_scale_ = ticks_per_ms > 0 ? 1.0 / ticks_per_ms : 1.0;
-}
-
-
class Position {
public:
explicit Position(ProfileNode* node)
@@ -345,33 +330,6 @@
}
-class CalculateTotalTicksCallback {
- public:
- void BeforeTraversingChild(ProfileNode*, ProfileNode*) { }
-
- void AfterAllChildrenTraversed(ProfileNode* node) {
- node->IncreaseTotalTicks(node->self_ticks());
- }
-
- void AfterChildTraversed(ProfileNode* parent, ProfileNode* child) {
- parent->IncreaseTotalTicks(child->total_ticks());
- }
-};
-
-
-void ProfileTree::CalculateTotalTicks() {
- CalculateTotalTicksCallback cb;
- TraverseDepthFirst(&cb);
-}
-
-
-void ProfileTree::ShortPrint() {
- OS::Print("root: %u %u %.2fms %.2fms\n",
- root_->total_ticks(), root_->self_ticks(),
- root_->GetTotalMillis(), root_->GetSelfMillis());
-}
-
-
CpuProfile::CpuProfile(const char* title, unsigned uid, bool record_samples)
: title_(title),
uid_(uid),
@@ -389,19 +347,6 @@
void CpuProfile::CalculateTotalTicksAndSamplingRate() {
end_time_us_ = OS::Ticks();
- top_down_.CalculateTotalTicks();
-
- double duration_ms = (end_time_us_ - start_time_us_) / 1000.;
- if (duration_ms < 1) duration_ms = 1;
- unsigned ticks = top_down_.root()->total_ticks();
- double rate = ticks / duration_ms;
- top_down_.SetTickRatePerMs(rate);
-}
-
-
-void CpuProfile::ShortPrint() {
- OS::Print("top down ");
- top_down_.ShortPrint();
}
diff --git a/src/profile-generator.h b/src/profile-generator.h
index 99aeb1f..a282af2 100644
--- a/src/profile-generator.h
+++ b/src/profile-generator.h
@@ -131,14 +131,10 @@
ProfileNode* FindOrAddChild(CodeEntry* entry);
INLINE(void IncrementSelfTicks()) { ++self_ticks_; }
INLINE(void IncreaseSelfTicks(unsigned amount)) { self_ticks_ += amount; }
- INLINE(void IncreaseTotalTicks(unsigned amount)) { total_ticks_ += amount; }
INLINE(CodeEntry* entry() const) { return entry_; }
INLINE(unsigned self_ticks() const) { return self_ticks_; }
- INLINE(unsigned total_ticks() const) { return total_ticks_; }
INLINE(const List<ProfileNode*>* children() const) { return &children_list_; }
- double GetSelfMillis() const;
- double GetTotalMillis() const;
unsigned id() const { return id_; }
void Print(int indent);
@@ -155,7 +151,6 @@
ProfileTree* tree_;
CodeEntry* entry_;
- unsigned total_ticks_;
unsigned self_ticks_;
// Mapping from CodeEntry* to ProfileNode*
HashMap children_;
@@ -173,17 +168,9 @@
ProfileNode* AddPathFromEnd(const Vector<CodeEntry*>& path);
void AddPathFromStart(const Vector<CodeEntry*>& path);
- void CalculateTotalTicks();
-
- double TicksToMillis(unsigned ticks) const {
- return ticks * ms_to_ticks_scale_;
- }
ProfileNode* root() const { return root_; }
- void SetTickRatePerMs(double ticks_per_ms);
-
unsigned next_node_id() { return next_node_id_++; }
- void ShortPrint();
void Print() {
root_->Print(0);
}
@@ -195,7 +182,6 @@
CodeEntry root_entry_;
unsigned next_node_id_;
ProfileNode* root_;
- double ms_to_ticks_scale_;
DISALLOW_COPY_AND_ASSIGN(ProfileTree);
};
@@ -221,7 +207,6 @@
void UpdateTicksScale();
- void ShortPrint();
void Print();
private:
diff --git a/src/property-details.h b/src/property-details.h
index 6b62ddb..7f44b79 100644
--- a/src/property-details.h
+++ b/src/property-details.h
@@ -148,7 +148,7 @@
bool IsHeapObject() const { return kind_ == kHeapObject; }
bool IsExternal() const { return kind_ == kExternal; }
bool IsSpecialization() const {
- return kind_ == kInteger32 || kind_ == kDouble;
+ return kind_ == kInteger32 || kind_ == kDouble || kind_ == kSmi;
}
const char* Mnemonic() const;
diff --git a/src/runtime.cc b/src/runtime.cc
index 65b1d35..71d792a 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -4722,6 +4722,19 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_IsValidSmi) {
+ HandleScope shs(isolate);
+ ASSERT(args.length() == 1);
+
+ CONVERT_NUMBER_CHECKED(int32_t, number, Int32, args[0]);
+ if (Smi::IsValid(number)) {
+ return isolate->heap()->true_value();
+ } else {
+ return isolate->heap()->false_value();
+ }
+}
+
+
// Returns a single character string where first character equals
// string->Get(index).
static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
@@ -7951,6 +7964,20 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosureFromStubFailure) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(SharedFunctionInfo, shared, 0);
+ Handle<Context> context(isolate->context());
+ PretenureFlag pretenure_flag = NOT_TENURED;
+ Handle<JSFunction> result =
+ isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
+ context,
+ pretenure_flag);
+ return *result;
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_NewClosure) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
diff --git a/src/runtime.h b/src/runtime.h
index e0e0b48..9054fc7 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -221,7 +221,8 @@
F(NumberToRadixString, 2, 1) \
F(NumberToFixed, 2, 1) \
F(NumberToExponential, 2, 1) \
- F(NumberToPrecision, 2, 1)
+ F(NumberToPrecision, 2, 1) \
+ F(IsValidSmi, 1, 1)
#define RUNTIME_FUNCTION_LIST_ALWAYS_2(F) \
@@ -395,6 +396,7 @@
\
/* Statements */ \
F(NewClosure, 3, 1) \
+ F(NewClosureFromStubFailure, 1, 1) \
F(NewObject, 1, 1) \
F(NewObjectFromBound, 1, 1) \
F(FinalizeInstanceSize, 1, 1) \
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index 45963a3..19cfd5a 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1176,7 +1176,8 @@
JSObject* recv = JSObject::cast(args[0]);
ExecutableAccessorInfo* callback = ExecutableAccessorInfo::cast(args[1]);
Address setter_address = v8::ToCData<Address>(callback->setter());
- v8::AccessorSetter fun = FUNCTION_CAST<v8::AccessorSetter>(setter_address);
+ v8::AccessorSetterCallback fun =
+ FUNCTION_CAST<v8::AccessorSetterCallback>(setter_address);
ASSERT(fun != NULL);
ASSERT(callback->IsCompatibleReceiver(recv));
Handle<Name> name = args.at<Name>(2);
@@ -1221,8 +1222,8 @@
Handle<String> name = Handle<String>::cast(name_handle);
Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
- v8::NamedPropertyGetter getter =
- FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
+ v8::NamedPropertyGetterCallback getter =
+ FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
ASSERT(getter != NULL);
Handle<JSObject> receiver =
@@ -1291,8 +1292,8 @@
Handle<String> name = Handle<String>::cast(name_handle);
Address getter_address = v8::ToCData<Address>(interceptor_info->getter());
- v8::NamedPropertyGetter getter =
- FUNCTION_CAST<v8::NamedPropertyGetter>(getter_address);
+ v8::NamedPropertyGetterCallback getter =
+ FUNCTION_CAST<v8::NamedPropertyGetterCallback>(getter_address);
ASSERT(getter != NULL);
PropertyCallbackArguments callback_args(isolate,
diff --git a/src/v8dll-main.cc b/src/v8dll-main.cc
index 49d8689..7f6c9f9 100644
--- a/src/v8dll-main.cc
+++ b/src/v8dll-main.cc
@@ -30,8 +30,8 @@
#undef USING_V8_SHARED
#include "../include/v8.h"
-#ifdef WIN32
-#include <windows.h> // NOLINT
+#if V8_OS_WIN
+#include "win32-headers.h"
extern "C" {
BOOL WINAPI DllMain(HANDLE hinstDLL,
@@ -41,4 +41,4 @@
return TRUE;
}
}
-#endif
+#endif // V8_OS_WIN
diff --git a/src/version.cc b/src/version.cc
index 72633e7..d83f18e 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
#define MINOR_VERSION 21
-#define BUILD_NUMBER 4
-#define PATCH_LEVEL 1
+#define BUILD_NUMBER 5
+#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/src/win32-headers.h b/src/win32-headers.h
index 2b5d7d7..c83937c 100644
--- a/src/win32-headers.h
+++ b/src/win32-headers.h
@@ -96,3 +96,4 @@
#undef GetObject
#undef CreateMutex
#undef CreateSemaphore
+#undef Yield
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index ca8216b..6c83dad 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -708,7 +708,7 @@
}
// Get the full codegen state from the stack and untag it.
- __ SmiToInteger32(r10, Operand(rsp, 1 * kPointerSize));
+ __ SmiToInteger32(r10, Operand(rsp, kPCOnStackSize));
// Switch on the state.
Label not_no_registers, not_tos_rax;
@@ -717,7 +717,7 @@
__ ret(1 * kPointerSize); // Remove state.
__ bind(¬_no_registers);
- __ movq(rax, Operand(rsp, 2 * kPointerSize));
+ __ movq(rax, Operand(rsp, kPCOnStackSize + kPointerSize));
__ cmpq(r10, Immediate(FullCodeGenerator::TOS_REG));
__ j(not_equal, ¬_tos_rax, Label::kNear);
__ ret(2 * kPointerSize); // Remove state, rax.
@@ -782,8 +782,8 @@
// 2. Get the function to call (passed as receiver) from the stack, check
// if it is a function.
Label slow, non_function;
- // The function to call is at position n+1 on the stack.
- __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
+ StackArgumentsAccessor args(rsp, rax);
+ __ movq(rdi, args.GetReceiverOperand());
__ JumpIfSmi(rdi, &non_function);
__ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
__ j(not_equal, &slow);
@@ -808,7 +808,7 @@
__ j(not_zero, &shift_arguments);
// Compute the receiver in non-strict mode.
- __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
+ __ movq(rbx, args.GetArgumentOperand(1));
__ JumpIfSmi(rbx, &convert_to_object, Label::kNear);
__ CompareRoot(rbx, Heap::kNullValueRootIndex);
@@ -837,7 +837,7 @@
}
// Restore the function to rdi.
- __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
+ __ movq(rdi, args.GetReceiverOperand());
__ jmp(&patch_receiver, Label::kNear);
// Use the global receiver object from the called function as the
@@ -851,7 +851,7 @@
__ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
__ bind(&patch_receiver);
- __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx);
+ __ movq(args.GetArgumentOperand(1), rbx);
__ jmp(&shift_arguments);
}
@@ -868,7 +868,7 @@
// CALL_NON_FUNCTION builtin expects the non-function callee as
// receiver, so overwrite the first argument which will ultimately
// become the receiver.
- __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi);
+ __ movq(args.GetArgumentOperand(1), rdi);
// 4. Shift arguments and return address one slot down on the stack
// (overwriting the original receiver). Adjust argument count to make
@@ -1178,10 +1178,11 @@
// Load the first argument into rax and get rid of the rest
// (including the receiver).
+ StackArgumentsAccessor args(rsp, rax);
Label no_arguments;
__ testq(rax, rax);
__ j(zero, &no_arguments);
- __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
+ __ movq(rbx, args.GetArgumentOperand(1));
__ PopReturnAddressTo(rcx);
__ lea(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
__ PushReturnAddressFrom(rcx);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 41507d1..9eed917 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -39,6 +39,17 @@
namespace internal {
+void FastNewClosureStub::InitializeInterfaceDescriptor(
+ Isolate* isolate,
+ CodeStubInterfaceDescriptor* descriptor) {
+ static Register registers[] = { rbx };
+ descriptor->register_param_count_ = 1;
+ descriptor->register_params_ = registers;
+ descriptor->deoptimization_handler_ =
+ Runtime::FunctionForId(Runtime::kNewClosureFromStubFailure)->entry;
+}
+
+
void ToNumberStub::InitializeInterfaceDescriptor(
Isolate* isolate,
CodeStubInterfaceDescriptor* descriptor) {
@@ -295,140 +306,6 @@
}
-void FastNewClosureStub::Generate(MacroAssembler* masm) {
- // Create a new closure from the given function info in new
- // space. Set the context to the current context in rsi.
- Counters* counters = masm->isolate()->counters();
-
- Label gc;
- __ Allocate(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT);
-
- __ IncrementCounter(counters->fast_new_closure_total(), 1);
-
- // Get the function info from the stack.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
-
- int map_index = Context::FunctionMapIndex(language_mode_, is_generator_);
-
- // Compute the function map in the current native context and set that
- // as the map of the allocated object.
- __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
- __ movq(rcx, FieldOperand(rcx, GlobalObject::kNativeContextOffset));
- __ movq(rbx, Operand(rcx, Context::SlotOffset(map_index)));
- __ movq(FieldOperand(rax, JSObject::kMapOffset), rbx);
-
- // Initialize the rest of the function. We don't have to update the
- // write barrier because the allocated object is in new space.
- __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex);
- __ LoadRoot(r8, Heap::kTheHoleValueRootIndex);
- __ LoadRoot(rdi, Heap::kUndefinedValueRootIndex);
- __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rbx);
- __ movq(FieldOperand(rax, JSObject::kElementsOffset), rbx);
- __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), r8);
- __ movq(FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset), rdx);
- __ movq(FieldOperand(rax, JSFunction::kContextOffset), rsi);
- __ movq(FieldOperand(rax, JSFunction::kLiteralsOffset), rbx);
-
- // Initialize the code pointer in the function to be the one
- // found in the shared function info object.
- // But first check if there is an optimized version for our context.
- Label check_optimized;
- Label install_unoptimized;
- if (FLAG_cache_optimized_code) {
- __ movq(rbx,
- FieldOperand(rdx, SharedFunctionInfo::kOptimizedCodeMapOffset));
- __ testq(rbx, rbx);
- __ j(not_zero, &check_optimized, Label::kNear);
- }
- __ bind(&install_unoptimized);
- __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset),
- rdi); // Initialize with undefined.
- __ movq(rdx, FieldOperand(rdx, SharedFunctionInfo::kCodeOffset));
- __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
- __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
-
- // Return and remove the on-stack parameter.
- __ ret(1 * kPointerSize);
-
- __ bind(&check_optimized);
-
- __ IncrementCounter(counters->fast_new_closure_try_optimized(), 1);
-
- // rcx holds native context, rbx points to fixed array of 3-element entries
- // (native context, optimized code, literals).
- // The optimized code map must never be empty, so check the first elements.
- Label install_optimized;
- // Speculatively move code object into edx.
- __ movq(rdx, FieldOperand(rbx, SharedFunctionInfo::kFirstCodeSlot));
- __ cmpq(rcx, FieldOperand(rbx, SharedFunctionInfo::kFirstContextSlot));
- __ j(equal, &install_optimized);
-
- // Iterate through the rest of map backwards. rdx holds an index.
- Label loop;
- Label restore;
- __ movq(rdx, FieldOperand(rbx, FixedArray::kLengthOffset));
- __ SmiToInteger32(rdx, rdx);
- __ bind(&loop);
- // Do not double check first entry.
- __ cmpq(rdx, Immediate(SharedFunctionInfo::kSecondEntryIndex));
- __ j(equal, &restore);
- __ subq(rdx, Immediate(SharedFunctionInfo::kEntryLength));
- __ cmpq(rcx, FieldOperand(rbx,
- rdx,
- times_pointer_size,
- FixedArray::kHeaderSize));
- __ j(not_equal, &loop, Label::kNear);
- // Hit: fetch the optimized code.
- __ movq(rdx, FieldOperand(rbx,
- rdx,
- times_pointer_size,
- FixedArray::kHeaderSize + 1 * kPointerSize));
-
- __ bind(&install_optimized);
- __ IncrementCounter(counters->fast_new_closure_install_optimized(), 1);
-
- // TODO(fschneider): Idea: store proper code pointers in the map and either
- // unmangle them on marking or do nothing as the whole map is discarded on
- // major GC anyway.
- __ lea(rdx, FieldOperand(rdx, Code::kHeaderSize));
- __ movq(FieldOperand(rax, JSFunction::kCodeEntryOffset), rdx);
-
- // Now link a function into a list of optimized functions.
- __ movq(rdx, ContextOperand(rcx, Context::OPTIMIZED_FUNCTIONS_LIST));
-
- __ movq(FieldOperand(rax, JSFunction::kNextFunctionLinkOffset), rdx);
- // No need for write barrier as JSFunction (rax) is in the new space.
-
- __ movq(ContextOperand(rcx, Context::OPTIMIZED_FUNCTIONS_LIST), rax);
- // Store JSFunction (rax) into rdx before issuing write barrier as
- // it clobbers all the registers passed.
- __ movq(rdx, rax);
- __ RecordWriteContextSlot(
- rcx,
- Context::SlotOffset(Context::OPTIMIZED_FUNCTIONS_LIST),
- rdx,
- rbx,
- kDontSaveFPRegs);
-
- // Return and remove the on-stack parameter.
- __ ret(1 * kPointerSize);
-
- __ bind(&restore);
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
- __ jmp(&install_unoptimized);
-
- // Create a new closure through the slower runtime call.
- __ bind(&gc);
- __ PopReturnAddressTo(rcx);
- __ pop(rdx);
- __ push(rsi);
- __ push(rdx);
- __ PushRoot(Heap::kFalseValueRootIndex);
- __ PushReturnAddressFrom(rcx);
- __ TailCallRuntime(Runtime::kNewClosure, 3, 1);
-}
-
-
void FastNewContextStub::Generate(MacroAssembler* masm) {
// Try to allocate the context in new space.
Label gc;
@@ -437,7 +314,8 @@
rax, rbx, rcx, &gc, TAG_OBJECT);
// Get the function from the stack.
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rcx, args.GetArgumentOperand(0));
// Set up the object header.
__ LoadRoot(kScratchRegister, Heap::kFunctionContextMapRootIndex);
@@ -483,10 +361,10 @@
rax, rbx, rcx, &gc, TAG_OBJECT);
// Get the function from the stack.
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
-
+ StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rcx, args.GetArgumentOperand(1));
// Get the serialized scope info from the stack.
- __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+ __ movq(rbx, args.GetArgumentOperand(0));
// Set up the object header.
__ LoadRoot(kScratchRegister, Heap::kBlockContextMapRootIndex);
@@ -1259,7 +1137,8 @@
if (tagged) {
Label input_not_smi, loaded;
// Test that rax is a number.
- __ movq(rax, Operand(rsp, kPointerSize));
+ StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rax, args.GetArgumentOperand(0));
__ JumpIfNotSmi(rax, &input_not_smi, Label::kNear);
// Input is a smi. Untag and load it onto the FPU stack.
// Then load the bits of the double into rbx.
@@ -1734,8 +1613,9 @@
// The exponent and base are supplied as arguments on the stack.
// This can only happen if the stub is called from non-optimized code.
// Load input parameters from stack.
- __ movq(base, Operand(rsp, 2 * kPointerSize));
- __ movq(exponent, Operand(rsp, 1 * kPointerSize));
+ StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(base, args.GetArgumentOperand(0));
+ __ movq(exponent, args.GetArgumentOperand(1));
__ JumpIfSmi(base, &base_is_smi, Label::kNear);
__ CompareRoot(FieldOperand(base, HeapObject::kMapOffset),
Heap::kHeapNumberMapRootIndex);
@@ -2168,7 +2048,8 @@
Factory* factory = masm->isolate()->factory();
- __ SmiToInteger64(rbx, Operand(rsp, 1 * kPointerSize));
+ StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ SmiToInteger64(rbx, args.GetArgumentOperand(2));
// rbx = parameter count (untagged)
// Check if the calling frame is an arguments adaptor frame.
@@ -2190,7 +2071,7 @@
ArgumentsAdaptorFrameConstants::kLengthOffset));
__ lea(rdx, Operand(rdx, rcx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
- __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+ __ movq(args.GetArgumentOperand(1), rdx);
// rbx = parameter count (untagged)
// rcx = argument count (untagged)
@@ -2251,7 +2132,7 @@
// Set up the callee in-object property.
STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
- __ movq(rdx, Operand(rsp, 3 * kPointerSize));
+ __ movq(rdx, args.GetArgumentOperand(0));
__ movq(FieldOperand(rax, JSObject::kHeaderSize +
Heap::kArgumentsCalleeIndex * kPointerSize),
rdx);
@@ -2302,7 +2183,7 @@
// Load tagged parameter count into r9.
__ Integer32ToSmi(r9, rbx);
__ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
- __ addq(r8, Operand(rsp, 1 * kPointerSize));
+ __ addq(r8, args.GetArgumentOperand(2));
__ subq(r8, r9);
__ Move(r11, factory->the_hole_value());
__ movq(rdx, rdi);
@@ -2341,7 +2222,7 @@
Label arguments_loop, arguments_test;
__ movq(r8, rbx);
- __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+ __ movq(rdx, args.GetArgumentOperand(1));
// Untag rcx for the loop below.
__ SmiToInteger64(rcx, rcx);
__ lea(kScratchRegister, Operand(r8, times_pointer_size, 0));
@@ -2368,7 +2249,7 @@
// rcx = argument count (untagged)
__ bind(&runtime);
__ Integer32ToSmi(rcx, rcx);
- __ movq(Operand(rsp, 1 * kPointerSize), rcx); // Patch argument count.
+ __ movq(args.GetArgumentOperand(2), rcx); // Patch argument count.
__ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
}
@@ -2387,12 +2268,13 @@
__ j(not_equal, &runtime);
// Patch the arguments.length and the parameters pointer.
+ StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
__ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+ __ movq(args.GetArgumentOperand(2), rcx);
__ SmiToInteger64(rcx, rcx);
__ lea(rdx, Operand(rdx, rcx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
- __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+ __ movq(args.GetArgumentOperand(1), rdx);
__ bind(&runtime);
__ TailCallRuntime(Runtime::kNewArgumentsFast, 3, 1);
@@ -2413,18 +2295,19 @@
__ j(equal, &adaptor_frame);
// Get the length from the frame.
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rcx, args.GetArgumentOperand(2));
__ SmiToInteger64(rcx, rcx);
__ jmp(&try_allocate);
// Patch the arguments.length and the parameters pointer.
__ bind(&adaptor_frame);
__ movq(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ movq(Operand(rsp, 1 * kPointerSize), rcx);
+ __ movq(args.GetArgumentOperand(2), rcx);
__ SmiToInteger64(rcx, rcx);
__ lea(rdx, Operand(rdx, rcx, times_pointer_size,
StandardFrameConstants::kCallerSPOffset));
- __ movq(Operand(rsp, 2 * kPointerSize), rdx);
+ __ movq(args.GetArgumentOperand(1), rdx);
// Try the new space allocation. Start out with computing the size of
// the arguments object and the elements array.
@@ -2454,7 +2337,7 @@
// Get the length (smi tagged) and set that as an in-object property too.
STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
- __ movq(rcx, Operand(rsp, 1 * kPointerSize));
+ __ movq(rcx, args.GetArgumentOperand(2));
__ movq(FieldOperand(rax, JSObject::kHeaderSize +
Heap::kArgumentsLengthIndex * kPointerSize),
rcx);
@@ -2465,7 +2348,7 @@
__ j(zero, &done);
// Get the parameters pointer from the stack.
- __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+ __ movq(rdx, args.GetArgumentOperand(1));
// Set up the elements pointer in the allocated arguments object and
// initialize the header in the elements fixed array.
@@ -2948,7 +2831,8 @@
const int kMaxInlineLength = 100;
Label slowcase;
Label done;
- __ movq(r8, Operand(rsp, kPointerSize * 3));
+ StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(r8, args.GetArgumentOperand(0));
__ JumpIfNotSmi(r8, &slowcase);
__ SmiToInteger32(rbx, r8);
__ cmpl(rbx, Immediate(kMaxInlineLength));
@@ -2986,11 +2870,11 @@
__ movq(FieldOperand(rax, JSObject::kElementsOffset), rcx);
// Set input, index and length fields from arguments.
- __ movq(r8, Operand(rsp, kPointerSize * 1));
+ __ movq(r8, args.GetArgumentOperand(2));
__ movq(FieldOperand(rax, JSRegExpResult::kInputOffset), r8);
- __ movq(r8, Operand(rsp, kPointerSize * 2));
+ __ movq(r8, args.GetArgumentOperand(1));
__ movq(FieldOperand(rax, JSRegExpResult::kIndexOffset), r8);
- __ movq(r8, Operand(rsp, kPointerSize * 3));
+ __ movq(r8, args.GetArgumentOperand(0));
__ movq(FieldOperand(rax, JSArray::kLengthOffset), r8);
// Fill out the elements FixedArray.
@@ -3121,7 +3005,8 @@
void NumberToStringStub::Generate(MacroAssembler* masm) {
Label runtime;
- __ movq(rbx, Operand(rsp, kPointerSize));
+ StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rbx, args.GetArgumentOperand(0));
// Generate code to lookup number in the number string cache.
GenerateLookupNumberStringCache(masm, rbx, rax, r8, r9, &runtime);
@@ -3506,6 +3391,7 @@
{
FrameScope scope(masm, StackFrame::INTERNAL);
+ __ Integer32ToSmi(rax, rax);
__ push(rax);
__ push(rdi);
__ push(rbx);
@@ -3516,6 +3402,7 @@
__ pop(rbx);
__ pop(rdi);
__ pop(rax);
+ __ SmiToInteger32(rax, rax);
}
__ jmp(&done);
@@ -3532,6 +3419,7 @@
// rdi : the function to call
Isolate* isolate = masm->isolate();
Label slow, non_function;
+ StackArgumentsAccessor args(rsp, argc_);
// The receiver might implicitly be the global object. This is
// indicated by passing the hole as the receiver to the call
@@ -3539,15 +3427,14 @@
if (ReceiverMightBeImplicit()) {
Label call;
// Get the receiver from the stack.
- // +1 ~ return address
- __ movq(rax, Operand(rsp, (argc_ + 1) * kPointerSize));
+ __ movq(rax, args.GetReceiverOperand());
// Call as function is indicated with the hole.
__ CompareRoot(rax, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &call, Label::kNear);
// Patch the receiver on the stack with the global receiver object.
__ movq(rcx, GlobalObjectOperand());
__ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rcx);
+ __ movq(args.GetReceiverOperand(), rcx);
__ bind(&call);
}
@@ -3609,7 +3496,7 @@
// CALL_NON_FUNCTION expects the non-function callee as receiver (instead
// of the original receiver from the call site).
__ bind(&non_function);
- __ movq(Operand(rsp, (argc_ + 1) * kPointerSize), rdi);
+ __ movq(args.GetReceiverOperand(), rdi);
__ Set(rax, argc_);
__ Set(rbx, 0);
__ SetCallKind(rcx, CALL_AS_METHOD);
@@ -4144,12 +4031,13 @@
static const unsigned int kWordBeforeResultValue = 0x458B4909;
// Only the inline check flag is supported on X64.
ASSERT(flags_ == kNoFlags || HasCallSiteInlineCheck());
- int extra_stack_space = HasCallSiteInlineCheck() ? kPointerSize : 0;
+ int extra_argument_offset = HasCallSiteInlineCheck() ? 1 : 0;
// Get the object - go slow case if it's a smi.
Label slow;
-
- __ movq(rax, Operand(rsp, 2 * kPointerSize + extra_stack_space));
+ StackArgumentsAccessor args(rsp, 2 + extra_argument_offset,
+ ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rax, args.GetArgumentOperand(0));
__ JumpIfSmi(rax, &slow);
// Check that the left hand is a JS object. Leave its map in rax.
@@ -4159,7 +4047,7 @@
__ j(above, &slow);
// Get the prototype of the function.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize + extra_stack_space));
+ __ movq(rdx, args.GetArgumentOperand(1));
// rdx is function, rax is map.
// If there is a call site cache don't look in the global cache, but do the
@@ -4194,8 +4082,8 @@
__ StoreRoot(rax, Heap::kInstanceofCacheMapRootIndex);
} else {
// Get return address and delta to inlined map check.
- __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
- __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+ __ movq(kScratchRegister, StackOperandForReturnAddress(0));
+ __ subq(kScratchRegister, args.GetArgumentOperand(2));
if (FLAG_debug_code) {
__ movl(rdi, Immediate(kWordBeforeMapCheckValue));
__ cmpl(Operand(kScratchRegister, kOffsetToMapCheckValue - 4), rdi);
@@ -4235,8 +4123,8 @@
// Assert it is a 1-byte signed value.
ASSERT(true_offset >= 0 && true_offset < 0x100);
__ movl(rax, Immediate(true_offset));
- __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
- __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+ __ movq(kScratchRegister, StackOperandForReturnAddress(0));
+ __ subq(kScratchRegister, args.GetArgumentOperand(2));
__ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
if (FLAG_debug_code) {
__ movl(rax, Immediate(kWordBeforeResultValue));
@@ -4245,7 +4133,7 @@
}
__ Set(rax, 0);
}
- __ ret(2 * kPointerSize + extra_stack_space);
+ __ ret((2 + extra_argument_offset) * kPointerSize);
__ bind(&is_not_instance);
if (!HasCallSiteInlineCheck()) {
@@ -4258,8 +4146,8 @@
// Assert it is a 1-byte signed value.
ASSERT(false_offset >= 0 && false_offset < 0x100);
__ movl(rax, Immediate(false_offset));
- __ movq(kScratchRegister, Operand(rsp, 0 * kPointerSize));
- __ subq(kScratchRegister, Operand(rsp, 1 * kPointerSize));
+ __ movq(kScratchRegister, StackOperandForReturnAddress(0));
+ __ subq(kScratchRegister, args.GetArgumentOperand(2));
__ movb(Operand(kScratchRegister, kOffsetToResultValue), rax);
if (FLAG_debug_code) {
__ movl(rax, Immediate(kWordBeforeResultValue));
@@ -4267,7 +4155,7 @@
__ Assert(equal, kInstanceofStubUnexpectedCallSiteCacheMov);
}
}
- __ ret(2 * kPointerSize + extra_stack_space);
+ __ ret((2 + extra_argument_offset) * kPointerSize);
// Slow-case: Go through the JavaScript implementation.
__ bind(&slow);
@@ -4425,8 +4313,9 @@
Builtins::JavaScript builtin_id = Builtins::ADD;
// Load the two arguments.
- __ movq(rax, Operand(rsp, 2 * kPointerSize)); // First argument (left).
- __ movq(rdx, Operand(rsp, 1 * kPointerSize)); // Second argument (right).
+ StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rax, args.GetArgumentOperand(0)); // First argument (left).
+ __ movq(rdx, args.GetArgumentOperand(1)); // Second argument (right).
// Make sure that both arguments are strings if not known in advance.
// Otherwise, at least one of the arguments is definitely a string,
@@ -5433,8 +5322,9 @@
// rsp[8] : right string
// rsp[16] : left string
- __ movq(rdx, Operand(rsp, 2 * kPointerSize)); // left
- __ movq(rax, Operand(rsp, 1 * kPointerSize)); // right
+ StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rdx, args.GetArgumentOperand(0)); // left
+ __ movq(rax, args.GetArgumentOperand(1)); // right
// Check for identity.
Label not_same;
@@ -5947,9 +5837,11 @@
// undefined value), it guarantees the hash table doesn't contain the
// property. It's true even if some slots represent deleted properties
// (their names are the null value).
+ StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER,
+ kPointerSize);
for (int i = kInlinedProbes; i < kTotalProbes; i++) {
// Compute the masked index: (hash + i + i * i) & mask.
- __ movq(scratch, Operand(rsp, 2 * kPointerSize));
+ __ movq(scratch, args.GetArgumentOperand(1));
if (i > 0) {
__ addl(scratch, Immediate(NameDictionary::GetProbeOffset(i)));
}
@@ -5969,7 +5861,7 @@
__ j(equal, ¬_in_dictionary);
// Stop if found the property.
- __ cmpq(scratch, Operand(rsp, 3 * kPointerSize));
+ __ cmpq(scratch, args.GetArgumentOperand(0));
__ j(equal, &in_dictionary);
if (i != kTotalProbes - 1 && mode_ == NEGATIVE_LOOKUP) {
@@ -6321,8 +6213,9 @@
Label fast_elements;
// Get array literal index, array literal and its map.
- __ movq(rdx, Operand(rsp, 1 * kPointerSize));
- __ movq(rbx, Operand(rsp, 2 * kPointerSize));
+ StackArgumentsAccessor args(rsp, 2, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rdx, args.GetArgumentOperand(1));
+ __ movq(rbx, args.GetArgumentOperand(0));
__ movq(rdi, FieldOperand(rbx, JSObject::kMapOffset));
__ CheckFastElements(rdi, &double_elements);
@@ -6489,7 +6382,8 @@
__ j(not_zero, &normal_sequence);
// look at the first argument
- __ movq(rcx, Operand(rsp, kPointerSize));
+ StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rcx, args.GetArgumentOperand(0));
__ testq(rcx, rcx);
__ j(zero, &normal_sequence);
@@ -6668,7 +6562,8 @@
if (IsFastPackedElementsKind(kind)) {
// We might need to create a holey array
// look at the first argument
- __ movq(rcx, Operand(rsp, kPointerSize));
+ StackArgumentsAccessor args(rsp, 1, ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ __ movq(rcx, args.GetArgumentOperand(0));
__ testq(rcx, rcx);
__ j(zero, &normal_sequence);
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index a39f14b..24773c2 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -744,6 +744,28 @@
}
+Operand StackArgumentsAccessor::GetArgumentOperand(int index) {
+ ASSERT(index >= 0);
+ ASSERT(base_reg_.is(rsp) || base_reg_.is(rbp));
+ int receiver = (receiver_mode_ == ARGUMENTS_CONTAIN_RECEIVER) ? 1 : 0;
+ int displacement_to_last_argument = base_reg_.is(rsp) ?
+ kPCOnStackSize : kFPOnStackSize + kPCOnStackSize;
+ displacement_to_last_argument += extra_displacement_to_last_argument_;
+ if (argument_count_reg_.is(no_reg)) {
+ // argument[0] is at base_reg_ + displacement_to_last_argument +
+ // (argument_count_immediate_ + receiver - 1) * kPointerSize.
+ ASSERT(argument_count_immediate_ + receiver > 0);
+ return Operand(base_reg_, displacement_to_last_argument +
+ (argument_count_immediate_ + receiver - 1 - index) * kPointerSize);
+ } else {
+ // argument[0] is at base_reg_ + displacement_to_last_argument +
+ // argument_count_reg_ * times_pointer_size + (receiver - 1) * kPointerSize.
+ return Operand(base_reg_, argument_count_reg_, times_pointer_size,
+ displacement_to_last_argument + (receiver - 1 - index) * kPointerSize);
+ }
+}
+
+
} } // namespace v8::internal
#endif // V8_TARGET_ARCH_X64
diff --git a/src/x64/codegen-x64.h b/src/x64/codegen-x64.h
index 5747e0b..9b8454a 100644
--- a/src/x64/codegen-x64.h
+++ b/src/x64/codegen-x64.h
@@ -103,6 +103,73 @@
DISALLOW_COPY_AND_ASSIGN(MathExpGenerator);
};
+
+enum StackArgumentsAccessorReceiverMode {
+ ARGUMENTS_CONTAIN_RECEIVER,
+ ARGUMENTS_DONT_CONTAIN_RECEIVER
+};
+
+
+class StackArgumentsAccessor BASE_EMBEDDED {
+ public:
+ StackArgumentsAccessor(
+ Register base_reg,
+ int argument_count_immediate,
+ StackArgumentsAccessorReceiverMode receiver_mode =
+ ARGUMENTS_CONTAIN_RECEIVER,
+ int extra_displacement_to_last_argument = 0)
+ : base_reg_(base_reg),
+ argument_count_reg_(no_reg),
+ argument_count_immediate_(argument_count_immediate),
+ receiver_mode_(receiver_mode),
+ extra_displacement_to_last_argument_(
+ extra_displacement_to_last_argument) { }
+
+ StackArgumentsAccessor(
+ Register base_reg,
+ Register argument_count_reg,
+ StackArgumentsAccessorReceiverMode receiver_mode =
+ ARGUMENTS_CONTAIN_RECEIVER,
+ int extra_displacement_to_last_argument = 0)
+ : base_reg_(base_reg),
+ argument_count_reg_(argument_count_reg),
+ argument_count_immediate_(0),
+ receiver_mode_(receiver_mode),
+ extra_displacement_to_last_argument_(
+ extra_displacement_to_last_argument) { }
+
+ StackArgumentsAccessor(
+ Register base_reg,
+ const ParameterCount& parameter_count,
+ StackArgumentsAccessorReceiverMode receiver_mode =
+ ARGUMENTS_CONTAIN_RECEIVER,
+ int extra_displacement_to_last_argument = 0)
+ : base_reg_(base_reg),
+ argument_count_reg_(parameter_count.is_reg() ?
+ parameter_count.reg() : no_reg),
+ argument_count_immediate_(parameter_count.is_immediate() ?
+ parameter_count.immediate() : 0),
+ receiver_mode_(receiver_mode),
+ extra_displacement_to_last_argument_(
+ extra_displacement_to_last_argument) { }
+
+ Operand GetArgumentOperand(int index);
+ Operand GetReceiverOperand() {
+ ASSERT(receiver_mode_ == ARGUMENTS_CONTAIN_RECEIVER);
+ return GetArgumentOperand(0);;
+ }
+
+ private:
+ const Register base_reg_;
+ const Register argument_count_reg_;
+ const int argument_count_immediate_;
+ const StackArgumentsAccessorReceiverMode receiver_mode_;
+ const int extra_displacement_to_last_argument_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(StackArgumentsAccessor);
+};
+
+
} } // namespace v8::internal
#endif // V8_X64_CODEGEN_X64_H_
diff --git a/src/x64/debug-x64.cc b/src/x64/debug-x64.cc
index e6bc929..c8e1c96 100644
--- a/src/x64/debug-x64.cc
+++ b/src/x64/debug-x64.cc
@@ -123,14 +123,8 @@
if ((object_regs & (1 << r)) != 0) {
__ push(reg);
}
- // Store the 64-bit value as two smis.
if ((non_object_regs & (1 << r)) != 0) {
- __ movq(kScratchRegister, reg);
- __ Integer32ToSmi(reg, reg);
- __ push(reg);
- __ sar(kScratchRegister, Immediate(32));
- __ Integer32ToSmi(kScratchRegister, kScratchRegister);
- __ push(kScratchRegister);
+ __ PushInt64AsTwoSmis(reg);
}
}
@@ -155,12 +149,7 @@
}
// Reconstruct the 64-bit value from two smis.
if ((non_object_regs & (1 << r)) != 0) {
- __ pop(kScratchRegister);
- __ SmiToInteger32(kScratchRegister, kScratchRegister);
- __ shl(kScratchRegister, Immediate(32));
- __ pop(reg);
- __ SmiToInteger32(reg, reg);
- __ or_(reg, kScratchRegister);
+ __ PopInt64AsTwoSmis(reg);
}
}
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index 9f2074c..04005ac 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -1292,7 +1292,7 @@
scope()->is_function_scope() &&
info->num_literals() == 0) {
FastNewClosureStub stub(info->language_mode(), info->is_generator());
- __ Push(info);
+ __ Move(rbx, info);
__ CallStub(&stub);
} else {
__ push(rsi);
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 4837b9a..84a47d6 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -904,8 +904,8 @@
// -----------------------------------
Label miss;
- // Get the receiver of the function from the stack.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
GenerateNameDictionaryReceiverCheck(masm, rdx, rax, rbx, &miss);
@@ -940,8 +940,8 @@
__ IncrementCounter(counters->keyed_call_miss(), 1);
}
- // Get the receiver of the function from the stack; 1 ~ return address.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
// Enter an internal frame.
{
@@ -965,7 +965,7 @@
// This can happen only for regular CallIC but not KeyedCallIC.
if (id == IC::kCallIC_Miss) {
Label invoke, global;
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize)); // receiver
+ __ movq(rdx, args.GetReceiverOperand());
__ JumpIfSmi(rdx, &invoke);
__ CmpObjectType(rdx, JS_GLOBAL_OBJECT_TYPE, rcx);
__ j(equal, &global);
@@ -975,7 +975,7 @@
// Patch the receiver on the stack.
__ bind(&global);
__ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+ __ movq(args.GetReceiverOperand(), rdx);
__ bind(&invoke);
}
@@ -1005,8 +1005,8 @@
// rsp[(argc + 1) * 8] : argument 0 = receiver
// -----------------------------------
- // Get the receiver of the function from the stack; 1 ~ return address.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
GenerateMonomorphicCacheProbe(masm, argc, Code::CALL_IC, extra_ic_state);
GenerateMiss(masm, argc, extra_ic_state);
}
@@ -1023,8 +1023,8 @@
// rsp[(argc + 1) * 8] : argument 0 = receiver
// -----------------------------------
- // Get the receiver of the function from the stack; 1 ~ return address.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
Label do_call, slow_call, slow_load;
Label check_number_dictionary, check_name, lookup_monomorphic_cache;
@@ -1302,7 +1302,8 @@
// rsp[(argc + 1) * 8] : argument 0 = receiver
// -----------------------------------
Label slow, notin;
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
Operand mapped_location = GenerateMappedArgumentsLookup(
masm, rdx, rcx, rbx, rax, r8, ¬in, &slow);
__ movq(rdi, mapped_location);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 85f0255..094d239 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1299,7 +1299,11 @@
LOperand* right = instr->right();
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
- __ movl(kScratchRegister, left);
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ movq(kScratchRegister, left);
+ } else {
+ __ movl(kScratchRegister, left);
+ }
}
bool can_overflow =
@@ -1347,14 +1351,14 @@
}
} else if (right->IsStackSlot()) {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ SmiToInteger32(left, left);
+ __ SmiToInteger64(left, left);
__ imul(left, ToOperand(right));
} else {
__ imull(left, ToOperand(right));
}
} else {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ SmiToInteger32(left, left);
+ __ SmiToInteger64(left, left);
__ imul(left, ToRegister(right));
} else {
__ imull(left, ToRegister(right));
@@ -1368,9 +1372,15 @@
if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
// Bail out if the result is supposed to be negative zero.
Label done;
- __ testl(left, left);
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ testq(left, left);
+ } else {
+ __ testl(left, left);
+ }
__ j(not_zero, &done, Label::kNear);
if (right->IsConstantOperand()) {
+ // Constant can't be represented as Smi due to immediate size limit.
+ ASSERT(!instr->hydrogen_value()->representation().IsSmi());
if (ToInteger32(LConstantOperand::cast(right)) < 0) {
DeoptimizeIf(no_condition, instr->environment());
} else if (ToInteger32(LConstantOperand::cast(right)) == 0) {
@@ -1378,11 +1388,19 @@
DeoptimizeIf(less, instr->environment());
}
} else if (right->IsStackSlot()) {
- __ orl(kScratchRegister, ToOperand(right));
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ or_(kScratchRegister, ToOperand(right));
+ } else {
+ __ orl(kScratchRegister, ToOperand(right));
+ }
DeoptimizeIf(sign, instr->environment());
} else {
// Test the non-zero operand for negative sign.
- __ orl(kScratchRegister, ToRegister(right));
+ if (instr->hydrogen_value()->representation().IsSmi()) {
+ __ or_(kScratchRegister, ToRegister(right));
+ } else {
+ __ orl(kScratchRegister, ToRegister(right));
+ }
DeoptimizeIf(sign, instr->environment());
}
__ bind(&done);
@@ -3906,6 +3924,14 @@
}
+void LCodeGen::DoStoreCodeEntry(LStoreCodeEntry* instr) {
+ Register function = ToRegister(instr->function());
+ Register code_object = ToRegister(instr->code_object());
+ __ lea(code_object, FieldOperand(code_object, Code::kHeaderSize));
+ __ movq(FieldOperand(function, JSFunction::kCodeEntryOffset), code_object);
+}
+
+
void LCodeGen::DoInnerAllocatedObject(LInnerAllocatedObject* instr) {
Register result = ToRegister(instr->result());
Register base = ToRegister(instr->base_object());
@@ -5167,7 +5193,7 @@
if (!pretenure && instr->hydrogen()->has_no_literals()) {
FastNewClosureStub stub(instr->hydrogen()->language_mode(),
instr->hydrogen()->is_generator());
- __ Push(instr->hydrogen()->shared_info());
+ __ Move(rbx, instr->hydrogen()->shared_info());
CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
} else {
__ push(rsi);
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 96fa719..57938b2 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -263,6 +263,14 @@
}
+void LStoreCodeEntry::PrintDataTo(StringStream* stream) {
+ stream->Add(" = ");
+ function()->PrintTo(stream);
+ stream->Add(".code_entry = ");
+ code_object()->PrintTo(stream);
+}
+
+
void LInnerAllocatedObject::PrintDataTo(StringStream* stream) {
stream->Add(" = ");
base_object()->PrintTo(stream);
@@ -1083,6 +1091,14 @@
}
+LInstruction* LChunkBuilder::DoStoreCodeEntry(
+ HStoreCodeEntry* store_code_entry) {
+ LOperand* function = UseRegister(store_code_entry->function());
+ LOperand* code_object = UseTempRegister(store_code_entry->code_object());
+ return new(zone()) LStoreCodeEntry(function, code_object);
+}
+
+
LInstruction* LChunkBuilder::DoInnerAllocatedObject(
HInnerAllocatedObject* inner_object) {
LOperand* base_object = UseRegisterAtStart(inner_object->base_object());
@@ -1827,8 +1843,9 @@
return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
} else {
ASSERT(to.IsInteger32());
- LOperand* value = UseRegister(instr->value());
- if (instr->value()->type().IsSmi()) {
+ HValue* val = instr->value();
+ LOperand* value = UseRegister(val);
+ if (val->type().IsSmi() || val->representation().IsSmi()) {
return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
} else {
bool truncating = instr->CanTruncateToInt32();
@@ -2374,8 +2391,7 @@
LInstruction* LChunkBuilder::DoCapturedObject(HCapturedObject* instr) {
- HEnvironment* env = current_block_->last_environment();
- instr->ReplayEnvironment(env);
+ instr->ReplayEnvironment(current_block_->last_environment());
// There are no real uses of a captured object.
return NULL;
@@ -2423,20 +2439,7 @@
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
- HEnvironment* env = current_block_->last_environment();
- ASSERT(env != NULL);
-
- env->set_ast_id(instr->ast_id());
-
- env->Drop(instr->pop_count());
- for (int i = instr->values()->length() - 1; i >= 0; --i) {
- HValue* value = instr->values()->at(i);
- if (instr->HasAssignedIndexAt(i)) {
- env->Bind(instr->GetAssignedIndexAt(i), value);
- } else {
- env->Push(value);
- }
- }
+ instr->ReplayEnvironment(current_block_->last_environment());
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index b3a20cf..00642ff 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -160,6 +160,7 @@
V(SmiTag) \
V(SmiUntag) \
V(StackCheck) \
+ V(StoreCodeEntry) \
V(StoreContextSlot) \
V(StoreGlobalCell) \
V(StoreGlobalGeneric) \
@@ -1693,7 +1694,24 @@
};
-class LInnerAllocatedObject V8_FINAL : public LTemplateInstruction<1, 1, 0> {
+class LStoreCodeEntry V8_FINAL: public LTemplateInstruction<0, 1, 1> {
+ public:
+ LStoreCodeEntry(LOperand* function, LOperand* code_object) {
+ inputs_[0] = function;
+ temps_[0] = code_object;
+ }
+
+ LOperand* function() { return inputs_[0]; }
+ LOperand* code_object() { return temps_[0]; }
+
+ virtual void PrintDataTo(StringStream* stream);
+
+ DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
+ DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
+};
+
+
+class LInnerAllocatedObject V8_FINAL: public LTemplateInstruction<1, 1, 0> {
public:
explicit LInnerAllocatedObject(LOperand* base_object) {
inputs_[0] = base_object;
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 5180e6b..0938007 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -685,22 +685,8 @@
}
-void MacroAssembler::PrepareCallApiFunction(int arg_stack_space,
- bool returns_handle) {
-#if defined(_WIN64) && !defined(__MINGW64__)
- if (!returns_handle) {
- EnterApiExitFrame(arg_stack_space);
- return;
- }
- // We need to prepare a slot for result handle on stack and put
- // a pointer to it into 1st arg register.
- EnterApiExitFrame(arg_stack_space + 1);
-
- // rcx must be used to pass the pointer to the return value slot.
- lea(rcx, StackSpaceOperand(arg_stack_space));
-#else
+void MacroAssembler::PrepareCallApiFunction(int arg_stack_space) {
EnterApiExitFrame(arg_stack_space);
-#endif
}
@@ -708,7 +694,6 @@
Address thunk_address,
Register thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset) {
Label prologue;
Label promote_scheduled_exception;
@@ -781,23 +766,6 @@
PopSafepointRegisters();
}
- // Can skip the result check for new-style callbacks
- // TODO(dcarney): may need to pass this information down
- // as some function_addresses might not have been registered
- if (returns_handle) {
- Label empty_result;
-#if defined(_WIN64) && !defined(__MINGW64__)
- // rax keeps a pointer to v8::Handle, unpack it.
- movq(rax, Operand(rax, 0));
-#endif
- // Check if the result handle holds 0.
- testq(rax, rax);
- j(zero, &empty_result);
- // It was non-zero. Dereference to get the result value.
- movq(rax, Operand(rax, 0));
- jmp(&prologue);
- bind(&empty_result);
- }
// Load the value from ReturnValue
movq(rax, Operand(rbp, return_value_offset * kPointerSize));
bind(&prologue);
@@ -998,7 +966,7 @@
void MacroAssembler::SafeMove(Register dst, Smi* src) {
ASSERT(!dst.is(kScratchRegister));
- ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi.
+ ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi.
if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
Move(dst, Smi::FromInt(src->value() ^ jit_cookie()));
Move(kScratchRegister, Smi::FromInt(jit_cookie()));
@@ -1010,7 +978,7 @@
void MacroAssembler::SafePush(Smi* src) {
- ASSERT(kSmiValueSize == 32); // JIT cookie can be converted to Smi.
+ ASSERT(SmiValuesAre32Bits()); // JIT cookie can be converted to Smi.
if (IsUnsafeInt(src->value()) && jit_cookie() != 0) {
Push(Smi::FromInt(src->value() ^ jit_cookie()));
Move(kScratchRegister, Smi::FromInt(jit_cookie()));
@@ -2228,6 +2196,30 @@
}
+void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) {
+ movq(scratch, src);
+ // High bits.
+ shr(src, Immediate(64 - kSmiShift));
+ shl(src, Immediate(kSmiShift));
+ push(src);
+ // Low bits.
+ shl(scratch, Immediate(kSmiShift));
+ push(scratch);
+}
+
+
+void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) {
+ pop(scratch);
+ // Low bits.
+ shr(scratch, Immediate(kSmiShift));
+ pop(dst);
+ shr(dst, Immediate(kSmiShift));
+ // High bits.
+ shl(dst, Immediate(64 - kSmiShift));
+ or_(dst, scratch);
+}
+
+
void MacroAssembler::JumpIfNotString(Register object,
Register object_map,
Label* not_string,
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index 61abc20..d9fb373 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -720,6 +720,14 @@
}
void Push(Smi* smi);
+
+ // Save away a 64-bit integer on the stack as two 32-bit integers
+ // masquerading as smis so that the garbage collector skips visiting them.
+ void PushInt64AsTwoSmis(Register src, Register scratch = kScratchRegister);
+ // Reconstruct a 64-bit integer from two 32-bit integers masquerading as
+ // smis on the top of stack.
+ void PopInt64AsTwoSmis(Register dst, Register scratch = kScratchRegister);
+
void Test(const Operand& dst, Smi* source);
@@ -1242,7 +1250,7 @@
// rcx (rcx must be preserverd until CallApiFunctionAndReturn). Saves
// context (rsi). Clobbers rax. Allocates arg_stack_space * kPointerSize
// inside the exit frame (not GCed) accessible via StackSpaceOperand.
- void PrepareCallApiFunction(int arg_stack_space, bool returns_handle);
+ void PrepareCallApiFunction(int arg_stack_space);
// Calls an API function. Allocates HandleScope, extracts returned value
// from handle and propagates exceptions. Clobbers r14, r15, rbx and
@@ -1252,7 +1260,6 @@
Address thunk_address,
Register thunk_last_arg,
int stack_space,
- bool returns_handle,
int return_value_offset_from_rbp);
// Before calling a C-function from generated code, align arguments on stack.
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index dcd317c..49d9de6 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -761,7 +761,7 @@
// position registers.
__ movq(Operand(rbp, kInputStartMinusOne), rax);
-#ifdef WIN32
+#if V8_OS_WIN
// Ensure that we have written to each stack page, in order. Skipping a page
// on Windows can cause segmentation faults. Assuming page size is 4k.
const int kPageSize = 4096;
@@ -771,7 +771,7 @@
i += kRegistersPerPage) {
__ movq(register_location(i), rax); // One write every page.
}
-#endif // WIN32
+#endif // V8_OS_WIN
// Initialize code object pointer.
__ Move(code_object_pointer(), masm_.CodeObject());
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 6883d38..55e4a9b 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -414,8 +414,10 @@
__ subq(rsp, Immediate(kFastApiCallArguments * kPointerSize));
__ movq(StackOperandForReturnAddress(0), scratch);
__ Move(scratch, Smi::FromInt(0));
- for (int i = 1; i <= kFastApiCallArguments; i++) {
- __ movq(Operand(rsp, i * kPointerSize), scratch);
+ StackArgumentsAccessor args(rsp, kFastApiCallArguments,
+ ARGUMENTS_DONT_CONTAIN_RECEIVER);
+ for (int i = 0; i < kFastApiCallArguments; i++) {
+ __ movq(args.GetArgumentOperand(i), scratch);
}
}
@@ -464,23 +466,26 @@
__ LoadHeapObject(rdi, function);
__ movq(rsi, FieldOperand(rdi, JSFunction::kContextOffset));
+ int api_call_argc = argc + kFastApiCallArguments;
+ StackArgumentsAccessor args(rsp, api_call_argc);
+
// Pass the additional arguments.
- __ movq(Operand(rsp, 2 * kPointerSize), rdi);
+ __ movq(args.GetArgumentOperand(api_call_argc - 1), rdi);
Handle<CallHandlerInfo> api_call_info = optimization.api_call_info();
Handle<Object> call_data(api_call_info->data(), masm->isolate());
if (masm->isolate()->heap()->InNewSpace(*call_data)) {
__ Move(rcx, api_call_info);
__ movq(rbx, FieldOperand(rcx, CallHandlerInfo::kDataOffset));
- __ movq(Operand(rsp, 3 * kPointerSize), rbx);
+ __ movq(args.GetArgumentOperand(api_call_argc - 2), rbx);
} else {
- __ Move(Operand(rsp, 3 * kPointerSize), call_data);
+ __ Move(args.GetArgumentOperand(api_call_argc - 2), call_data);
}
__ movq(kScratchRegister,
ExternalReference::isolate_address(masm->isolate()));
- __ movq(Operand(rsp, 4 * kPointerSize), kScratchRegister);
+ __ movq(args.GetArgumentOperand(api_call_argc - 3), kScratchRegister);
__ LoadRoot(kScratchRegister, Heap::kUndefinedValueRootIndex);
- __ movq(Operand(rsp, 5 * kPointerSize), kScratchRegister);
- __ movq(Operand(rsp, 6 * kPointerSize), kScratchRegister);
+ __ movq(args.GetArgumentOperand(api_call_argc - 4), kScratchRegister);
+ __ movq(args.GetArgumentOperand(api_call_argc - 5), kScratchRegister);
// Prepare arguments.
STATIC_ASSERT(kFastApiCallArguments == 6);
@@ -488,16 +493,10 @@
// Function address is a foreign pointer outside V8's heap.
Address function_address = v8::ToCData<Address>(api_call_info->callback());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(masm->isolate(), function_address);
-#if defined(__MINGW64__)
+#if defined(__MINGW64__) || defined(_WIN64)
Register arguments_arg = rcx;
Register callback_arg = rdx;
-#elif defined(_WIN64)
- // Win64 uses first register--rcx--for returned value.
- Register arguments_arg = returns_handle ? rdx : rcx;
- Register callback_arg = returns_handle ? r8 : rdx;
#else
Register arguments_arg = rdi;
Register callback_arg = rsi;
@@ -507,7 +506,7 @@
// it's not controlled by GC.
const int kApiStackSpace = 4;
- __ PrepareCallApiFunction(kApiStackSpace, returns_handle);
+ __ PrepareCallApiFunction(kApiStackSpace);
__ movq(StackSpaceOperand(0), rbx); // v8::Arguments::implicit_args_.
__ addq(rbx, Immediate(argc * kPointerSize));
@@ -519,15 +518,12 @@
// v8::InvocationCallback's argument.
__ lea(arguments_arg, StackSpaceOperand(0));
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeInvocationCallback)
- : FUNCTION_ADDR(&InvokeFunctionCallback);
+ Address thunk_address = FUNCTION_ADDR(&InvokeFunctionCallback);
__ CallApiFunctionAndReturn(function_address,
thunk_address,
callback_arg,
- argc + kFastApiCallArguments + 1,
- returns_handle,
+ api_call_argc + 1,
kFastApiCallArguments + 1);
}
@@ -1075,7 +1071,7 @@
int depth = 0;
if (save_at_depth == depth) {
- __ movq(Operand(rsp, kPointerSize), object_reg);
+ __ movq(Operand(rsp, kPCOnStackSize), object_reg);
}
// Check the maps in the prototype chain.
@@ -1135,7 +1131,7 @@
}
if (save_at_depth == depth) {
- __ movq(Operand(rsp, kPointerSize), reg);
+ __ movq(Operand(rsp, kPCOnStackSize), reg);
}
// Go to the next object in the prototype chain.
@@ -1304,18 +1300,11 @@
// passed as the const ExecutableAccessorInfo& to the C++ callback.
Address getter_address = v8::ToCData<Address>(callback->getter());
- bool returns_handle =
- !CallbackTable::ReturnsVoid(isolate(), getter_address);
-#if defined(__MINGW64__)
+#if defined(__MINGW64__) || defined(_WIN64)
Register getter_arg = r8;
Register accessor_info_arg = rdx;
Register name_arg = rcx;
-#elif defined(_WIN64)
- // Win64 uses first register--rcx--for returned value.
- Register getter_arg = returns_handle ? r9 : r8;
- Register accessor_info_arg = returns_handle ? r8 : rdx;
- Register name_arg = returns_handle ? rdx : rcx;
#else
Register getter_arg = rdx;
Register accessor_info_arg = rsi;
@@ -1332,7 +1321,7 @@
// Allocate v8::AccessorInfo in non-GCed stack space.
const int kArgStackSpace = 1;
- __ PrepareCallApiFunction(kArgStackSpace, returns_handle);
+ __ PrepareCallApiFunction(kArgStackSpace);
STATIC_ASSERT(PropertyCallbackArguments::kArgsLength == 6);
__ lea(rax, Operand(name_arg, 6 * kPointerSize));
@@ -1343,15 +1332,12 @@
// could be used to pass arguments.
__ lea(accessor_info_arg, StackSpaceOperand(0));
- Address thunk_address = returns_handle
- ? FUNCTION_ADDR(&InvokeAccessorGetter)
- : FUNCTION_ADDR(&InvokeAccessorGetterCallback);
+ Address thunk_address = FUNCTION_ADDR(&InvokeAccessorGetterCallback);
__ CallApiFunctionAndReturn(getter_address,
thunk_address,
getter_arg,
kStackSpace,
- returns_handle,
5);
}
@@ -1470,11 +1456,8 @@
Label* miss) {
ASSERT(holder->IsGlobalObject());
- // Get the number of arguments.
- const int argc = arguments().immediate();
-
- // Get the receiver from the stack.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, arguments());
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the maps haven't changed.
@@ -1538,9 +1521,8 @@
GenerateNameCheck(name, &miss);
- // Get the receiver from the stack.
- const int argc = arguments().immediate();
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, arguments());
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &miss);
@@ -1561,7 +1543,7 @@
// necessary.
if (object->IsGlobalObject()) {
__ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+ __ movq(args.GetReceiverOperand(), rdx);
}
// Invoke the function.
@@ -1591,11 +1573,11 @@
// Check that function is still array
const int argc = arguments().immediate();
+ StackArgumentsAccessor args(rsp, argc);
GenerateNameCheck(name, &miss);
if (cell.is_null()) {
- // Get the receiver from the stack.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &miss);
@@ -1647,9 +1629,9 @@
Label miss;
GenerateNameCheck(name, &miss);
- // Get the receiver from the stack.
const int argc = arguments().immediate();
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &miss);
@@ -1688,7 +1670,7 @@
__ j(greater, &attempt_to_grow_elements);
// Check if value is a smi.
- __ movq(rcx, Operand(rsp, argc * kPointerSize));
+ __ movq(rcx, args.GetArgumentOperand(1));
__ JumpIfNotSmi(rcx, &with_write_barrier);
// Save new length.
@@ -1723,7 +1705,7 @@
__ cmpl(rax, rcx);
__ j(greater, &call_builtin);
- __ movq(rcx, Operand(rsp, argc * kPointerSize));
+ __ movq(rcx, args.GetArgumentOperand(1));
__ StoreNumberToDoubleElements(
rcx, rdi, rax, xmm0, &call_builtin, argc * kDoubleSize);
@@ -1800,7 +1782,7 @@
__ jmp(&call_builtin);
}
- __ movq(rbx, Operand(rsp, argc * kPointerSize));
+ __ movq(rbx, args.GetArgumentOperand(1));
// Growing elements that are SMI-only requires special handling in case
// the new element is non-Smi. For now, delegate to the builtin.
Label no_fast_elements_check;
@@ -1849,7 +1831,7 @@
__ RecordWrite(rdi, rdx, rbx, kDontSaveFPRegs, OMIT_REMEMBERED_SET);
// Restore receiver to rdx as finish sequence assumes it's here.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ __ movq(rdx, args.GetReceiverOperand());
// Increment element's and array's sizes.
__ SmiAddConstant(FieldOperand(rdi, FixedArray::kLengthOffset),
@@ -1898,9 +1880,9 @@
Label miss, return_undefined, call_builtin;
GenerateNameCheck(name, &miss);
- // Get the receiver from the stack.
const int argc = arguments().immediate();
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &miss);
@@ -1978,6 +1960,7 @@
if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
const int argc = arguments().immediate();
+ StackArgumentsAccessor args(rsp, argc);
Label miss;
Label name_miss;
@@ -2003,9 +1986,9 @@
Register receiver = rbx;
Register index = rdi;
Register result = rax;
- __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
+ __ movq(receiver, args.GetReceiverOperand());
if (argc > 0) {
- __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
+ __ movq(index, args.GetArgumentOperand(1));
} else {
__ LoadRoot(index, Heap::kUndefinedValueRootIndex);
}
@@ -2059,6 +2042,8 @@
if (!object->IsString() || !cell.is_null()) return Handle<Code>::null();
const int argc = arguments().immediate();
+ StackArgumentsAccessor args(rsp, argc);
+
Label miss;
Label name_miss;
Label index_out_of_range;
@@ -2084,9 +2069,9 @@
Register index = rdi;
Register scratch = rdx;
Register result = rax;
- __ movq(receiver, Operand(rsp, (argc + 1) * kPointerSize));
+ __ movq(receiver, args.GetReceiverOperand());
if (argc > 0) {
- __ movq(index, Operand(rsp, (argc - 0) * kPointerSize));
+ __ movq(index, args.GetArgumentOperand(1));
} else {
__ LoadRoot(index, Heap::kUndefinedValueRootIndex);
}
@@ -2139,13 +2124,14 @@
// If the object is not a JSObject or we got an unexpected number of
// arguments, bail out to the regular call.
const int argc = arguments().immediate();
+ StackArgumentsAccessor args(rsp, argc);
if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
Label miss;
GenerateNameCheck(name, &miss);
if (cell.is_null()) {
- __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+ __ movq(rdx, args.GetArgumentOperand(argc - 1));
__ JumpIfSmi(rdx, &miss);
CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
name, &miss);
@@ -2158,7 +2144,7 @@
// Load the char code argument.
Register code = rbx;
- __ movq(code, Operand(rsp, 1 * kPointerSize));
+ __ movq(code, args.GetArgumentOperand(argc));
// Check the code is a smi.
Label slow;
@@ -2345,13 +2331,14 @@
// If the object is not a JSObject or we got an unexpected number of
// arguments, bail out to the regular call.
const int argc = arguments().immediate();
+ StackArgumentsAccessor args(rsp, argc);
if (!object->IsJSObject() || argc != 1) return Handle<Code>::null();
Label miss;
GenerateNameCheck(name, &miss);
if (cell.is_null()) {
- __ movq(rdx, Operand(rsp, 2 * kPointerSize));
+ __ movq(rdx, args.GetArgumentOperand(argc - 1));
__ JumpIfSmi(rdx, &miss);
CheckPrototypes(Handle<JSObject>::cast(object), rdx, holder, rbx, rax, rdi,
name, &miss);
@@ -2362,7 +2349,7 @@
GenerateLoadFunctionFromCell(cell, function, &miss);
}
// Load the (only) argument into rax.
- __ movq(rax, Operand(rsp, 1 * kPointerSize));
+ __ movq(rax, args.GetArgumentOperand(argc));
// Check if the argument is a smi.
Label not_smi;
@@ -2452,9 +2439,9 @@
Label miss, miss_before_stack_reserved;
GenerateNameCheck(name, &miss_before_stack_reserved);
- // Get the receiver from the stack.
const int argc = arguments().immediate();
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, argc);
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the receiver isn't a smi.
__ JumpIfSmi(rdx, &miss_before_stack_reserved);
@@ -2506,9 +2493,8 @@
Label miss;
GenerateNameCheck(name, &miss);
- // Get the receiver from the stack.
- const int argc = arguments().immediate();
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, arguments());
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the receiver isn't a smi.
if (check != NUMBER_CHECK) {
@@ -2532,7 +2518,7 @@
// necessary.
if (object->IsGlobalObject()) {
__ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+ __ movq(args.GetReceiverOperand(), rdx);
}
break;
@@ -2652,21 +2638,20 @@
Label miss;
GenerateNameCheck(name, &miss);
- // Get the number of arguments.
- const int argc = arguments().immediate();
LookupResult lookup(isolate());
LookupPostInterceptor(holder, name, &lookup);
// Get the receiver from the stack.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ StackArgumentsAccessor args(rsp, arguments());
+ __ movq(rdx, args.GetReceiverOperand());
CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state_);
compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
&miss);
// Restore receiver.
- __ movq(rdx, Operand(rsp, (argc + 1) * kPointerSize));
+ __ movq(rdx, args.GetReceiverOperand());
// Check that the function really is a function.
__ JumpIfSmi(rax, &miss);
@@ -2677,7 +2662,7 @@
// necessary.
if (object->IsGlobalObject()) {
__ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+ __ movq(args.GetReceiverOperand(), rdx);
}
// Invoke the function.
@@ -2724,15 +2709,14 @@
Label miss;
GenerateNameCheck(name, &miss);
- // Get the number of arguments.
- const int argc = arguments().immediate();
+ StackArgumentsAccessor args(rsp, arguments());
GenerateGlobalReceiverCheck(object, holder, name, &miss);
GenerateLoadFunctionFromCell(cell, function, &miss);
// Patch the receiver on the stack with the global proxy.
if (object->IsGlobalObject()) {
__ movq(rdx, FieldOperand(rdx, GlobalObject::kGlobalReceiverOffset));
- __ movq(Operand(rsp, (argc + 1) * kPointerSize), rdx);
+ __ movq(args.GetReceiverOperand(), rdx);
}
// Set up the context (function already in rdi).
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 0d3ff15..ebfea0e 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -117,3 +117,6 @@
# Profiling doesn't work on Native Client.
test-cpu-profiler/*: SKIP
+
+# Fails since 16322 (new test).
+test-code-stubs-arm/ConvertDToI: SKIP
diff --git a/test/cctest/test-accessors.cc b/test/cctest/test-accessors.cc
index 7e0ee70..105ecf1 100644
--- a/test/cctest/test-accessors.cc
+++ b/test/cctest/test-accessors.cc
@@ -41,7 +41,6 @@
using ::v8::String;
using ::v8::Script;
using ::v8::Function;
-using ::v8::AccessorInfo;
using ::v8::Extension;
static void handle_property(Local<String> name,
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 192f114..ccf1cbd 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -25,17 +25,17 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include <limits.h>
-
-#ifndef WIN32
-#include <signal.h> // kill
-#include <unistd.h> // getpid
-#endif // WIN32
+#include <climits>
+#include <csignal>
#include <string>
#include <map>
#include "v8.h"
+#if V8_OS_POSIX
+#include <unistd.h> // NOLINT
+#endif
+
#include "api.h"
#include "arguments.h"
#include "cctest.h"
@@ -53,8 +53,6 @@
static const bool kLogThreading = false;
-using ::v8::AccessorInfo;
-using ::v8::Arguments;
using ::v8::Boolean;
using ::v8::BooleanObject;
using ::v8::Context;
@@ -1360,7 +1358,7 @@
int32_t value = i::Smi::kMaxValue;
// We cannot add one to a Smi::kMaxValue without wrapping.
- if (i::kSmiValueSize < 32) {
+ if (i::SmiValuesAre31Bits()) {
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
@@ -1379,7 +1377,7 @@
v8::Isolate* isolate = v8::Isolate::GetCurrent();
// We cannot add one to a Smi::kMaxValue without wrapping.
- if (i::kSmiValueSize < 32) {
+ if (i::SmiValuesAre31Bits()) {
// The casts allow this to compile, even if Smi::kMaxValue is 2^31-1.
// The code will not be run in that case, due to the "if" guard.
int32_t value =
@@ -9608,6 +9606,26 @@
}
+THREADED_TEST(FunctionRemovePrototype) {
+ LocalContext context;
+ v8::HandleScope handle_scope(context->GetIsolate());
+
+ Local<v8::FunctionTemplate> t1 = v8::FunctionTemplate::New();
+ t1->RemovePrototype();
+ Local<v8::Function> fun = t1->GetFunction();
+ context->Global()->Set(v8_str("fun"), fun);
+ CHECK(!CompileRun("'prototype' in fun")->BooleanValue());
+
+ v8::TryCatch try_catch;
+ CompileRun("new fun()");
+ CHECK(try_catch.HasCaught());
+
+ try_catch.Reset();
+ fun->NewInstance();
+ CHECK(try_catch.HasCaught());
+}
+
+
THREADED_TEST(GetterSetterExceptions) {
LocalContext context;
v8::HandleScope handle_scope(context->GetIsolate());
@@ -20013,7 +20031,7 @@
}
-#ifndef WIN32
+#if V8_OS_POSIX
class ThreadInterruptTest {
public:
ThreadInterruptTest() : sem_(NULL), sem_value_(0) { }
@@ -20255,4 +20273,4 @@
v8::V8::SetFailedAccessCheckCallbackFunction(NULL);
}
-#endif // WIN32
+#endif // V8_OS_POSIX
diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc
index 484eb8e..9281337 100644
--- a/test/cctest/test-debug.cc
+++ b/test/cctest/test-debug.cc
@@ -661,10 +661,11 @@
// Debug event handler which counts the break points which have been hit.
int break_point_hit_count = 0;
int break_point_hit_count_deoptimize = 0;
-static void DebugEventBreakPointHitCount(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakPointHitCount(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
+ v8::Handle<v8::Object> event_data = event_details.GetEventData();
v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
Debug* debug = isolate->debug();
// When hitting a debug event listener there must be a break set.
@@ -773,10 +774,11 @@
uncaught_exception_hit_count = 0;
}
-static void DebugEventCounter(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventCounter(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
+ v8::Handle<v8::Object> event_data = event_details.GetEventData();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
@@ -835,10 +837,10 @@
v8::Local<v8::Function> evaluate_check_function;
// The actual debug event described by the longer comment above.
-static void DebugEventEvaluate(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventEvaluate(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -862,10 +864,10 @@
// This debug event listener removes a breakpoint in a function
int debug_event_remove_break_point = 0;
-static void DebugEventRemoveBreakPoint(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventRemoveBreakPoint(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Value> data = event_details.GetCallbackData();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -881,10 +883,9 @@
// Debug event handler which counts break points hit and performs a step
// afterwards.
StepAction step_action = StepIn; // Step action to perform when stepping.
-static void DebugEventStep(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventStep(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -908,10 +909,10 @@
const char* expected_step_sequence = NULL;
// The actual debug event described by the longer comment above.
-static void DebugEventStepSequence(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventStepSequence(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -939,10 +940,8 @@
// Debug event handler which performs a garbage collection.
static void DebugEventBreakPointCollectGarbage(
- v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -965,10 +964,9 @@
// Debug event handler which re-issues a debug break and calls the garbage
// collector to have the heap verified.
-static void DebugEventBreak(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreak(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
v8::internal::Debug* debug = v8::internal::Isolate::Current()->debug();
// When hitting a debug event listener there must be a break set.
CHECK_NE(debug->break_id(), 0);
@@ -991,10 +989,10 @@
// reached.
int max_break_point_hit_count = 0;
bool terminate_after_max_break_point_hit = false;
-static void DebugEventBreakMax(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakMax(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
v8::internal::Isolate* isolate = v8::internal::Isolate::Current();
v8::internal::Debug* debug = isolate->debug();
// When hitting a debug event listener there must be a break set.
@@ -1179,8 +1177,7 @@
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function foo(){bar=0;}"))->Run();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -1201,7 +1198,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1211,8 +1208,7 @@
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("bar=1"))->Run();
v8::Script::Compile(v8::String::New("function foo(){var x=bar;}"))->Run();
v8::Local<v8::Function> foo =
@@ -1234,7 +1230,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1244,8 +1240,7 @@
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
v8::Script::Compile(v8::String::New("function foo(){bar();}"))->Run();
v8::Local<v8::Function> foo =
@@ -1267,7 +1262,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1277,8 +1272,7 @@
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
v8::Script::Compile(v8::String::New("function bar(){return 1;}"))->Run();
v8::Script::Compile(v8::String::New("function foo(){return bar();}"))->Run();
v8::Local<v8::Function> foo =
@@ -1300,7 +1294,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1310,8 +1304,7 @@
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
v8::Script::Compile(v8::String::New("function bar(){ this.x = 1;}"))->Run();
v8::Script::Compile(v8::String::New(
"function foo(){return new bar(1).x;}"))->Run();
@@ -1334,7 +1327,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1355,8 +1348,7 @@
"frame_source_column");
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function foo(){}"))->Run();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -1381,7 +1373,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1404,8 +1396,7 @@
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointCollectGarbage,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointCollectGarbage);
v8::Local<v8::Function> foo;
// Test IC store break point with garbage collection.
@@ -1433,7 +1424,7 @@
SetBreakPoint(foo, 0);
CallWithBreakPoints(env->Global(), foo, 1, 25);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1468,8 +1459,7 @@
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> foo;
// Test IC store break point with garbage collection.
@@ -1515,7 +1505,7 @@
CallAndGC(env->Global(), foo);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1527,8 +1517,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function bar(){}"))->Run();
v8::Script::Compile(v8::String::New("function foo(){bar();bar();}"))->Run();
// 012345678901234567890
@@ -1566,7 +1555,7 @@
foo->Run();
CHECK_EQ(8, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1583,8 +1572,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -1668,7 +1656,7 @@
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1687,8 +1675,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> source = v8::String::New(
"function f() {\n"
@@ -1776,7 +1763,7 @@
g->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Make sure that the break point numbers are consecutive.
@@ -1796,8 +1783,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -1841,7 +1827,7 @@
f->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1853,8 +1839,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"count = 0;\n"
@@ -1903,7 +1888,7 @@
}
CHECK_EQ(5, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1915,8 +1900,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -1958,7 +1942,7 @@
}
CHECK_EQ(5, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -1970,8 +1954,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script = v8::String::New(
@@ -2017,7 +2000,7 @@
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2029,8 +2012,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script_f = v8::String::New(
@@ -2083,7 +2065,7 @@
g->Call(env->Global(), 0, NULL);
CHECK_EQ(2, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2095,8 +2077,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::String> script = v8::String::New(
@@ -2139,7 +2120,7 @@
f->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2155,8 +2136,7 @@
frame_function_name_source,
"frame_function_name");
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::Function> f;
v8::Local<v8::Function> g;
@@ -2245,7 +2225,7 @@
v8::Script::Compile(script, &origin)->Run();
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2256,8 +2236,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script = v8::String::New(
"function f() {\n"
@@ -2290,7 +2269,7 @@
f = v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("f")));
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2302,8 +2281,7 @@
v8::HandleScope scope(env->GetIsolate());
env.ExposeDebug();
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Local<v8::String> script_source = v8::String::New(
"function f() {\n"
@@ -2323,7 +2301,7 @@
ClearBreakPointFromJS(sbp1);
ClearBreakPointFromJS(sbp2);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2339,7 +2317,7 @@
debug_event_remove_break_point = SetBreakPoint(foo, 0);
// Register the debug event listener pasing the function
- v8::Debug::SetDebugEventListener(DebugEventRemoveBreakPoint, foo);
+ v8::Debug::SetDebugEventListener2(DebugEventRemoveBreakPoint, foo);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -2349,7 +2327,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(0, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2359,8 +2337,7 @@
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function bar(){debugger}"))->Run();
v8::Script::Compile(v8::String::New(
"function foo(){debugger;debugger;}"))->Run();
@@ -2377,7 +2354,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2387,8 +2364,7 @@
break_point_hit_count = 0;
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
v8::Script::Compile(v8::String::New("function foo(){debugger;}"))->Run();
v8::Local<v8::Function> foo =
v8::Local<v8::Function>::Cast(env->Global()->Get(v8::String::New("foo")));
@@ -2404,7 +2380,7 @@
CHECK_EQ(2, break_point_hit_count);
ClearBreakPoint(bp);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2421,7 +2397,7 @@
evaluate_check_source,
"evaluate_check");
// Register the debug event listener
- v8::Debug::SetDebugEventListener(DebugEventEvaluate);
+ v8::Debug::SetDebugEventListener2(DebugEventEvaluate);
// Different expected vaules of x and a when in a break point (u = undefined,
// d = Hello, world!).
@@ -2521,7 +2497,7 @@
};
bar->Call(env->Global(), 2, argv_bar_3);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2702,17 +2678,12 @@
DebugProcessDebugMessagesData process_debug_messages_data;
static void DebugProcessDebugMessagesHandler(
- const uint16_t* message,
- int length,
- v8::Debug::ClientData* client_data) {
-
- const int kBufferSize = 100000;
- char print_buffer[kBufferSize];
- Utf16ToAscii(message, length, print_buffer, kBufferSize);
-
+ const v8::Debug::Message& message) {
+ v8::Handle<v8::String> json = message.GetJSON();
+ v8::String::AsciiValue ascii(json);
EvaluateResult* array_item = process_debug_messages_data.current();
- bool res = GetEvaluateStringResult(print_buffer,
+ bool res = GetEvaluateStringResult(*ascii,
array_item->buffer,
EvaluateResult::kBufferSize);
if (res) {
@@ -2724,7 +2695,7 @@
// Test that the evaluation of expressions works even from ProcessDebugMessages
// i.e. with empty stack.
TEST(DebugEvaluateWithoutStack) {
- v8::Debug::SetMessageHandler(DebugProcessDebugMessagesHandler);
+ v8::Debug::SetMessageHandler2(DebugProcessDebugMessagesHandler);
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -2778,8 +2749,8 @@
0);
CHECK_EQ(strcmp("805", process_debug_messages_data.results[2].buffer), 0);
- v8::Debug::SetMessageHandler(NULL);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetMessageHandler2(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2800,7 +2771,7 @@
SetBreakPoint(foo, 3);
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -2809,11 +2780,11 @@
// With stepping all break locations are hit.
CHECK_EQ(4, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
SetBreakPoint(foo, 3);
break_point_hit_count = 0;
@@ -2822,7 +2793,7 @@
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2833,7 +2804,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of keyed load. The statement 'y=1'
// is there to have more than one breakable statement in the loop, TODO(315).
@@ -2870,7 +2841,7 @@
// With stepping all break locations are hit.
CHECK_EQ(34, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2881,7 +2852,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of keyed store. The statement 'y=1'
// is there to have more than one breakable statement in the loop, TODO(315).
@@ -2917,7 +2888,7 @@
// With stepping all break locations are hit.
CHECK_EQ(33, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2928,7 +2899,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of named load.
v8::Local<v8::Function> foo = CompileFunction(
@@ -2961,7 +2932,7 @@
// With stepping all break locations are hit.
CHECK_EQ(54, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -2971,7 +2942,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping of named store.
v8::Local<v8::Function> foo = CompileFunction(
@@ -2996,7 +2967,7 @@
// With stepping all expected break locations are hit.
CHECK_EQ(expected, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3013,7 +2984,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping.
v8::Local<v8::Function> foo = CompileFunction(&env,
@@ -3036,11 +3007,11 @@
// With stepping all break locations are hit.
CHECK_EQ(11, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
SetBreakPoint(foo, 0);
break_point_hit_count = 0;
@@ -3049,7 +3020,7 @@
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3059,7 +3030,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3082,7 +3053,7 @@
CHECK_EQ(6, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3092,7 +3063,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3115,7 +3086,7 @@
CHECK_EQ(6, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3125,7 +3096,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3158,7 +3129,7 @@
CHECK_EQ(5, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3168,7 +3139,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3214,7 +3185,7 @@
CHECK_EQ(7, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3224,7 +3195,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3254,7 +3225,7 @@
CHECK_EQ(202, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3264,7 +3235,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3294,7 +3265,7 @@
CHECK_EQ(202, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3304,7 +3275,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3335,7 +3306,7 @@
CHECK_EQ(203, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3345,7 +3316,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3386,7 +3357,7 @@
CHECK_EQ(456, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3396,7 +3367,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3438,7 +3409,7 @@
CHECK_EQ(504, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3448,7 +3419,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3486,7 +3457,7 @@
CHECK_EQ(8, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3496,7 +3467,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3517,7 +3488,7 @@
CHECK_EQ(4, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3527,7 +3498,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3553,7 +3524,7 @@
CHECK_EQ(5, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3568,7 +3539,7 @@
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3604,7 +3575,7 @@
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3619,7 +3590,7 @@
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3656,7 +3627,7 @@
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded(true);
}
@@ -3671,7 +3642,7 @@
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create a function for testing stepping. Run it to allow it to get
// optimized.
@@ -3691,7 +3662,7 @@
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3708,7 +3679,7 @@
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -3717,11 +3688,11 @@
// With stepping all break locations are hit.
CHECK_EQ(3, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3729,7 +3700,7 @@
// Without stepping only active break points are hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3747,7 +3718,7 @@
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
break_point_hit_count = 0;
@@ -3756,11 +3727,11 @@
// With stepping all break locations are hit.
CHECK_EQ(7, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3768,7 +3739,7 @@
// Without stepping only the debugger statement is hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3792,7 +3763,7 @@
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStep);
+ v8::Debug::SetDebugEventListener2(DebugEventStep);
step_action = StepIn;
// Check stepping where the if condition in bar is false.
@@ -3807,11 +3778,11 @@
foo->Call(env->Global(), argc, argv);
CHECK_EQ(8, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
// Register a debug event listener which just counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
break_point_hit_count = 0;
foo->Call(env->Global(), 0, NULL);
@@ -3819,7 +3790,7 @@
// Without stepping only the debugger statement is hit.
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3831,7 +3802,7 @@
env.ExposeDebug();
// Register a debug event listener which counts.
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Create a script that returns a function.
const char* src = "(function (evt) {})";
@@ -3850,7 +3821,7 @@
CHECK_EQ(1, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -3878,7 +3849,7 @@
CompileFunction(&env, "function notCaught(){throws();}", "notCaught");
v8::V8::AddMessageListener(MessageCallbackCount);
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Initial state should be no break on exceptions.
DebugEventCounterClear();
@@ -3996,7 +3967,7 @@
CHECK_EQ(1, uncaught_exception_hit_count);
CHECK_EQ(1, message_callback_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
v8::V8::RemoveMessageListeners(MessageCallbackCount);
}
@@ -4018,7 +3989,7 @@
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
v8::V8::AddMessageListener(MessageCallbackCount);
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
DebugEventCounterClear();
MessageCallbackCountClear();
@@ -4072,7 +4043,7 @@
"frame_function_name");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventStepSequence);
+ v8::Debug::SetDebugEventListener2(DebugEventStepSequence);
// Create functions for testing stepping.
const char* src = "function a() { n(); }; "
@@ -4144,7 +4115,7 @@
break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4158,7 +4129,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventBreak);
+ v8::Debug::SetDebugEventListener2(DebugEventBreak);
// Create a function for testing stepping.
const char* src = "function f0() {}"
@@ -4198,7 +4169,7 @@
CHECK_EQ(4 * ARRAY_SIZE(argv), break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4210,7 +4181,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Create a function for testing stepping.
const char* src = "function f() {g()};function g(){i=0; while(i<10){i++}}";
@@ -4235,7 +4206,7 @@
CHECK_EQ(2, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4251,7 +4222,7 @@
v8::HandleScope scope(isolate);
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventCounter);
+ v8::Debug::SetDebugEventListener2(DebugEventCounter);
// Set the debug break flag.
v8::Debug::DebugBreak();
@@ -4270,7 +4241,7 @@
CHECK_EQ(0, break_point_hit_count);
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -4875,11 +4846,11 @@
void Run();
};
-static void MessageHandler(const uint16_t* message, int length,
- v8::Debug::ClientData* client_data) {
- static char print_buffer[1000];
- Utf16ToAscii(message, length, print_buffer);
- if (IsBreakEventMessage(print_buffer)) {
+
+static void MessageHandler(const v8::Debug::Message& message) {
+ v8::Handle<v8::String> json = message.GetJSON();
+ v8::String::AsciiValue ascii(json);
+ if (IsBreakEventMessage(*ascii)) {
// Lets test script wait until break occurs to send commands.
// Signals when a break is reported.
message_queue_barriers.semaphore_2->Signal();
@@ -4981,7 +4952,7 @@
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
message_queue_barriers.Initialize();
- v8::Debug::SetMessageHandler(MessageHandler);
+ v8::Debug::SetMessageHandler2(MessageHandler);
message_queue_debugger_thread.Start();
const char* source_1 = "a = 3; b = 4; c = new Object(); c.d = 5;";
@@ -5447,15 +5418,13 @@
}
-static void DummyDebugEventListener(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DummyDebugEventListener(
+ const v8::Debug::EventDetails& event_details) {
}
TEST(SetDebugEventListenerOnUninitializedVM) {
- v8::Debug::SetDebugEventListener(DummyDebugEventListener);
+ v8::Debug::SetDebugEventListener2(DummyDebugEventListener);
}
@@ -5646,8 +5615,7 @@
// Set a debug event listener.
break_point_hit_count = 0;
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
{
v8::HandleScope scope(env->GetIsolate());
// Create a couple of functions for the test.
@@ -5672,7 +5640,7 @@
// Remove the debug event listener without clearing breakpoints. Do this
// outside a handle scope.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded(true);
// Now set a debug message handler.
@@ -5750,7 +5718,7 @@
// Clear debug message handler.
message_handler_hit_count = 0;
- v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetMessageHandler2(NULL);
// Run code to throw a unhandled exception. This should end up in the message
// handler.
@@ -5769,7 +5737,7 @@
message_handler_hit_count++;
// Clear debug message handler.
- v8::Debug::SetMessageHandler(NULL);
+ v8::Debug::SetMessageHandler2(NULL);
}
@@ -6203,8 +6171,7 @@
compiled_script_data_source,
"compiled_script_data");
- v8::Debug::SetDebugEventListener(DebugEventBreakPointHitCount,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakPointHitCount);
// Test function source.
v8::Local<v8::String> script = v8::String::New(
@@ -6391,10 +6358,9 @@
// Debug event handler which gets the function on the top frame and schedules a
// break a number of times.
static void DebugEventDebugBreak(
- v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
break_point_hit_count++;
@@ -6445,7 +6411,7 @@
v8::Local<v8::Value> result = f->Call(env->Global(), argc, argv);
CHECK_EQ(12, result->Int32Value());
- v8::Debug::SetDebugEventListener(DebugEventDebugBreak);
+ v8::Debug::SetDebugEventListener2(DebugEventDebugBreak);
v8::Debug::DebugBreak();
result = f->Call(env->Global(), argc, argv);
@@ -6576,10 +6542,9 @@
// Debug event listener which counts the script collected events.
int script_collected_count = 0;
-static void DebugEventScriptCollectedEvent(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventScriptCollectedEvent(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
// Count the number of breaks.
if (event == v8::ScriptCollected) {
script_collected_count++;
@@ -6603,8 +6568,7 @@
HEAP->CollectAllGarbage(Heap::kAbortIncrementalMarkingMask);
script_collected_count = 0;
- v8::Debug::SetDebugEventListener(DebugEventScriptCollectedEvent,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventScriptCollectedEvent);
{
v8::Script::Compile(v8::String::New("eval('a=1')"))->Run();
v8::Script::Compile(v8::String::New("eval('a=2')"))->Run();
@@ -6616,7 +6580,7 @@
CHECK_EQ(2, script_collected_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -7017,7 +6981,7 @@
"foo");
// Register a debug event listener which steps and counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
// Set the debug break flag before calling the code using function.apply.
v8::Debug::DebugBreak();
@@ -7031,7 +6995,7 @@
// When keeping the debug break several break will happen.
CHECK_GT(break_point_hit_count, 1);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
@@ -7060,10 +7024,9 @@
// an object with property 'a' == 1. If the property has custom accessor
// this handler will eventually invoke it.
static void DebugEventGetAtgumentPropertyValue(
- v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
break_point_hit_count++;
CHECK(debugger_context == v8::Context::GetCurrent());
@@ -7100,7 +7063,7 @@
named->NewInstance());
// Register the debug event listener
- v8::Debug::SetDebugEventListener(DebugEventGetAtgumentPropertyValue);
+ v8::Debug::SetDebugEventListener2(DebugEventGetAtgumentPropertyValue);
// Create a function that invokes debugger.
v8::Local<v8::Function> foo = CompileFunction(
@@ -7113,7 +7076,7 @@
foo->Call(env->Global(), 0, NULL);
CHECK_EQ(1, break_point_hit_count);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
debugee_context = v8::Handle<v8::Context>();
debugger_context = v8::Handle<v8::Context>();
CheckDebuggerUnloaded();
@@ -7146,7 +7109,7 @@
v8::Context::Scope context_scope(expected_context);
v8::Script::Compile(v8::String::New("(function(){debugger;})();"))->Run();
expected_context.Clear();
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
expected_context_data = v8::Handle<v8::Value>();
CheckDebuggerUnloaded();
}
@@ -7213,16 +7176,16 @@
CHECK_EQ(TestClientData::constructor_call_counter,
TestClientData::destructor_call_counter);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
static bool debug_event_break_deoptimize_done = false;
-static void DebugEventBreakDeoptimize(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakDeoptimize(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
if (!frame_function_name.IsEmpty()) {
// Get the name of the function.
@@ -7265,8 +7228,7 @@
// This tests lazy deoptimization bailout for the stack check, as the first
// time in function bar when using debug break and no break points will be at
// the initial stack check.
- v8::Debug::SetDebugEventListener(DebugEventBreakDeoptimize,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakDeoptimize);
// Compile and run function bar which will optimize it for some flag settings.
v8::Script::Compile(v8::String::New("function bar(){}; bar()"))->Run();
@@ -7277,14 +7239,14 @@
CHECK(debug_event_break_deoptimize_done);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
}
-static void DebugEventBreakWithOptimizedStack(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventBreakWithOptimizedStack(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
+ v8::Handle<v8::Object> exec_state = event_details.GetExecutionState();
if (event == v8::Break) {
if (!frame_function_name.IsEmpty()) {
for (int i = 0; i < 2; i++) {
@@ -7329,8 +7291,7 @@
static void ScheduleBreak(const v8::FunctionCallbackInfo<v8::Value>& args) {
- v8::Debug::SetDebugEventListener(DebugEventBreakWithOptimizedStack,
- v8::Undefined());
+ v8::Debug::SetDebugEventListener2(DebugEventBreakWithOptimizedStack);
v8::Debug::DebugBreak();
}
@@ -7413,7 +7374,7 @@
v8::HandleScope scope(env->GetIsolate());
// Register a debug event listener which sets the break flag and counts.
- v8::Debug::SetDebugEventListener(DebugEventBreakMax);
+ v8::Debug::SetDebugEventListener2(DebugEventBreakMax);
// Create a function for getting the frame count when hitting the break.
frame_count = CompileFunction(&env, frame_count_source, "frame_count");
@@ -7447,17 +7408,16 @@
TestDebugBreakInLoop("for (;a == 1;) {", loop_bodies, "}");
// Get rid of the debug event listener.
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CheckDebuggerUnloaded();
}
v8::Local<v8::Script> inline_script;
-static void DebugBreakInlineListener(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugBreakInlineListener(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
if (event != v8::Break) return;
int expected_frame_count = 4;
@@ -7484,7 +7444,7 @@
CHECK_EQ(expected_line_number[i],
i::GetScriptLineNumber(source_script, result->Int32Value()));
}
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
v8::V8::TerminateExecution();
}
@@ -7507,16 +7467,15 @@
"g(false); \n"
"%OptimizeFunctionOnNextCall(g); \n"
"g(true);";
- v8::Debug::SetDebugEventListener(DebugBreakInlineListener);
+ v8::Debug::SetDebugEventListener2(DebugBreakInlineListener);
inline_script = v8::Script::Compile(v8::String::New(source));
inline_script->Run();
}
-static void DebugEventStepNext(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void DebugEventStepNext(
+ const v8::Debug::EventDetails& event_details) {
+ v8::DebugEvent event = event_details.GetEvent();
if (event == v8::Break) {
PrepareStep(StepNext);
}
@@ -7541,7 +7500,7 @@
// on the stack.
DebugLocalContext env;
v8::HandleScope scope(env->GetIsolate());
- v8::Debug::SetDebugEventListener(DebugEventStepNext);
+ v8::Debug::SetDebugEventListener2(DebugEventStepNext);
// We step through the first script. It exits through an exception. We run
// this inside a new frame to record a different FP than the second script
@@ -7553,7 +7512,7 @@
const char* script_2 = "[0].forEach(function() { });";
CompileRun(script_2);
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
}
@@ -7561,10 +7520,7 @@
int CountNativeContexts();
-static void NopListener(v8::DebugEvent event,
- v8::Handle<v8::Object> exec_state,
- v8::Handle<v8::Object> event_data,
- v8::Handle<v8::Value> data) {
+static void NopListener(const v8::Debug::EventDetails& event_details) {
}
@@ -7573,15 +7529,15 @@
v8::HandleScope scope(env->GetIsolate());
CHECK_EQ(1, CountNativeContexts());
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
CompileRun("debugger;");
CHECK_EQ(1, CountNativeContexts());
- v8::Debug::SetDebugEventListener(NopListener);
+ v8::Debug::SetDebugEventListener2(NopListener);
CompileRun("debugger;");
CHECK_EQ(2, CountNativeContexts());
- v8::Debug::SetDebugEventListener(NULL);
+ v8::Debug::SetDebugEventListener2(NULL);
}
diff --git a/test/cctest/test-lockers.cc b/test/cctest/test-lockers.cc
index a8e870e..90e1f75 100644
--- a/test/cctest/test-lockers.cc
+++ b/test/cctest/test-lockers.cc
@@ -41,7 +41,6 @@
#include "parser.h"
#include "unicode-inl.h"
-using ::v8::AccessorInfo;
using ::v8::Context;
using ::v8::Extension;
using ::v8::Function;
diff --git a/test/cctest/test-platform-nullos.cc b/test/cctest/test-platform-nullos.cc
deleted file mode 100644
index 3afbd90..0000000
--- a/test/cctest/test-platform-nullos.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-//
-// Tests of the TokenLock class from lock.h
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <unistd.h> // for usleep()
-
-#include "v8.h"
-
-#include "platform.h"
-#include "cctest.h"
-
-using namespace ::v8::internal;
-
-
-static void yield() {
- UNIMPLEMENTED();
-}
-
-static const int kLockCounterLimit = 50;
-static int busy_lock_counter = 0;
-
-
-static void LoopIncrement(Mutex* mutex, int rem) {
- while (true) {
- int count = 0;
- int last_count = -1;
- do {
- CHECK_EQ(0, mutex->Lock());
- count = busy_lock_counter;
- CHECK_EQ(0, mutex->Unlock());
- yield();
- } while (count % 2 == rem && count < kLockCounterLimit);
- if (count >= kLockCounterLimit) break;
- CHECK_EQ(0, mutex->Lock());
- CHECK_EQ(count, busy_lock_counter);
- CHECK(last_count == -1 || count == last_count + 1);
- busy_lock_counter++;
- last_count = count;
- CHECK_EQ(0, mutex->Unlock());
- yield();
- }
-}
-
-
-static void* RunTestBusyLock(void* arg) {
- LoopIncrement(static_cast<Mutex*>(arg), 0);
- return 0;
-}
-
-
-// Runs two threads that repeatedly acquire the lock and conditionally
-// increment a variable.
-TEST(BusyLock) {
- pthread_t other;
- Mutex* mutex = OS::CreateMutex();
- int thread_created = pthread_create(&other,
- NULL,
- &RunTestBusyLock,
- mutex);
- CHECK_EQ(0, thread_created);
- LoopIncrement(mutex, 1);
- pthread_join(other, NULL);
- delete mutex;
-}
-
-
-TEST(VirtualMemory) {
- VirtualMemory* vm = new VirtualMemory(1 * MB);
- CHECK(vm->IsReserved());
- void* block_addr = vm->address();
- size_t block_size = 4 * KB;
- CHECK(vm->Commit(block_addr, block_size, false));
- // Check whether we can write to memory.
- int* addr = static_cast<int*>(block_addr);
- addr[KB-1] = 2;
- CHECK(vm->Uncommit(block_addr, block_size));
- delete vm;
-}
diff --git a/test/cctest/test-profile-generator.cc b/test/cctest/test-profile-generator.cc
index f56275c..5dd92b6 100644
--- a/test/cctest/test-profile-generator.cc
+++ b/test/cctest/test-profile-generator.cc
@@ -132,14 +132,12 @@
CHECK_EQ(NULL, helper.Walk(&entry3));
ProfileNode* node1 = helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
ProfileNode* node2 = helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node2);
CHECK_NE(node1, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
@@ -147,18 +145,14 @@
CHECK_NE(NULL, node3);
CHECK_NE(node1, node3);
CHECK_NE(node2, node3);
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(1, node3->self_ticks());
tree.AddPathFromStart(path_vec);
CHECK_EQ(node1, helper.Walk(&entry1));
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
CodeEntry* path2[] = {&entry1, &entry2, &entry2};
@@ -172,12 +166,10 @@
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
CHECK_NE(NULL, node4);
CHECK_NE(node3, node4);
- CHECK_EQ(0, node4->total_ticks());
CHECK_EQ(1, node4->self_ticks());
}
@@ -199,14 +191,12 @@
CHECK_EQ(NULL, helper.Walk(&entry3));
ProfileNode* node1 = helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry3));
ProfileNode* node2 = helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node2);
CHECK_NE(node1, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry2));
@@ -214,18 +204,14 @@
CHECK_NE(NULL, node3);
CHECK_NE(node1, node3);
CHECK_NE(node2, node3);
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(1, node3->self_ticks());
tree.AddPathFromEnd(path_vec);
CHECK_EQ(node1, helper.Walk(&entry1));
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(0, node1->self_ticks());
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(0, node2->self_ticks());
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
CodeEntry* path2[] = {&entry2, &entry2, &entry1};
@@ -239,28 +225,18 @@
CHECK_EQ(node2, helper.Walk(&entry1, &entry2));
CHECK_EQ(NULL, helper.Walk(&entry1, &entry2, &entry1));
CHECK_EQ(node3, helper.Walk(&entry1, &entry2, &entry3));
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(2, node3->self_ticks());
ProfileNode* node4 = helper.Walk(&entry1, &entry2, &entry2);
CHECK_NE(NULL, node4);
CHECK_NE(node3, node4);
- CHECK_EQ(0, node4->total_ticks());
CHECK_EQ(1, node4->self_ticks());
}
TEST(ProfileTreeCalculateTotalTicks) {
ProfileTree empty_tree;
- CHECK_EQ(0, empty_tree.root()->total_ticks());
- CHECK_EQ(0, empty_tree.root()->self_ticks());
- empty_tree.CalculateTotalTicks();
- CHECK_EQ(0, empty_tree.root()->total_ticks());
CHECK_EQ(0, empty_tree.root()->self_ticks());
empty_tree.root()->IncrementSelfTicks();
- CHECK_EQ(0, empty_tree.root()->total_ticks());
- CHECK_EQ(1, empty_tree.root()->self_ticks());
- empty_tree.CalculateTotalTicks();
- CHECK_EQ(1, empty_tree.root()->total_ticks());
CHECK_EQ(1, empty_tree.root()->self_ticks());
CodeEntry entry1(i::Logger::FUNCTION_TAG, "aaa");
@@ -271,17 +247,11 @@
ProfileTree single_child_tree;
single_child_tree.AddPathFromStart(e1_path_vec);
single_child_tree.root()->IncrementSelfTicks();
- CHECK_EQ(0, single_child_tree.root()->total_ticks());
CHECK_EQ(1, single_child_tree.root()->self_ticks());
ProfileTreeTestHelper single_child_helper(&single_child_tree);
ProfileNode* node1 = single_child_helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
- CHECK_EQ(1, node1->self_ticks());
- single_child_tree.CalculateTotalTicks();
- CHECK_EQ(2, single_child_tree.root()->total_ticks());
CHECK_EQ(1, single_child_tree.root()->self_ticks());
- CHECK_EQ(1, node1->total_ticks());
CHECK_EQ(1, node1->self_ticks());
CodeEntry entry2(i::Logger::FUNCTION_TAG, "bbb");
@@ -297,24 +267,16 @@
flat_tree.AddPathFromStart(e1_e2_path_vec);
flat_tree.AddPathFromStart(e1_e2_path_vec);
// Results in {root,0,0} -> {entry1,0,2} -> {entry2,0,3}
- CHECK_EQ(0, flat_tree.root()->total_ticks());
CHECK_EQ(0, flat_tree.root()->self_ticks());
node1 = flat_helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
ProfileNode* node2 = flat_helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(3, node2->self_ticks());
- flat_tree.CalculateTotalTicks();
// Must calculate {root,5,0} -> {entry1,5,2} -> {entry2,3,3}
- CHECK_EQ(5, flat_tree.root()->total_ticks());
CHECK_EQ(0, flat_tree.root()->self_ticks());
- CHECK_EQ(5, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
- CHECK_EQ(3, node2->total_ticks());
- CHECK_EQ(3, node2->self_ticks());
CodeEntry* e2_path[] = {&entry2};
Vector<CodeEntry*> e2_path_vec(
@@ -339,37 +301,26 @@
// Results in -> {entry1,0,2} -> {entry2,0,1}
// {root,0,0} -> {entry2,0,3}
// -> {entry3,0,4}
- CHECK_EQ(0, wide_tree.root()->total_ticks());
CHECK_EQ(0, wide_tree.root()->self_ticks());
node1 = wide_helper.Walk(&entry1);
CHECK_NE(NULL, node1);
- CHECK_EQ(0, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
ProfileNode* node1_2 = wide_helper.Walk(&entry1, &entry2);
CHECK_NE(NULL, node1_2);
- CHECK_EQ(0, node1_2->total_ticks());
CHECK_EQ(1, node1_2->self_ticks());
node2 = wide_helper.Walk(&entry2);
CHECK_NE(NULL, node2);
- CHECK_EQ(0, node2->total_ticks());
CHECK_EQ(3, node2->self_ticks());
ProfileNode* node3 = wide_helper.Walk(&entry3);
CHECK_NE(NULL, node3);
- CHECK_EQ(0, node3->total_ticks());
CHECK_EQ(4, node3->self_ticks());
- wide_tree.CalculateTotalTicks();
// Calculates -> {entry1,3,2} -> {entry2,1,1}
// {root,10,0} -> {entry2,3,3}
// -> {entry3,4,4}
- CHECK_EQ(10, wide_tree.root()->total_ticks());
CHECK_EQ(0, wide_tree.root()->self_ticks());
- CHECK_EQ(3, node1->total_ticks());
CHECK_EQ(2, node1->self_ticks());
- CHECK_EQ(1, node1_2->total_ticks());
CHECK_EQ(1, node1_2->self_ticks());
- CHECK_EQ(3, node2->total_ticks());
CHECK_EQ(3, node2->self_ticks());
- CHECK_EQ(4, node3->total_ticks());
CHECK_EQ(4, node3->self_ticks());
}
diff --git a/test/mjsunit/allocation-folding.js b/test/mjsunit/allocation-folding.js
index fe5fa6d..ec07392 100644
--- a/test/mjsunit/allocation-folding.js
+++ b/test/mjsunit/allocation-folding.js
@@ -56,7 +56,7 @@
doubles(); doubles(); doubles();
%OptimizeFunctionOnNextCall(doubles);
-var result = doubles();
+result = doubles();
gc();
@@ -72,8 +72,31 @@
doubles_int(); doubles_int(); doubles_int();
%OptimizeFunctionOnNextCall(doubles_int);
-var result = doubles_int();
+result = doubles_int();
gc();
assertEquals(result[1], 3.1);
+
+// Test allocation folding over a branch.
+
+function branch_int(left) {
+ var elem1 = [1, 2];
+ var elem2;
+ if (left) {
+ elem2 = [3, 4];
+ } else {
+ elem2 = [5, 6];
+ }
+ return elem2;
+}
+
+branch_int(1); branch_int(1); branch_int(1);
+%OptimizeFunctionOnNextCall(branch_int);
+result = branch_int(1);
+var result2 = branch_int(0);
+
+gc();
+
+assertEquals(result[1], 4);
+assertEquals(result2[1], 6);
diff --git a/test/mjsunit/array-push-non-smi-value.js b/test/mjsunit/array-push-non-smi-value.js
new file mode 100644
index 0000000..460dd2a
--- /dev/null
+++ b/test/mjsunit/array-push-non-smi-value.js
@@ -0,0 +1,36 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Check pushes of non-SMI values.
+var a = [];
+function func() {
+ return a.push(0x40000000) > 60;
+}
+
+assertFalse(func());
+assertFalse(func());
+assertFalse(func());
diff --git a/test/mjsunit/compiler/increment-typefeedback.js b/test/mjsunit/compiler/increment-typefeedback.js
new file mode 100644
index 0000000..7989592
--- /dev/null
+++ b/test/mjsunit/compiler/increment-typefeedback.js
@@ -0,0 +1,39 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax
+
+function f(x) {
+ x++;
+ return x;
+}
+
+f(0.5);
+f(0.5);
+%OptimizeFunctionOnNextCall(f);
+f(0.5);
+assertOptimized(f);
diff --git a/test/mjsunit/smi-mul.js b/test/mjsunit/smi-mul.js
new file mode 100644
index 0000000..6f23d5e
--- /dev/null
+++ b/test/mjsunit/smi-mul.js
@@ -0,0 +1,67 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+// Flags: --allow-natives-syntax --noalways-opt
+
+function mul(a, b) {
+ return a * b;
+}
+
+
+mul(-1, 2);
+mul(-1, 2);
+%OptimizeFunctionOnNextCall(mul);
+assertEquals(-2, mul(-1, 2));
+assertOptimized(mul);
+
+// Deopt on minus zero.
+assertEquals(-0, mul(-1, 0));
+assertUnoptimized(mul);
+
+
+function mul2(a, b) {
+ return a * b;
+}
+
+mul2(-1, 2);
+mul2(-1, 2);
+%OptimizeFunctionOnNextCall(mul2);
+
+// 2^30 is a smi boundary on arm and ia32.
+var two_30 = 1 << 30;
+// 2^31 is a smi boundary on x64.
+var two_31 = 2 * two_30;
+
+if (%IsValidSmi(two_31)) {
+ // Deopt on two_31 on x64.
+ assertEquals(two_31, mul2(-two_31, -1));
+ assertUnoptimized(mul2);
+} else {
+ // Deopt on two_30 on ia32.
+ assertEquals(two_30, mul2(-two_30, -1));
+ assertUnoptimized(mul2);
+}