Version 3.26.0 (based on bleeding_edge revision r20354)
Deprecate Start/StopCpuProfiling methods (issue 3213).
Don't crash if we get a timezone change notification on an uninitialized isolate (Chromium issue 357362).
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@20359 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/ChangeLog b/ChangeLog
index 879515d..708e04e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2014-03-31: Version 3.26.0
+
+ Deprecate Start/StopCpuProfiling methods (issue 3213).
+
+ Don't crash if we get a timezone change notification on an uninitialized
+ isolate (Chromium issue 357362).
+
+ Performance and stability improvements on all platforms.
+
+
2014-03-28: Version 3.25.30
NativeContext::map_cache reference should be strong in heap snapshots
diff --git a/include/v8-profiler.h b/include/v8-profiler.h
index 1691f29..f5b760a 100644
--- a/include/v8-profiler.h
+++ b/include/v8-profiler.h
@@ -164,7 +164,9 @@
void StartProfiling(Handle<String> title, bool record_samples = false);
/** Deprecated. Use StartProfiling instead. */
- void StartCpuProfiling(Handle<String> title, bool record_samples = false);
+ V8_DEPRECATED("Use StartProfiling",
+ void StartCpuProfiling(Handle<String> title,
+ bool record_samples = false));
/**
* Stops collecting CPU profile with a given title and returns it.
@@ -173,7 +175,8 @@
CpuProfile* StopProfiling(Handle<String> title);
/** Deprecated. Use StopProfiling instead. */
- const CpuProfile* StopCpuProfiling(Handle<String> title);
+ V8_DEPRECATED("Use StopProfiling",
+ const CpuProfile* StopCpuProfiling(Handle<String> title));
/**
* Tells the profiler whether the embedder is idle.
diff --git a/include/v8-util.h b/include/v8-util.h
index 3f8cc6d..accc6a4 100644
--- a/include/v8-util.h
+++ b/include/v8-util.h
@@ -30,6 +30,7 @@
#include "v8.h"
#include <map>
+#include <vector>
/**
* Support for Persistent containers.
@@ -42,6 +43,10 @@
typedef uintptr_t PersistentContainerValue;
static const uintptr_t kPersistentContainerNotFound = 0;
+enum PersistentContainerCallbackType {
+ kNotWeak,
+ kWeak
+};
/**
@@ -92,38 +97,34 @@
/**
* A default trait implementation for PersistentValueMap, which inherits
* a std:map backing map from StdMapTraits and holds non-weak persistent
- * objects.
+ * objects and has no special Dispose handling.
*
- * Users have to implement their own dispose trait.
+ * You should not derive from this class, since MapType depends on the
+ * surrounding class, and hence a subclass cannot simply inherit the methods.
*/
template<typename K, typename V>
-class StrongMapTraits : public StdMapTraits<K, V> {
+class DefaultPersistentValueMapTraits : public StdMapTraits<K, V> {
public:
// Weak callback & friends:
- static const bool kIsWeak = false;
- typedef typename StdMapTraits<K, V>::Impl Impl;
+ static const PersistentContainerCallbackType kCallbackType = kNotWeak;
+ typedef PersistentValueMap<K, V, DefaultPersistentValueMapTraits<K, V> >
+ MapType;
typedef void WeakCallbackDataType;
+
static WeakCallbackDataType* WeakCallbackParameter(
- Impl* impl, const K& key, Local<V> value);
- static Impl* ImplFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data);
+ MapType* map, const K& key, Local<V> value) {
+ return NULL;
+ }
+ static MapType* MapFromWeakCallbackData(
+ const WeakCallbackData<V, WeakCallbackDataType>& data) {
+ return NULL;
+ }
static K KeyFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data);
- static void DisposeCallbackData(WeakCallbackDataType* data);
-};
-
-
-/**
- * A default trait implementation for PersistentValueMap, with a std::map
- * backing map, non-weak persistents as values, and no special dispose
- * handling. Can be used as-is.
- */
-template<typename K, typename V>
-class DefaultPersistentValueMapTraits : public StrongMapTraits<K, V> {
- public:
- typedef typename StrongMapTraits<K, V>::Impl Impl;
- static void Dispose(Isolate* isolate, UniquePersistent<V> value,
- Impl* impl, K key) { }
+ const WeakCallbackData<V, WeakCallbackDataType>& data) {
+ return K();
+ }
+ static void DisposeCallbackData(WeakCallbackDataType* data) { }
+ static void Dispose(Isolate* isolate, UniquePersistent<V> value, K key) { }
};
@@ -154,7 +155,7 @@
/**
* Return whether the map holds weak persistents.
*/
- V8_INLINE bool IsWeak() { return Traits::kIsWeak; }
+ V8_INLINE bool IsWeak() { return Traits::kCallbackType != kNotWeak; }
/**
* Get value stored in map.
@@ -167,7 +168,7 @@
* Check whether a value is contained in the map.
*/
V8_INLINE bool Contains(const K& key) {
- return Traits::Get(&impl_, key) != 0;
+ return Traits::Get(&impl_, key) != kPersistentContainerNotFound;
}
/**
@@ -175,14 +176,8 @@
* Return true if a value was found.
*/
V8_INLINE bool SetReturnValue(const K& key,
- ReturnValue<Value>& returnValue) {
- PersistentContainerValue value = Traits::Get(&impl_, key);
- bool hasValue = value != 0;
- if (hasValue) {
- returnValue.SetInternal(
- *reinterpret_cast<internal::Object**>(FromVal(value)));
- }
- return hasValue;
+ ReturnValue<Value> returnValue) {
+ return SetReturnValueFromVal(returnValue, Traits::Get(&impl_, key));
}
/**
@@ -231,12 +226,76 @@
typename Traits::Impl impl;
Traits::Swap(impl_, impl);
for (It i = Traits::Begin(&impl); i != Traits::End(&impl); ++i) {
- Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(), &impl,
- Traits::Key(i));
+ Traits::Dispose(isolate_, Release(Traits::Value(i)).Pass(),
+ Traits::Key(i));
}
}
}
+ /**
+ * Helper class for GetReference/SetWithReference. Do not use outside
+ * that context.
+ */
+ class PersistentValueReference {
+ public:
+ PersistentValueReference() : value_(kPersistentContainerNotFound) { }
+ PersistentValueReference(const PersistentValueReference& other)
+ : value_(other.value_) { }
+
+ Local<V> NewLocal(Isolate* isolate) const {
+ return Local<V>::New(isolate, FromVal(value_));
+ }
+ bool IsEmpty() const {
+ return value_ == kPersistentContainerNotFound;
+ }
+ template<typename T>
+ bool SetReturnValue(ReturnValue<T> returnValue) {
+ return SetReturnValueFromVal(returnValue, value_);
+ }
+ void Reset() {
+ value_ = kPersistentContainerNotFound;
+ }
+ void operator=(const PersistentValueReference& other) {
+ value_ = other.value_;
+ }
+
+ private:
+ friend class PersistentValueMap;
+
+ explicit PersistentValueReference(PersistentContainerValue value)
+ : value_(value) { }
+
+ void operator=(PersistentContainerValue value) {
+ value_ = value;
+ }
+
+ PersistentContainerValue value_;
+ };
+
+ /**
+ * Get a reference to a map value. This enables fast, repeated access
+ * to a value stored in the map while the map remains unchanged.
+ *
+ * Careful: This is potentially unsafe, so please use with care.
+ * The value will become invalid if the value for this key changes
+ * in the underlying map, as a result of Set or Remove for the same
+ * key; as a result of the weak callback for the same key; or as a
+ * result of calling Clear() or destruction of the map.
+ */
+ V8_INLINE PersistentValueReference GetReference(const K& key) {
+ return PersistentValueReference(Traits::Get(&impl_, key));
+ }
+
+ /**
+ * Put a value into the map and update the reference.
+ * Restrictions of GetReference apply here as well.
+ */
+ UniquePersistent<V> Set(const K& key, UniquePersistent<V> value,
+ PersistentValueReference* reference) {
+ *reference = Leak(&value);
+ return SetUnique(key, &value);
+ }
+
private:
PersistentValueMap(PersistentValueMap&);
void operator=(PersistentValueMap&);
@@ -246,10 +305,10 @@
* by the Traits class.
*/
UniquePersistent<V> SetUnique(const K& key, UniquePersistent<V>* persistent) {
- if (Traits::kIsWeak) {
+ if (Traits::kCallbackType != kNotWeak) {
Local<V> value(Local<V>::New(isolate_, *persistent));
persistent->template SetWeak<typename Traits::WeakCallbackDataType>(
- Traits::WeakCallbackParameter(&impl_, key, value), WeakCallback);
+ Traits::WeakCallbackParameter(this, key, value), WeakCallback);
}
PersistentContainerValue old_value =
Traits::Set(&impl_, key, ClearAndLeak(persistent));
@@ -258,11 +317,12 @@
static void WeakCallback(
const WeakCallbackData<V, typename Traits::WeakCallbackDataType>& data) {
- if (Traits::kIsWeak) {
- typename Traits::Impl* impl = Traits::ImplFromWeakCallbackData(data);
+ if (Traits::kCallbackType != kNotWeak) {
+ PersistentValueMap<K, V, Traits>* persistentValueMap =
+ Traits::MapFromWeakCallbackData(data);
K key = Traits::KeyFromWeakCallbackData(data);
- PersistentContainerValue value = Traits::Remove(impl, key);
- Traits::Dispose(data.GetIsolate(), Release(value).Pass(), impl, key);
+ Traits::Dispose(data.GetIsolate(),
+ persistentValueMap->Remove(key).Pass(), key);
}
}
@@ -270,6 +330,16 @@
return reinterpret_cast<V*>(v);
}
+ V8_INLINE static bool SetReturnValueFromVal(
+ ReturnValue<Value>& returnValue, PersistentContainerValue value) {
+ bool hasValue = value != kPersistentContainerNotFound;
+ if (hasValue) {
+ returnValue.SetInternal(
+ *reinterpret_cast<internal::Object**>(FromVal(value)));
+ }
+ return hasValue;
+ }
+
V8_INLINE static PersistentContainerValue ClearAndLeak(
UniquePersistent<V>* persistent) {
V* v = persistent->val_;
@@ -277,6 +347,11 @@
return reinterpret_cast<PersistentContainerValue>(v);
}
+ V8_INLINE static PersistentContainerValue Leak(
+ UniquePersistent<V>* persistent) {
+ return reinterpret_cast<PersistentContainerValue>(persistent->val_);
+ }
+
/**
* Return a container value as UniquePersistent and make sure the weak
* callback is properly disposed of. All remove functionality should go
@@ -285,7 +360,7 @@
V8_INLINE static UniquePersistent<V> Release(PersistentContainerValue v) {
UniquePersistent<V> p;
p.val_ = FromVal(v);
- if (Traits::kIsWeak && !p.IsEmpty()) {
+ if (Traits::kCallbackType != kNotWeak && !p.IsEmpty()) {
Traits::DisposeCallbackData(
p.template ClearWeak<typename Traits::WeakCallbackDataType>());
}
@@ -313,42 +388,121 @@
};
+class DefaultPersistentValueVectorTraits {
+ public:
+ typedef std::vector<PersistentContainerValue> Impl;
+
+ static void Append(Impl* impl, PersistentContainerValue value) {
+ impl->push_back(value);
+ }
+ static bool IsEmpty(const Impl* impl) {
+ return impl->empty();
+ }
+ static size_t Size(const Impl* impl) {
+ return impl->size();
+ }
+ static PersistentContainerValue Get(const Impl* impl, size_t i) {
+ return (i < impl->size()) ? impl->at(i) : kPersistentContainerNotFound;
+ }
+ static void ReserveCapacity(Impl* impl, size_t capacity) {
+ impl->reserve(capacity);
+ }
+ static void Clear(Impl* impl) {
+ impl->clear();
+ }
+};
+
+
/**
- * Empty default implementations for StrongTraits methods.
+ * A vector wrapper that safely stores UniquePersistent values.
+ * C++11 embedders don't need this class, as they can use UniquePersistent
+ * directly in std containers.
*
- * These should not be necessary, since they're only used in code that
- * is surrounded by if(Traits::kIsWeak), which for StrongMapTraits is
- * compile-time false. Most compilers can live without them; however
- * the compiler we use from 64-bit Win differs.
- *
- * TODO(vogelheim): Remove these once they're no longer necessary.
+ * This class relies on a backing vector implementation, whose type and methods
+ * are described by the Traits class. The backing map will handle values of type
+ * PersistentContainerValue, with all conversion into and out of V8
+ * handles being transparently handled by this class.
*/
-template<typename K, typename V>
-typename StrongMapTraits<K, V>::WeakCallbackDataType*
- StrongMapTraits<K, V>::WeakCallbackParameter(
- Impl* impl, const K& key, Local<V> value) {
- return NULL;
-}
+template<typename V, typename Traits = DefaultPersistentValueVectorTraits>
+class PersistentValueVector {
+ public:
+ explicit PersistentValueVector(Isolate* isolate) : isolate_(isolate) { }
+ ~PersistentValueVector() {
+ Clear();
+ }
-template<typename K, typename V>
-typename StrongMapTraits<K, V>::Impl*
- StrongMapTraits<K, V>::ImplFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data) {
- return NULL;
-}
+ /**
+ * Append a value to the vector.
+ */
+ void Append(Local<V> value) {
+ UniquePersistent<V> persistent(isolate_, value);
+ Traits::Append(&impl_, ClearAndLeak(&persistent));
+ }
+ /**
+ * Append a persistent's value to the vector.
+ */
+ void Append(UniquePersistent<V> persistent) {
+ Traits::Append(&impl_, ClearAndLeak(&persistent));
+ };
-template<typename K, typename V>
-K StrongMapTraits<K, V>::KeyFromWeakCallbackData(
- const WeakCallbackData<V, WeakCallbackDataType>& data) {
- return K();
-}
+ /**
+ * Are there any values in the vector?
+ */
+ bool IsEmpty() const {
+ return Traits::IsEmpty(&impl_);
+ }
+ /**
+ * How many elements are in the vector?
+ */
+ size_t Size() const {
+ return Traits::Size(&impl_);
+ }
-template<typename K, typename V>
-void StrongMapTraits<K, V>::DisposeCallbackData(WeakCallbackDataType* data) {
-}
+ /**
+ * Retrieve the i-th value in the vector.
+ */
+ Local<V> Get(size_t index) const {
+ return Local<V>::New(isolate_, FromVal(Traits::Get(&impl_, index)));
+ }
+
+ /**
+ * Remove all elements from the vector.
+ */
+ void Clear() {
+ size_t length = Traits::Size(&impl_);
+ for (size_t i = 0; i < length; i++) {
+ UniquePersistent<V> p;
+ p.val_ = FromVal(Traits::Get(&impl_, i));
+ }
+ Traits::Clear(&impl_);
+ }
+
+ /**
+ * Reserve capacity in the vector.
+ * (Efficiency gains depend on the backing implementation.)
+ */
+ void ReserveCapacity(size_t capacity) {
+ Traits::ReserveCapacity(&impl_, capacity);
+ }
+
+ private:
+ static PersistentContainerValue ClearAndLeak(
+ UniquePersistent<V>* persistent) {
+ V* v = persistent->val_;
+ persistent->val_ = 0;
+ return reinterpret_cast<PersistentContainerValue>(v);
+ }
+
+ static V* FromVal(PersistentContainerValue v) {
+ return reinterpret_cast<V*>(v);
+ }
+
+ Isolate* isolate_;
+ typename Traits::Impl impl_;
+};
} // namespace v8
diff --git a/include/v8.h b/include/v8.h
index 608e3c5..5f5e08d 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -129,6 +129,7 @@
class M = NonCopyablePersistentTraits<T> > class Persistent;
template<class T> class UniquePersistent;
template<class K, class V, class T> class PersistentValueMap;
+template<class V, class T> class PersistentValueVector;
template<class T, class P> class WeakCallbackObject;
class FunctionTemplate;
class ObjectTemplate;
@@ -417,6 +418,7 @@
friend class HandleScope;
friend class EscapableHandleScope;
template<class F1, class F2, class F3> friend class PersistentValueMap;
+ template<class F1, class F2> friend class PersistentValueVector;
V8_INLINE static Local<T> New(Isolate* isolate, T* that);
};
@@ -586,6 +588,7 @@
template<class F> friend class PersistentBase;
template<class F> friend class ReturnValue;
template<class F1, class F2, class F3> friend class PersistentValueMap;
+ template<class F1, class F2> friend class PersistentValueVector;
friend class Object;
explicit V8_INLINE PersistentBase(T* val) : val_(val) {}
diff --git a/src/api.cc b/src/api.cc
index 5dcf592..56fc792 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -1941,7 +1941,7 @@
i::Handle<i::JSObject> obj(i::JSObject::cast(raw_obj), isolate_);
i::Handle<i::String> name = isolate_->factory()->stack_string();
if (!i::JSReceiver::HasProperty(obj, name)) return v8::Local<Value>();
- i::Handle<i::Object> value = i::GetProperty(isolate_, obj, name);
+ i::Handle<i::Object> value = i::Object::GetProperty(obj, name);
if (value.is_null()) return v8::Local<Value>();
return v8::Utils::ToLocal(scope.CloseAndEscape(value));
} else {
@@ -3143,7 +3143,8 @@
i::Handle<i::Object> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
EXCEPTION_PREAMBLE(isolate);
- i::Handle<i::Object> result = i::GetProperty(isolate, self, key_obj);
+ i::Handle<i::Object> result =
+ i::Runtime::GetObjectProperty(isolate, self, key_obj);
has_pending_exception = result.is_null();
EXCEPTION_BAILOUT_CHECK(isolate, Local<Value>());
return Utils::ToLocal(result);
@@ -5710,6 +5711,7 @@
void v8::Date::DateTimeConfigurationChangeNotification(Isolate* isolate) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ if (!i_isolate->IsInitialized()) return;
ON_BAILOUT(i_isolate, "v8::Date::DateTimeConfigurationChangeNotification()",
return);
LOG_API(i_isolate, "Date::DateTimeConfigurationChangeNotification");
@@ -5832,7 +5834,7 @@
bool Value::IsPromise() const {
i::Handle<i::Object> val = Utils::OpenHandle(this);
- if (!val->IsJSObject()) return false;
+ if (!i::FLAG_harmony_promises || !val->IsJSObject()) return false;
i::Handle<i::JSObject> obj = i::Handle<i::JSObject>::cast(val);
i::Isolate* isolate = obj->GetIsolate();
LOG_API(isolate, "IsPromise");
@@ -6156,8 +6158,10 @@
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->for_string();
i::Handle<i::JSObject> symbols =
- i::Handle<i::JSObject>::cast(i::JSObject::GetProperty(registry, part));
- i::Handle<i::Object> symbol = i::JSObject::GetProperty(symbols, i_name);
+ i::Handle<i::JSObject>::cast(
+ i::Object::GetPropertyOrElement(registry, part));
+ i::Handle<i::Object> symbol =
+ i::Object::GetPropertyOrElement(symbols, i_name);
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = i_isolate->factory()->NewSymbol();
@@ -6174,8 +6178,10 @@
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->for_api_string();
i::Handle<i::JSObject> symbols =
- i::Handle<i::JSObject>::cast(i::JSObject::GetProperty(registry, part));
- i::Handle<i::Object> symbol = i::JSObject::GetProperty(symbols, i_name);
+ i::Handle<i::JSObject>::cast(
+ i::Object::GetPropertyOrElement(registry, part));
+ i::Handle<i::Object> symbol =
+ i::Object::GetPropertyOrElement(symbols, i_name);
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = i_isolate->factory()->NewSymbol();
@@ -6204,8 +6210,10 @@
i::Handle<i::JSObject> registry = i_isolate->GetSymbolRegistry();
i::Handle<i::String> part = i_isolate->factory()->private_api_string();
i::Handle<i::JSObject> privates =
- i::Handle<i::JSObject>::cast(i::JSObject::GetProperty(registry, part));
- i::Handle<i::Object> symbol = i::JSObject::GetProperty(privates, i_name);
+ i::Handle<i::JSObject>::cast(
+ i::Object::GetPropertyOrElement(registry, part));
+ i::Handle<i::Object> symbol =
+ i::Object::GetPropertyOrElement(privates, i_name);
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = i_isolate->factory()->NewPrivateSymbol();
@@ -6955,7 +6963,8 @@
i::Handle<i::JSObject> debug(isolate_debug->debug_context()->global_object());
i::Handle<i::String> name = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("MakeMirror"));
- i::Handle<i::Object> fun_obj = i::GetProperty(isolate, debug, name);
+ i::Handle<i::Object> fun_obj = i::Object::GetProperty(debug, name);
+ ASSERT(!fun_obj.is_null());
i::Handle<i::JSFunction> fun = i::Handle<i::JSFunction>::cast(fun_obj);
v8::Handle<v8::Function> v8_fun = Utils::ToLocal(fun);
const int kArgc = 1;
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index 832296b..aadfb29 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1428,7 +1428,7 @@
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in exponent.
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index b5ec2d5..2ca8016 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -3759,26 +3759,6 @@
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(r0);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(r0);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 55705b8..c280999 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -2225,17 +2225,18 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), r0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 7152ba2..9cf94ee 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -4381,15 +4381,15 @@
scratch, GetLinkRegisterState(), kDontSaveFPRegs);
} else {
ASSERT(ToRegister(instr->context()).is(cp));
+ ASSERT(object_reg.is(r0));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ Move(r0, object_reg);
__ Move(r1, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ bind(¬_applicable);
}
diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc
index b097fc5..7e8267b 100644
--- a/src/arm64/code-stubs-arm64.cc
+++ b/src/arm64/code-stubs-arm64.cc
@@ -1389,7 +1389,7 @@
__ Bind(&call_runtime);
// Put the arguments back on the stack.
__ Push(base_tagged, exponent_tagged);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// Return.
__ Bind(&done);
diff --git a/src/arm64/full-codegen-arm64.cc b/src/arm64/full-codegen-arm64.cc
index d40e74a..d8f1402 100644
--- a/src/arm64/full-codegen-arm64.cc
+++ b/src/arm64/full-codegen-arm64.cc
@@ -3492,26 +3492,6 @@
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(x0);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(x0);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ASM_LOCATION("FullCodeGenerator::EmitCallFunction");
ZoneList<Expression*>* args = expr->arguments();
diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
index 60bf51e..6dccc5f 100644
--- a/src/arm64/lithium-arm64.cc
+++ b/src/arm64/lithium-arm64.cc
@@ -2365,17 +2365,18 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL,
TempRegister(), TempRegister());
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), x0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
- new(zone()) LTransitionElementsKind(object, context, TempRegister());
- return AssignPointerMap(result);
+ new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
+ return MarkAsCall(result, instr);
}
}
diff --git a/src/arm64/lithium-arm64.h b/src/arm64/lithium-arm64.h
index da3c5f1..fcb1552 100644
--- a/src/arm64/lithium-arm64.h
+++ b/src/arm64/lithium-arm64.h
@@ -2778,7 +2778,7 @@
LTransitionElementsKind(LOperand* object,
LOperand* context,
LOperand* temp1,
- LOperand* temp2 = NULL) {
+ LOperand* temp2) {
inputs_[0] = object;
inputs_[1] = context;
temps_[0] = temp1;
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc
index cd931e9..abae911 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -5659,7 +5659,6 @@
void LCodeGen::DoTransitionElementsKind(LTransitionElementsKind* instr) {
Register object = ToRegister(instr->object());
- Register temp1 = ToRegister(instr->temp1());
Handle<Map> from_map = instr->original_map();
Handle<Map> to_map = instr->transitioned_map();
@@ -5667,26 +5666,34 @@
ElementsKind to_kind = instr->to_kind();
Label not_applicable;
- __ CheckMap(object, temp1, from_map, ¬_applicable, DONT_DO_SMI_CHECK);
if (IsSimpleMapChangeTransition(from_kind, to_kind)) {
+ Register temp1 = ToRegister(instr->temp1());
Register new_map = ToRegister(instr->temp2());
+ __ CheckMap(object, temp1, from_map, ¬_applicable, DONT_DO_SMI_CHECK);
__ Mov(new_map, Operand(to_map));
__ Str(new_map, FieldMemOperand(object, HeapObject::kMapOffset));
// Write barrier.
__ RecordWriteField(object, HeapObject::kMapOffset, new_map, temp1,
GetLinkRegisterState(), kDontSaveFPRegs);
} else {
+ {
+ UseScratchRegisterScope temps(masm());
+ // Use the temp register only in a restricted scope - the codegen checks
+ // that we do not use any register across a call.
+ __ CheckMap(object, temps.AcquireX(), from_map, ¬_applicable,
+ DONT_DO_SMI_CHECK);
+ }
+ ASSERT(object.is(x0));
ASSERT(ToRegister(instr->context()).is(cp));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ Mov(x0, object);
__ Mov(x1, Operand(to_map));
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ Bind(¬_applicable);
}
diff --git a/src/arraybuffer.js b/src/arraybuffer.js
index d5fd9ad..07924e4 100644
--- a/src/arraybuffer.js
+++ b/src/arraybuffer.js
@@ -45,7 +45,7 @@
throw MakeTypeError('incompatible_method_receiver',
['ArrayBuffer.prototype.byteLength', this]);
}
- return %ArrayBufferGetByteLength(this);
+ return %_ArrayBufferGetByteLength(this);
}
// ES6 Draft 15.13.5.5.3
@@ -60,7 +60,7 @@
end = TO_INTEGER(end);
}
var first;
- var byte_length = %ArrayBufferGetByteLength(this);
+ var byte_length = %_ArrayBufferGetByteLength(this);
if (relativeStart < 0) {
first = MathMax(byte_length + relativeStart, 0);
} else {
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index c4d7adf..dc0d902 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -1,44 +1,12 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include "v8.h"
+#include "bootstrapper.h"
#include "accessors.h"
-#include "api.h"
-#include "bootstrapper.h"
-#include "compiler.h"
-#include "debug.h"
-#include "execution.h"
-#include "global-handles.h"
#include "isolate-inl.h"
-#include "macro-assembler.h"
#include "natives.h"
-#include "objects-visiting.h"
-#include "platform.h"
#include "snapshot.h"
#include "trig-table.h"
#include "extensions/externalize-string-extension.h"
@@ -51,7 +19,6 @@
namespace v8 {
namespace internal {
-
NativesExternalStringResource::NativesExternalStringResource(
Bootstrapper* bootstrapper,
const char* source,
@@ -154,7 +121,7 @@
void Bootstrapper::TearDown() {
if (delete_these_non_arrays_on_tear_down_ != NULL) {
int len = delete_these_non_arrays_on_tear_down_->length();
- ASSERT(len < 24); // Don't use this mechanism for unbounded allocations.
+ ASSERT(len < 20); // Don't use this mechanism for unbounded allocations.
for (int i = 0; i < len; i++) {
delete delete_these_non_arrays_on_tear_down_->at(i);
delete_these_non_arrays_on_tear_down_->at(i) = NULL;
@@ -1114,18 +1081,6 @@
native_context()->set_data_view_fun(*data_view_fun);
}
- { // -- W e a k M a p
- InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
- isolate->initial_object_prototype(),
- Builtins::kIllegal, true, true);
- }
-
- { // -- W e a k S e t
- InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
- isolate->initial_object_prototype(),
- Builtins::kIllegal, true, true);
- }
-
{ // --- arguments_boilerplate_
// Make sure we can recognize argument objects at runtime.
// This is done by introducing an anonymous function with
@@ -1373,6 +1328,19 @@
}
}
+ if (FLAG_harmony_weak_collections) {
+ { // -- W e a k M a p
+ InstallFunction(global, "WeakMap", JS_WEAK_MAP_TYPE, JSWeakMap::kSize,
+ isolate()->initial_object_prototype(),
+ Builtins::kIllegal, true, true);
+ }
+ { // -- W e a k S e t
+ InstallFunction(global, "WeakSet", JS_WEAK_SET_TYPE, JSWeakSet::kSize,
+ isolate()->initial_object_prototype(),
+ Builtins::kIllegal, true, true);
+ }
+ }
+
if (FLAG_harmony_generators) {
// Create generator meta-objects and install them on the builtins object.
Handle<JSObject> builtins(native_context()->builtins());
@@ -1567,7 +1535,6 @@
void Genesis::InstallNativeFunctions() {
HandleScope scope(isolate());
INSTALL_NATIVE(JSFunction, "CreateDate", create_date_fun);
-
INSTALL_NATIVE(JSFunction, "ToNumber", to_number_fun);
INSTALL_NATIVE(JSFunction, "ToString", to_string_fun);
INSTALL_NATIVE(JSFunction, "ToDetailString", to_detail_string_fun);
@@ -1575,7 +1542,6 @@
INSTALL_NATIVE(JSFunction, "ToInteger", to_integer_fun);
INSTALL_NATIVE(JSFunction, "ToUint32", to_uint32_fun);
INSTALL_NATIVE(JSFunction, "ToInt32", to_int32_fun);
-
INSTALL_NATIVE(JSFunction, "GlobalEval", global_eval_fun);
INSTALL_NATIVE(JSFunction, "Instantiate", instantiate_fun);
INSTALL_NATIVE(JSFunction, "ConfigureTemplateInstance",
@@ -1584,14 +1550,6 @@
INSTALL_NATIVE(JSObject, "functionCache", function_cache);
INSTALL_NATIVE(JSFunction, "ToCompletePropertyDescriptor",
to_complete_property_descriptor);
-
- INSTALL_NATIVE(JSFunction, "IsPromise", is_promise);
- INSTALL_NATIVE(JSFunction, "PromiseCreate", promise_create);
- INSTALL_NATIVE(JSFunction, "PromiseResolve", promise_resolve);
- INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject);
- INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain);
- INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch);
-
INSTALL_NATIVE(JSFunction, "NotifyChange", observers_notify_change);
INSTALL_NATIVE(JSFunction, "EnqueueSpliceRecord", observers_enqueue_splice);
INSTALL_NATIVE(JSFunction, "BeginPerformSplice",
@@ -1606,6 +1564,15 @@
INSTALL_NATIVE(JSFunction, "EnqueueExternalMicrotask",
enqueue_external_microtask);
+ if (FLAG_harmony_promises) {
+ INSTALL_NATIVE(JSFunction, "IsPromise", is_promise);
+ INSTALL_NATIVE(JSFunction, "PromiseCreate", promise_create);
+ INSTALL_NATIVE(JSFunction, "PromiseResolve", promise_resolve);
+ INSTALL_NATIVE(JSFunction, "PromiseReject", promise_reject);
+ INSTALL_NATIVE(JSFunction, "PromiseChain", promise_chain);
+ INSTALL_NATIVE(JSFunction, "PromiseCatch", promise_catch);
+ }
+
if (FLAG_harmony_proxies) {
INSTALL_NATIVE(JSFunction, "DerivedHasTrap", derived_has_trap);
INSTALL_NATIVE(JSFunction, "DerivedGetTrap", derived_get_trap);
@@ -1938,8 +1905,8 @@
// Install Function.prototype.call and apply.
{ Handle<String> key = factory()->function_class_string();
Handle<JSFunction> function =
- Handle<JSFunction>::cast(
- GetProperty(isolate(), isolate()->global_object(), key));
+ Handle<JSFunction>::cast(Object::GetProperty(
+ isolate()->global_object(), key));
Handle<JSObject> proto =
Handle<JSObject>(JSObject::cast(function->instance_prototype()));
@@ -2055,6 +2022,8 @@
INSTALL_EXPERIMENTAL_NATIVE(i, symbols, "symbol.js")
INSTALL_EXPERIMENTAL_NATIVE(i, proxies, "proxy.js")
INSTALL_EXPERIMENTAL_NATIVE(i, collections, "collection.js")
+ INSTALL_EXPERIMENTAL_NATIVE(i, weak_collections, "weak_collection.js")
+ INSTALL_EXPERIMENTAL_NATIVE(i, promises, "promise.js")
INSTALL_EXPERIMENTAL_NATIVE(i, generators, "generator.js")
INSTALL_EXPERIMENTAL_NATIVE(i, iteration, "array-iterator.js")
INSTALL_EXPERIMENTAL_NATIVE(i, strings, "harmony-string.js")
@@ -2076,8 +2045,8 @@
Handle<GlobalObject> global(native_context->global_object());
const char* period_pos = strchr(holder_expr, '.');
if (period_pos == NULL) {
- return Handle<JSObject>::cast(GetProperty(
- isolate, global, factory->InternalizeUtf8String(holder_expr)));
+ return Handle<JSObject>::cast(Object::GetPropertyOrElement(
+ global, factory->InternalizeUtf8String(holder_expr)));
}
ASSERT_EQ(".prototype", period_pos);
Vector<const char> property(holder_expr,
@@ -2085,7 +2054,7 @@
Handle<String> property_string = factory->InternalizeUtf8String(property);
ASSERT(!property_string.is_null());
Handle<JSFunction> function = Handle<JSFunction>::cast(
- GetProperty(isolate, global, property_string));
+ Object::GetProperty(global, property_string));
return Handle<JSObject>(JSObject::cast(function->prototype()));
}
diff --git a/src/bootstrapper.h b/src/bootstrapper.h
index e683a45..6dea116 100644
--- a/src/bootstrapper.h
+++ b/src/bootstrapper.h
@@ -1,46 +1,21 @@
-// 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.
-
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_BOOTSTRAPPER_H_
#define V8_BOOTSTRAPPER_H_
-#include "allocation.h"
+#include "factory.h"
namespace v8 {
namespace internal {
-
// A SourceCodeCache uses a FixedArray to store pairs of
// (AsciiString*, JSFunction*), mapping names of native code files
// (runtime.js, etc.) to precompiled functions. Instead of mapping
// names to functions it might make sense to let the JS2C tool
// generate an index for each native JS file.
-class SourceCodeCache BASE_EMBEDDED {
+class SourceCodeCache V8_FINAL BASE_EMBEDDED {
public:
explicit SourceCodeCache(Script::Type type): type_(type), cache_(NULL) { }
@@ -88,7 +63,7 @@
// The Boostrapper is the public interface for creating a JavaScript global
// context.
-class Bootstrapper {
+class Bootstrapper V8_FINAL {
public:
static void InitializeOncePerProcess();
static void TearDownExtensions();
@@ -158,7 +133,7 @@
};
-class BootstrapperActive BASE_EMBEDDED {
+class BootstrapperActive V8_FINAL BASE_EMBEDDED {
public:
explicit BootstrapperActive(Bootstrapper* bootstrapper)
: bootstrapper_(bootstrapper) {
@@ -176,20 +151,15 @@
};
-class NativesExternalStringResource
+class NativesExternalStringResource V8_FINAL
: public v8::String::ExternalAsciiStringResource {
public:
NativesExternalStringResource(Bootstrapper* bootstrapper,
const char* source,
size_t length);
+ virtual const char* data() const V8_OVERRIDE { return data_; }
+ virtual size_t length() const V8_OVERRIDE { return length_; }
- const char* data() const {
- return data_;
- }
-
- size_t length() const {
- return length_;
- }
private:
const char* data_;
size_t length_;
diff --git a/src/builtins.cc b/src/builtins.cc
index 689e845..fd4723f 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -207,19 +207,6 @@
}
-static void FillWithHoles(Heap* heap, FixedArray* dst, int from, int to) {
- ASSERT(dst->map() != heap->fixed_cow_array_map());
- MemsetPointer(dst->data_start() + from, heap->the_hole_value(), to - from);
-}
-
-
-static void FillWithHoles(FixedDoubleArray* dst, int from, int to) {
- for (int i = from; i < to; i++) {
- dst->set_the_hole(i);
- }
-}
-
-
static FixedArrayBase* LeftTrimFixedArray(Heap* heap,
FixedArrayBase* elms,
int to_trim) {
@@ -898,12 +885,12 @@
Handle<FixedDoubleArray> elms =
Handle<FixedDoubleArray>::cast(elms_obj);
MoveDoubleElements(*elms, 0, *elms, delta, len - delta);
- FillWithHoles(*elms, len - delta, len);
+ elms->FillWithHoles(len - delta, len);
} else {
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
DisallowHeapAllocation no_gc;
heap->MoveElements(*elms, 0, delta, len - delta);
- FillWithHoles(heap, *elms, len - delta, len);
+ elms->FillWithHoles(len - delta, len);
}
}
elms_changed = true;
@@ -914,14 +901,14 @@
MoveDoubleElements(*elms, actual_start + item_count,
*elms, actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
- FillWithHoles(*elms, new_length, len);
+ elms->FillWithHoles(new_length, len);
} else {
Handle<FixedArray> elms = Handle<FixedArray>::cast(elms_obj);
DisallowHeapAllocation no_gc;
heap->MoveElements(*elms, actual_start + item_count,
actual_start + actual_delete_count,
(len - actual_delete_count - actual_start));
- FillWithHoles(heap, *elms, new_length, len);
+ elms->FillWithHoles(new_length, len);
}
}
} else if (item_count > actual_delete_count) {
diff --git a/src/date.cc b/src/date.cc
index 70d6be9..c22bc76 100644
--- a/src/date.cc
+++ b/src/date.cc
@@ -49,9 +49,10 @@
void DateCache::ResetDateCache() {
static const int kMaxStamp = Smi::kMaxValue;
- stamp_ = Smi::FromInt(stamp_->value() + 1);
- if (stamp_->value() > kMaxStamp) {
+ if (stamp_->value() >= kMaxStamp) {
stamp_ = Smi::FromInt(0);
+ } else {
+ stamp_ = Smi::FromInt(stamp_->value() + 1);
}
ASSERT(stamp_ != Smi::FromInt(kInvalidStamp));
for (int i = 0; i < kDSTSize; ++i) {
diff --git a/src/execution.cc b/src/execution.cc
index 7442d17..da07d0f 100644
--- a/src/execution.cc
+++ b/src/execution.cc
@@ -1,49 +1,18 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include <stdlib.h>
+#include "execution.h"
-#include "v8.h"
-
-#include "api.h"
#include "bootstrapper.h"
#include "codegen.h"
-#include "debug.h"
#include "deoptimizer.h"
#include "isolate-inl.h"
-#include "runtime-profiler.h"
-#include "simulator.h"
-#include "v8threads.h"
#include "vm-state-inl.h"
namespace v8 {
namespace internal {
-
StackGuard::StackGuard()
: isolate_(NULL) {
}
@@ -783,8 +752,8 @@
return factory->undefined_value();
}
- Handle<Object> char_at = GetProperty(
- isolate, isolate->js_builtins_object(), factory->char_at_string());
+ Handle<Object> char_at = Object::GetProperty(
+ isolate->js_builtins_object(), factory->char_at_string());
if (!char_at->IsJSFunction()) {
return factory->undefined_value();
}
@@ -999,8 +968,6 @@
isolate->debugger()->OnDebugBreak(isolate->factory()->undefined_value(),
debug_command_only);
}
-
-
#endif
MaybeObject* Execution::HandleStackGuardInterrupt(Isolate* isolate) {
@@ -1053,5 +1020,4 @@
return isolate->heap()->undefined_value();
}
-
} } // namespace v8::internal
diff --git a/src/execution.h b/src/execution.h
index 592ecbd..f328cae 100644
--- a/src/execution.h
+++ b/src/execution.h
@@ -1,39 +1,15 @@
-// Copyright 2011 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_EXECUTION_H_
#define V8_EXECUTION_H_
-#include "allocation.h"
+#include "handles.h"
namespace v8 {
namespace internal {
-
// Flag used to set the interrupt causes.
enum InterruptFlag {
INTERRUPT = 1 << 0,
@@ -49,10 +25,7 @@
};
-class Isolate;
-
-
-class Execution : public AllStatic {
+class Execution V8_FINAL : public AllStatic {
public:
// Call a function, the caller supplies a receiver and an array
// of arguments. Arguments are Object* type. After function returns,
@@ -185,7 +158,7 @@
// StackGuard contains the handling of the limits that are used to limit the
// number of nested invocations of JavaScript and the stack size used in each
// invocation.
-class StackGuard {
+class StackGuard V8_FINAL {
public:
// Pass the address beyond which the stack should not grow. The stack
// is assumed to grow downwards.
@@ -290,7 +263,7 @@
static const uintptr_t kIllegalLimit = 0xfffffff8;
#endif
- class ThreadLocal {
+ class ThreadLocal V8_FINAL {
public:
ThreadLocal() { Clear(); }
// You should hold the ExecutionAccess lock when you call Initialize or
@@ -334,7 +307,6 @@
DISALLOW_COPY_AND_ASSIGN(StackGuard);
};
-
} } // namespace v8::internal
#endif // V8_EXECUTION_H_
diff --git a/src/factory.cc b/src/factory.cc
index 0868db8..cd30743 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -1,47 +1,14 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include "v8.h"
-
-#include "api.h"
-#include "debug.h"
-#include "execution.h"
#include "factory.h"
+
#include "isolate-inl.h"
-#include "macro-assembler.h"
-#include "objects.h"
-#include "objects-visiting.h"
-#include "platform.h"
-#include "scopeinfo.h"
namespace v8 {
namespace internal {
-
Handle<Box> Factory::NewBox(Handle<Object> value, PretenureFlag pretenure) {
CALL_HEAP_FUNCTION(
isolate(),
@@ -2023,5 +1990,4 @@
return value ? true_value() : false_value();
}
-
} } // namespace v8::internal
diff --git a/src/factory.h b/src/factory.h
index 00f20ff..da58a71 100644
--- a/src/factory.h
+++ b/src/factory.h
@@ -1,43 +1,18 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_FACTORY_H_
#define V8_FACTORY_H_
-#include "globals.h"
-#include "handles.h"
-#include "heap.h"
+#include "isolate.h"
namespace v8 {
namespace internal {
// Interface for handle based allocation.
-class Factory {
+class Factory V8_FINAL {
public:
// Allocate a new boxed value.
Handle<Box> NewBox(
@@ -312,8 +287,14 @@
PretenureFlag pretenure = NOT_TENURED);
Handle<Object> NewNumberFromUint(uint32_t value,
PretenureFlag pretenure = NOT_TENURED);
- inline Handle<Object> NewNumberFromSize(size_t value,
- PretenureFlag pretenure = NOT_TENURED);
+ Handle<Object> NewNumberFromSize(size_t value,
+ PretenureFlag pretenure = NOT_TENURED) {
+ if (Smi::IsValid(static_cast<intptr_t>(value))) {
+ return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)),
+ isolate());
+ }
+ return NewNumber(static_cast<double>(value), pretenure);
+ }
Handle<HeapNumber> NewHeapNumber(double value,
PretenureFlag pretenure = NOT_TENURED);
@@ -619,18 +600,6 @@
Handle<Map> map);
};
-
-Handle<Object> Factory::NewNumberFromSize(size_t value,
- PretenureFlag pretenure) {
- if (Smi::IsValid(static_cast<intptr_t>(value))) {
- return Handle<Object>(Smi::FromIntptr(static_cast<intptr_t>(value)),
- isolate());
- } else {
- return NewNumber(static_cast<double>(value), pretenure);
- }
-}
-
-
} } // namespace v8::internal
#endif // V8_FACTORY_H_
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index b93d03b..3f0f7ec 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -175,9 +175,12 @@
"enable harmony modules (implies block scoping)")
DEFINE_bool(harmony_symbols, false,
"enable harmony symbols (a.k.a. private names)")
+DEFINE_bool(harmony_promises, false, "enable harmony promises")
DEFINE_bool(harmony_proxies, false, "enable harmony proxies")
DEFINE_bool(harmony_collections, false,
- "enable harmony collections (sets, maps)")
+ "enable harmony collections (sets, maps, weak sets, weak maps)")
+DEFINE_bool(harmony_weak_collections, false,
+ "enable only harmony weak collections (weak sets and maps)")
DEFINE_bool(harmony_generators, false, "enable harmony generators")
DEFINE_bool(harmony_iteration, false, "enable harmony iteration (for-of)")
DEFINE_bool(harmony_numeric_literals, false,
@@ -197,10 +200,14 @@
DEFINE_implication(harmony, harmony_numeric_literals)
DEFINE_implication(harmony, harmony_strings)
DEFINE_implication(harmony, harmony_arrays)
+DEFINE_implication(harmony_collections, harmony_weak_collections)
+DEFINE_implication(harmony_promises, harmony_weak_collections)
DEFINE_implication(harmony_modules, harmony_scoping)
DEFINE_implication(harmony, es_staging)
DEFINE_implication(es_staging, harmony_maths)
+DEFINE_implication(es_staging, harmony_promises)
+DEFINE_implication(es_staging, harmony_weak_collections)
// Flags for experimental implementation features.
DEFINE_bool(packed_arrays, true, "optimizes arrays that have no holes")
diff --git a/src/handles-inl.h b/src/handles-inl.h
index a25b4a2..19a02cc 100644
--- a/src/handles-inl.h
+++ b/src/handles-inl.h
@@ -52,14 +52,15 @@
template <typename T>
-inline bool Handle<T>::is_identical_to(const Handle<T> other) const {
+inline bool Handle<T>::is_identical_to(const Handle<T> o) const {
ASSERT(location_ == NULL || !(*location_)->IsFailure());
- if (location_ == other.location_) return true;
- if (location_ == NULL || other.location_ == NULL) return false;
// Dereferencing deferred handles to check object equality is safe.
- SLOW_ASSERT(IsDereferenceAllowed(NO_DEFERRED_CHECK) &&
- other.IsDereferenceAllowed(NO_DEFERRED_CHECK));
- return *location_ == *other.location_;
+ SLOW_ASSERT(
+ (location_ == NULL || IsDereferenceAllowed(NO_DEFERRED_CHECK)) &&
+ (o.location_ == NULL || o.IsDereferenceAllowed(NO_DEFERRED_CHECK)));
+ if (location_ == o.location_) return true;
+ if (location_ == NULL || o.location_ == NULL) return false;
+ return *location_ == *o.location_;
}
diff --git a/src/handles.cc b/src/handles.cc
index 398a682..ea0f8ae 100644
--- a/src/handles.cc
+++ b/src/handles.cc
@@ -197,15 +197,8 @@
const char* name) {
Isolate* isolate = obj->GetIsolate();
Handle<String> str = isolate->factory()->InternalizeUtf8String(name);
- CALL_HEAP_FUNCTION(isolate, obj->GetProperty(*str), Object);
-}
-
-
-Handle<Object> GetProperty(Isolate* isolate,
- Handle<Object> obj,
- Handle<Object> key) {
- CALL_HEAP_FUNCTION(isolate,
- Runtime::GetObjectProperty(isolate, obj, key), Object);
+ ASSERT(!str.is_null());
+ return Object::GetPropertyOrElement(obj, str);
}
@@ -477,9 +470,8 @@
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("nameOrSourceURL"));
Handle<JSValue> script_wrapper = GetScriptWrapper(script);
- Handle<Object> property = GetProperty(isolate,
- script_wrapper,
- name_or_source_url_key);
+ Handle<Object> property =
+ Object::GetProperty(script_wrapper, name_or_source_url_key);
ASSERT(property->IsJSFunction());
Handle<JSFunction> method = Handle<JSFunction>::cast(property);
bool caught_exception;
@@ -627,20 +619,21 @@
bool cache_result) {
Isolate* isolate = object->GetIsolate();
if (object->HasFastProperties()) {
+ int own_property_count = object->map()->EnumLength();
+ // If the enum length of the given map is set to kInvalidEnumCache, this
+ // means that the map itself has never used the present enum cache. The
+ // first step to using the cache is to set the enum length of the map by
+ // counting the number of own descriptors that are not DONT_ENUM or
+ // SYMBOLIC.
+ if (own_property_count == kInvalidEnumCacheSentinel) {
+ own_property_count = object->map()->NumberOfDescribedProperties(
+ OWN_DESCRIPTORS, DONT_SHOW);
+ } else {
+ ASSERT(own_property_count == object->map()->NumberOfDescribedProperties(
+ OWN_DESCRIPTORS, DONT_SHOW));
+ }
+
if (object->map()->instance_descriptors()->HasEnumCache()) {
- int own_property_count = object->map()->EnumLength();
- // If we have an enum cache, but the enum length of the given map is set
- // to kInvalidEnumCache, this means that the map itself has never used the
- // present enum cache. The first step to using the cache is to set the
- // enum length of the map by counting the number of own descriptors that
- // are not DONT_ENUM or SYMBOLIC.
- if (own_property_count == kInvalidEnumCacheSentinel) {
- own_property_count = object->map()->NumberOfDescribedProperties(
- OWN_DESCRIPTORS, DONT_SHOW);
-
- if (cache_result) object->map()->SetEnumLength(own_property_count);
- }
-
DescriptorArray* desc = object->map()->instance_descriptors();
Handle<FixedArray> keys(desc->GetEnumCache(), isolate);
@@ -649,6 +642,7 @@
// enum cache was generated for a previous (smaller) version of the
// Descriptor Array. In that case we regenerate the enum cache.
if (own_property_count <= keys->length()) {
+ if (cache_result) object->map()->SetEnumLength(own_property_count);
isolate->counters()->enum_cache_hits()->Increment();
return ReduceFixedArrayTo(keys, own_property_count);
}
@@ -663,23 +657,22 @@
}
isolate->counters()->enum_cache_misses()->Increment();
- int num_enum = map->NumberOfDescribedProperties(ALL_DESCRIPTORS, DONT_SHOW);
- Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum);
- Handle<FixedArray> indices = isolate->factory()->NewFixedArray(num_enum);
+ Handle<FixedArray> storage = isolate->factory()->NewFixedArray(
+ own_property_count);
+ Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
+ own_property_count);
Handle<DescriptorArray> descs =
Handle<DescriptorArray>(object->map()->instance_descriptors(), isolate);
- int real_size = map->NumberOfOwnDescriptors();
- int enum_size = 0;
+ int size = map->NumberOfOwnDescriptors();
int index = 0;
- for (int i = 0; i < descs->number_of_descriptors(); i++) {
+ for (int i = 0; i < size; i++) {
PropertyDetails details = descs->GetDetails(i);
Object* key = descs->GetKey(i);
if (!(details.IsDontEnum() || key->IsSymbol())) {
- if (i < real_size) ++enum_size;
storage->set(index, key);
if (!indices.is_null()) {
if (details.type() != FIELD) {
@@ -706,10 +699,9 @@
indices.is_null() ? Object::cast(Smi::FromInt(0))
: Object::cast(*indices));
if (cache_result) {
- object->map()->SetEnumLength(enum_size);
+ object->map()->SetEnumLength(own_property_count);
}
-
- return ReduceFixedArrayTo(storage, enum_size);
+ return storage;
} else {
Handle<NameDictionary> dictionary(object->property_dictionary());
int length = dictionary->NumberOfEnumElements();
diff --git a/src/handles.h b/src/handles.h
index 8538658..bcd7eb2 100644
--- a/src/handles.h
+++ b/src/handles.h
@@ -240,10 +240,6 @@
Handle<Object> GetProperty(Handle<JSReceiver> obj, const char* name);
-Handle<Object> GetProperty(Isolate* isolate,
- Handle<Object> obj,
- Handle<Object> key);
-
Handle<String> LookupSingleCharacterStringFromCode(Isolate* isolate,
uint32_t index);
diff --git a/src/harmony-math.js b/src/harmony-math.js
index 298fa58..c8fac07 100644
--- a/src/harmony-math.js
+++ b/src/harmony-math.js
@@ -156,7 +156,7 @@
// ES6 draft 09-27-13, section 20.2.2.16.
function MathFround(x) {
- return %Math_fround(TO_NUMBER_INLINE(x));
+ return %MathFround(TO_NUMBER_INLINE(x));
}
diff --git a/src/hydrogen-environment-liveness.cc b/src/hydrogen-environment-liveness.cc
index d7501ac..726198d 100644
--- a/src/hydrogen-environment-liveness.cc
+++ b/src/hydrogen-environment-liveness.cc
@@ -84,8 +84,8 @@
}
HSimulate* simulate = first_simulate_.at(successor_id);
if (simulate == NULL) continue;
- ASSERT(simulate->closure().is_identical_to(
- block->last_environment()->closure()));
+ ASSERT(VerifyClosures(simulate->closure(),
+ block->last_environment()->closure()));
ZapEnvironmentSlot(i, simulate);
}
}
@@ -97,7 +97,7 @@
if (!marker->CheckFlag(HValue::kEndsLiveRange)) return;
HSimulate* simulate = marker->next_simulate();
if (simulate != NULL) {
- ASSERT(simulate->closure().is_identical_to(marker->closure()));
+ ASSERT(VerifyClosures(simulate->closure(), marker->closure()));
ZapEnvironmentSlot(marker->index(), simulate);
}
}
@@ -241,4 +241,14 @@
}
}
+
+#ifdef DEBUG
+bool HEnvironmentLivenessAnalysisPhase::VerifyClosures(
+ Handle<JSFunction> a, Handle<JSFunction> b) {
+ Heap::RelocationLock for_heap_access(isolate()->heap());
+ AllowHandleDereference for_verification;
+ return a.is_identical_to(b);
+}
+#endif
+
} } // namespace v8::internal
diff --git a/src/hydrogen-environment-liveness.h b/src/hydrogen-environment-liveness.h
index 248ec5c..6ad02d7 100644
--- a/src/hydrogen-environment-liveness.h
+++ b/src/hydrogen-environment-liveness.h
@@ -55,6 +55,9 @@
void ZapEnvironmentSlotsForInstruction(HEnvironmentMarker* marker);
void UpdateLivenessAtBlockEnd(HBasicBlock* block, BitVector* live);
void UpdateLivenessAtInstruction(HInstruction* instr, BitVector* live);
+#ifdef DEBUG
+ bool VerifyClosures(Handle<JSFunction> a, Handle<JSFunction> b);
+#endif
int block_count_;
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 1e6ac19..81ecb89 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -6025,6 +6025,11 @@
JSArrayBuffer::kBackingStoreOffset, Representation::External());
}
+ static HObjectAccess ForJSArrayBufferByteLength() {
+ return HObjectAccess::ForObservableJSObjectOffset(
+ JSArrayBuffer::kByteLengthOffset, Representation::Tagged());
+ }
+
static HObjectAccess ForExternalArrayExternalPointer() {
return HObjectAccess::ForObservableJSObjectOffset(
ExternalArray::kExternalPointerOffset, Representation::External());
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index a7ef0cb..80eff3b 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -8510,6 +8510,10 @@
HValue* buffer, HValue* byte_offset, HValue* length) {
Handle<Map> external_array_map(
isolate()->heap()->MapForExternalArrayType(array_type));
+
+ // The HForceRepresentation is to prevent possible deopt on int-smi
+ // conversion after allocation but before the new object fields are set.
+ length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
HValue* elements =
Add<HAllocate>(
Add<HConstant>(ExternalArray::kAlignedSize),
@@ -8518,6 +8522,8 @@
external_array_map->instance_type());
AddStoreMapConstant(elements, external_array_map);
+ Add<HStoreNamedField>(elements,
+ HObjectAccess::ForFixedArrayLength(), length);
HValue* backing_store = Add<HLoadNamedField>(
buffer, static_cast<HValue*>(NULL),
@@ -8535,13 +8541,10 @@
typed_array_start = external_pointer;
}
-
Add<HStoreNamedField>(elements,
HObjectAccess::ForExternalArrayExternalPointer(),
typed_array_start);
- Add<HStoreNamedField>(elements,
- HObjectAccess::ForFixedArrayLength(), length);
return elements;
}
@@ -8565,6 +8568,9 @@
total_size->ClearFlag(HValue::kCanOverflow);
}
+ // The HForceRepresentation is to prevent possible deopt on int-smi
+ // conversion after allocation but before the new object fields are set.
+ length = AddUncasted<HForceRepresentation>(length, Representation::Smi());
Handle<Map> fixed_typed_array_map(
isolate()->heap()->MapForFixedTypedArray(array_type));
HValue* elements =
@@ -8576,6 +8582,7 @@
Add<HStoreNamedField>(elements,
HObjectAccess::ForFixedArrayLength(),
length);
+
HValue* filler = Add<HConstant>(static_cast<int32_t>(0));
{
@@ -8588,8 +8595,6 @@
builder.EndBody();
}
- Add<HStoreNamedField>(
- elements, HObjectAccess::ForFixedArrayLength(), length);
return elements;
}
@@ -8725,6 +8730,58 @@
}
+void HOptimizedGraphBuilder::GenerateArrayBufferGetByteLength(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSArrayBufferByteLength());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteLength(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSArrayBufferViewByteLength());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateArrayBufferViewGetByteOffset(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSArrayBufferViewByteOffset());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
+void HOptimizedGraphBuilder::GenerateTypedArrayGetLength(
+ CallRuntime* expr) {
+ ASSERT(expr->arguments()->length() == 1);
+ CHECK_ALIVE(VisitForValue(expr->arguments()->at(0)));
+ HValue* buffer = Pop();
+ HInstruction* result = New<HLoadNamedField>(
+ buffer,
+ static_cast<HValue*>(NULL),
+ HObjectAccess::ForJSTypedArrayLength());
+ return ast_context()->ReturnInstruction(result, expr->id());
+}
+
+
void HOptimizedGraphBuilder::VisitCallRuntime(CallRuntime* expr) {
ASSERT(!HasStackOverflow());
ASSERT(current_block() != NULL);
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index ab29167..dca7ae7 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -1014,7 +1014,7 @@
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in exponent.
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 70a968e..1a7d828 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -3539,7 +3539,7 @@
MathPowStub stub(MathPowStub::ON_STACK);
__ CallStub(&stub);
} else {
- __ CallRuntime(Runtime::kMath_pow, 2);
+ __ CallRuntime(Runtime::kHiddenMathPowSlow, 2);
}
context()->Plug(eax);
}
@@ -3726,26 +3726,6 @@
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(eax);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(eax);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 0dbe3da..b3c06d6 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4736,16 +4736,14 @@
kDontSaveFPRegs);
} else {
ASSERT(ToRegister(instr->context()).is(esi));
+ ASSERT(object_reg.is(eax));
PushSafepointRegistersScope scope(this);
- if (!object_reg.is(eax)) {
- __ mov(eax, object_reg);
- }
__ mov(ebx, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ RecordSafepointWithLazyDeopt(instr,
+ RECORD_SAFEPOINT_WITH_REGISTERS_AND_NO_ARGUMENTS);
}
__ bind(¬_applicable);
}
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index 696c6be..8fa6dbd 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -2345,7 +2345,6 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
@@ -2355,10 +2354,11 @@
new_map_reg, temp_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), eax);
LOperand* context = UseFixed(instr->context(), esi);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
diff --git a/src/ic.cc b/src/ic.cc
index a327173..f01c3d1 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -1082,7 +1082,9 @@
MaybeObject* KeyedLoadIC::Load(Handle<Object> object, Handle<Object> key) {
if (MigrateDeprecated(object)) {
- return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
+ Handle<Object> result = Runtime::GetObjectProperty(isolate(), object, key);
+ RETURN_IF_EMPTY_HANDLE(isolate(), result);
+ return *result;
}
MaybeObject* maybe_object = NULL;
@@ -1121,7 +1123,9 @@
}
if (maybe_object != NULL) return maybe_object;
- return Runtime::GetObjectPropertyOrFail(isolate(), object, key);
+ Handle<Object> result = Runtime::GetObjectProperty(isolate(), object, key);
+ RETURN_IF_EMPTY_HANDLE(isolate(), result);
+ return *result;
}
diff --git a/src/isolate.cc b/src/isolate.cc
index 7e06a2e..384204e 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -875,7 +875,7 @@
// attach the stack trace as a hidden property.
Handle<String> key = factory()->stack_overflow_string();
Handle<JSObject> boilerplate =
- Handle<JSObject>::cast(GetProperty(this, js_builtins_object(), key));
+ Handle<JSObject>::cast(Object::GetProperty(js_builtins_object(), key));
Handle<JSObject> exception = JSObject::Copy(boilerplate);
DoThrow(*exception, NULL);
diff --git a/src/json-stringifier.h b/src/json-stringifier.h
index 3926969..17c6b6f 100644
--- a/src/json-stringifier.h
+++ b/src/json-stringifier.h
@@ -671,7 +671,7 @@
map->instance_descriptors()->GetFieldIndex(i)),
isolate_);
} else {
- property = GetProperty(isolate_, object, key);
+ property = Object::GetPropertyOrElement(object, key);
RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, property, EXCEPTION);
}
Result result = SerializeProperty(property, comma, key);
@@ -690,7 +690,7 @@
Handle<Object> property;
if (key->IsString()) {
key_handle = Handle<String>(String::cast(key), isolate_);
- property = GetProperty(isolate_, object, key_handle);
+ property = Object::GetPropertyOrElement(object, key_handle);
} else {
ASSERT(key->IsNumber());
key_handle = factory_->NumberToString(Handle<Object>(key, isolate_));
@@ -701,7 +701,7 @@
} else if (key_handle->AsArrayIndex(&index)) {
property = Object::GetElement(isolate_, object, index);
} else {
- property = GetProperty(isolate_, object, key_handle);
+ property = Object::GetPropertyOrElement(object, key_handle);
}
}
RETURN_IF_EMPTY_HANDLE_VALUE(isolate_, property, EXCEPTION);
diff --git a/src/math.js b/src/math.js
index da96d96..6a38770 100644
--- a/src/math.js
+++ b/src/math.js
@@ -52,24 +52,24 @@
// ECMA 262 - 15.8.2.2
function MathAcos(x) {
- return %Math_acos(TO_NUMBER_INLINE(x));
+ return %MathAcos(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.3
function MathAsin(x) {
- return %Math_asin(TO_NUMBER_INLINE(x));
+ return %MathAsin(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.4
function MathAtan(x) {
- return %Math_atan(TO_NUMBER_INLINE(x));
+ return %MathAtan(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.5
// The naming of y and x matches the spec, as does the order in which
// ToNumber (valueOf) is called.
function MathAtan2(y, x) {
- return %Math_atan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x));
+ return %MathAtan2(TO_NUMBER_INLINE(y), TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.6
@@ -85,7 +85,7 @@
// ECMA 262 - 15.8.2.8
function MathExp(x) {
- return %Math_exp(TO_NUMBER_INLINE(x));
+ return %MathExp(TO_NUMBER_INLINE(x));
}
// ECMA 262 - 15.8.2.9
@@ -100,7 +100,7 @@
// has to be -0, which wouldn't be the case with the shift.
return TO_UINT32(x);
} else {
- return %Math_floor(x);
+ return %MathFloor(x);
}
}
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 332ed4b..7851b58 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -1511,7 +1511,7 @@
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in exponent.
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 87c0764..a676fea 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -3798,26 +3798,6 @@
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(v0);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(v0);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 970a1bf..e6f52d8 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -4401,16 +4401,16 @@
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
scratch, GetRAState(), kDontSaveFPRegs);
} else {
+ ASSERT(object_reg.is(a0));
ASSERT(ToRegister(instr->context()).is(cp));
PushSafepointRegistersScope scope(
this, Safepoint::kWithRegistersAndDoubles);
- __ mov(a0, object_reg);
__ li(a1, Operand(to_map));
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
RecordSafepointWithRegistersAndDoubles(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ instr->pointer_map(), 0, Safepoint::kLazyDeopt);
}
__ bind(¬_applicable);
}
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index 752f676..1ff8915 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -2178,17 +2178,18 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
+ LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, NULL, new_map_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), a0);
LOperand* context = UseFixed(instr->context(), cp);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
diff --git a/src/objects-inl.h b/src/objects-inl.h
index 9d55037..ddd321c 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -2227,6 +2227,18 @@
}
+double* FixedDoubleArray::data_start() {
+ return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
+}
+
+
+void FixedDoubleArray::FillWithHoles(int from, int to) {
+ for (int i = from; i < to; i++) {
+ set_the_hole(i);
+ }
+}
+
+
SMI_ACCESSORS(
ConstantPoolArray, first_code_ptr_index, kFirstCodePointerIndexOffset)
SMI_ACCESSORS(
@@ -2420,8 +2432,10 @@
}
-double* FixedDoubleArray::data_start() {
- return reinterpret_cast<double*>(FIELD_ADDR(this, kHeaderSize));
+void FixedArray::FillWithHoles(int from, int to) {
+ for (int i = from; i < to; i++) {
+ set_the_hole(i);
+ }
}
diff --git a/src/objects.cc b/src/objects.cc
index 45220ee..9a6b26a 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -487,14 +487,18 @@
}
-Handle<Object> Object::GetProperty(Handle<Object> object,
- Handle<Name> name) {
- // TODO(rossberg): The index test should not be here but in the GetProperty
- // method (or somewhere else entirely). Needs more global clean-up.
+Handle<Object> Object::GetPropertyOrElement(Handle<Object> object,
+ Handle<Name> name) {
uint32_t index;
Isolate* isolate = name->GetIsolate();
if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index);
- CALL_HEAP_FUNCTION(isolate, object->GetProperty(*name), Object);
+ return GetProperty(object, name);
+}
+
+
+Handle<Object> Object::GetProperty(Handle<Object> object,
+ Handle<Name> name) {
+ CALL_HEAP_FUNCTION(name->GetIsolate(), object->GetProperty(*name), Object);
}
@@ -2722,8 +2726,8 @@
}
Handle<DescriptorArray> new_descriptors = DescriptorArray::Merge(
- updated_descriptors, verbatim, valid, descriptors, modify_index,
- store_mode, old_descriptors);
+ updated, verbatim, valid, descriptors, modify_index,
+ store_mode, old_map);
ASSERT(store_mode == ALLOW_AS_CONSTANT ||
new_descriptors->GetDetails(modify_index).type() == FIELD);
@@ -3602,9 +3606,8 @@
Handle<String> configurable_name =
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("configurable_"));
- Handle<Object> configurable(
- v8::internal::GetProperty(isolate, desc, configurable_name));
- ASSERT(!isolate->has_pending_exception());
+ Handle<Object> configurable = Object::GetProperty(desc, configurable_name);
+ ASSERT(!configurable.is_null());
ASSERT(configurable->IsTrue() || configurable->IsFalse());
if (configurable->IsFalse()) {
Handle<String> trap =
@@ -3622,17 +3625,15 @@
Handle<String> hasWritable_name =
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("hasWritable_"));
- Handle<Object> hasWritable(
- v8::internal::GetProperty(isolate, desc, hasWritable_name));
- ASSERT(!isolate->has_pending_exception());
+ Handle<Object> hasWritable = Object::GetProperty(desc, hasWritable_name);
+ ASSERT(!hasWritable.is_null());
ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse());
if (hasWritable->IsTrue()) {
Handle<String> writable_name =
isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("writable_"));
- Handle<Object> writable(
- v8::internal::GetProperty(isolate, desc, writable_name));
- ASSERT(!isolate->has_pending_exception());
+ Handle<Object> writable = Object::GetProperty(desc, writable_name);
+ ASSERT(!writable.is_null());
ASSERT(writable->IsTrue() || writable->IsFalse());
*done = writable->IsFalse();
if (!*done) return isolate->factory()->the_hole_value();
@@ -3647,8 +3648,8 @@
// We have an AccessorDescriptor.
Handle<String> set_name = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("set_"));
- Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_name));
- ASSERT(!isolate->has_pending_exception());
+ Handle<Object> setter = Object::GetProperty(desc, set_name);
+ ASSERT(!setter.is_null());
if (!setter->IsUndefined()) {
// TODO(rossberg): nicer would be to cast to some JSCallable here...
return SetPropertyWithDefinedSetter(
@@ -3726,21 +3727,21 @@
// Convert result to PropertyAttributes.
Handle<String> enum_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("enumerable_"));
- Handle<Object> enumerable(v8::internal::GetProperty(isolate, desc, enum_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> enumerable = Object::GetProperty(desc, enum_n);
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, enumerable, NONE);
Handle<String> conf_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("configurable_"));
- Handle<Object> configurable(v8::internal::GetProperty(isolate, desc, conf_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> configurable = Object::GetProperty(desc, conf_n);
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, configurable, NONE);
Handle<String> writ_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("writable_"));
- Handle<Object> writable(v8::internal::GetProperty(isolate, desc, writ_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> writable = Object::GetProperty(desc, writ_n);
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, writable, NONE);
if (!writable->BooleanValue()) {
Handle<String> set_n = isolate->factory()->InternalizeOneByteString(
STATIC_ASCII_VECTOR("set_"));
- Handle<Object> setter(v8::internal::GetProperty(isolate, desc, set_n));
- if (isolate->has_pending_exception()) return NONE;
+ Handle<Object> setter = Object::GetProperty(desc, set_n);
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, setter, NONE);
writable = isolate->factory()->ToBoolean(!setter->IsUndefined());
}
@@ -3803,8 +3804,8 @@
Handle<Object> handler(this->handler(), isolate);
Handle<String> trap_name = isolate->factory()->InternalizeUtf8String(name);
- Handle<Object> trap(v8::internal::GetProperty(isolate, handler, trap_name));
- if (isolate->has_pending_exception()) return trap;
+ Handle<Object> trap = Object::GetPropertyOrElement(handler, trap_name);
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, trap, Handle<Object>());
if (trap->IsUndefined()) {
if (derived.is_null()) {
@@ -4070,7 +4071,7 @@
bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup->IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
+ old_value = Object::GetPropertyOrElement(object, name);
CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
}
@@ -4116,7 +4117,7 @@
LookupResult new_lookup(isolate);
object->LocalLookup(*name, &new_lookup, true);
if (new_lookup.IsDataProperty()) {
- Handle<Object> new_value = Object::GetProperty(object, name);
+ Handle<Object> new_value = Object::GetPropertyOrElement(object, name);
CHECK_NOT_EMPTY_HANDLE(isolate, new_value);
if (!new_value->SameValue(*old_value)) {
EnqueueChangeRecord(object, "update", name, old_value);
@@ -4195,7 +4196,7 @@
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsProperty()) {
if (lookup.IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
+ old_value = Object::GetPropertyOrElement(object, name);
CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
}
old_attributes = lookup.GetAttributes();
@@ -4241,7 +4242,7 @@
object->LocalLookup(*name, &new_lookup, true);
bool value_changed = false;
if (new_lookup.IsDataProperty()) {
- Handle<Object> new_value = Object::GetProperty(object, name);
+ Handle<Object> new_value = Object::GetPropertyOrElement(object, name);
CHECK_NOT_EMPTY_HANDLE(isolate, new_value);
value_changed = !old_value->SameValue(*new_value);
}
@@ -5231,7 +5232,7 @@
bool is_observed = object->map()->is_observed() &&
*name != isolate->heap()->hidden_string();
if (is_observed && lookup.IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
+ old_value = Object::GetPropertyOrElement(object, name);
CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
}
Handle<Object> result;
@@ -6339,7 +6340,7 @@
object->LocalLookup(*name, &lookup, true);
preexists = lookup.IsProperty();
if (preexists && lookup.IsDataProperty()) {
- old_value = Object::GetProperty(object, name);
+ old_value = Object::GetPropertyOrElement(object, name);
CHECK_NOT_EMPTY_HANDLE(isolate, old_value);
}
}
@@ -7968,97 +7969,89 @@
}
-Handle<DescriptorArray> DescriptorArray::Merge(Handle<DescriptorArray> desc,
+// Creates a new descriptor array by merging the descriptor array of |right_map|
+// into the (at least partly) updated descriptor array of |left_map|.
+// The method merges two descriptor array in three parts. Both descriptor arrays
+// are identical up to |verbatim|. They also overlap in keys up to |valid|.
+// Between |verbatim| and |valid|, the resulting descriptor type as well as the
+// representation are generalized from both |left_map| and |right_map|. Beyond
+// |valid|, the descriptors are copied verbatim from |right_map| up to
+// |new_size|.
+// In case of incompatible types, the type and representation of |right_map| is
+// used.
+Handle<DescriptorArray> DescriptorArray::Merge(Handle<Map> left_map,
int verbatim,
int valid,
int new_size,
int modify_index,
StoreMode store_mode,
- Handle<DescriptorArray> other) {
- CALL_HEAP_FUNCTION(desc->GetIsolate(),
- desc->Merge(verbatim, valid, new_size, modify_index,
- store_mode, *other),
- DescriptorArray);
-}
-
-
-// Generalize the |other| descriptor array by merging it into the (at least
-// partly) updated |this| descriptor array.
-// The method merges two descriptor array in three parts. Both descriptor arrays
-// are identical up to |verbatim|. They also overlap in keys up to |valid|.
-// Between |verbatim| and |valid|, the resulting descriptor type as well as the
-// representation are generalized from both |this| and |other|. Beyond |valid|,
-// the descriptors are copied verbatim from |other| up to |new_size|.
-// In case of incompatible types, the type and representation of |other| is
-// used.
-MaybeObject* DescriptorArray::Merge(int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- DescriptorArray* other) {
+ Handle<Map> right_map) {
ASSERT(verbatim <= valid);
ASSERT(valid <= new_size);
- DescriptorArray* result;
// Allocate a new descriptor array large enough to hold the required
// descriptors, with minimally the exact same size as this descriptor array.
- MaybeObject* maybe_descriptors = DescriptorArray::Allocate(
- GetIsolate(), new_size,
- Max(new_size, other->number_of_descriptors()) - new_size);
- if (!maybe_descriptors->To(&result)) return maybe_descriptors;
- ASSERT(result->length() > length() ||
+ Factory* factory = left_map->GetIsolate()->factory();
+ Handle<DescriptorArray> left(left_map->instance_descriptors());
+ Handle<DescriptorArray> right(right_map->instance_descriptors());
+ Handle<DescriptorArray> result = factory->NewDescriptorArray(
+ new_size, Max(new_size, right->number_of_descriptors()) - new_size);
+ ASSERT(result->length() > left->length() ||
result->NumberOfSlackDescriptors() > 0 ||
- result->number_of_descriptors() == other->number_of_descriptors());
+ result->number_of_descriptors() == right->number_of_descriptors());
ASSERT(result->number_of_descriptors() == new_size);
- DescriptorArray::WhitenessWitness witness(result);
-
int descriptor;
// 0 -> |verbatim|
int current_offset = 0;
for (descriptor = 0; descriptor < verbatim; descriptor++) {
- if (GetDetails(descriptor).type() == FIELD) current_offset++;
- result->CopyFrom(descriptor, other, descriptor, witness);
+ if (left->GetDetails(descriptor).type() == FIELD) current_offset++;
+ Descriptor d(right->GetKey(descriptor),
+ right->GetValue(descriptor),
+ right->GetDetails(descriptor));
+ result->Set(descriptor, &d);
}
// |verbatim| -> |valid|
for (; descriptor < valid; descriptor++) {
- Name* key = GetKey(descriptor);
- PropertyDetails details = GetDetails(descriptor);
- PropertyDetails other_details = other->GetDetails(descriptor);
-
- if (details.type() == FIELD || other_details.type() == FIELD ||
+ PropertyDetails left_details = left->GetDetails(descriptor);
+ PropertyDetails right_details = right->GetDetails(descriptor);
+ if (left_details.type() == FIELD || right_details.type() == FIELD ||
(store_mode == FORCE_FIELD && descriptor == modify_index) ||
- (details.type() == CONSTANT &&
- other_details.type() == CONSTANT &&
- GetValue(descriptor) != other->GetValue(descriptor))) {
- Representation representation =
- details.representation().generalize(other_details.representation());
- FieldDescriptor d(key,
+ (left_details.type() == CONSTANT &&
+ right_details.type() == CONSTANT &&
+ left->GetValue(descriptor) != right->GetValue(descriptor))) {
+ Representation representation = left_details.representation().generalize(
+ right_details.representation());
+ FieldDescriptor d(left->GetKey(descriptor),
current_offset++,
- other_details.attributes(),
+ right_details.attributes(),
representation);
- result->Set(descriptor, &d, witness);
+ result->Set(descriptor, &d);
} else {
- result->CopyFrom(descriptor, other, descriptor, witness);
+ Descriptor d(right->GetKey(descriptor),
+ right->GetValue(descriptor),
+ right_details);
+ result->Set(descriptor, &d);
}
}
// |valid| -> |new_size|
for (; descriptor < new_size; descriptor++) {
- PropertyDetails details = other->GetDetails(descriptor);
- if (details.type() == FIELD ||
+ PropertyDetails right_details = right->GetDetails(descriptor);
+ if (right_details.type() == FIELD ||
(store_mode == FORCE_FIELD && descriptor == modify_index)) {
- Name* key = other->GetKey(descriptor);
- FieldDescriptor d(key,
+ FieldDescriptor d(right->GetKey(descriptor),
current_offset++,
- details.attributes(),
- details.representation());
- result->Set(descriptor, &d, witness);
+ right_details.attributes(),
+ right_details.representation());
+ result->Set(descriptor, &d);
} else {
- result->CopyFrom(descriptor, other, descriptor, witness);
+ Descriptor d(right->GetKey(descriptor),
+ right->GetValue(descriptor),
+ right_details);
+ result->Set(descriptor, &d);
}
}
diff --git a/src/objects.h b/src/objects.h
index e3ed08c..abfa963 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -1557,6 +1557,9 @@
Name* key,
PropertyAttributes* attributes);
+ static Handle<Object> GetPropertyOrElement(Handle<Object> object,
+ Handle<Name> key);
+
static Handle<Object> GetProperty(Handle<Object> object,
Handle<Name> key);
static Handle<Object> GetProperty(Handle<Object> object,
@@ -3046,6 +3049,8 @@
// Gives access to raw memory which stores the array's data.
inline Object** data_start();
+ inline void FillWithHoles(int from, int to);
+
// Shrink length and insert filler objects.
void Shrink(int length);
@@ -3156,6 +3161,8 @@
// Gives access to raw memory which stores the array's data.
inline double* data_start();
+ inline void FillWithHoles(int from, int to);
+
// Code Generation support.
static int OffsetOfElementAt(int index) { return SizeFor(index); }
@@ -3432,19 +3439,14 @@
DescriptorArray* src,
int src_index,
const WhitenessWitness&);
- static Handle<DescriptorArray> Merge(Handle<DescriptorArray> desc,
+ static Handle<DescriptorArray> Merge(Handle<Map> left_map,
int verbatim,
int valid,
int new_size,
int modify_index,
StoreMode store_mode,
- Handle<DescriptorArray> other);
- MUST_USE_RESULT MaybeObject* Merge(int verbatim,
- int valid,
- int new_size,
- int modify_index,
- StoreMode store_mode,
- DescriptorArray* other);
+ Handle<Map> right_map)
+ V8_WARN_UNUSED_RESULT;
bool IsMoreGeneralThan(int verbatim,
int valid,
diff --git a/src/parser.h b/src/parser.h
index f496267..4bb9aad 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -441,16 +441,14 @@
template<typename FunctionState>
static void SetUpFunctionState(FunctionState* function_state, Zone* zone) {
Isolate* isolate = zone->isolate();
- function_state->isolate_ = isolate;
function_state->saved_ast_node_id_ = isolate->ast_node_id();
isolate->set_ast_node_id(BailoutId::FirstUsable().ToInt());
}
template<typename FunctionState>
- static void TearDownFunctionState(FunctionState* function_state) {
+ static void TearDownFunctionState(FunctionState* function_state, Zone* zone) {
if (function_state->outer_function_state_ != NULL) {
- function_state->isolate_->set_ast_node_id(
- function_state->saved_ast_node_id_);
+ zone->isolate()->set_ast_node_id(function_state->saved_ast_node_id_);
}
}
diff --git a/src/preparser.h b/src/preparser.h
index 080b772..38d12e1 100644
--- a/src/preparser.h
+++ b/src/preparser.h
@@ -228,8 +228,8 @@
FunctionState* outer_function_state_;
typename Traits::Type::Scope** scope_stack_;
typename Traits::Type::Scope* outer_scope_;
- Isolate* isolate_; // Only used by ParserTraits.
int saved_ast_node_id_; // Only used by ParserTraits.
+ typename Traits::Type::Zone* extra_param_;
typename Traits::Type::Factory factory_;
friend class ParserTraits;
@@ -829,7 +829,7 @@
template<typename FunctionState>
static void SetUpFunctionState(FunctionState* function_state, void*) {}
template<typename FunctionState>
- static void TearDownFunctionState(FunctionState* function_state) {}
+ static void TearDownFunctionState(FunctionState* function_state, void*) {}
// Helper functions for recursive descent.
static bool IsEvalOrArguments(PreParserIdentifier identifier) {
@@ -1181,8 +1181,8 @@
outer_function_state_(*function_state_stack),
scope_stack_(scope_stack),
outer_scope_(*scope_stack),
- isolate_(NULL),
saved_ast_node_id_(0),
+ extra_param_(extra_param),
factory_(extra_param) {
*scope_stack_ = scope;
*function_state_stack = this;
@@ -1194,7 +1194,7 @@
ParserBase<Traits>::FunctionState::~FunctionState() {
*scope_stack_ = outer_scope_;
*function_state_stack_ = outer_function_state_;
- Traits::TearDownFunctionState(this);
+ Traits::TearDownFunctionState(this, extra_param_);
}
diff --git a/src/promise.js b/src/promise.js
index 50f91ae..5a834bd 100644
--- a/src/promise.js
+++ b/src/promise.js
@@ -34,19 +34,7 @@
// var $WeakMap = global.WeakMap
-var $Promise = function Promise(resolver) {
- if (resolver === promiseRaw) return;
- if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
- if (typeof resolver !== 'function')
- throw MakeTypeError('resolver_not_a_function', [resolver]);
- var promise = PromiseInit(this);
- try {
- resolver(function(x) { PromiseResolve(promise, x) },
- function(r) { PromiseReject(promise, r) });
- } catch (e) {
- PromiseReject(promise, e);
- }
-}
+var $Promise = Promise;
//-------------------------------------------------------------------
@@ -64,6 +52,20 @@
return IS_SPEC_OBJECT(x) && %HasLocalProperty(x, promiseStatus);
}
+function Promise(resolver) {
+ if (resolver === promiseRaw) return;
+ if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
+ if (typeof resolver !== 'function')
+ throw MakeTypeError('resolver_not_a_function', [resolver]);
+ var promise = PromiseInit(this);
+ try {
+ resolver(function(x) { PromiseResolve(promise, x) },
+ function(r) { PromiseReject(promise, r) });
+ } catch (e) {
+ PromiseReject(promise, e);
+ }
+}
+
function PromiseSet(promise, status, value, onResolve, onReject) {
SET_PRIVATE(promise, promiseStatus, status);
SET_PRIVATE(promise, promiseValue, value);
@@ -97,7 +99,7 @@
function PromiseNopResolver() {}
function PromiseCreate() {
- return new $Promise(PromiseNopResolver)
+ return new Promise(PromiseNopResolver)
}
@@ -106,7 +108,7 @@
function PromiseDeferred() {
if (this === $Promise) {
// Optimized case, avoid extra closure.
- var promise = PromiseInit(new $Promise(promiseRaw));
+ var promise = PromiseInit(new Promise(promiseRaw));
return {
promise: promise,
resolve: function(x) { PromiseResolve(promise, x) },
@@ -125,7 +127,7 @@
function PromiseResolved(x) {
if (this === $Promise) {
// Optimized case, avoid extra closure.
- return PromiseSet(new $Promise(promiseRaw), +1, x);
+ return PromiseSet(new Promise(promiseRaw), +1, x);
} else {
return new this(function(resolve, reject) { resolve(x) });
}
@@ -134,7 +136,7 @@
function PromiseRejected(r) {
if (this === $Promise) {
// Optimized case, avoid extra closure.
- return PromiseSet(new $Promise(promiseRaw), -1, r);
+ return PromiseSet(new Promise(promiseRaw), -1, r);
} else {
return new this(function(resolve, reject) { reject(r) });
}
diff --git a/src/runtime.cc b/src/runtime.cc
index 5142fd3..849de3c 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -628,8 +628,8 @@
Handle<JSObject> registry = isolate->GetSymbolRegistry();
Handle<String> part = isolate->factory()->private_intern_string();
Handle<JSObject> privates =
- Handle<JSObject>::cast(JSObject::GetProperty(registry, part));
- Handle<Object> symbol = JSObject::GetProperty(privates, name);
+ Handle<JSObject>::cast(Object::GetPropertyOrElement(registry, part));
+ Handle<Object> symbol = Object::GetPropertyOrElement(privates, name);
if (!symbol->IsSymbol()) {
ASSERT(symbol->IsUndefined());
symbol = isolate->factory()->NewPrivateSymbol();
@@ -1132,33 +1132,26 @@
}
-#define TYPED_ARRAY_GETTER(getter, accessor) \
- RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGet##getter) { \
+#define BUFFER_VIEW_GETTER(Type, getter, accessor) \
+ RUNTIME_FUNCTION(MaybeObject*, Runtime_##Type##Get##getter) { \
HandleScope scope(isolate); \
ASSERT(args.length() == 1); \
- CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0); \
- if (!holder->IsJSTypedArray()) \
- return isolate->Throw(*isolate->factory()->NewTypeError( \
- "not_typed_array", HandleVector<Object>(NULL, 0))); \
- Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder)); \
- return typed_array->accessor(); \
+ CONVERT_ARG_HANDLE_CHECKED(JS##Type, holder, 0); \
+ return holder->accessor(); \
}
-TYPED_ARRAY_GETTER(ByteLength, byte_length)
-TYPED_ARRAY_GETTER(ByteOffset, byte_offset)
-TYPED_ARRAY_GETTER(Length, length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteLength, byte_length)
+BUFFER_VIEW_GETTER(ArrayBufferView, ByteOffset, byte_offset)
+BUFFER_VIEW_GETTER(TypedArray, Length, length)
+BUFFER_VIEW_GETTER(DataView, Buffer, buffer)
-#undef TYPED_ARRAY_GETTER
+#undef BUFFER_VIEW_GETTER
RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayGetBuffer) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, holder, 0);
- if (!holder->IsJSTypedArray())
- return isolate->Throw(*isolate->factory()->NewTypeError(
- "not_typed_array", HandleVector<Object>(NULL, 0)));
- Handle<JSTypedArray> typed_array(JSTypedArray::cast(*holder));
- return *typed_array->GetBuffer();
+ CONVERT_ARG_HANDLE_CHECKED(JSTypedArray, holder, 0);
+ return *holder->GetBuffer();
}
@@ -1236,7 +1229,8 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_TypedArrayMaxSizeInHeap) {
- ASSERT_OBJECT_SIZE(FLAG_typed_array_max_size_in_heap);
+ ASSERT_OBJECT_SIZE(
+ FLAG_typed_array_max_size_in_heap + FixedTypedArrayBase::kDataOffset);
return Smi::FromInt(FLAG_typed_array_max_size_in_heap);
}
@@ -1272,30 +1266,6 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetBuffer) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
- return data_view->buffer();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteOffset) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
- return data_view->byte_offset();
-}
-
-
-RUNTIME_FUNCTION(MaybeObject*, Runtime_DataViewGetByteLength) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSDataView, data_view, 0);
- return data_view->byte_length();
-}
-
-
inline static bool NeedToFlipBytes(bool is_little_endian) {
#ifdef V8_TARGET_LITTLE_ENDIAN
return !is_little_endian;
@@ -1958,8 +1928,8 @@
if (raw_accessors == NULL) {
elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
- // GetProperty does access check.
- Handle<Object> value = GetProperty(isolate, obj, name);
+ // Runtime::GetObjectProperty does access check.
+ Handle<Object> value = Runtime::GetObjectProperty(isolate, obj, name);
RETURN_IF_EMPTY_HANDLE_VALUE(isolate, value, Handle<Object>::null());
elms->set(VALUE_INDEX, *value);
} else {
@@ -4979,59 +4949,46 @@
return isolate->heap()->ToBoolean(JSReceiver::HasProperty(object, name));
}
-MaybeObject* Runtime::GetObjectPropertyOrFail(
- Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key) {
- CALL_HEAP_FUNCTION_PASS_EXCEPTION(isolate,
- GetObjectProperty(isolate, object, key));
-}
-MaybeObject* Runtime::GetObjectProperty(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key) {
- HandleScope scope(isolate);
-
+Handle<Object> Runtime::GetObjectProperty(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> key) {
if (object->IsUndefined() || object->IsNull()) {
Handle<Object> args[2] = { key, object };
- Handle<Object> error =
- isolate->factory()->NewTypeError("non_object_property_load",
- HandleVector(args, 2));
- return isolate->Throw(*error);
+ isolate->Throw(*isolate->factory()->NewTypeError("non_object_property_load",
+ HandleVector(args, 2)));
+ return Handle<Object>();
}
// Check if the given key is an array index.
uint32_t index;
if (key->ToArrayIndex(&index)) {
- Handle<Object> result = GetElementOrCharAt(isolate, object, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ return GetElementOrCharAt(isolate, object, index);
}
// Convert the key to a name - possibly by calling back into JavaScript.
Handle<Name> name = ToName(isolate, key);
- RETURN_IF_EMPTY_HANDLE(isolate, name);
+ RETURN_IF_EMPTY_HANDLE_VALUE(isolate, name, Handle<Object>());
// Check if the name is trivially convertible to an index and get
// the element if so.
if (name->AsArrayIndex(&index)) {
- Handle<Object> result = GetElementOrCharAt(isolate, object, index);
- RETURN_IF_EMPTY_HANDLE(isolate, result);
- return *result;
+ return GetElementOrCharAt(isolate, object, index);
} else {
- return object->GetProperty(*name);
+ return Object::GetProperty(object, name);
}
}
RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) {
- SealHandleScope shs(isolate);
+ HandleScope scope(isolate);
ASSERT(args.length() == 2);
Handle<Object> object = args.at<Object>(0);
Handle<Object> key = args.at<Object>(1);
-
- return Runtime::GetObjectProperty(isolate, object, key);
+ Handle<Object> result = Runtime::GetObjectProperty(isolate, object, key);
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
@@ -5134,9 +5091,11 @@
}
// Fall back to GetObjectProperty.
- return Runtime::GetObjectProperty(isolate,
- args.at<Object>(0),
- args.at<Object>(1));
+ HandleScope scope(isolate);
+ Handle<Object> result = Runtime::GetObjectProperty(
+ isolate, args.at<Object>(0), args.at<Object>(1));
+ RETURN_IF_EMPTY_HANDLE(isolate, result);
+ return *result;
}
@@ -7761,19 +7720,19 @@
}
-#define RUNTIME_UNARY_MATH(NAME) \
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_##NAME) { \
+#define RUNTIME_UNARY_MATH(Name, name) \
+RUNTIME_FUNCTION(MaybeObject*, Runtime_Math##Name) { \
SealHandleScope shs(isolate); \
ASSERT(args.length() == 1); \
- isolate->counters()->math_##NAME()->Increment(); \
+ isolate->counters()->math_##name()->Increment(); \
CONVERT_DOUBLE_ARG_CHECKED(x, 0); \
- return isolate->heap()->AllocateHeapNumber(std::NAME(x)); \
+ return isolate->heap()->AllocateHeapNumber(std::name(x)); \
}
-RUNTIME_UNARY_MATH(acos)
-RUNTIME_UNARY_MATH(asin)
-RUNTIME_UNARY_MATH(atan)
-RUNTIME_UNARY_MATH(log)
+RUNTIME_UNARY_MATH(Acos, acos)
+RUNTIME_UNARY_MATH(Asin, asin)
+RUNTIME_UNARY_MATH(Atan, atan)
+RUNTIME_UNARY_MATH(Log, log)
#undef RUNTIME_UNARY_MATH
@@ -7809,7 +7768,7 @@
static const double kPiDividedBy4 = 0.78539816339744830962;
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_atan2) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MathAtan2) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
isolate->counters()->math_atan2()->Increment();
@@ -7832,7 +7791,7 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MathExp) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
isolate->counters()->math_exp()->Increment();
@@ -7843,7 +7802,7 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_floor) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MathFloor) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
isolate->counters()->math_floor()->Increment();
@@ -7855,7 +7814,7 @@
// Slow version of Math.pow. We check for fast paths for special cases.
// Used if SSE2/VFP3 is not available.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow) {
+RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_MathPowSlow) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
isolate->counters()->math_pow()->Increment();
@@ -7878,7 +7837,7 @@
// Fast version of Math.pow if we know that y is not an integer and y is not
// -0.5 or 0.5. Used as slow case from full codegen.
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_pow_cfunction) {
+RUNTIME_FUNCTION(MaybeObject*, RuntimeHidden_MathPow) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
isolate->counters()->math_pow()->Increment();
@@ -7938,7 +7897,7 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MathSqrt) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
isolate->counters()->math_sqrt()->Increment();
@@ -7948,7 +7907,7 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_fround) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_MathFround) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -11553,7 +11512,7 @@
ASSERT(!frame->GetParameter(i)->IsTheHole());
HandleScope scope(isolate);
Handle<String> name(scope_info->ParameterName(i));
- Handle<Object> value = GetProperty(isolate, target, name);
+ Handle<Object> value = Object::GetPropertyOrElement(target, name);
frame->SetParameterValue(i, *value);
}
@@ -11561,8 +11520,8 @@
for (int i = 0; i < scope_info->StackLocalCount(); ++i) {
if (frame->GetExpression(i)->IsTheHole()) continue;
HandleScope scope(isolate);
- Handle<Object> value = GetProperty(
- isolate, target, Handle<String>(scope_info->StackLocalName(i)));
+ Handle<Object> value = Object::GetPropertyOrElement(
+ target, Handle<String>(scope_info->StackLocalName(i)));
frame->SetExpression(i, *value);
}
}
@@ -11606,7 +11565,7 @@
Runtime::SetObjectProperty(isolate,
target,
key,
- GetProperty(isolate, ext, key),
+ Object::GetPropertyOrElement(ext, key),
NONE,
SLOPPY),
Handle<JSObject>());
@@ -11756,7 +11715,7 @@
RETURN_IF_EMPTY_HANDLE_VALUE(
isolate,
Runtime::SetObjectProperty(isolate, closure_scope, key,
- GetProperty(isolate, ext, key),
+ Object::GetPropertyOrElement(ext, key),
NONE, SLOPPY),
Handle<JSObject>());
}
diff --git a/src/runtime.h b/src/runtime.h
index 58cd525..be0e545 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -157,18 +157,14 @@
F(SmiLexicographicCompare, 2, 1) \
\
/* Math */ \
- F(Math_acos, 1, 1) \
- F(Math_asin, 1, 1) \
- F(Math_atan, 1, 1) \
- F(Math_log, 1, 1) \
- F(Math_sqrt, 1, 1) \
- F(Math_exp, 1, 1) \
- F(Math_floor, 1, 1) \
- F(Math_pow, 2, 1) \
- F(Math_pow_cfunction, 2, 1) \
- F(Math_atan2, 2, 1) \
+ F(MathAcos, 1, 1) \
+ F(MathAsin, 1, 1) \
+ F(MathAtan, 1, 1) \
+ F(MathFloor, 1, 1) \
+ F(MathAtan2, 2, 1) \
+ F(MathExp, 1, 1) \
F(RoundNumber, 1, 1) \
- F(Math_fround, 1, 1) \
+ F(MathFround, 1, 1) \
\
/* Regular expressions */ \
F(RegExpCompile, 3, 1) \
@@ -332,21 +328,15 @@
\
/* Harmony typed arrays */ \
F(ArrayBufferInitialize, 2, 1)\
- F(ArrayBufferGetByteLength, 1, 1)\
F(ArrayBufferSliceImpl, 3, 1) \
F(ArrayBufferIsView, 1, 1) \
F(ArrayBufferNeuter, 1, 1) \
\
F(TypedArrayInitializeFromArrayLike, 4, 1) \
F(TypedArrayGetBuffer, 1, 1) \
- F(TypedArrayGetByteLength, 1, 1) \
- F(TypedArrayGetByteOffset, 1, 1) \
- F(TypedArrayGetLength, 1, 1) \
F(TypedArraySetFastCases, 3, 1) \
\
F(DataViewGetBuffer, 1, 1) \
- F(DataViewGetByteLength, 1, 1) \
- F(DataViewGetByteOffset, 1, 1) \
F(DataViewGetInt8, 3, 1) \
F(DataViewGetUint8, 3, 1) \
F(DataViewGetInt16, 3, 1) \
@@ -556,6 +546,7 @@
// by id from code generator, but not via native call by name.
// Entries have the form F(name, number of arguments, number of return values).
#define RUNTIME_HIDDEN_FUNCTION_LIST(F) \
+ /* String and Regexp */ \
F(NumberToString, 1, 1) \
F(RegExpConstructResult, 3, 1) \
F(RegExpExec, 4, 1) \
@@ -634,7 +625,11 @@
F(InitializeConstContextSlot, 3, 1) \
\
/* Eval */ \
- F(ResolvePossiblyDirectEval, 5, 2)
+ F(ResolvePossiblyDirectEval, 5, 2) \
+ \
+ /* Maths */ \
+ F(MathPowSlow, 2, 1) \
+ F(MathPow, 2, 1)
// ----------------------------------------------------------------------------
// INLINE_FUNCTION_LIST defines all inlined functions accessed
@@ -663,8 +658,6 @@
F(IsSpecObject, 1, 1) \
F(IsStringWrapperSafeForDefaultValueOf, 1, 1) \
F(MathPow, 2, 1) \
- F(MathSqrt, 1, 1) \
- F(MathLog, 1, 1) \
F(IsMinusZero, 1, 1) \
F(HasCachedArrayIndex, 1, 1) \
F(GetCachedArrayIndex, 1, 1) \
@@ -690,13 +683,22 @@
// a corresponding runtime function, that is called from non-optimized code.
// Entries have the form F(name, number of arguments, number of return values).
#define INLINE_OPTIMIZED_FUNCTION_LIST(F) \
- F(DoubleHi, 1, 1) \
- F(DoubleLo, 1, 1) \
- F(ConstructDouble, 2, 1) \
+ /* Typed Arrays */ \
F(TypedArrayInitialize, 5, 1) \
F(DataViewInitialize, 4, 1) \
F(MaxSmi, 0, 1) \
- F(TypedArrayMaxSizeInHeap, 0, 1)
+ F(TypedArrayMaxSizeInHeap, 0, 1) \
+ F(ArrayBufferViewGetByteLength, 1, 1) \
+ F(ArrayBufferViewGetByteOffset, 1, 1) \
+ F(TypedArrayGetLength, 1, 1) \
+ /* ArrayBuffer */ \
+ F(ArrayBufferGetByteLength, 1, 1) \
+ /* Maths */ \
+ F(ConstructDouble, 2, 1) \
+ F(DoubleHi, 1, 1) \
+ F(DoubleLo, 1, 1) \
+ F(MathSqrt, 1, 1) \
+ F(MathLog, 1, 1)
//---------------------------------------------------------------------------
@@ -846,15 +848,9 @@
Handle<JSReceiver> object,
Handle<Object> key);
- MUST_USE_RESULT static MaybeObject* GetObjectProperty(
- Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key);
-
- MUST_USE_RESULT static MaybeObject* GetObjectPropertyOrFail(
- Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key);
+ static Handle<Object> GetObjectProperty(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> key);
static void SetupArrayBuffer(Isolate* isolate,
Handle<JSArrayBuffer> array_buffer,
diff --git a/src/scanner-character-streams.cc b/src/scanner-character-streams.cc
index cbef3f9..201b597 100644
--- a/src/scanner-character-streams.cc
+++ b/src/scanner-character-streams.cc
@@ -126,8 +126,6 @@
: string_(data),
length_(end_position) {
ASSERT(end_position >= start_position);
- buffer_cursor_ = buffer_;
- buffer_end_ = buffer_;
pos_ = start_position;
}
diff --git a/src/scanner-character-streams.h b/src/scanner-character-streams.h
index 319ee8f..80ef9bd 100644
--- a/src/scanner-character-streams.h
+++ b/src/scanner-character-streams.h
@@ -72,7 +72,6 @@
virtual unsigned FillBuffer(unsigned position, unsigned length);
Handle<String> string_;
- unsigned start_position_;
unsigned length_;
};
diff --git a/src/spaces.cc b/src/spaces.cc
index 6c03daa..2ca8c98 100644
--- a/src/spaces.cc
+++ b/src/spaces.cc
@@ -1051,7 +1051,7 @@
int size = 0;
switch (identity()) {
case OLD_POINTER_SPACE:
- size = 72 * kPointerSize * KB;
+ size = 96 * kPointerSize * KB;
break;
case OLD_DATA_SPACE:
size = 192 * KB;
diff --git a/src/string-stream.cc b/src/string-stream.cc
index e2d15f5..93eb222 100644
--- a/src/string-stream.cc
+++ b/src/string-stream.cc
@@ -1,35 +1,11 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
-#include "v8.h"
-
-#include "factory.h"
#include "string-stream.h"
+#include "handles-inl.h"
+
namespace v8 {
namespace internal {
diff --git a/src/string-stream.h b/src/string-stream.h
index e3db2a8..ecc0e80 100644
--- a/src/string-stream.h
+++ b/src/string-stream.h
@@ -1,40 +1,18 @@
-// 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.
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#ifndef V8_STRING_STREAM_H_
#define V8_STRING_STREAM_H_
+#include "handles.h"
+
namespace v8 {
namespace internal {
-
class StringAllocator {
public:
- virtual ~StringAllocator() {}
+ virtual ~StringAllocator() { }
// Allocate a number of bytes.
virtual char* allocate(unsigned bytes) = 0;
// Allocate a larger number of bytes and copy the old buffer to the new one.
@@ -46,11 +24,12 @@
// Normal allocator uses new[] and delete[].
-class HeapStringAllocator: public StringAllocator {
+class HeapStringAllocator V8_FINAL : public StringAllocator {
public:
~HeapStringAllocator() { DeleteArray(space_); }
- char* allocate(unsigned bytes);
- char* grow(unsigned* bytes);
+ virtual char* allocate(unsigned bytes) V8_OVERRIDE;
+ virtual char* grow(unsigned* bytes) V8_OVERRIDE;
+
private:
char* space_;
};
@@ -59,18 +38,19 @@
// Allocator for use when no new c++ heap allocation is allowed.
// Given a preallocated buffer up front and does no allocation while
// building message.
-class NoAllocationStringAllocator: public StringAllocator {
+class NoAllocationStringAllocator V8_FINAL : public StringAllocator {
public:
NoAllocationStringAllocator(char* memory, unsigned size);
- char* allocate(unsigned bytes) { return space_; }
- char* grow(unsigned* bytes);
+ virtual char* allocate(unsigned bytes) V8_OVERRIDE { return space_; }
+ virtual char* grow(unsigned* bytes) V8_OVERRIDE;
+
private:
unsigned size_;
char* space_;
};
-class FmtElm {
+class FmtElm V8_FINAL {
public:
FmtElm(int value) : type_(INT) { // NOLINT
data_.u_int_ = value;
@@ -110,7 +90,7 @@
};
-class StringStream {
+class StringStream V8_FINAL {
public:
explicit StringStream(StringAllocator* allocator):
allocator_(allocator),
@@ -120,9 +100,6 @@
buffer_[0] = 0;
}
- ~StringStream() {
- }
-
bool Put(char c);
bool Put(String* str);
bool Put(String* str, int start, int end);
@@ -175,7 +152,6 @@
static bool IsMentionedObjectCacheClear(Isolate* isolate);
#endif
-
static const int kInitialCapacity = 16;
private:
@@ -194,7 +170,7 @@
// Utility class to print a list of items to a stream, divided by a separator.
-class SimpleListPrinter {
+class SimpleListPrinter V8_FINAL {
public:
explicit SimpleListPrinter(StringStream* stream, char separator = ',') {
separator_ = separator;
@@ -217,7 +193,6 @@
StringStream* stream_;
};
-
} } // namespace v8::internal
#endif // V8_STRING_STREAM_H_
diff --git a/src/typedarray.js b/src/typedarray.js
index 109d627..e86c86c 100644
--- a/src/typedarray.js
+++ b/src/typedarray.js
@@ -57,7 +57,7 @@
length = ToPositiveInteger(length, "invalid_typed_array_length");
}
- var bufferByteLength = %ArrayBufferGetByteLength(buffer);
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
var offset;
if (IS_UNDEFINED(byteOffset)) {
offset = 0;
@@ -125,7 +125,6 @@
}
function NAMEConstructor(arg1, arg2, arg3) {
-
if (%_IsConstructCall()) {
if (IS_ARRAYBUFFER(arg1)) {
NAMEConstructByArrayBuffer(this, arg1, arg2, arg3);
@@ -139,34 +138,52 @@
throw MakeTypeError("constructor_not_function", ["NAME"])
}
}
-endmacro
-TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+ function NAME_GetBuffer() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.buffer", this]);
+ }
+ return %TypedArrayGetBuffer(this);
+ }
-function TypedArrayGetBuffer() {
- return %TypedArrayGetBuffer(this);
-}
+ function NAME_GetByteLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.byteLength", this]);
+ }
+ return %_ArrayBufferViewGetByteLength(this);
+ }
-function TypedArrayGetByteLength() {
- return %TypedArrayGetByteLength(this);
-}
+ function NAME_GetByteOffset() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.byteOffset", this]);
+ }
+ return %_ArrayBufferViewGetByteOffset(this);
+ }
-function TypedArrayGetByteOffset() {
- return %TypedArrayGetByteOffset(this);
-}
+ function NAME_GetLength() {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.length", this]);
+ }
+ return %_TypedArrayGetLength(this);
+ }
-function TypedArrayGetLength() {
- return %TypedArrayGetLength(this);
-}
+ var $NAME = global.NAME;
-function CreateSubArray(elementSize, constructor) {
- return function(begin, end) {
+ function NAMESubArray(begin, end) {
+ if (!(%_ClassOf(this) === 'NAME')) {
+ throw MakeTypeError('incompatible_method_receiver',
+ ["NAME.subarray", this]);
+ }
var beginInt = TO_INTEGER(begin);
if (!IS_UNDEFINED(end)) {
end = TO_INTEGER(end);
}
- var srcLength = %TypedArrayGetLength(this);
+ var srcLength = %_TypedArrayGetLength(this);
if (beginInt < 0) {
beginInt = MathMax(0, srcLength + beginInt);
} else {
@@ -184,11 +201,14 @@
}
var newLength = endInt - beginInt;
var beginByteOffset =
- %TypedArrayGetByteOffset(this) + beginInt * elementSize;
- return new constructor(%TypedArrayGetBuffer(this),
- beginByteOffset, newLength);
+ %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE;
+ return new $NAME(%TypedArrayGetBuffer(this),
+ beginByteOffset, newLength);
}
-}
+endmacro
+
+TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR)
+
function TypedArraySetFromArrayLike(target, source, sourceLength, offset) {
if (offset > 0) {
@@ -296,34 +316,34 @@
// -------------------------------------------------------------------
-function SetupTypedArray(constructor, fun, elementSize) {
+function SetupTypedArrays() {
+macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
%CheckIsBootstrapping();
- %SetCode(constructor, fun);
- %FunctionSetPrototype(constructor, new $Object());
+ %SetCode(global.NAME, NAMEConstructor);
+ %FunctionSetPrototype(global.NAME, new $Object());
- %SetProperty(constructor, "BYTES_PER_ELEMENT", elementSize,
+ %SetProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
- %SetProperty(constructor.prototype,
- "constructor", constructor, DONT_ENUM);
- %SetProperty(constructor.prototype,
- "BYTES_PER_ELEMENT", elementSize,
+ %SetProperty(global.NAME.prototype,
+ "constructor", global.NAME, DONT_ENUM);
+ %SetProperty(global.NAME.prototype,
+ "BYTES_PER_ELEMENT", ELEMENT_SIZE,
READ_ONLY | DONT_ENUM | DONT_DELETE);
- InstallGetter(constructor.prototype, "buffer", TypedArrayGetBuffer);
- InstallGetter(constructor.prototype, "byteOffset", TypedArrayGetByteOffset);
- InstallGetter(constructor.prototype, "byteLength", TypedArrayGetByteLength);
- InstallGetter(constructor.prototype, "length", TypedArrayGetLength);
+ InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer);
+ InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset);
+ InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength);
+ InstallGetter(global.NAME.prototype, "length", NAME_GetLength);
- InstallFunctions(constructor.prototype, DONT_ENUM, $Array(
- "subarray", CreateSubArray(elementSize, constructor),
+ InstallFunctions(global.NAME.prototype, DONT_ENUM, $Array(
+ "subarray", NAMESubArray,
"set", TypedArraySet
));
-}
-
-macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE)
- SetupTypedArray (global.NAME, NAMEConstructor, ELEMENT_SIZE);
endmacro
TYPED_ARRAYS(SETUP_TYPED_ARRAY)
+}
+
+SetupTypedArrays();
// --------------------------- DataView -----------------------------
@@ -341,7 +361,7 @@
byteLength = TO_INTEGER(byteLength);
}
- var bufferByteLength = %ArrayBufferGetByteLength(buffer);
+ var bufferByteLength = %_ArrayBufferGetByteLength(buffer);
var offset = IS_UNDEFINED(byteOffset) ? 0 : byteOffset;
if (offset > bufferByteLength) {
@@ -373,7 +393,7 @@
throw MakeTypeError('incompatible_method_receiver',
['DataView.byteOffset', this]);
}
- return %DataViewGetByteOffset(this);
+ return %_ArrayBufferViewGetByteOffset(this);
}
function DataViewGetByteLength() {
@@ -381,7 +401,7 @@
throw MakeTypeError('incompatible_method_receiver',
['DataView.byteLength', this]);
}
- return %DataViewGetByteLength(this);
+ return %_ArrayBufferViewGetByteLength(this);
}
macro DATA_VIEW_TYPES(FUNCTION)
diff --git a/src/version.cc b/src/version.cc
index 904b067..0df368a 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -33,8 +33,8 @@
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
-#define MINOR_VERSION 25
-#define BUILD_NUMBER 30
+#define MINOR_VERSION 26
+#define BUILD_NUMBER 0
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 60383da..75eeff5 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -467,24 +467,30 @@
// Assembler Instruction implementations.
-void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) {
+void Assembler::arithmetic_op(byte opcode,
+ Register reg,
+ const Operand& op,
+ int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(reg, op);
+ emit_rex(reg, op, size);
emit(opcode);
emit_operand(reg, op);
}
-void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) {
+void Assembler::arithmetic_op(byte opcode,
+ Register reg,
+ Register rm_reg,
+ int size) {
EnsureSpace ensure_space(this);
ASSERT((opcode & 0xC6) == 2);
if (rm_reg.low_bits() == 4) { // Forces SIB byte.
// Swap reg and rm_reg and change opcode operand order.
- emit_rex_64(rm_reg, reg);
+ emit_rex(rm_reg, reg, size);
emit(opcode ^ 0x02);
emit_modrm(rm_reg, reg);
} else {
- emit_rex_64(reg, rm_reg);
+ emit_rex(reg, rm_reg, size);
emit(opcode);
emit_modrm(reg, rm_reg);
}
@@ -520,37 +526,45 @@
}
-void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) {
+void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
+ EnsureSpace ensure_space(this);
+ if (!reg.is_byte_register()) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(reg);
+ }
+ emit(opcode);
+ emit_operand(reg, op);
+}
+
+
+void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
EnsureSpace ensure_space(this);
ASSERT((opcode & 0xC6) == 2);
- if (rm_reg.low_bits() == 4) { // Forces SIB byte.
+ if (rm_reg.low_bits() == 4) { // Forces SIB byte.
// Swap reg and rm_reg and change opcode operand order.
- emit_optional_rex_32(rm_reg, reg);
- emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD.
+ if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(rm_reg, reg);
+ }
+ emit(opcode ^ 0x02);
emit_modrm(rm_reg, reg);
} else {
- emit_optional_rex_32(reg, rm_reg);
+ if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(reg, rm_reg);
+ }
emit(opcode);
emit_modrm(reg, rm_reg);
}
}
-void Assembler::arithmetic_op_32(byte opcode,
- Register reg,
- const Operand& rm_reg) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(reg, rm_reg);
- emit(opcode);
- emit_operand(reg, rm_reg);
-}
-
-
void Assembler::immediate_arithmetic_op(byte subcode,
Register dst,
- Immediate src) {
+ Immediate src,
+ int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(dst);
+ emit_rex(dst, size);
if (is_int8(src.value_)) {
emit(0x83);
emit_modrm(subcode, dst);
@@ -567,9 +581,10 @@
void Assembler::immediate_arithmetic_op(byte subcode,
const Operand& dst,
- Immediate src) {
+ Immediate src,
+ int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(dst);
+ emit_rex(dst, size);
if (is_int8(src.value_)) {
emit(0x83);
emit_operand(subcode, dst);
@@ -621,43 +636,6 @@
}
-void Assembler::immediate_arithmetic_op_32(byte subcode,
- Register dst,
- Immediate src) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(dst);
- if (is_int8(src.value_)) {
- emit(0x83);
- emit_modrm(subcode, dst);
- emit(src.value_);
- } else if (dst.is(rax)) {
- emit(0x05 | (subcode << 3));
- emitl(src.value_);
- } else {
- emit(0x81);
- emit_modrm(subcode, dst);
- emitl(src.value_);
- }
-}
-
-
-void Assembler::immediate_arithmetic_op_32(byte subcode,
- const Operand& dst,
- Immediate src) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(dst);
- if (is_int8(src.value_)) {
- emit(0x83);
- emit_operand(subcode, dst);
- emit(src.value_);
- } else {
- emit(0x81);
- emit_operand(subcode, dst);
- emitl(src.value_);
- }
-}
-
-
void Assembler::immediate_arithmetic_op_8(byte subcode,
const Operand& dst,
Immediate src) {
@@ -675,8 +653,8 @@
Immediate src) {
EnsureSpace ensure_space(this);
if (!dst.is_byte_register()) {
- // Use 64-bit mode byte registers.
- emit_rex_64(dst);
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(dst);
}
ASSERT(is_int8(src.value_) || is_uint8(src.value_));
emit(0x80);
@@ -685,15 +663,19 @@
}
-void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
+void Assembler::shift(Register dst,
+ Immediate shift_amount,
+ int subcode,
+ int size) {
EnsureSpace ensure_space(this);
- ASSERT(is_uint6(shift_amount.value_)); // illegal shift count
+ ASSERT(size == kInt64Size ? is_uint6(shift_amount.value_)
+ : is_uint5(shift_amount.value_));
if (shift_amount.value_ == 1) {
- emit_rex_64(dst);
+ emit_rex(dst, size);
emit(0xD1);
emit_modrm(subcode, dst);
} else {
- emit_rex_64(dst);
+ emit_rex(dst, size);
emit(0xC1);
emit_modrm(subcode, dst);
emit(shift_amount.value_);
@@ -701,38 +683,14 @@
}
-void Assembler::shift(Register dst, int subcode) {
+void Assembler::shift(Register dst, int subcode, int size) {
EnsureSpace ensure_space(this);
- emit_rex_64(dst);
+ emit_rex(dst, size);
emit(0xD3);
emit_modrm(subcode, dst);
}
-void Assembler::shift_32(Register dst, int subcode) {
- EnsureSpace ensure_space(this);
- emit_optional_rex_32(dst);
- emit(0xD3);
- emit_modrm(subcode, dst);
-}
-
-
-void Assembler::shift_32(Register dst, Immediate shift_amount, int subcode) {
- EnsureSpace ensure_space(this);
- ASSERT(is_uint5(shift_amount.value_)); // illegal shift count
- if (shift_amount.value_ == 1) {
- emit_optional_rex_32(dst);
- emit(0xD1);
- emit_modrm(subcode, dst);
- } else {
- emit_optional_rex_32(dst);
- emit(0xC1);
- emit_modrm(subcode, dst);
- emit(shift_amount.value_);
- }
-}
-
-
void Assembler::bt(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
emit_rex_64(src, dst);
diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h
index d47ca32..92d63d2 100644
--- a/src/x64/assembler-x64.h
+++ b/src/x64/assembler-x64.h
@@ -532,6 +532,18 @@
V(xor)
+// Shift instructions on operands/registers with kPointerSize, kInt32Size and
+// kInt64Size.
+#define SHIFT_INSTRUCTION_LIST(V) \
+ V(rol, 0x0) \
+ V(ror, 0x1) \
+ V(rcl, 0x2) \
+ V(rcr, 0x3) \
+ V(shl, 0x4) \
+ V(shr, 0x5) \
+ V(sar, 0x7) \
+
+
class Assembler : public AssemblerBase {
private:
// We check before assembling an instruction that there is sufficient
@@ -680,6 +692,8 @@
// - Instructions on 64-bit (quadword) operands/registers use 'q'.
// - Instructions on operands/registers with pointer size use 'p'.
+ STATIC_ASSERT(kPointerSize == kInt64Size || kPointerSize == kInt32Size);
+
#define DECLARE_INSTRUCTION(instruction) \
template<class P1> \
void instruction##p(P1 p1) { \
@@ -806,15 +820,15 @@
void cmpb_al(Immediate src);
void cmpb(Register dst, Register src) {
- arithmetic_op(0x3A, dst, src);
+ arithmetic_op_8(0x3A, dst, src);
}
void cmpb(Register dst, const Operand& src) {
- arithmetic_op(0x3A, dst, src);
+ arithmetic_op_8(0x3A, dst, src);
}
void cmpb(const Operand& dst, Register src) {
- arithmetic_op(0x38, src, dst);
+ arithmetic_op_8(0x38, src, dst);
}
void cmpb(const Operand& dst, Immediate src) {
@@ -856,33 +870,32 @@
// Multiply rax by src, put the result in rdx:rax.
void mul(Register src);
- void rcl(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x2);
+#define DECLARE_SHIFT_INSTRUCTION(instruction, subcode) \
+ void instruction##p(Register dst, Immediate imm8) { \
+ shift(dst, imm8, subcode, kPointerSize); \
+ } \
+ \
+ void instruction##l(Register dst, Immediate imm8) { \
+ shift(dst, imm8, subcode, kInt32Size); \
+ } \
+ \
+ void instruction##q(Register dst, Immediate imm8) { \
+ shift(dst, imm8, subcode, kInt64Size); \
+ } \
+ \
+ void instruction##p_cl(Register dst) { \
+ shift(dst, subcode, kPointerSize); \
+ } \
+ \
+ void instruction##l_cl(Register dst) { \
+ shift(dst, subcode, kInt32Size); \
+ } \
+ \
+ void instruction##q_cl(Register dst) { \
+ shift(dst, subcode, kInt64Size); \
}
-
- void rol(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x0);
- }
-
- void roll(Register dst, Immediate imm8) {
- shift_32(dst, imm8, 0x0);
- }
-
- void rcr(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x3);
- }
-
- void ror(Register dst, Immediate imm8) {
- shift(dst, imm8, 0x1);
- }
-
- void rorl(Register dst, Immediate imm8) {
- shift_32(dst, imm8, 0x1);
- }
-
- void rorl_cl(Register dst) {
- shift_32(dst, 0x1);
- }
+ SHIFT_INSTRUCTION_LIST(DECLARE_SHIFT_INSTRUCTION)
+#undef DECLARE_SHIFT_INSTRUCTION
// Shifts dst:src left by cl bits, affecting only dst.
void shld(Register dst, Register src);
@@ -890,60 +903,6 @@
// Shifts src:dst right by cl bits, affecting only dst.
void shrd(Register dst, Register src);
- // Shifts dst right, duplicating sign bit, by shift_amount bits.
- // Shifting by 1 is handled efficiently.
- void sar(Register dst, Immediate shift_amount) {
- shift(dst, shift_amount, 0x7);
- }
-
- // Shifts dst right, duplicating sign bit, by shift_amount bits.
- // Shifting by 1 is handled efficiently.
- void sarl(Register dst, Immediate shift_amount) {
- shift_32(dst, shift_amount, 0x7);
- }
-
- // Shifts dst right, duplicating sign bit, by cl % 64 bits.
- void sar_cl(Register dst) {
- shift(dst, 0x7);
- }
-
- // Shifts dst right, duplicating sign bit, by cl % 64 bits.
- void sarl_cl(Register dst) {
- shift_32(dst, 0x7);
- }
-
- void shl(Register dst, Immediate shift_amount) {
- shift(dst, shift_amount, 0x4);
- }
-
- void shl_cl(Register dst) {
- shift(dst, 0x4);
- }
-
- void shll_cl(Register dst) {
- shift_32(dst, 0x4);
- }
-
- void shll(Register dst, Immediate shift_amount) {
- shift_32(dst, shift_amount, 0x4);
- }
-
- void shr(Register dst, Immediate shift_amount) {
- shift(dst, shift_amount, 0x5);
- }
-
- void shr_cl(Register dst) {
- shift(dst, 0x5);
- }
-
- void shrl_cl(Register dst) {
- shift_32(dst, 0x5);
- }
-
- void shrl(Register dst, Immediate shift_amount) {
- shift_32(dst, shift_amount, 0x5);
- }
-
void store_rax(void* dst, RelocInfo::Mode mode);
void store_rax(ExternalReference ref);
@@ -1425,14 +1384,16 @@
// AND, OR, XOR, or CMP. The encodings of these operations are all
// similar, differing just in the opcode or in the reg field of the
// ModR/M byte.
+ void arithmetic_op_8(byte opcode, Register reg, Register rm_reg);
+ void arithmetic_op_8(byte opcode, Register reg, const Operand& rm_reg);
void arithmetic_op_16(byte opcode, Register reg, Register rm_reg);
void arithmetic_op_16(byte opcode, Register reg, const Operand& rm_reg);
- void arithmetic_op_32(byte opcode, Register reg, Register rm_reg);
- void arithmetic_op_32(byte opcode, Register reg, const Operand& rm_reg);
- void arithmetic_op(byte opcode, Register reg, Register rm_reg);
- void arithmetic_op(byte opcode, Register reg, const Operand& rm_reg);
- void immediate_arithmetic_op(byte subcode, Register dst, Immediate src);
- void immediate_arithmetic_op(byte subcode, const Operand& dst, Immediate src);
+ // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
+ void arithmetic_op(byte opcode, Register reg, Register rm_reg, int size);
+ void arithmetic_op(byte opcode,
+ Register reg,
+ const Operand& rm_reg,
+ int size);
// Operate on a byte in memory or register.
void immediate_arithmetic_op_8(byte subcode,
Register dst,
@@ -1447,20 +1408,20 @@
void immediate_arithmetic_op_16(byte subcode,
const Operand& dst,
Immediate src);
- // Operate on a 32-bit word in memory or register.
- void immediate_arithmetic_op_32(byte subcode,
- Register dst,
- Immediate src);
- void immediate_arithmetic_op_32(byte subcode,
- const Operand& dst,
- Immediate src);
+ // Operate on operands/registers with pointer size, 32-bit or 64-bit size.
+ void immediate_arithmetic_op(byte subcode,
+ Register dst,
+ Immediate src,
+ int size);
+ void immediate_arithmetic_op(byte subcode,
+ const Operand& dst,
+ Immediate src,
+ int size);
// Emit machine code for a shift operation.
- void shift(Register dst, Immediate shift_amount, int subcode);
- void shift_32(Register dst, Immediate shift_amount, int subcode);
+ void shift(Register dst, Immediate shift_amount, int subcode, int size);
// Shift dst by cl % 64 bits.
- void shift(Register dst, int subcode);
- void shift_32(Register dst, int subcode);
+ void shift(Register dst, int subcode, int size);
void emit_farith(int b1, int b2, int i);
@@ -1473,138 +1434,63 @@
// Arithmetics
void emit_add(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x03, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x03, dst, src);
- }
+ arithmetic_op(0x03, dst, src, size);
}
void emit_add(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x0, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x0, dst, src);
- }
+ immediate_arithmetic_op(0x0, dst, src, size);
}
void emit_add(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x03, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x03, dst, src);
- }
+ arithmetic_op(0x03, dst, src, size);
}
void emit_add(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x1, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x1, src, dst);
- }
+ arithmetic_op(0x1, src, dst, size);
}
void emit_add(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x0, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x0, dst, src);
- }
+ immediate_arithmetic_op(0x0, dst, src, size);
}
void emit_and(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x23, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x23, dst, src);
- }
+ arithmetic_op(0x23, dst, src, size);
}
void emit_and(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x23, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x23, dst, src);
- }
+ arithmetic_op(0x23, dst, src, size);
}
void emit_and(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x21, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x21, src, dst);
- }
+ arithmetic_op(0x21, src, dst, size);
}
void emit_and(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x4, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x4, dst, src);
- }
+ immediate_arithmetic_op(0x4, dst, src, size);
}
void emit_and(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x4, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x4, dst, src);
- }
+ immediate_arithmetic_op(0x4, dst, src, size);
}
void emit_cmp(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x3B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x3B, dst, src);
- }
+ arithmetic_op(0x3B, dst, src, size);
}
void emit_cmp(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x3B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x3B, dst, src);
- }
+ arithmetic_op(0x3B, dst, src, size);
}
void emit_cmp(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x39, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x39, src, dst);
- }
+ arithmetic_op(0x39, src, dst, size);
}
void emit_cmp(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x7, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x7, dst, src);
- }
+ immediate_arithmetic_op(0x7, dst, src, size);
}
void emit_cmp(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x7, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x7, dst, src);
- }
+ immediate_arithmetic_op(0x7, dst, src, size);
}
void emit_dec(Register dst, int size);
@@ -1644,99 +1530,49 @@
void emit_not(const Operand& dst, int size);
void emit_or(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x0B, dst, src);
- } else {
- arithmetic_op_32(0x0B, dst, src);
- }
+ arithmetic_op(0x0B, dst, src, size);
}
void emit_or(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x0B, dst, src);
- } else {
- arithmetic_op_32(0x0B, dst, src);
- }
+ arithmetic_op(0x0B, dst, src, size);
}
void emit_or(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x9, src, dst);
- } else {
- arithmetic_op_32(0x9, src, dst);
- }
+ arithmetic_op(0x9, src, dst, size);
}
void emit_or(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x1, dst, src);
- } else {
- immediate_arithmetic_op_32(0x1, dst, src);
- }
+ immediate_arithmetic_op(0x1, dst, src, size);
}
void emit_or(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x1, dst, src);
- } else {
- immediate_arithmetic_op_32(0x1, dst, src);
- }
+ immediate_arithmetic_op(0x1, dst, src, size);
}
void emit_repmovs(int size);
void emit_sbb(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x1b, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x1b, dst, src);
- }
+ arithmetic_op(0x1b, dst, src, size);
}
void emit_sub(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x2B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x2B, dst, src);
- }
+ arithmetic_op(0x2B, dst, src, size);
}
void emit_sub(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x5, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x5, dst, src);
- }
+ immediate_arithmetic_op(0x5, dst, src, size);
}
void emit_sub(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x2B, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x2B, dst, src);
- }
+ arithmetic_op(0x2B, dst, src, size);
}
void emit_sub(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x29, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x29, src, dst);
- }
+ arithmetic_op(0x29, src, dst, size);
}
void emit_sub(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x5, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x5, dst, src);
- }
+ immediate_arithmetic_op(0x5, dst, src, size);
}
void emit_test(Register dst, Register src, int size);
@@ -1748,52 +1584,29 @@
void emit_xchg(Register dst, Register src, int size);
void emit_xor(Register dst, Register src, int size) {
- if (size == kInt64Size) {
- if (dst.code() == src.code()) {
- arithmetic_op_32(0x33, dst, src);
- } else {
- arithmetic_op(0x33, dst, src);
- }
+ if (size == kInt64Size && dst.code() == src.code()) {
+ // 32 bit operations zero the top 32 bits of 64 bit registers. Therefore
+ // there is no need to make this a 64 bit operation.
+ arithmetic_op(0x33, dst, src, kInt32Size);
} else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x33, dst, src);
+ arithmetic_op(0x33, dst, src, size);
}
}
void emit_xor(Register dst, const Operand& src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x33, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x33, dst, src);
- }
+ arithmetic_op(0x33, dst, src, size);
}
void emit_xor(Register dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x6, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x6, dst, src);
- }
+ immediate_arithmetic_op(0x6, dst, src, size);
}
void emit_xor(const Operand& dst, Immediate src, int size) {
- if (size == kInt64Size) {
- immediate_arithmetic_op(0x6, dst, src);
- } else {
- ASSERT(size == kInt32Size);
- immediate_arithmetic_op_32(0x6, dst, src);
- }
+ immediate_arithmetic_op(0x6, dst, src, size);
}
void emit_xor(const Operand& dst, Register src, int size) {
- if (size == kInt64Size) {
- arithmetic_op(0x31, src, dst);
- } else {
- ASSERT(size == kInt32Size);
- arithmetic_op_32(0x31, src, dst);
- }
+ arithmetic_op(0x31, src, dst, size);
}
friend class CodePatcher;
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index d5b1a73..66ac556 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -214,7 +214,7 @@
// Now allocate the JSObject on the heap.
__ movzxbp(rdi, FieldOperand(rax, Map::kInstanceSizeOffset));
- __ shl(rdi, Immediate(kPointerSizeLog2));
+ __ shlp(rdi, Immediate(kPointerSizeLog2));
if (create_memento) {
__ addp(rdi, Immediate(AllocationMemento::kSize));
}
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index c949a42..f1c45c9 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -875,7 +875,7 @@
if (exponent_type_ == ON_STACK) {
// The arguments are still on the stack.
__ bind(&call_runtime);
- __ TailCallRuntime(Runtime::kMath_pow_cfunction, 2, 1);
+ __ TailCallRuntime(Runtime::kHiddenMathPow, 2, 1);
// The stub is called from non-optimized code, which expects the result
// as heap number in rax.
@@ -3121,7 +3121,8 @@
// Copy from edi to esi using rep movs instruction.
__ movl(kScratchRegister, count);
- __ shr(count, Immediate(kPointerSizeLog2)); // Number of doublewords to copy.
+ // Number of doublewords to copy.
+ __ shrl(count, Immediate(kPointerSizeLog2));
__ repmovsp();
// Find number of bytes left.
@@ -5024,7 +5025,7 @@
__ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset));
// Retrieve elements_kind from bit field 2.
__ andp(rcx, Immediate(Map::kElementsKindMask));
- __ shr(rcx, Immediate(Map::kElementsKindShift));
+ __ shrp(rcx, Immediate(Map::kElementsKindShift));
if (FLAG_debug_code) {
Label done;
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index 9b92dc8..afcf581 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -608,10 +608,10 @@
__ movsd(result, Operand(kScratchRegister, 6 * kDoubleSize));
__ leaq(temp1, Operand(temp2, 0x1ff800));
__ andq(temp2, Immediate(0x7ff));
- __ shr(temp1, Immediate(11));
+ __ shrq(temp1, Immediate(11));
__ mulsd(double_scratch, Operand(kScratchRegister, 5 * kDoubleSize));
__ Move(kScratchRegister, ExternalReference::math_exp_log_table());
- __ shl(temp1, Immediate(52));
+ __ shlq(temp1, Immediate(52));
__ orq(temp1, Operand(kScratchRegister, temp2, times_8, 0));
__ Move(kScratchRegister, ExternalReference::math_exp_constants(0));
__ subsd(double_scratch, input);
diff --git a/src/x64/frames-x64.h b/src/x64/frames-x64.h
index 1fb77ff..0faa349 100644
--- a/src/x64/frames-x64.h
+++ b/src/x64/frames-x64.h
@@ -56,11 +56,12 @@
static const int kXMMRegistersBlockSize =
kXMMRegisterSize * kCalleeSaveXMMRegisters;
static const int kCallerFPOffset =
- -10 * kPointerSize - kXMMRegistersBlockSize;
+ -3 * kPointerSize + -7 * kRegisterSize - kXMMRegistersBlockSize;
#else
- static const int kCallerFPOffset = -8 * kPointerSize;
+ // We have 3 Push and 5 pushq in the JSEntryStub::GenerateBody.
+ static const int kCallerFPOffset = -3 * kPointerSize + -5 * kRegisterSize;
#endif
- static const int kArgvOffset = 6 * kPointerSize;
+ static const int kArgvOffset = 6 * kPointerSize;
};
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index f0b9438..6d1e956 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -108,8 +108,8 @@
Label ok;
ASSERT(scratch.is(rsp) == (pointers == 0));
if (pointers != 0) {
- __ movq(scratch, rsp);
- __ subq(scratch, Immediate(pointers * kPointerSize));
+ __ movp(scratch, rsp);
+ __ subp(scratch, Immediate(pointers * kPointerSize));
}
__ CompareRoot(scratch, Heap::kStackLimitRootIndex);
__ j(above_equal, &ok, Label::kNear);
@@ -195,7 +195,7 @@
const int kMaxPushes = 32;
if (locals_count >= kMaxPushes) {
int loop_iterations = locals_count / kMaxPushes;
- __ movq(rcx, Immediate(loop_iterations));
+ __ movp(rcx, Immediate(loop_iterations));
Label loop_header;
__ bind(&loop_header);
// Do pushes.
@@ -203,7 +203,7 @@
__ Push(rdx);
}
// Continue loop if not done.
- __ decq(rcx);
+ __ decp(rcx);
__ j(not_zero, &loop_header, Label::kNear);
}
int remaining = locals_count % kMaxPushes;
@@ -3698,26 +3698,6 @@
}
-void FullCodeGenerator::EmitMathLog(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_log, 1);
- context()->Plug(rax);
-}
-
-
-void FullCodeGenerator::EmitMathSqrt(CallRuntime* expr) {
- // Load the argument on the stack and call the runtime function.
- ZoneList<Expression*>* args = expr->arguments();
- ASSERT(args->length() == 1);
- VisitForStackValue(args->at(0));
- __ CallRuntime(Runtime::kMath_sqrt, 1);
- context()->Plug(rax);
-}
-
-
void FullCodeGenerator::EmitCallFunction(CallRuntime* expr) {
ZoneList<Expression*>* args = expr->arguments();
ASSERT(args->length() >= 2);
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index ea118d0..b998e0d 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -421,9 +421,9 @@
// based on 32 bits of the map pointer and the string hash.
__ movp(rbx, FieldOperand(rdx, HeapObject::kMapOffset));
__ movl(rcx, rbx);
- __ shr(rcx, Immediate(KeyedLookupCache::kMapHashShift));
+ __ shrl(rcx, Immediate(KeyedLookupCache::kMapHashShift));
__ movl(rdi, FieldOperand(rax, String::kHashFieldOffset));
- __ shr(rdi, Immediate(String::kHashShift));
+ __ shrl(rdi, Immediate(String::kHashShift));
__ xorp(rcx, rdi);
int mask = (KeyedLookupCache::kCapacityMask & KeyedLookupCache::kHashMask);
__ andp(rcx, Immediate(mask));
@@ -439,7 +439,7 @@
for (int i = 0; i < kEntriesPerBucket - 1; i++) {
Label try_next_entry;
__ movp(rdi, rcx);
- __ shl(rdi, Immediate(kPointerSizeLog2 + 1));
+ __ shlp(rdi, Immediate(kPointerSizeLog2 + 1));
__ LoadAddress(kScratchRegister, cache_keys);
int off = kPointerSize * i * 2;
__ cmpp(rbx, Operand(kScratchRegister, rdi, times_1, off));
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 894a4dd..849e2d4 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -1559,7 +1559,7 @@
case Token::SHL:
if (shift_count != 0) {
if (instr->hydrogen_value()->representation().IsSmi()) {
- __ shl(ToRegister(left), Immediate(shift_count));
+ __ shlp(ToRegister(left), Immediate(shift_count));
} else {
__ shll(ToRegister(left), Immediate(shift_count));
}
@@ -2706,7 +2706,7 @@
__ SmiToInteger32(reg, reg);
Register return_addr_reg = reg.is(rcx) ? rbx : rcx;
__ PopReturnAddressTo(return_addr_reg);
- __ shl(reg, Immediate(kPointerSizeLog2));
+ __ shlp(reg, Immediate(kPointerSizeLog2));
__ addp(rsp, reg);
__ jmp(return_addr_reg);
}
@@ -3470,8 +3470,8 @@
__ bind(&allocated);
__ movq(tmp2, FieldOperand(input_reg, HeapNumber::kValueOffset));
- __ shl(tmp2, Immediate(1));
- __ shr(tmp2, Immediate(1));
+ __ shlq(tmp2, Immediate(1));
+ __ shrq(tmp2, Immediate(1));
__ movq(FieldOperand(tmp, HeapNumber::kValueOffset), tmp2);
__ StoreToSafepointRegisterSlot(input_reg, tmp);
@@ -4318,17 +4318,14 @@
__ RecordWriteField(object_reg, HeapObject::kMapOffset, new_map_reg,
ToRegister(instr->temp()), kDontSaveFPRegs);
} else {
+ ASSERT(object_reg.is(rax));
ASSERT(ToRegister(instr->context()).is(rsi));
PushSafepointRegistersScope scope(this);
- if (!object_reg.is(rax)) {
- __ movp(rax, object_reg);
- }
__ Move(rbx, to_map);
bool is_js_array = from_map->instance_type() == JS_ARRAY_TYPE;
TransitionElementsKindStub stub(from_kind, to_kind, is_js_array);
__ CallStub(&stub);
- RecordSafepointWithRegisters(
- instr->pointer_map(), 0, Safepoint::kNoLazyDeopt);
+ RecordSafepointWithLazyDeopt(instr, RECORD_SAFEPOINT_WITH_REGISTERS, 0);
}
__ bind(¬_applicable);
}
@@ -5042,7 +5039,7 @@
Register result_reg = ToRegister(instr->result());
if (instr->hydrogen()->bits() == HDoubleBits::HIGH) {
__ movq(result_reg, value_reg);
- __ shr(result_reg, Immediate(32));
+ __ shrq(result_reg, Immediate(32));
} else {
__ movd(result_reg, value_reg);
}
@@ -5114,7 +5111,7 @@
__ movl(temp, Immediate((size / kPointerSize) - 1));
} else {
temp = ToRegister(instr->size());
- __ sar(temp, Immediate(kPointerSizeLog2));
+ __ sarp(temp, Immediate(kPointerSizeLog2));
__ decl(temp);
}
Label loop;
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 8c4f24e..0dba33d 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -2243,7 +2243,6 @@
LInstruction* LChunkBuilder::DoTransitionElementsKind(
HTransitionElementsKind* instr) {
- LOperand* object = UseRegister(instr->object());
if (IsSimpleMapChangeTransition(instr->from_kind(), instr->to_kind())) {
LOperand* object = UseRegister(instr->object());
LOperand* new_map_reg = TempRegister();
@@ -2252,10 +2251,11 @@
object, NULL, new_map_reg, temp_reg);
return result;
} else {
+ LOperand* object = UseFixed(instr->object(), rax);
LOperand* context = UseFixed(instr->context(), rsi);
LTransitionElementsKind* result =
new(zone()) LTransitionElementsKind(object, context, NULL, NULL);
- return AssignPointerMap(result);
+ return MarkAsCall(result, instr);
}
}
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 6f313f7..422ab2d 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -577,7 +577,7 @@
// key: string key
// hash: key's hash field, including its array index value.
andp(hash, Immediate(String::kArrayIndexValueMask));
- shr(hash, Immediate(String::kHashShift));
+ shrp(hash, Immediate(String::kHashShift));
// Here we actually clobber the key which will be used if calling into
// runtime later. However as the new key is the numeric value of a string key
// there is no difference in using either key.
@@ -1096,7 +1096,7 @@
if (!dst.is(src)) {
movl(dst, src);
}
- shl(dst, Immediate(kSmiShift));
+ shlp(dst, Immediate(kSmiShift));
}
@@ -1121,7 +1121,7 @@
} else {
leal(dst, Operand(src, constant));
}
- shl(dst, Immediate(kSmiShift));
+ shlp(dst, Immediate(kSmiShift));
}
@@ -1130,7 +1130,7 @@
if (!dst.is(src)) {
movp(dst, src);
}
- shr(dst, Immediate(kSmiShift));
+ shrq(dst, Immediate(kSmiShift));
}
@@ -1144,7 +1144,7 @@
if (!dst.is(src)) {
movp(dst, src);
}
- sar(dst, Immediate(kSmiShift));
+ sarq(dst, Immediate(kSmiShift));
}
@@ -1229,9 +1229,9 @@
movp(dst, src);
}
if (power < kSmiShift) {
- sar(dst, Immediate(kSmiShift - power));
+ sarp(dst, Immediate(kSmiShift - power));
} else if (power > kSmiShift) {
- shl(dst, Immediate(power - kSmiShift));
+ shlp(dst, Immediate(power - kSmiShift));
}
}
@@ -1241,7 +1241,7 @@
int power) {
ASSERT((0 <= power) && (power < 32));
if (dst.is(src)) {
- shr(dst, Immediate(power + kSmiShift));
+ shrp(dst, Immediate(power + kSmiShift));
} else {
UNIMPLEMENTED(); // Not used.
}
@@ -1284,7 +1284,7 @@
STATIC_ASSERT(kSmiTag == 0);
// Test that both bits of the mask 0x8000000000000001 are zero.
movp(kScratchRegister, src);
- rol(kScratchRegister, Immediate(1));
+ rolp(kScratchRegister, Immediate(1));
testb(kScratchRegister, Immediate(3));
return zero;
}
@@ -1308,7 +1308,7 @@
}
movp(kScratchRegister, first);
orp(kScratchRegister, second);
- rol(kScratchRegister, Immediate(1));
+ rolp(kScratchRegister, Immediate(1));
testl(kScratchRegister, Immediate(3));
return zero;
}
@@ -2034,8 +2034,8 @@
ASSERT(is_uint5(shift_value));
if (shift_value > 0) {
if (dst.is(src)) {
- sar(dst, Immediate(shift_value + kSmiShift));
- shl(dst, Immediate(kSmiShift));
+ sarp(dst, Immediate(shift_value + kSmiShift));
+ shlp(dst, Immediate(kSmiShift));
} else {
UNIMPLEMENTED(); // Not used.
}
@@ -2050,7 +2050,7 @@
movp(dst, src);
}
if (shift_value > 0) {
- shl(dst, Immediate(shift_value));
+ shlp(dst, Immediate(shift_value));
}
}
@@ -2067,8 +2067,8 @@
testp(dst, dst);
j(negative, on_not_smi_result, near_jump);
}
- shr(dst, Immediate(shift_value + kSmiShift));
- shl(dst, Immediate(kSmiShift));
+ shrq(dst, Immediate(shift_value + kSmiShift));
+ shlq(dst, Immediate(kSmiShift));
}
}
@@ -2084,7 +2084,7 @@
SmiToInteger32(rcx, src2);
// Shift amount specified by lower 5 bits, not six as the shl opcode.
andq(rcx, Immediate(0x1f));
- shl_cl(dst);
+ shlq_cl(dst);
}
@@ -2107,8 +2107,8 @@
}
SmiToInteger32(rcx, src2);
orl(rcx, Immediate(kSmiShift));
- shr_cl(dst); // Shift is rcx modulo 0x1f + 32.
- shl(dst, Immediate(kSmiShift));
+ shrq_cl(dst); // Shift is rcx modulo 0x1f + 32.
+ shlq(dst, Immediate(kSmiShift));
testq(dst, dst);
if (src1.is(rcx) || src2.is(rcx)) {
Label positive_result;
@@ -2144,8 +2144,8 @@
}
SmiToInteger32(rcx, src2);
orl(rcx, Immediate(kSmiShift));
- sar_cl(dst); // Shift 32 + original rcx & 0x1f.
- shl(dst, Immediate(kSmiShift));
+ sarp_cl(dst); // Shift 32 + original rcx & 0x1f.
+ shlp(dst, Immediate(kSmiShift));
if (src1.is(rcx)) {
movp(src1, kScratchRegister);
} else if (src2.is(rcx)) {
@@ -2201,9 +2201,9 @@
movq(dst, src);
}
if (shift < kSmiShift) {
- sar(dst, Immediate(kSmiShift - shift));
+ sarq(dst, Immediate(kSmiShift - shift));
} else {
- shl(dst, Immediate(shift - kSmiShift));
+ shlq(dst, Immediate(shift - kSmiShift));
}
return SmiIndex(dst, times_1);
}
@@ -2218,9 +2218,9 @@
}
negq(dst);
if (shift < kSmiShift) {
- sar(dst, Immediate(kSmiShift - shift));
+ sarq(dst, Immediate(kSmiShift - shift));
} else {
- shl(dst, Immediate(shift - kSmiShift));
+ shlq(dst, Immediate(shift - kSmiShift));
}
return SmiIndex(dst, times_1);
}
@@ -2246,11 +2246,11 @@
void MacroAssembler::PushInt64AsTwoSmis(Register src, Register scratch) {
movp(scratch, src);
// High bits.
- shr(src, Immediate(64 - kSmiShift));
- shl(src, Immediate(kSmiShift));
+ shrp(src, Immediate(64 - kSmiShift));
+ shlp(src, Immediate(kSmiShift));
Push(src);
// Low bits.
- shl(scratch, Immediate(kSmiShift));
+ shlp(scratch, Immediate(kSmiShift));
Push(scratch);
}
@@ -2258,11 +2258,11 @@
void MacroAssembler::PopInt64AsTwoSmis(Register dst, Register scratch) {
Pop(scratch);
// Low bits.
- shr(scratch, Immediate(kSmiShift));
+ shrp(scratch, Immediate(kSmiShift));
Pop(dst);
- shr(dst, Immediate(kSmiShift));
+ shrp(dst, Immediate(kSmiShift));
// High bits.
- shl(dst, Immediate(64 - kSmiShift));
+ shlp(dst, Immediate(64 - kSmiShift));
orp(dst, scratch);
}
@@ -2315,7 +2315,7 @@
// but times_twice_pointer_size (multiplication by 16) scale factor
// is not supported by addrmode on x64 platform.
// So we have to premultiply entry index before lookup.
- shl(scratch, Immediate(kPointerSizeLog2 + 1));
+ shlp(scratch, Immediate(kPointerSizeLog2 + 1));
Register index = scratch;
Register probe = mask;
@@ -2338,7 +2338,7 @@
// but times_twice_pointer_size (multiplication by 16) scale factor
// is not supported by addrmode on x64 platform.
// So we have to premultiply entry index before lookup.
- shl(scratch, Immediate(kPointerSizeLog2 + 1));
+ shlp(scratch, Immediate(kPointerSizeLog2 + 1));
// Check if the entry is the smi we are looking for.
cmpp(object,
@@ -2893,7 +2893,7 @@
// a fixed array of (smi-tagged) code offsets.
// rax = exception, rdi = code object, rdx = state.
movp(rbx, FieldOperand(rdi, Code::kHandlerTableOffset));
- shr(rdx, Immediate(StackHandler::kKindWidth));
+ shrp(rdx, Immediate(StackHandler::kKindWidth));
movp(rdx,
FieldOperand(rbx, rdx, times_pointer_size, FixedArray::kHeaderSize));
SmiToInteger64(rdx, rdx);
@@ -4882,7 +4882,7 @@
shrl(rcx, Immediate(kPointerSizeLog2));
andp(rcx, Immediate((1 << Bitmap::kBitsPerCellLog2) - 1));
movl(mask_reg, Immediate(1));
- shl_cl(mask_reg);
+ shlp_cl(mask_reg);
}
@@ -4966,7 +4966,7 @@
addp(length, Immediate(0x04));
// Value now either 4 (if ASCII) or 8 (if UC16), i.e. char-size shifted by 2.
imulp(length, FieldOperand(value, String::kLengthOffset));
- shr(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
+ shrp(length, Immediate(2 + kSmiTagSize + kSmiShiftSize));
addp(length, Immediate(SeqString::kHeaderSize + kObjectAlignmentMask));
andp(length, Immediate(~kObjectAlignmentMask));
@@ -5065,7 +5065,7 @@
movp(current, FieldOperand(current, HeapObject::kMapOffset));
movp(scratch1, FieldOperand(current, Map::kBitField2Offset));
andp(scratch1, Immediate(Map::kElementsKindMask));
- shr(scratch1, Immediate(Map::kElementsKindShift));
+ shrp(scratch1, Immediate(Map::kElementsKindShift));
cmpp(scratch1, Immediate(DICTIONARY_ELEMENTS));
j(equal, found);
movp(current, FieldOperand(current, Map::kPrototypeOffset));
diff --git a/src/x64/macro-assembler-x64.h b/src/x64/macro-assembler-x64.h
index af65a65..7685adf 100644
--- a/src/x64/macro-assembler-x64.h
+++ b/src/x64/macro-assembler-x64.h
@@ -1026,9 +1026,9 @@
void DecodeField(Register reg) {
static const int shift = Field::kShift + kSmiShift;
static const int mask = Field::kMask >> Field::kShift;
- shr(reg, Immediate(shift));
+ shrp(reg, Immediate(shift));
andp(reg, Immediate(mask));
- shl(reg, Immediate(kSmiShift));
+ shlp(reg, Immediate(kSmiShift));
}
// Abort execution if argument is not a number, enabled via --debug-code.
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index c819c71..d7b9c38 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -692,12 +692,12 @@
#else
// GCC passes arguments in rdi, rsi, rdx, rcx, r8, r9 (and then on stack).
// Push register parameters on stack for reference.
- ASSERT_EQ(kInputString, -1 * kPointerSize);
- ASSERT_EQ(kStartIndex, -2 * kPointerSize);
- ASSERT_EQ(kInputStart, -3 * kPointerSize);
- ASSERT_EQ(kInputEnd, -4 * kPointerSize);
- ASSERT_EQ(kRegisterOutput, -5 * kPointerSize);
- ASSERT_EQ(kNumOutputRegisters, -6 * kPointerSize);
+ ASSERT_EQ(kInputString, -1 * kRegisterSize);
+ ASSERT_EQ(kStartIndex, -2 * kRegisterSize);
+ ASSERT_EQ(kInputStart, -3 * kRegisterSize);
+ ASSERT_EQ(kInputEnd, -4 * kRegisterSize);
+ ASSERT_EQ(kRegisterOutput, -5 * kRegisterSize);
+ ASSERT_EQ(kNumOutputRegisters, -6 * kRegisterSize);
__ pushq(rdi);
__ pushq(rsi);
__ pushq(rdx);
@@ -838,7 +838,7 @@
}
__ addp(rax, rcx); // Convert to index from start, not end.
if (mode_ == UC16) {
- __ sar(rax, Immediate(1)); // Convert byte index to character index.
+ __ sarp(rax, Immediate(1)); // Convert byte index to character index.
}
__ movl(Operand(rbx, i * kIntSize), rax);
}
diff --git a/src/x64/regexp-macro-assembler-x64.h b/src/x64/regexp-macro-assembler-x64.h
index b230ea4..4354f70 100644
--- a/src/x64/regexp-macro-assembler-x64.h
+++ b/src/x64/regexp-macro-assembler-x64.h
@@ -135,8 +135,8 @@
// Offsets from rbp of function parameters and stored registers.
static const int kFramePointer = 0;
// Above the frame pointer - function parameters and return address.
- static const int kReturn_eip = kFramePointer + kPointerSize;
- static const int kFrameAlign = kReturn_eip + kPointerSize;
+ static const int kReturn_eip = kFramePointer + kRegisterSize;
+ static const int kFrameAlign = kReturn_eip + kRegisterSize;
#ifdef _WIN64
// Parameters (first four passed as registers, but with room on stack).
@@ -145,49 +145,50 @@
// use this space to store the register passed parameters.
static const int kInputString = kFrameAlign;
// StartIndex is passed as 32 bit int.
- static const int kStartIndex = kInputString + kPointerSize;
- static const int kInputStart = kStartIndex + kPointerSize;
- static const int kInputEnd = kInputStart + kPointerSize;
- static const int kRegisterOutput = kInputEnd + kPointerSize;
+ static const int kStartIndex = kInputString + kRegisterSize;
+ static const int kInputStart = kStartIndex + kRegisterSize;
+ static const int kInputEnd = kInputStart + kRegisterSize;
+ static const int kRegisterOutput = kInputEnd + kRegisterSize;
// For the case of global regular expression, we have room to store at least
// one set of capture results. For the case of non-global regexp, we ignore
// this value. NumOutputRegisters is passed as 32-bit value. The upper
// 32 bit of this 64-bit stack slot may contain garbage.
- static const int kNumOutputRegisters = kRegisterOutput + kPointerSize;
- static const int kStackHighEnd = kNumOutputRegisters + kPointerSize;
+ static const int kNumOutputRegisters = kRegisterOutput + kRegisterSize;
+ static const int kStackHighEnd = kNumOutputRegisters + kRegisterSize;
// DirectCall is passed as 32 bit int (values 0 or 1).
- static const int kDirectCall = kStackHighEnd + kPointerSize;
- static const int kIsolate = kDirectCall + kPointerSize;
+ static const int kDirectCall = kStackHighEnd + kRegisterSize;
+ static const int kIsolate = kDirectCall + kRegisterSize;
#else
// In AMD64 ABI Calling Convention, the first six integer parameters
// are passed as registers, and caller must allocate space on the stack
// if it wants them stored. We push the parameters after the frame pointer.
- static const int kInputString = kFramePointer - kPointerSize;
- static const int kStartIndex = kInputString - kPointerSize;
- static const int kInputStart = kStartIndex - kPointerSize;
- static const int kInputEnd = kInputStart - kPointerSize;
- static const int kRegisterOutput = kInputEnd - kPointerSize;
+ static const int kInputString = kFramePointer - kRegisterSize;
+ static const int kStartIndex = kInputString - kRegisterSize;
+ static const int kInputStart = kStartIndex - kRegisterSize;
+ static const int kInputEnd = kInputStart - kRegisterSize;
+ static const int kRegisterOutput = kInputEnd - kRegisterSize;
+
// For the case of global regular expression, we have room to store at least
// one set of capture results. For the case of non-global regexp, we ignore
// this value.
- static const int kNumOutputRegisters = kRegisterOutput - kPointerSize;
+ static const int kNumOutputRegisters = kRegisterOutput - kRegisterSize;
static const int kStackHighEnd = kFrameAlign;
- static const int kDirectCall = kStackHighEnd + kPointerSize;
- static const int kIsolate = kDirectCall + kPointerSize;
+ static const int kDirectCall = kStackHighEnd + kRegisterSize;
+ static const int kIsolate = kDirectCall + kRegisterSize;
#endif
#ifdef _WIN64
// Microsoft calling convention has three callee-saved registers
// (that we are using). We push these after the frame pointer.
- static const int kBackup_rsi = kFramePointer - kPointerSize;
- static const int kBackup_rdi = kBackup_rsi - kPointerSize;
- static const int kBackup_rbx = kBackup_rdi - kPointerSize;
+ static const int kBackup_rsi = kFramePointer - kRegisterSize;
+ static const int kBackup_rdi = kBackup_rsi - kRegisterSize;
+ static const int kBackup_rbx = kBackup_rdi - kRegisterSize;
static const int kLastCalleeSaveRegister = kBackup_rbx;
#else
// AMD64 Calling Convention has only one callee-save register that
// we use. We push this after the frame pointer (and after the
// parameters).
- static const int kBackup_rbx = kNumOutputRegisters - kPointerSize;
+ static const int kBackup_rbx = kNumOutputRegisters - kRegisterSize;
static const int kLastCalleeSaveRegister = kBackup_rbx;
#endif
diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status
index 2f09743..2c95a02 100644
--- a/test/cctest/cctest.status
+++ b/test/cctest/cctest.status
@@ -90,6 +90,9 @@
# BUG(v8:3155).
'test-strings/AsciiArrayJoin': [PASS, ['mode == debug', FAIL]],
+
+ # BUG(v8:3247).
+ 'test-mark-compact/NoPromotion': [SKIP],
}], # 'arch == arm64'
['arch == arm64 and simulator_run == True', {
diff --git a/test/cctest/profiler-extension.cc b/test/cctest/profiler-extension.cc
index 80d9f90..1fdd1ba 100644
--- a/test/cctest/profiler-extension.cc
+++ b/test/cctest/profiler-extension.cc
@@ -34,7 +34,7 @@
namespace internal {
-const v8::CpuProfile* ProfilerExtension::last_profile = NULL;
+v8::CpuProfile* ProfilerExtension::last_profile = NULL;
const char* ProfilerExtension::kSource =
"native function startProfiling();"
"native function stopProfiling();";
@@ -58,7 +58,7 @@
const v8::FunctionCallbackInfo<v8::Value>& args) {
last_profile = NULL;
v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler();
- cpu_profiler->StartCpuProfiling((args.Length() > 0)
+ cpu_profiler->StartProfiling((args.Length() > 0)
? args[0].As<v8::String>()
: v8::String::Empty(args.GetIsolate()));
}
@@ -67,7 +67,7 @@
void ProfilerExtension::StopProfiling(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::CpuProfiler* cpu_profiler = args.GetIsolate()->GetCpuProfiler();
- last_profile = cpu_profiler->StopCpuProfiling((args.Length() > 0)
+ last_profile = cpu_profiler->StopProfiling((args.Length() > 0)
? args[0].As<v8::String>()
: v8::String::Empty(args.GetIsolate()));
}
diff --git a/test/cctest/profiler-extension.h b/test/cctest/profiler-extension.h
index 392a7ef..c26a29c 100644
--- a/test/cctest/profiler-extension.h
+++ b/test/cctest/profiler-extension.h
@@ -43,7 +43,7 @@
v8::Handle<v8::String> name);
static void StartProfiling(const v8::FunctionCallbackInfo<v8::Value>& args);
static void StopProfiling(const v8::FunctionCallbackInfo<v8::Value>& args);
- static const v8::CpuProfile* last_profile;
+ static v8::CpuProfile* last_profile;
private:
static const char* kSource;
};
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 5ee43d3..3e30717 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -93,7 +93,7 @@
v8::String::NewFromUtf8(env->GetIsolate(), "my_profile1");
v8::CpuProfiler* cpu_profiler = env->GetIsolate()->GetCpuProfiler();
- cpu_profiler->StartCpuProfiling(profile_name);
+ cpu_profiler->StartProfiling(profile_name);
(*test)();
reinterpret_cast<i::CpuProfiler*>(cpu_profiler)->DeleteAllProfiles();
}
@@ -3498,22 +3498,23 @@
template<typename K, typename V>
class WeakStdMapTraits : public v8::StdMapTraits<K, V> {
public:
- typedef typename v8::DefaultPersistentValueMapTraits<K, V>::Impl Impl;
- static const bool kIsWeak = true;
+ typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V> >
+ MapType;
+ static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak;
struct WeakCallbackDataType {
- Impl* impl;
+ MapType* map;
K key;
};
static WeakCallbackDataType* WeakCallbackParameter(
- Impl* impl, const K& key, Local<V> value) {
+ MapType* map, const K& key, Local<V> value) {
WeakCallbackDataType* data = new WeakCallbackDataType;
- data->impl = impl;
+ data->map = map;
data->key = key;
return data;
}
- static Impl* ImplFromWeakCallbackData(
+ static MapType* MapFromWeakCallbackData(
const v8::WeakCallbackData<V, WeakCallbackDataType>& data) {
- return data.GetParameter()->impl;
+ return data.GetParameter()->map;
}
static K KeyFromWeakCallbackData(
const v8::WeakCallbackData<V, WeakCallbackDataType>& data) {
@@ -3523,7 +3524,7 @@
delete data;
}
static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value,
- Impl* impl, K key) { }
+ K key) { }
};
@@ -3545,6 +3546,10 @@
CHECK_EQ(1, static_cast<int>(map.Size()));
obj = map.Get(7);
CHECK_EQ(expected, obj);
+ {
+ typename Map::PersistentValueReference ref = map.GetReference(7);
+ CHECK_EQ(expected, ref.NewLocal(isolate));
+ }
v8::UniquePersistent<v8::Object> removed = map.Remove(7);
CHECK_EQ(0, static_cast<int>(map.Size()));
CHECK(expected == removed);
@@ -3554,6 +3559,15 @@
CHECK_EQ(1, static_cast<int>(map.Size()));
map.Set(8, expected);
CHECK_EQ(1, static_cast<int>(map.Size()));
+ {
+ typename Map::PersistentValueReference ref;
+ Local<v8::Object> expected2 = v8::Object::New(isolate);
+ removed = map.Set(8,
+ v8::UniquePersistent<v8::Object>(isolate, expected2), &ref);
+ CHECK_EQ(1, static_cast<int>(map.Size()));
+ CHECK(expected == removed);
+ CHECK_EQ(expected2, ref.NewLocal(isolate));
+ }
}
CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count());
if (map.IsWeak()) {
@@ -3572,12 +3586,55 @@
TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object> >();
// Custom traits with weak callbacks:
- typedef v8::StdPersistentValueMap<int, v8::Object,
+ typedef v8::PersistentValueMap<int, v8::Object,
WeakStdMapTraits<int, v8::Object> > WeakPersistentValueMap;
TestPersistentValueMap<WeakPersistentValueMap>();
}
+TEST(PersistentValueVector) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::internal::GlobalHandles* global_handles =
+ reinterpret_cast<v8::internal::Isolate*>(isolate)->global_handles();
+ int handle_count = global_handles->global_handles_count();
+ HandleScope scope(isolate);
+
+ v8::PersistentValueVector<v8::Object> vector(isolate);
+
+ Local<v8::Object> obj1 = v8::Object::New(isolate);
+ Local<v8::Object> obj2 = v8::Object::New(isolate);
+ v8::UniquePersistent<v8::Object> obj3(isolate, v8::Object::New(isolate));
+
+ CHECK(vector.IsEmpty());
+ CHECK_EQ(0, static_cast<int>(vector.Size()));
+
+ vector.ReserveCapacity(3);
+ CHECK(vector.IsEmpty());
+
+ vector.Append(obj1);
+ vector.Append(obj2);
+ vector.Append(obj1);
+ vector.Append(obj3.Pass());
+ vector.Append(obj1);
+
+ CHECK(!vector.IsEmpty());
+ CHECK_EQ(5, static_cast<int>(vector.Size()));
+ CHECK(obj3.IsEmpty());
+ CHECK_EQ(obj1, vector.Get(0));
+ CHECK_EQ(obj1, vector.Get(2));
+ CHECK_EQ(obj1, vector.Get(4));
+ CHECK_EQ(obj2, vector.Get(1));
+
+ CHECK_EQ(5 + handle_count, global_handles->global_handles_count());
+
+ vector.Clear();
+ CHECK(vector.IsEmpty());
+ CHECK_EQ(0, static_cast<int>(vector.Size()));
+ CHECK_EQ(handle_count, global_handles->global_handles_count());
+}
+
+
THREADED_TEST(GlobalHandleUpcast) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -4038,7 +4095,7 @@
v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>(
iso)->heap();
- heap->CollectGarbage(i::NEW_SPACE);
+ heap->CollectAllGarbage(i::Heap::kNoGCFlags);
// All objects should be alive.
CHECK_EQ(0, counter.NumberOfWeakCalls());
@@ -4070,7 +4127,7 @@
v8_str("x"), Local<Value>::New(iso, g1s1.handle));
}
- heap->CollectGarbage(i::NEW_SPACE);
+ heap->CollectAllGarbage(i::Heap::kNoGCFlags);
// All objects should be gone. 7 global handles in total.
CHECK_EQ(7, counter.NumberOfWeakCalls());
@@ -22191,6 +22248,8 @@
TEST(Promises) {
+ i::FLAG_harmony_promises = true;
+
LocalContext context;
v8::Isolate* isolate = context->GetIsolate();
v8::HandleScope scope(isolate);
diff --git a/test/cctest/test-assembler-x64.cc b/test/cctest/test-assembler-x64.cc
index 446cec6..eddc107 100644
--- a/test/cctest/test-assembler-x64.cc
+++ b/test/cctest/test-assembler-x64.cc
@@ -141,6 +141,37 @@
}
+TEST(AssemblerX64CmpbOperation) {
+ // Allocate an executable page of memory.
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(OS::Allocate(Assembler::kMinimalBufferSize,
+ &actual_size,
+ true));
+ CHECK(buffer);
+ Assembler assm(CcTest::i_isolate(), buffer, static_cast<int>(actual_size));
+
+ // Assemble a function that compare argument byte returing 1 if equal else 0.
+ // On Windows, it compares rcx with rdx which does not require REX prefix;
+ // on Linux, it compares rdi with rsi which requires REX prefix.
+
+ Label done;
+ __ movq(rax, Immediate(1));
+ __ cmpb(arg1, arg2);
+ __ j(equal, &done);
+ __ movq(rax, Immediate(0));
+ __ bind(&done);
+ __ ret(0);
+
+ CodeDesc desc;
+ assm.GetCode(&desc);
+ // Call the function from C++.
+ int result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2002);
+ CHECK_EQ(1, result);
+ result = FUNCTION_CAST<F2>(buffer)(0x1002, 0x2003);
+ CHECK_EQ(0, result);
+}
+
+
TEST(AssemblerX64ImulOperation) {
// Allocate an executable page of memory.
size_t actual_size;
@@ -576,7 +607,7 @@
// Store input vector on the stack.
for (int i = 0; i < ELEMENT_COUNT; i++) {
__ movl(rax, Immediate(vec->Get(i)->Int32Value()));
- __ shl(rax, Immediate(0x20));
+ __ shlq(rax, Immediate(0x20));
__ orq(rax, Immediate(vec->Get(++i)->Int32Value()));
__ pushq(rax);
}
diff --git a/test/cctest/test-cpu-profiler.cc b/test/cctest/test-cpu-profiler.cc
index ed0b190..9bcefa4 100644
--- a/test/cctest/test-cpu-profiler.cc
+++ b/test/cctest/test-cpu-profiler.cc
@@ -355,33 +355,33 @@
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Local<v8::String> name1 = v8::String::NewFromUtf8(env->GetIsolate(), "1");
- cpu_profiler->StartCpuProfiling(name1);
- const v8::CpuProfile* p1 = cpu_profiler->StopCpuProfiling(name1);
+ cpu_profiler->StartProfiling(name1);
+ v8::CpuProfile* p1 = cpu_profiler->StopProfiling(name1);
CHECK_NE(NULL, p1);
CHECK_EQ(1, iprofiler->GetProfilesCount());
CHECK(FindCpuProfile(cpu_profiler, p1));
- const_cast<v8::CpuProfile*>(p1)->Delete();
+ p1->Delete();
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Local<v8::String> name2 = v8::String::NewFromUtf8(env->GetIsolate(), "2");
- cpu_profiler->StartCpuProfiling(name2);
- const v8::CpuProfile* p2 = cpu_profiler->StopCpuProfiling(name2);
+ cpu_profiler->StartProfiling(name2);
+ v8::CpuProfile* p2 = cpu_profiler->StopProfiling(name2);
CHECK_NE(NULL, p2);
CHECK_EQ(1, iprofiler->GetProfilesCount());
CHECK(FindCpuProfile(cpu_profiler, p2));
v8::Local<v8::String> name3 = v8::String::NewFromUtf8(env->GetIsolate(), "3");
- cpu_profiler->StartCpuProfiling(name3);
- const v8::CpuProfile* p3 = cpu_profiler->StopCpuProfiling(name3);
+ cpu_profiler->StartProfiling(name3);
+ v8::CpuProfile* p3 = cpu_profiler->StopProfiling(name3);
CHECK_NE(NULL, p3);
CHECK_EQ(2, iprofiler->GetProfilesCount());
CHECK_NE(p2, p3);
CHECK(FindCpuProfile(cpu_profiler, p3));
CHECK(FindCpuProfile(cpu_profiler, p2));
- const_cast<v8::CpuProfile*>(p2)->Delete();
+ p2->Delete();
CHECK_EQ(1, iprofiler->GetProfilesCount());
CHECK(!FindCpuProfile(cpu_profiler, p2));
CHECK(FindCpuProfile(cpu_profiler, p3));
- const_cast<v8::CpuProfile*>(p3)->Delete();
+ p3->Delete();
CHECK_EQ(0, iprofiler->GetProfilesCount());
}
@@ -393,13 +393,13 @@
v8::Local<v8::String> profile_name =
v8::String::NewFromUtf8(env->GetIsolate(), "test");
- cpu_profiler->StartCpuProfiling(profile_name);
- const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
+ cpu_profiler->StartProfiling(profile_name);
+ const v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name);
CHECK(profile->GetStartTime() <= profile->GetEndTime());
}
-static const v8::CpuProfile* RunProfiler(
+static v8::CpuProfile* RunProfiler(
v8::Handle<v8::Context> env, v8::Handle<v8::Function> function,
v8::Handle<v8::Value> argv[], int argc,
unsigned min_js_samples) {
@@ -407,7 +407,7 @@
v8::Local<v8::String> profile_name =
v8::String::NewFromUtf8(env->GetIsolate(), "my_profile");
- cpu_profiler->StartCpuProfiling(profile_name);
+ cpu_profiler->StartProfiling(profile_name);
i::Sampler* sampler =
reinterpret_cast<i::Isolate*>(env->GetIsolate())->logger()->sampler();
@@ -416,12 +416,11 @@
function->Call(env->Global(), argc, argv);
} while (sampler->js_and_external_sample_count() < min_js_samples);
- const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
+ v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
- reinterpret_cast<i::CpuProfile*>(
- const_cast<v8::CpuProfile*>(profile))->Print();
+ reinterpret_cast<i::CpuProfile*>(profile)->Print();
return profile;
}
@@ -553,7 +552,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), profiling_interval_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
function->Call(env->Global(), ARRAY_SIZE(args), args);
@@ -585,7 +584,7 @@
CheckSimpleBranch(env->GetIsolate(), fooNode, delayBranch,
ARRAY_SIZE(delayBranch));
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -627,7 +626,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), repeat_count)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -654,7 +653,7 @@
}
}
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -747,7 +746,7 @@
int32_t repeat_count = 1;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 180);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -756,7 +755,7 @@
GetChild(isolate, startNode, "get foo");
GetChild(isolate, startNode, "set foo");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -804,7 +803,7 @@
int32_t repeat_count = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 200);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -813,7 +812,7 @@
GetChild(isolate, startNode, "get foo");
GetChild(isolate, startNode, "set foo");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -858,7 +857,7 @@
int32_t repeat_count = 1;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -866,7 +865,7 @@
GetChild(isolate, root, "start");
GetChild(isolate, startNode, "fooMethod");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -915,7 +914,7 @@
int32_t repeat_count = 100;
v8::Handle<v8::Value> args[] = { v8::Integer::New(isolate, repeat_count) };
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -924,7 +923,7 @@
GetChild(isolate, root, "start");
GetChild(isolate, startNode, "fooMethod");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -956,7 +955,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), duration_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -973,7 +972,7 @@
GetChild(env->GetIsolate(), root, "start");
GetChild(env->GetIsolate(), startNode, "foo");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1017,7 +1016,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), duration_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -1056,7 +1055,7 @@
CheckChildrenNames(unresolvedNode, names);
}
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1100,7 +1099,7 @@
v8::Integer::New(env->GetIsolate(), duration_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env.local(), function, args, ARRAY_SIZE(args), 100);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -1145,7 +1144,7 @@
}
}
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1207,7 +1206,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), duration_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 10);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -1234,7 +1233,7 @@
CHECK_EQ(1, barNode->GetChildrenCount());
GetChild(env->GetIsolate(), barNode, "foo");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1292,7 +1291,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), duration_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 10);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -1317,7 +1316,7 @@
CHECK_EQ(1, barNode->GetChildrenCount());
GetChild(env->GetIsolate(), barNode, "foo");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1386,7 +1385,7 @@
v8::Handle<v8::Value> args[] = {
v8::Integer::New(env->GetIsolate(), duration_ms)
};
- const v8::CpuProfile* profile =
+ v8::CpuProfile* profile =
RunProfiler(env, function, args, ARRAY_SIZE(args), 10);
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
@@ -1415,7 +1414,7 @@
CHECK_EQ(1, nativeNode2->GetChildrenCount());
GetChild(env->GetIsolate(), nativeNode2, "foo");
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1430,7 +1429,7 @@
v8::Local<v8::String> profile_name =
v8::String::NewFromUtf8(env->GetIsolate(), "my_profile");
- cpu_profiler->StartCpuProfiling(profile_name);
+ cpu_profiler->StartProfiling(profile_name);
i::Isolate* isolate = CcTest::i_isolate();
i::ProfilerEventsProcessor* processor = isolate->cpu_profiler()->processor();
@@ -1446,11 +1445,10 @@
processor->AddCurrentStack(isolate);
- const v8::CpuProfile* profile = cpu_profiler->StopCpuProfiling(profile_name);
+ v8::CpuProfile* profile = cpu_profiler->StopProfiling(profile_name);
CHECK_NE(NULL, profile);
// Dump collected profile to have a better diagnostic in case of failure.
- reinterpret_cast<i::CpuProfile*>(
- const_cast<v8::CpuProfile*>(profile))->Print();
+ reinterpret_cast<i::CpuProfile*>(profile)->Print();
const v8::CpuProfileNode* root = profile->GetTopDownRoot();
ScopedVector<v8::Handle<v8::String> > names(3);
@@ -1472,7 +1470,7 @@
CHECK_EQ(0, idleNode->GetChildrenCount());
CHECK_GE(idleNode->GetHitCount(), 3);
- const_cast<v8::CpuProfile*>(profile)->Delete();
+ profile->Delete();
}
@@ -1545,24 +1543,24 @@
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Handle<v8::String> outer = v8::String::NewFromUtf8(isolate, "outer");
- profiler->StartCpuProfiling(outer);
+ profiler->StartProfiling(outer);
CHECK_EQ(0, iprofiler->GetProfilesCount());
v8::Handle<v8::String> inner = v8::String::NewFromUtf8(isolate, "inner");
- profiler->StartCpuProfiling(inner);
+ profiler->StartProfiling(inner);
CHECK_EQ(0, iprofiler->GetProfilesCount());
- const v8::CpuProfile* inner_profile = profiler->StopCpuProfiling(inner);
+ v8::CpuProfile* inner_profile = profiler->StopProfiling(inner);
CHECK(inner_profile);
CHECK_EQ(1, iprofiler->GetProfilesCount());
- const_cast<v8::CpuProfile*>(inner_profile)->Delete();
+ inner_profile->Delete();
inner_profile = NULL;
CHECK_EQ(0, iprofiler->GetProfilesCount());
- const v8::CpuProfile* outer_profile = profiler->StopCpuProfiling(outer);
+ v8::CpuProfile* outer_profile = profiler->StopProfiling(outer);
CHECK(outer_profile);
CHECK_EQ(1, iprofiler->GetProfilesCount());
- const_cast<v8::CpuProfile*>(outer_profile)->Delete();
+ outer_profile->Delete();
outer_profile = NULL;
CHECK_EQ(0, iprofiler->GetProfilesCount());
}
diff --git a/test/cctest/test-disasm-x64.cc b/test/cctest/test-disasm-x64.cc
index 5ca12b9..1b3edf4 100644
--- a/test/cctest/test-disasm-x64.cc
+++ b/test/cctest/test-disasm-x64.cc
@@ -179,22 +179,22 @@
__ nop();
- __ rcl(rdx, Immediate(1));
- __ rcl(rdx, Immediate(7));
- __ rcr(rdx, Immediate(1));
- __ rcr(rdx, Immediate(7));
- __ sar(rdx, Immediate(1));
- __ sar(rdx, Immediate(6));
- __ sar_cl(rdx);
+ __ rclq(rdx, Immediate(1));
+ __ rclq(rdx, Immediate(7));
+ __ rcrq(rdx, Immediate(1));
+ __ rcrq(rdx, Immediate(7));
+ __ sarq(rdx, Immediate(1));
+ __ sarq(rdx, Immediate(6));
+ __ sarq_cl(rdx);
__ sbbq(rdx, rbx);
__ shld(rdx, rbx);
- __ shl(rdx, Immediate(1));
- __ shl(rdx, Immediate(6));
- __ shl_cl(rdx);
+ __ shlq(rdx, Immediate(1));
+ __ shlq(rdx, Immediate(6));
+ __ shlq_cl(rdx);
__ shrd(rdx, rbx);
- __ shr(rdx, Immediate(1));
- __ shr(rdx, Immediate(7));
- __ shr_cl(rdx);
+ __ shrq(rdx, Immediate(1));
+ __ shrq(rdx, Immediate(7));
+ __ shrq_cl(rdx);
// Immediates
diff --git a/test/cctest/test-macro-assembler-x64.cc b/test/cctest/test-macro-assembler-x64.cc
index f29dacc..609bc69 100644
--- a/test/cctest/test-macro-assembler-x64.cc
+++ b/test/cctest/test-macro-assembler-x64.cc
@@ -1516,7 +1516,7 @@
__ Move(rcx, Smi::FromInt(x));
SmiIndex index = masm->SmiToIndex(rdx, rcx, i);
ASSERT(index.reg.is(rcx) || index.reg.is(rdx));
- __ shl(index.reg, Immediate(index.scale));
+ __ shlq(index.reg, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(x) << i);
__ cmpq(index.reg, r8);
__ j(not_equal, exit);
@@ -1524,7 +1524,7 @@
__ Move(rcx, Smi::FromInt(x));
index = masm->SmiToIndex(rcx, rcx, i);
ASSERT(index.reg.is(rcx));
- __ shl(rcx, Immediate(index.scale));
+ __ shlq(rcx, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(x) << i);
__ cmpq(rcx, r8);
__ j(not_equal, exit);
@@ -1533,7 +1533,7 @@
__ Move(rcx, Smi::FromInt(x));
index = masm->SmiToNegativeIndex(rdx, rcx, i);
ASSERT(index.reg.is(rcx) || index.reg.is(rdx));
- __ shl(index.reg, Immediate(index.scale));
+ __ shlq(index.reg, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(-x) << i);
__ cmpq(index.reg, r8);
__ j(not_equal, exit);
@@ -1541,7 +1541,7 @@
__ Move(rcx, Smi::FromInt(x));
index = masm->SmiToNegativeIndex(rcx, rcx, i);
ASSERT(index.reg.is(rcx));
- __ shl(rcx, Immediate(index.scale));
+ __ shlq(rcx, Immediate(index.scale));
__ Set(r8, static_cast<intptr_t>(-x) << i);
__ cmpq(rcx, r8);
__ j(not_equal, exit);
diff --git a/test/cctest/test-microtask-delivery.cc b/test/cctest/test-microtask-delivery.cc
index 0172726..108337a 100644
--- a/test/cctest/test-microtask-delivery.cc
+++ b/test/cctest/test-microtask-delivery.cc
@@ -36,6 +36,7 @@
class HarmonyIsolate {
public:
HarmonyIsolate() {
+ i::FLAG_harmony_promises = true;
isolate_ = Isolate::New();
isolate_->Enter();
}
diff --git a/test/mjsunit/debug-script.js b/test/mjsunit/debug-script.js
index 80d423e..1a7283c 100644
--- a/test/mjsunit/debug-script.js
+++ b/test/mjsunit/debug-script.js
@@ -59,7 +59,7 @@
}
// This has to be updated if the number of native scripts change.
-assertTrue(named_native_count == 19 || named_native_count == 20);
+assertTrue(named_native_count == 17 || named_native_count == 18);
// Only the 'gc' extension is loaded.
assertEquals(1, extension_count);
// This script and mjsunit.js has been loaded. If using d8, d8 loads
diff --git a/test/mjsunit/es6/promises.js b/test/mjsunit/es6/promises.js
index 96a7bbb..ba5a306 100644
--- a/test/mjsunit/es6/promises.js
+++ b/test/mjsunit/es6/promises.js
@@ -25,7 +25,7 @@
// (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
+// Flags: --harmony-promises --allow-natives-syntax
var asyncAssertsExpected = 0;
diff --git a/test/mjsunit/es6/regress/regress-2034.js b/test/mjsunit/es6/regress/regress-2034.js
index 5c738bf..1b7dac0 100644
--- a/test/mjsunit/es6/regress/regress-2034.js
+++ b/test/mjsunit/es6/regress/regress-2034.js
@@ -25,6 +25,8 @@
// (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: --harmony-weak-collections
+
var key = {};
var map = new WeakMap;
Object.preventExtensions(key);
diff --git a/test/mjsunit/es6/regress/regress-2156.js b/test/mjsunit/es6/regress/regress-2156.js
index fba2a29..a34e381 100644
--- a/test/mjsunit/es6/regress/regress-2156.js
+++ b/test/mjsunit/es6/regress/regress-2156.js
@@ -25,7 +25,7 @@
// (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
+// Flags: --allow-natives-syntax --harmony-weak-collections
var key1 = {};
var key2 = {};
diff --git a/test/mjsunit/es6/regress/regress-2829.js b/test/mjsunit/es6/regress/regress-2829.js
index b48039c..8d8f3f8 100644
--- a/test/mjsunit/es6/regress/regress-2829.js
+++ b/test/mjsunit/es6/regress/regress-2829.js
@@ -25,6 +25,8 @@
// (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: --harmony-weak-collections
+
(function test1() {
var wm1 = new WeakMap();
wm1.set(Object.prototype, 23);
diff --git a/test/mjsunit/es6/weak_collections.js b/test/mjsunit/es6/weak_collections.js
index 74235e7..af23903 100644
--- a/test/mjsunit/es6/weak_collections.js
+++ b/test/mjsunit/es6/weak_collections.js
@@ -25,7 +25,7 @@
// (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: --expose-gc --allow-natives-syntax
+// Flags: --harmony-weak-collections --expose-gc --allow-natives-syntax
// Note: this test is superseded by harmony/collections.js.
@@ -225,7 +225,7 @@
assertTrue(C.prototype instanceof Object);
assertEquals({
value: {},
- writable: false,
+ writable: true, // TODO(2793): This should be non-writable.
enumerable: false,
configurable: false
}, Object.getOwnPropertyDescriptor(C, "prototype"));
diff --git a/test/mjsunit/es7/object-observe.js b/test/mjsunit/es7/object-observe.js
index f5e84a6..0aa3601 100644
--- a/test/mjsunit/es7/object-observe.js
+++ b/test/mjsunit/es7/object-observe.js
@@ -25,7 +25,8 @@
// (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: --harmony-proxies --harmony-collections
+// Flags: --harmony-observation --harmony-proxies
+// Flags: --harmony-collections --harmony-weak-collections
// Flags: --harmony-symbols --allow-natives-syntax
var allObservers = [];
diff --git a/test/mjsunit/harmony/collections.js b/test/mjsunit/harmony/collections.js
index 804a320..b33d080 100644
--- a/test/mjsunit/harmony/collections.js
+++ b/test/mjsunit/harmony/collections.js
@@ -25,7 +25,7 @@
// (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: --harmony-collections
+// Flags: --harmony-collections --harmony-weak-collections
// Flags: --expose-gc --allow-natives-syntax
@@ -290,20 +290,19 @@
// Test prototype property of Set, Map, WeakMap and WeakSet.
-// TODO(2793): Should all be non-writable, and the extra flag removed.
-function TestPrototype(C, writable) {
+function TestPrototype(C) {
assertTrue(C.prototype instanceof Object);
assertEquals({
value: {},
- writable: writable,
+ writable: true, // TODO(2793): This should be non-writable.
enumerable: false,
configurable: false
}, Object.getOwnPropertyDescriptor(C, "prototype"));
}
-TestPrototype(Set, true);
-TestPrototype(Map, true);
-TestPrototype(WeakMap, false);
-TestPrototype(WeakSet, false);
+TestPrototype(Set);
+TestPrototype(Map);
+TestPrototype(WeakMap);
+TestPrototype(WeakSet);
// Test constructor property of the Set, Map, WeakMap and WeakSet prototype.
diff --git a/test/mjsunit/es6/microtask-delivery.js b/test/mjsunit/harmony/microtask-delivery.js
similarity index 97%
rename from test/mjsunit/es6/microtask-delivery.js
rename to test/mjsunit/harmony/microtask-delivery.js
index f74385e..566a39d 100644
--- a/test/mjsunit/es6/microtask-delivery.js
+++ b/test/mjsunit/harmony/microtask-delivery.js
@@ -25,7 +25,7 @@
// (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
+// Flags: --harmony-observation --harmony-promises --allow-natives-syntax
var ordering = [];
function reset() {
diff --git a/test/mjsunit/harmony/private.js b/test/mjsunit/harmony/private.js
index 2257998..a14afe0 100644
--- a/test/mjsunit/harmony/private.js
+++ b/test/mjsunit/harmony/private.js
@@ -25,7 +25,7 @@
// (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: --harmony-symbols --harmony-collections
+// Flags: --harmony-symbols --harmony-collections --harmony-weak-collections
// Flags: --expose-gc --allow-natives-syntax
var symbols = []
diff --git a/test/mjsunit/harmony/proxies-hash.js b/test/mjsunit/harmony/proxies-hash.js
index 789de35..6f0b19f 100644
--- a/test/mjsunit/harmony/proxies-hash.js
+++ b/test/mjsunit/harmony/proxies-hash.js
@@ -25,7 +25,7 @@
// (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: --harmony-proxies --harmony-collections
+// Flags: --harmony-proxies --harmony-collections --harmony-weak-collections
// Helper.
diff --git a/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js b/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
index 301ece7..4b65169 100644
--- a/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
+++ b/test/mjsunit/harmony/regress/regress-observe-empty-double-array.js
@@ -25,7 +25,7 @@
// (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
+// Flags: --harmony-observation --allow-natives-syntax
//
// Test passes if it does not crash.
diff --git a/test/mjsunit/harmony/symbols.js b/test/mjsunit/harmony/symbols.js
index 2204392..e7bf360 100644
--- a/test/mjsunit/harmony/symbols.js
+++ b/test/mjsunit/harmony/symbols.js
@@ -25,7 +25,7 @@
// (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: --harmony-symbols --harmony-collections
+// Flags: --harmony-symbols --harmony-collections --harmony-weak-collections
// Flags: --expose-gc --allow-natives-syntax
var symbols = []
diff --git a/test/mjsunit/harmony/typedarrays.js b/test/mjsunit/harmony/typedarrays.js
index e20fbad..f26b0be 100644
--- a/test/mjsunit/harmony/typedarrays.js
+++ b/test/mjsunit/harmony/typedarrays.js
@@ -310,6 +310,11 @@
SubarrayTestCase(constructor, item, 10,90, 100, 90);
SubarrayTestCase(constructor, item, 10,90, 100, -10);
+
+ var method = constructor.prototype.subarray;
+ method.call(new constructor(100), 0, 100);
+ var o = {};
+ assertThrows(function() { method.call(o, 0, 100); }, TypeError);
}
TestSubArray(Uint8Array, 0xFF);
diff --git a/test/mjsunit/mjsunit.status b/test/mjsunit/mjsunit.status
index 3283070..28d3510 100644
--- a/test/mjsunit/mjsunit.status
+++ b/test/mjsunit/mjsunit.status
@@ -367,6 +367,10 @@
# Lead to OOM:
'string-oom-*': [SKIP],
+
+ # Crashes.
+ 'harmony/private': [SKIP],
+ 'harmony/symbols': [SKIP],
}], # 'arch == nacl_ia32 or arch == nacl_x64'
##############################################################################
diff --git a/test/mjsunit/regress/regress-357105.js b/test/mjsunit/regress/regress-357105.js
new file mode 100644
index 0000000..d3eefd0
--- /dev/null
+++ b/test/mjsunit/regress/regress-357105.js
@@ -0,0 +1,23 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --expose-gc
+
+var global = { };
+
+function do_nothing() { }
+
+function f(opt_gc) {
+ var x = new Array(3);
+ x[0] = 10;
+ opt_gc();
+ global[1] = 15.5;
+ return x;
+}
+
+gc();
+global = f(gc);
+global = f(do_nothing);
+%OptimizeFunctionOnNextCall(f);
+global = f(do_nothing);
diff --git a/test/mjsunit/regress/regress-crbug-350864.js b/test/mjsunit/regress/regress-crbug-350864.js
index 8a793cb..15b3242 100644
--- a/test/mjsunit/regress/regress-crbug-350864.js
+++ b/test/mjsunit/regress/regress-crbug-350864.js
@@ -25,7 +25,7 @@
// (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: --harmony-symbols
+// Flags: --harmony_symbols --harmony-weak-collections
var v0 = new WeakMap;
var v1 = {};
diff --git a/test/mjsunit/regress/regress-enum-prop-keys-cache-size.js b/test/mjsunit/regress/regress-enum-prop-keys-cache-size.js
new file mode 100644
index 0000000..1227500
--- /dev/null
+++ b/test/mjsunit/regress/regress-enum-prop-keys-cache-size.js
@@ -0,0 +1,19 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax --stress-compaction
+
+%SetAllocationTimeout(100000, 100000);
+
+var x = {};
+x.a = 1;
+x.b = 2;
+x = {};
+
+var y = {};
+y.a = 1;
+
+%SetAllocationTimeout(100000, 0);
+
+for (var z in y) { }
diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp
index f7bdf52..52143e9 100644
--- a/tools/gyp/v8.gyp
+++ b/tools/gyp/v8.gyp
@@ -1073,8 +1073,6 @@
'../../src/regexp.js',
'../../src/arraybuffer.js',
'../../src/typedarray.js',
- '../../src/weak_collection.js',
- '../../src/promise.js',
'../../src/object-observe.js',
'../../src/macros.py',
],
@@ -1083,6 +1081,8 @@
'../../src/symbol.js',
'../../src/proxy.js',
'../../src/collection.js',
+ '../../src/weak_collection.js',
+ '../../src/promise.js',
'../../src/generator.js',
'../../src/array-iterator.js',
'../../src/harmony-string.js',