Version 3.2.10
Fixed bug in external float arrays on ARM (issue 1323).
Minor performance improvements and bug fixes.
git-svn-id: http://v8.googlecode.com/svn/trunk@7596 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index c2b2df8..a2373cd 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -4625,7 +4625,7 @@
int V8::GetCurrentThreadId() {
i::Isolate* isolate = i::Isolate::Current();
EnsureInitializedForIsolate(isolate, "V8::GetCurrentThreadId()");
- return isolate->thread_id();
+ return isolate->thread_id().ToInteger();
}
@@ -4636,10 +4636,11 @@
// If the thread_id identifies the current thread just terminate
// execution right away. Otherwise, ask the thread manager to
// terminate the thread with the given id if any.
- if (thread_id == isolate->thread_id()) {
+ i::ThreadId internal_tid = i::ThreadId::FromInteger(thread_id);
+ if (isolate->thread_id().Equals(internal_tid)) {
isolate->stack_guard()->TerminateExecution();
} else {
- isolate->thread_manager()->TerminateExecution(thread_id);
+ isolate->thread_manager()->TerminateExecution(internal_tid);
}
}
diff --git a/src/arm/assembler-arm.cc b/src/arm/assembler-arm.cc
index 73dddfd..fd8e8b5 100644
--- a/src/arm/assembler-arm.cc
+++ b/src/arm/assembler-arm.cc
@@ -59,12 +59,12 @@
#endif // def CAN_USE_ARMV7_INSTRUCTIONS
// If the compiler is allowed to use VFP then we can use VFP too in our code
// generation even when generating snapshots. This won't work for cross
- // compilation.
+ // compilation. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
#if defined(__VFP_FP__) && !defined(__SOFTFP__)
- answer |= 1u << VFP3;
+ answer |= 1u << VFP3 | 1u << ARMv7;
#endif // defined(__VFP_FP__) && !defined(__SOFTFP__)
#ifdef CAN_USE_VFP_INSTRUCTIONS
- answer |= 1u << VFP3;
+ answer |= 1u << VFP3 | 1u << ARMv7;
#endif // def CAN_USE_VFP_INSTRUCTIONS
return answer;
}
@@ -77,9 +77,10 @@
initialized_ = true;
#endif
#ifndef __arm__
- // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is enabled.
+ // For the simulator=arm build, use VFP when FLAG_enable_vfp3 is
+ // enabled. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
if (FLAG_enable_vfp3) {
- supported_ |= 1u << VFP3;
+ supported_ |= 1u << VFP3 | 1u << ARMv7;
}
// For the simulator=arm build, use ARMv7 when FLAG_enable_armv7 is enabled
if (FLAG_enable_armv7) {
@@ -93,10 +94,11 @@
}
if (OS::ArmCpuHasFeature(VFP3)) {
- // This implementation also sets the VFP flags if
- // runtime detection of VFP returns true.
- supported_ |= 1u << VFP3;
- found_by_runtime_probing_ |= 1u << VFP3;
+ // This implementation also sets the VFP flags if runtime
+ // detection of VFP returns true. VFPv3 implies ARMv7, see ARM DDI
+ // 0406B, page A1-6.
+ supported_ |= 1u << VFP3 | 1u << ARMv7;
+ found_by_runtime_probing_ |= 1u << VFP3 | 1u << ARMv7;
}
if (OS::ArmCpuHasFeature(ARMv7)) {
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 6af30c4..4912449 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -2474,15 +2474,11 @@
Register key = ToRegister(instr->key());
ExternalArrayType array_type = instr->array_type();
if (array_type == kExternalFloatArray) {
- if (CpuFeatures::IsSupported(VFP3)) {
- CpuFeatures::Scope scope(VFP3);
- DwVfpRegister result(ToDoubleRegister(instr->result()));
- __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
- __ vldr(result, scratch0(), 0);
- } else {
- Register result(ToRegister(instr->result()));
- __ ldr(result, MemOperand(external_pointer, key, LSL, 2));
- }
+ CpuFeatures::Scope scope(VFP3);
+ DwVfpRegister result(ToDoubleRegister(instr->result()));
+ __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
+ __ vldr(result.low(), scratch0(), 0);
+ __ vcvt_f64_f32(result, result.low());
} else {
Register result(ToRegister(instr->result()));
switch (array_type) {
@@ -3182,15 +3178,11 @@
Register key = ToRegister(instr->key());
ExternalArrayType array_type = instr->array_type();
if (array_type == kExternalFloatArray) {
- if (CpuFeatures::IsSupported(VFP3)) {
- CpuFeatures::Scope scope(VFP3);
- DwVfpRegister value(ToDoubleRegister(instr->value()));
- __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
- __ vstr(value, scratch0(), 0);
- } else {
- Register value(ToRegister(instr->value()));
- __ str(value, MemOperand(external_pointer, key, LSL, 2));
- }
+ CpuFeatures::Scope scope(VFP3);
+ DwVfpRegister value(ToDoubleRegister(instr->value()));
+ __ add(scratch0(), external_pointer, Operand(key, LSL, 2));
+ __ vcvt_f32_f64(double_scratch0().low(), value);
+ __ vstr(double_scratch0().low(), scratch0(), 0);
} else {
Register value(ToRegister(instr->value()));
switch (array_type) {
diff --git a/src/ast.cc b/src/ast.cc
index 6ea8c27..7ae0f34 100644
--- a/src/ast.cc
+++ b/src/ast.cc
@@ -349,6 +349,143 @@
// ----------------------------------------------------------------------------
// Inlining support
+bool Declaration::IsInlineable() const {
+ UNREACHABLE();
+ return false;
+}
+
+
+bool TargetCollector::IsInlineable() const {
+ UNREACHABLE();
+ return false;
+}
+
+
+bool Slot::IsInlineable() const {
+ UNREACHABLE();
+ return false;
+}
+
+
+bool ForInStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool WithEnterStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool WithExitStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool SwitchStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool TryStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool TryCatchStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool TryFinallyStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool CatchExtensionObject::IsInlineable() const {
+ return false;
+}
+
+
+bool DebuggerStatement::IsInlineable() const {
+ return false;
+}
+
+
+bool Throw::IsInlineable() const {
+ // TODO(1143): Make functions containing throw inlineable.
+ return false;
+}
+
+
+bool MaterializedLiteral::IsInlineable() const {
+ // TODO(1322): Allow materialized literals.
+ return false;
+}
+
+
+bool FunctionLiteral::IsInlineable() const {
+ // TODO(1322): Allow materialized literals.
+ return false;
+}
+
+
+bool ThisFunction::IsInlineable() const {
+ return false;
+}
+
+
+bool SharedFunctionInfoLiteral::IsInlineable() const {
+ return false;
+}
+
+
+bool ValidLeftHandSideSentinel::IsInlineable() const {
+ UNREACHABLE();
+ return false;
+}
+
+
+bool ForStatement::IsInlineable() const {
+ return (init() == NULL || init()->IsInlineable())
+ && (cond() == NULL || cond()->IsInlineable())
+ && (next() == NULL || next()->IsInlineable())
+ && body()->IsInlineable();
+}
+
+
+bool WhileStatement::IsInlineable() const {
+ return cond()->IsInlineable()
+ && body()->IsInlineable();
+}
+
+
+bool DoWhileStatement::IsInlineable() const {
+ return cond()->IsInlineable()
+ && body()->IsInlineable();
+}
+
+
+bool ContinueStatement::IsInlineable() const {
+ return true;
+}
+
+
+bool BreakStatement::IsInlineable() const {
+ return true;
+}
+
+
+bool EmptyStatement::IsInlineable() const {
+ return true;
+}
+
+
+bool Literal::IsInlineable() const {
+ return true;
+}
+
+
bool Block::IsInlineable() const {
const int count = statements_.length();
for (int i = 0; i < count; ++i) {
@@ -364,8 +501,9 @@
bool IfStatement::IsInlineable() const {
- return condition()->IsInlineable() && then_statement()->IsInlineable() &&
- else_statement()->IsInlineable();
+ return condition()->IsInlineable()
+ && then_statement()->IsInlineable()
+ && else_statement()->IsInlineable();
}
diff --git a/src/ast.h b/src/ast.h
index 7f52c88..65a25a9 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -159,7 +159,7 @@
virtual Slot* AsSlot() { return NULL; }
// True if the node is simple enough for us to inline calls containing it.
- virtual bool IsInlineable() const { return false; }
+ virtual bool IsInlineable() const = 0;
static int Count() { return Isolate::Current()->ast_node_count(); }
static void ResetIds() { Isolate::Current()->set_ast_node_id(0); }
@@ -291,6 +291,7 @@
public:
virtual bool IsValidLeftHandSide() { return true; }
virtual void Accept(AstVisitor* v) { UNREACHABLE(); }
+ virtual bool IsInlineable() const;
};
@@ -375,6 +376,7 @@
VariableProxy* proxy() const { return proxy_; }
Variable::Mode mode() const { return mode_; }
FunctionLiteral* fun() const { return fun_; } // may be NULL
+ virtual bool IsInlineable() const;
private:
VariableProxy* proxy_;
@@ -433,6 +435,8 @@
virtual int ContinueId() const { return continue_id_; }
int BackEdgeId() const { return back_edge_id_; }
+ virtual bool IsInlineable() const;
+
private:
Expression* cond_;
int condition_position_;
@@ -459,6 +463,7 @@
void set_may_have_function_literal(bool value) {
may_have_function_literal_ = value;
}
+ virtual bool IsInlineable() const;
// Bailout support.
virtual int ContinueId() const { return EntryId(); }
@@ -506,6 +511,7 @@
bool is_fast_smi_loop() { return loop_variable_ != NULL; }
Variable* loop_variable() { return loop_variable_; }
void set_loop_variable(Variable* var) { loop_variable_ = var; }
+ virtual bool IsInlineable() const;
private:
Statement* init_;
@@ -533,6 +539,7 @@
Expression* each() const { return each_; }
Expression* enumerable() const { return enumerable_; }
+ virtual bool IsInlineable() const;
// Bailout support.
int AssignmentId() const { return assignment_id_; }
@@ -573,6 +580,7 @@
DECLARE_NODE_TYPE(ContinueStatement)
IterationStatement* target() const { return target_; }
+ virtual bool IsInlineable() const;
private:
IterationStatement* target_;
@@ -587,6 +595,7 @@
DECLARE_NODE_TYPE(BreakStatement)
BreakableStatement* target() const { return target_; }
+ virtual bool IsInlineable() const;
private:
BreakableStatement* target_;
@@ -618,6 +627,7 @@
Expression* expression() const { return expression_; }
bool is_catch_block() const { return is_catch_block_; }
+ virtual bool IsInlineable() const;
private:
Expression* expression_;
@@ -629,6 +639,8 @@
public:
WithExitStatement() { }
+ virtual bool IsInlineable() const;
+
DECLARE_NODE_TYPE(WithExitStatement)
};
@@ -679,6 +691,7 @@
Expression* tag() const { return tag_; }
ZoneList<CaseClause*>* cases() const { return cases_; }
+ virtual bool IsInlineable() const;
private:
Expression* tag_;
@@ -744,6 +757,7 @@
virtual TargetCollector* AsTargetCollector() { return this; }
ZoneList<Label*>* targets() { return targets_; }
+ virtual bool IsInlineable() const;
private:
ZoneList<Label*>* targets_;
@@ -761,6 +775,7 @@
Block* try_block() const { return try_block_; }
ZoneList<Label*>* escaping_targets() const { return escaping_targets_; }
+ virtual bool IsInlineable() const;
private:
Block* try_block_;
@@ -782,6 +797,7 @@
VariableProxy* catch_var() const { return catch_var_; }
Block* catch_block() const { return catch_block_; }
+ virtual bool IsInlineable() const;
private:
VariableProxy* catch_var_;
@@ -798,6 +814,7 @@
DECLARE_NODE_TYPE(TryFinallyStatement)
Block* finally_block() const { return finally_block_; }
+ virtual bool IsInlineable() const;
private:
Block* finally_block_;
@@ -807,6 +824,7 @@
class DebuggerStatement: public Statement {
public:
DECLARE_NODE_TYPE(DebuggerStatement)
+ virtual bool IsInlineable() const;
};
@@ -814,7 +832,7 @@
public:
DECLARE_NODE_TYPE(EmptyStatement)
- virtual bool IsInlineable() const { return true; }
+ virtual bool IsInlineable() const;
};
@@ -825,7 +843,6 @@
DECLARE_NODE_TYPE(Literal)
virtual bool IsTrivial() { return true; }
- virtual bool IsInlineable() const { return true; }
virtual bool IsSmiLiteral() { return handle_->IsSmi(); }
// Check if this literal is identical to the other literal.
@@ -864,6 +881,7 @@
}
Handle<Object> handle() const { return handle_; }
+ virtual bool IsInlineable() const;
private:
Handle<Object> handle_;
@@ -885,6 +903,7 @@
bool is_simple() const { return is_simple_; }
int depth() const { return depth_; }
+ virtual bool IsInlineable() const;
private:
int literal_index_;
@@ -1034,6 +1053,7 @@
Literal* key() const { return key_; }
VariableProxy* value() const { return value_; }
+ virtual bool IsInlineable() const;
private:
Literal* key_;
@@ -1160,6 +1180,7 @@
Type type() const { return type_; }
int index() const { return index_; }
bool is_arguments() const { return var_->is_arguments(); }
+ virtual bool IsInlineable() const;
private:
Variable* var_;
@@ -1643,6 +1664,7 @@
Expression* exception() const { return exception_; }
virtual int position() const { return pos_; }
+ virtual bool IsInlineable() const;
private:
Expression* exception_;
@@ -1715,6 +1737,7 @@
bool pretenure() { return pretenure_; }
void set_pretenure(bool value) { pretenure_ = value; }
+ virtual bool IsInlineable() const;
private:
Handle<String> name_;
@@ -1745,6 +1768,7 @@
Handle<SharedFunctionInfo> shared_function_info() const {
return shared_function_info_;
}
+ virtual bool IsInlineable() const;
private:
Handle<SharedFunctionInfo> shared_function_info_;
@@ -1754,6 +1778,7 @@
class ThisFunction: public Expression {
public:
DECLARE_NODE_TYPE(ThisFunction)
+ virtual bool IsInlineable() const;
};
diff --git a/src/conversions.cc b/src/conversions.cc
index c3d7bdf..1458584 100644
--- a/src/conversions.cc
+++ b/src/conversions.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -109,11 +109,11 @@
// Returns true if a nonspace found and false if the end has reached.
template <class Iterator, class EndMark>
-static inline bool AdvanceToNonspace(ScannerConstants* scanner_constants,
+static inline bool AdvanceToNonspace(UnicodeCache* unicode_cache,
Iterator* current,
EndMark end) {
while (*current != end) {
- if (!scanner_constants->IsWhiteSpace(**current)) return true;
+ if (!unicode_cache->IsWhiteSpace(**current)) return true;
++*current;
}
return false;
@@ -134,7 +134,7 @@
// Parsing integers with radix 2, 4, 8, 16, 32. Assumes current != end.
template <int radix_log_2, class Iterator, class EndMark>
-static double InternalStringToIntDouble(ScannerConstants* scanner_constants,
+static double InternalStringToIntDouble(UnicodeCache* unicode_cache,
Iterator current,
EndMark end,
bool negative,
@@ -161,7 +161,7 @@
digit = static_cast<char>(*current) - 'A' + 10;
} else {
if (allow_trailing_junk ||
- !AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ !AdvanceToNonspace(unicode_cache, ¤t, end)) {
break;
} else {
return JUNK_STRING_VALUE;
@@ -193,7 +193,7 @@
}
if (!allow_trailing_junk &&
- AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
@@ -237,14 +237,14 @@
template <class Iterator, class EndMark>
-static double InternalStringToInt(ScannerConstants* scanner_constants,
+static double InternalStringToInt(UnicodeCache* unicode_cache,
Iterator current,
EndMark end,
int radix) {
const bool allow_trailing_junk = true;
const double empty_string_val = JUNK_STRING_VALUE;
- if (!AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
return empty_string_val;
}
@@ -254,12 +254,12 @@
if (*current == '+') {
// Ignore leading sign; skip following spaces.
++current;
- if (!AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
} else if (*current == '-') {
++current;
- if (!AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
negative = true;
@@ -312,21 +312,21 @@
switch (radix) {
case 2:
return InternalStringToIntDouble<1>(
- scanner_constants, current, end, negative, allow_trailing_junk);
+ unicode_cache, current, end, negative, allow_trailing_junk);
case 4:
return InternalStringToIntDouble<2>(
- scanner_constants, current, end, negative, allow_trailing_junk);
+ unicode_cache, current, end, negative, allow_trailing_junk);
case 8:
return InternalStringToIntDouble<3>(
- scanner_constants, current, end, negative, allow_trailing_junk);
+ unicode_cache, current, end, negative, allow_trailing_junk);
case 16:
return InternalStringToIntDouble<4>(
- scanner_constants, current, end, negative, allow_trailing_junk);
+ unicode_cache, current, end, negative, allow_trailing_junk);
case 32:
return InternalStringToIntDouble<5>(
- scanner_constants, current, end, negative, allow_trailing_junk);
+ unicode_cache, current, end, negative, allow_trailing_junk);
default:
UNREACHABLE();
}
@@ -352,7 +352,7 @@
}
if (!allow_trailing_junk &&
- AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
@@ -418,7 +418,7 @@
} while (!done);
if (!allow_trailing_junk &&
- AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
@@ -432,7 +432,7 @@
// 2. *current - gets the current character in the sequence.
// 3. ++current (advances the position).
template <class Iterator, class EndMark>
-static double InternalStringToDouble(ScannerConstants* scanner_constants,
+static double InternalStringToDouble(UnicodeCache* unicode_cache,
Iterator current,
EndMark end,
int flags,
@@ -445,7 +445,7 @@
// 'parsing_done'.
// 4. 'current' is not dereferenced after the 'parsing_done' label.
// 5. Code before 'parsing_done' may rely on 'current != end'.
- if (!AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ if (!AdvanceToNonspace(unicode_cache, ¤t, end)) {
return empty_string_val;
}
@@ -483,7 +483,7 @@
}
if (!allow_trailing_junk &&
- AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
@@ -505,7 +505,7 @@
return JUNK_STRING_VALUE; // "0x".
}
- return InternalStringToIntDouble<4>(scanner_constants,
+ return InternalStringToIntDouble<4>(unicode_cache,
current,
end,
negative,
@@ -643,7 +643,7 @@
}
if (!allow_trailing_junk &&
- AdvanceToNonspace(scanner_constants, ¤t, end)) {
+ AdvanceToNonspace(unicode_cache, ¤t, end)) {
return JUNK_STRING_VALUE;
}
@@ -651,7 +651,7 @@
exponent += insignificant_digits;
if (octal) {
- return InternalStringToIntDouble<3>(scanner_constants,
+ return InternalStringToIntDouble<3>(unicode_cache,
buffer,
buffer + buffer_pos,
negative,
@@ -671,23 +671,22 @@
}
-double StringToDouble(String* str, int flags, double empty_string_val) {
- ScannerConstants* scanner_constants =
- Isolate::Current()->scanner_constants();
+double StringToDouble(UnicodeCache* unicode_cache,
+ String* str, int flags, double empty_string_val) {
StringShape shape(str);
if (shape.IsSequentialAscii()) {
const char* begin = SeqAsciiString::cast(str)->GetChars();
const char* end = begin + str->length();
- return InternalStringToDouble(scanner_constants, begin, end, flags,
+ return InternalStringToDouble(unicode_cache, begin, end, flags,
empty_string_val);
} else if (shape.IsSequentialTwoByte()) {
const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
const uc16* end = begin + str->length();
- return InternalStringToDouble(scanner_constants, begin, end, flags,
+ return InternalStringToDouble(unicode_cache, begin, end, flags,
empty_string_val);
} else {
StringInputBuffer buffer(str);
- return InternalStringToDouble(scanner_constants,
+ return InternalStringToDouble(unicode_cache,
StringInputBufferIterator(&buffer),
StringInputBufferIterator::EndMarker(),
flags,
@@ -696,21 +695,21 @@
}
-double StringToInt(String* str, int radix) {
- ScannerConstants* scanner_constants =
- Isolate::Current()->scanner_constants();
+double StringToInt(UnicodeCache* unicode_cache,
+ String* str,
+ int radix) {
StringShape shape(str);
if (shape.IsSequentialAscii()) {
const char* begin = SeqAsciiString::cast(str)->GetChars();
const char* end = begin + str->length();
- return InternalStringToInt(scanner_constants, begin, end, radix);
+ return InternalStringToInt(unicode_cache, begin, end, radix);
} else if (shape.IsSequentialTwoByte()) {
const uc16* begin = SeqTwoByteString::cast(str)->GetChars();
const uc16* end = begin + str->length();
- return InternalStringToInt(scanner_constants, begin, end, radix);
+ return InternalStringToInt(unicode_cache, begin, end, radix);
} else {
StringInputBuffer buffer(str);
- return InternalStringToInt(scanner_constants,
+ return InternalStringToInt(unicode_cache,
StringInputBufferIterator(&buffer),
StringInputBufferIterator::EndMarker(),
radix);
@@ -718,22 +717,20 @@
}
-double StringToDouble(const char* str, int flags, double empty_string_val) {
- ScannerConstants* scanner_constants =
- Isolate::Current()->scanner_constants();
+double StringToDouble(UnicodeCache* unicode_cache,
+ const char* str, int flags, double empty_string_val) {
const char* end = str + StrLength(str);
- return InternalStringToDouble(scanner_constants, str, end, flags,
+ return InternalStringToDouble(unicode_cache, str, end, flags,
empty_string_val);
}
-double StringToDouble(Vector<const char> str,
+double StringToDouble(UnicodeCache* unicode_cache,
+ Vector<const char> str,
int flags,
double empty_string_val) {
- ScannerConstants* scanner_constants =
- Isolate::Current()->scanner_constants();
const char* end = str.start() + str.length();
- return InternalStringToDouble(scanner_constants, str.start(), end, flags,
+ return InternalStringToDouble(unicode_cache, str.start(), end, flags,
empty_string_val);
}
diff --git a/src/conversions.h b/src/conversions.h
index 312e6ae..a14dc9a 100644
--- a/src/conversions.h
+++ b/src/conversions.h
@@ -1,4 +1,4 @@
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -28,6 +28,8 @@
#ifndef V8_CONVERSIONS_H_
#define V8_CONVERSIONS_H_
+#include "scanner-base.h"
+
namespace v8 {
namespace internal {
@@ -91,15 +93,22 @@
// Converts a string into a double value according to ECMA-262 9.3.1
-double StringToDouble(String* str, int flags, double empty_string_val = 0);
-double StringToDouble(Vector<const char> str,
+double StringToDouble(UnicodeCache* unicode_cache,
+ String* str,
+ int flags,
+ double empty_string_val = 0);
+double StringToDouble(UnicodeCache* unicode_cache,
+ Vector<const char> str,
int flags,
double empty_string_val = 0);
// This version expects a zero-terminated character array.
-double StringToDouble(const char* str, int flags, double empty_string_val = 0);
+double StringToDouble(UnicodeCache* unicode_cache,
+ const char* str,
+ int flags,
+ double empty_string_val = 0);
// Converts a string into an integer.
-double StringToInt(String* str, int radix);
+double StringToInt(UnicodeCache* unicode_cache, String* str, int radix);
// Converts a double to a string value according to ECMA-262 9.8.1.
// The buffer should be large enough for any floating point number.
diff --git a/src/dateparser-inl.h b/src/dateparser-inl.h
index ac28c62..7f8fac8 100644
--- a/src/dateparser-inl.h
+++ b/src/dateparser-inl.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -34,9 +34,11 @@
namespace internal {
template <typename Char>
-bool DateParser::Parse(Vector<Char> str, FixedArray* out) {
+bool DateParser::Parse(Vector<Char> str,
+ FixedArray* out,
+ UnicodeCache* unicode_cache) {
ASSERT(out->length() >= OUTPUT_SIZE);
- InputReader<Char> in(str);
+ InputReader<Char> in(unicode_cache, str);
TimeZoneComposer tz;
TimeComposer time;
DayComposer day;
diff --git a/src/dateparser.h b/src/dateparser.h
index 51109ee..9d29715 100644
--- a/src/dateparser.h
+++ b/src/dateparser.h
@@ -1,4 +1,4 @@
-// Copyright 2008 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -49,7 +49,7 @@
// [7]: UTC offset in seconds, or null value if no timezone specified
// If parsing fails, return false (content of output array is not defined).
template <typename Char>
- static bool Parse(Vector<Char> str, FixedArray* output);
+ static bool Parse(Vector<Char> str, FixedArray* output, UnicodeCache* cache);
enum {
YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND, UTC_OFFSET, OUTPUT_SIZE
@@ -67,11 +67,11 @@
template <typename Char>
class InputReader BASE_EMBEDDED {
public:
- explicit InputReader(Vector<Char> s)
+ InputReader(UnicodeCache* unicode_cache, Vector<Char> s)
: index_(0),
buffer_(s),
has_read_number_(false),
- scanner_constants_(Isolate::Current()->scanner_constants()) {
+ unicode_cache_(unicode_cache) {
Next();
}
@@ -122,7 +122,7 @@
}
bool SkipWhiteSpace() {
- if (scanner_constants_->IsWhiteSpace(ch_)) {
+ if (unicode_cache_->IsWhiteSpace(ch_)) {
Next();
return true;
}
@@ -158,7 +158,7 @@
Vector<Char> buffer_;
bool has_read_number_;
uint32_t ch_;
- ScannerConstants* scanner_constants_;
+ UnicodeCache* unicode_cache_;
};
enum KeywordType { INVALID, MONTH_NAME, TIME_ZONE_NAME, AM_PM };
diff --git a/src/extensions/experimental/experimental.gyp b/src/extensions/experimental/experimental.gyp
index 761f4c7..a8585fd 100644
--- a/src/extensions/experimental/experimental.gyp
+++ b/src/extensions/experimental/experimental.gyp
@@ -41,6 +41,7 @@
'break-iterator.h',
'i18n-extension.cc',
'i18n-extension.h',
+ '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
],
'include_dirs': [
'<(icu_src_dir)/public/common',
@@ -48,8 +49,39 @@
],
'dependencies': [
'<(icu_src_dir)/icu.gyp:*',
+ 'js2c_i18n#host',
'../../../tools/gyp/v8.gyp:v8',
],
},
+ {
+ 'target_name': 'js2c_i18n',
+ 'type': 'none',
+ 'toolsets': ['host'],
+ 'variables': {
+ 'library_files': [
+ 'i18n.js'
+ ],
+ },
+ 'actions': [
+ {
+ 'action_name': 'js2c_i18n',
+ 'inputs': [
+ '../../../tools/js2c.py',
+ '<@(library_files)',
+ ],
+ 'outputs': [
+ '<(SHARED_INTERMEDIATE_DIR)/i18n-js.cc',
+ '<(SHARED_INTERMEDIATE_DIR)/i18n-js-empty.cc'
+ ],
+ 'action': [
+ 'python',
+ '../../../tools/js2c.py',
+ '<@(_outputs)',
+ 'I18N',
+ '<@(library_files)'
+ ],
+ },
+ ],
+ },
], # targets
}
diff --git a/src/extensions/experimental/i18n-extension.cc b/src/extensions/experimental/i18n-extension.cc
index f14fd9e..6e3ab15 100644
--- a/src/extensions/experimental/i18n-extension.cc
+++ b/src/extensions/experimental/i18n-extension.cc
@@ -31,6 +31,7 @@
#include <string>
#include "break-iterator.h"
+#include "natives.h"
#include "unicode/locid.h"
#include "unicode/uloc.h"
@@ -39,73 +40,19 @@
I18NExtension* I18NExtension::extension_ = NULL;
-// TODO(cira): maybe move JS code to a .js file and generata cc files from it?
-// TODO(cira): Remove v8 prefix from v8Locale once we have stable API.
-const char* const I18NExtension::kSource =
- "v8Locale = function(optLocale) {"
- " native function NativeJSLocale();"
- " var properties = NativeJSLocale(optLocale);"
- " this.locale = properties.locale;"
- " this.language = properties.language;"
- " this.script = properties.script;"
- " this.region = properties.region;"
- "};"
- "v8Locale.availableLocales = function() {"
- " native function NativeJSAvailableLocales();"
- " return NativeJSAvailableLocales();"
- "};"
- "v8Locale.prototype.maximizedLocale = function() {"
- " native function NativeJSMaximizedLocale();"
- " return new v8Locale(NativeJSMaximizedLocale(this.locale));"
- "};"
- "v8Locale.prototype.minimizedLocale = function() {"
- " native function NativeJSMinimizedLocale();"
- " return new v8Locale(NativeJSMinimizedLocale(this.locale));"
- "};"
- "v8Locale.prototype.displayLocale_ = function(displayLocale) {"
- " var result = this.locale;"
- " if (displayLocale !== undefined) {"
- " result = displayLocale.locale;"
- " }"
- " return result;"
- "};"
- "v8Locale.prototype.displayLanguage = function(optDisplayLocale) {"
- " var displayLocale = this.displayLocale_(optDisplayLocale);"
- " native function NativeJSDisplayLanguage();"
- " return NativeJSDisplayLanguage(this.locale, displayLocale);"
- "};"
- "v8Locale.prototype.displayScript = function(optDisplayLocale) {"
- " var displayLocale = this.displayLocale_(optDisplayLocale);"
- " native function NativeJSDisplayScript();"
- " return NativeJSDisplayScript(this.locale, displayLocale);"
- "};"
- "v8Locale.prototype.displayRegion = function(optDisplayLocale) {"
- " var displayLocale = this.displayLocale_(optDisplayLocale);"
- " native function NativeJSDisplayRegion();"
- " return NativeJSDisplayRegion(this.locale, displayLocale);"
- "};"
- "v8Locale.prototype.displayName = function(optDisplayLocale) {"
- " var displayLocale = this.displayLocale_(optDisplayLocale);"
- " native function NativeJSDisplayName();"
- " return NativeJSDisplayName(this.locale, displayLocale);"
- "};"
- "v8Locale.v8BreakIterator = function(locale, type) {"
- " native function NativeJSBreakIterator();"
- " var iterator = NativeJSBreakIterator(locale, type);"
- " iterator.type = type;"
- " return iterator;"
- "};"
- "v8Locale.v8BreakIterator.BreakType = {"
- " 'unknown': -1,"
- " 'none': 0,"
- " 'number': 100,"
- " 'word': 200,"
- " 'kana': 300,"
- " 'ideo': 400"
- "};"
- "v8Locale.prototype.v8CreateBreakIterator = function(type) {"
- " return new v8Locale.v8BreakIterator(this.locale, type);"
- "};";
+// Returns a pointer to static string containing the actual
+// JavaScript code generated from i18n.js file.
+static const char* GetScriptSource() {
+ int index = NativesCollection<I18N>::GetIndex("i18n");
+ Vector<const char> script_data =
+ NativesCollection<I18N>::GetScriptSource(index);
+
+ return script_data.start();
+}
+
+I18NExtension::I18NExtension()
+ : v8::Extension("v8/i18n", GetScriptSource()) {
+}
v8::Handle<v8::FunctionTemplate> I18NExtension::GetNativeFunction(
v8::Handle<v8::String> name) {
diff --git a/src/extensions/experimental/i18n-extension.h b/src/extensions/experimental/i18n-extension.h
index 629332b..54c973f 100644
--- a/src/extensions/experimental/i18n-extension.h
+++ b/src/extensions/experimental/i18n-extension.h
@@ -36,7 +36,8 @@
class I18NExtension : public v8::Extension {
public:
- I18NExtension() : v8::Extension("v8/i18n", kSource) {}
+ I18NExtension();
+
virtual v8::Handle<v8::FunctionTemplate> GetNativeFunction(
v8::Handle<v8::String> name);
@@ -55,7 +56,6 @@
static I18NExtension* get();
private:
- static const char* const kSource;
static I18NExtension* extension_;
};
diff --git a/src/extensions/experimental/i18n.js b/src/extensions/experimental/i18n.js
new file mode 100644
index 0000000..baf3859
--- /dev/null
+++ b/src/extensions/experimental/i18n.js
@@ -0,0 +1,103 @@
+// Copyright 2006-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.
+
+// TODO(cira): Remove v8 prefix from v8Locale once we have stable API.
+v8Locale = function(optLocale) {
+ native function NativeJSLocale();
+ var properties = NativeJSLocale(optLocale);
+ this.locale = properties.locale;
+ this.language = properties.language;
+ this.script = properties.script;
+ this.region = properties.region;
+};
+
+v8Locale.availableLocales = function() {
+ native function NativeJSAvailableLocales();
+ return NativeJSAvailableLocales();
+};
+
+v8Locale.prototype.maximizedLocale = function() {
+ native function NativeJSMaximizedLocale();
+ return new v8Locale(NativeJSMaximizedLocale(this.locale));
+};
+
+v8Locale.prototype.minimizedLocale = function() {
+ native function NativeJSMinimizedLocale();
+ return new v8Locale(NativeJSMinimizedLocale(this.locale));
+};
+
+v8Locale.prototype.displayLocale_ = function(displayLocale) {
+ var result = this.locale;
+ if (displayLocale !== undefined) {
+ result = displayLocale.locale;
+ }
+ return result;
+};
+
+v8Locale.prototype.displayLanguage = function(optDisplayLocale) {
+ var displayLocale = this.displayLocale_(optDisplayLocale);
+ native function NativeJSDisplayLanguage();
+ return NativeJSDisplayLanguage(this.locale, displayLocale);
+};
+
+v8Locale.prototype.displayScript = function(optDisplayLocale) {
+ var displayLocale = this.displayLocale_(optDisplayLocale);
+ native function NativeJSDisplayScript();
+ return NativeJSDisplayScript(this.locale, displayLocale);
+};
+
+v8Locale.prototype.displayRegion = function(optDisplayLocale) {
+ var displayLocale = this.displayLocale_(optDisplayLocale);
+ native function NativeJSDisplayRegion();
+ return NativeJSDisplayRegion(this.locale, displayLocale);
+};
+
+v8Locale.prototype.displayName = function(optDisplayLocale) {
+ var displayLocale = this.displayLocale_(optDisplayLocale);
+ native function NativeJSDisplayName();
+ return NativeJSDisplayName(this.locale, displayLocale);
+};
+
+v8Locale.v8BreakIterator = function(locale, type) {
+ native function NativeJSBreakIterator();
+ var iterator = NativeJSBreakIterator(locale, type);
+ iterator.type = type;
+ return iterator;
+};
+
+v8Locale.v8BreakIterator.BreakType = {
+ 'unknown': -1,
+ 'none': 0,
+ 'number': 100,
+ 'word': 200,
+ 'kana': 300,
+ 'ideo': 400
+};
+
+v8Locale.prototype.v8CreateBreakIterator = function(type) {
+ return new v8Locale.v8BreakIterator(this.locale, type);
+};
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index d6cb6e3..15f8def 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -162,7 +162,8 @@
DEFINE_bool(enable_sahf, true,
"enable use of SAHF instruction if available (X64 only)")
DEFINE_bool(enable_vfp3, true,
- "enable use of VFP3 instructions if available (ARM only)")
+ "enable use of VFP3 instructions if available - this implies "
+ "enabling ARMv7 instructions (ARM only)")
DEFINE_bool(enable_armv7, true,
"enable use of ARMv7 instructions if available (ARM only)")
DEFINE_bool(enable_fpu, true,
diff --git a/src/heap.cc b/src/heap.cc
index c77364b..9a3cfe4 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -3386,8 +3386,8 @@
const uc32 kMaxSupportedChar = 0xFFFF;
// Count the number of characters in the UTF-8 string and check if
// it is an ASCII string.
- Access<ScannerConstants::Utf8Decoder>
- decoder(isolate_->scanner_constants()->utf8_decoder());
+ Access<UnicodeCache::Utf8Decoder>
+ decoder(isolate_->unicode_cache()->utf8_decoder());
decoder->Reset(string.start(), string.length());
int chars = 0;
while (decoder->has_more()) {
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index c736553..a623775 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -274,7 +274,7 @@
return kind_ == other.kind_;
}
- Kind kind() const { return kind_; }
+ Kind kind() const { return static_cast<Kind>(kind_); }
bool IsNone() const { return kind_ == kNone; }
bool IsTagged() const { return kind_ == kTagged; }
bool IsInteger32() const { return kind_ == kInteger32; }
@@ -288,7 +288,10 @@
private:
explicit Representation(Kind k) : kind_(k) { }
- Kind kind_;
+ // Make sure kind fits in int8.
+ STATIC_ASSERT(kNumRepresentations <= (1 << kBitsPerByte));
+
+ int8_t kind_;
};
@@ -395,9 +398,12 @@
kUninitialized = 0x1fff // 0001 1111 1111 1111
};
+ // Make sure type fits in int16.
+ STATIC_ASSERT(kUninitialized < (1 << (2 * kBitsPerByte)));
+
explicit HType(Type t) : type_(t) { }
- Type type_;
+ int16_t type_;
};
@@ -611,8 +617,8 @@
int id_;
Representation representation_;
- SmallPointerList<HValue> uses_;
HType type_;
+ SmallPointerList<HValue> uses_;
Range* range_;
int flags_;
diff --git a/src/isolate.cc b/src/isolate.cc
index b8a7fb7..e42d78e 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1,4 +1,4 @@
-// Copyright 2006-2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -54,6 +54,21 @@
namespace v8 {
namespace internal {
+Atomic32 ThreadId::highest_thread_id_ = 0;
+
+int ThreadId::AllocateThreadId() {
+ int new_id = NoBarrier_AtomicIncrement(&highest_thread_id_, 1);
+ return new_id;
+}
+
+int ThreadId::GetCurrentThreadId() {
+ int thread_id = Thread::GetThreadLocalInt(Isolate::thread_id_key_);
+ if (thread_id == 0) {
+ thread_id = AllocateThreadId();
+ Thread::SetThreadLocalInt(Isolate::thread_id_key_, thread_id);
+ }
+ return thread_id;
+}
// Create a dummy thread that will wait forever on a semaphore. The only
// purpose for this thread is to have some stack area to save essential data
@@ -245,7 +260,6 @@
Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_;
Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex();
Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL;
-Isolate::ThreadId Isolate::highest_thread_id_ = 0;
class IsolateInitializer {
@@ -265,20 +279,12 @@
static IsolateInitializer* static_initializer = EnsureDefaultIsolateAllocated();
-Isolate::ThreadId Isolate::AllocateThreadId() {
- ThreadId new_id;
- {
- ScopedLock lock(process_wide_mutex_);
- new_id = ++highest_thread_id_;
- }
- return new_id;
-}
+
Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData(
ThreadId thread_id) {
- ASSERT(thread_id != 0);
- ASSERT(Thread::GetThreadLocalInt(thread_id_key_) == thread_id);
+ ASSERT(!thread_id.Equals(ThreadId::Invalid()));
PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id);
{
ScopedLock lock(process_wide_mutex_);
@@ -292,11 +298,7 @@
Isolate::PerIsolateThreadData*
Isolate::FindOrAllocatePerThreadDataForThisThread() {
- ThreadId thread_id = Thread::GetThreadLocalInt(thread_id_key_);
- if (thread_id == 0) {
- thread_id = AllocateThreadId();
- Thread::SetThreadLocalInt(thread_id_key_, thread_id);
- }
+ ThreadId thread_id = ThreadId::Current();
PerIsolateThreadData* per_thread = NULL;
{
ScopedLock lock(process_wide_mutex_);
@@ -361,7 +363,8 @@
Isolate::PerIsolateThreadData*
- Isolate::ThreadDataTable::Lookup(Isolate* isolate, ThreadId thread_id) {
+ Isolate::ThreadDataTable::Lookup(Isolate* isolate,
+ ThreadId thread_id) {
for (PerIsolateThreadData* data = list_; data != NULL; data = data->next_) {
if (data->Matches(isolate, thread_id)) return data;
}
@@ -383,7 +386,8 @@
}
-void Isolate::ThreadDataTable::Remove(Isolate* isolate, ThreadId thread_id) {
+void Isolate::ThreadDataTable::Remove(Isolate* isolate,
+ ThreadId thread_id) {
PerIsolateThreadData* data = Lookup(isolate, thread_id);
if (data != NULL) {
Remove(data);
@@ -429,7 +433,7 @@
context_slot_cache_(NULL),
descriptor_lookup_cache_(NULL),
handle_scope_implementer_(NULL),
- scanner_constants_(NULL),
+ unicode_cache_(NULL),
in_use_list_(0),
free_list_(0),
preallocated_storage_preallocated_(false),
@@ -564,8 +568,8 @@
producer_heap_profile_ = NULL;
#endif
- delete scanner_constants_;
- scanner_constants_ = NULL;
+ delete unicode_cache_;
+ unicode_cache_ = NULL;
delete regexp_stack_;
regexp_stack_ = NULL;
@@ -672,7 +676,7 @@
keyed_lookup_cache_ = new KeyedLookupCache();
context_slot_cache_ = new ContextSlotCache();
descriptor_lookup_cache_ = new DescriptorLookupCache();
- scanner_constants_ = new ScannerConstants();
+ unicode_cache_ = new UnicodeCache();
pc_to_code_cache_ = new PcToCodeCache(this);
write_input_buffer_ = new StringInputBuffer();
global_handles_ = new GlobalHandles(this);
@@ -833,8 +837,8 @@
ASSERT(Current() == this);
ASSERT(entry_stack_ != NULL);
ASSERT(entry_stack_->previous_thread_data == NULL ||
- entry_stack_->previous_thread_data->thread_id() ==
- Thread::GetThreadLocalInt(thread_id_key_));
+ entry_stack_->previous_thread_data->thread_id().Equals(
+ ThreadId::Current()));
// Same thread re-enters the isolate, no need to re-init anything.
entry_stack_->entry_count++;
return;
@@ -872,8 +876,8 @@
void Isolate::Exit() {
ASSERT(entry_stack_ != NULL);
ASSERT(entry_stack_->previous_thread_data == NULL ||
- entry_stack_->previous_thread_data->thread_id() ==
- Thread::GetThreadLocalInt(thread_id_key_));
+ entry_stack_->previous_thread_data->thread_id().Equals(
+ ThreadId::Current()));
if (--entry_stack_->entry_count > 0) return;
diff --git a/src/isolate.h b/src/isolate.h
index dd0a1fe..01b721d 100644
--- a/src/isolate.h
+++ b/src/isolate.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -72,7 +72,7 @@
class ProducerHeapProfile;
class RegExpStack;
class SaveContext;
-class ScannerConstants;
+class UnicodeCache;
class StringInputBuffer;
class StringTracker;
class StubCache;
@@ -136,6 +136,53 @@
#endif
+// Platform-independent, reliable thread identifier.
+class ThreadId {
+ public:
+ // Creates an invalid ThreadId.
+ ThreadId() : id_(kInvalidId) {}
+
+ // Returns ThreadId for current thread.
+ static ThreadId Current() { return ThreadId(GetCurrentThreadId()); }
+
+ // Returns invalid ThreadId (guaranteed not to be equal to any thread).
+ static ThreadId Invalid() { return ThreadId(kInvalidId); }
+
+ // Compares ThreadIds for equality.
+ INLINE(bool Equals(const ThreadId& other) const) {
+ return id_ == other.id_;
+ }
+
+ // Checks whether this ThreadId refers to any thread.
+ INLINE(bool IsValid() const) {
+ return id_ != kInvalidId;
+ }
+
+ // Converts ThreadId to an integer representation
+ // (required for public API: V8::V8::GetCurrentThreadId).
+ int ToInteger() const { return id_; }
+
+ // Converts ThreadId to an integer representation
+ // (required for public API: V8::V8::TerminateExecution).
+ static ThreadId FromInteger(int id) { return ThreadId(id); }
+
+ private:
+ static const int kInvalidId = -1;
+
+ explicit ThreadId(int id) : id_(id) {}
+
+ static int AllocateThreadId();
+
+ static int GetCurrentThreadId();
+
+ int id_;
+
+ static Atomic32 highest_thread_id_;
+
+ friend class Isolate;
+};
+
+
class ThreadLocalTop BASE_EMBEDDED {
public:
// Initialize the thread data.
@@ -176,7 +223,7 @@
// The context where the current execution method is created and for variable
// lookups.
Context* context_;
- int thread_id_;
+ ThreadId thread_id_;
MaybeObject* pending_exception_;
bool has_pending_message_;
Object* pending_message_obj_;
@@ -188,9 +235,6 @@
// unify them later.
MaybeObject* scheduled_exception_;
bool external_caught_exception_;
- // True if unhandled message is being currently reported by
- // MessageHandler::ReportMessage.
- bool in_exception_reporting_;
SaveContext* save_context_;
v8::TryCatch* catcher_;
@@ -332,8 +376,6 @@
public:
~Isolate();
- typedef int ThreadId;
-
// A thread has a PerIsolateThreadData instance for each isolate that it has
// entered. That instance is allocated when the isolate is initially entered
// and reused on subsequent entries.
@@ -366,7 +408,7 @@
#endif
bool Matches(Isolate* isolate, ThreadId thread_id) const {
- return isolate_ == isolate && thread_id_ == thread_id;
+ return isolate_ == isolate && thread_id_.Equals(thread_id);
}
private:
@@ -458,9 +500,6 @@
return thread_id_key_;
}
- // Atomically allocates a new thread ID.
- static ThreadId AllocateThreadId();
-
// If a client attempts to create a Locker without specifying an isolate,
// we assume that the client is using legacy behavior. Set up the current
// thread to be inside the implicit isolate (or fail a check if we have
@@ -486,8 +525,8 @@
}
// Access to current thread id.
- int thread_id() { return thread_local_top_.thread_id_; }
- void set_thread_id(int id) { thread_local_top_.thread_id_ = id; }
+ ThreadId thread_id() { return thread_local_top_.thread_id_; }
+ void set_thread_id(ThreadId id) { thread_local_top_.thread_id_ = id; }
// Interface to pending exception.
MaybeObject* pending_exception() {
@@ -526,12 +565,6 @@
bool* external_caught_exception_address() {
return &thread_local_top_.external_caught_exception_;
}
- bool in_exception_reporting() {
- return thread_local_top_.in_exception_reporting_;
- }
- void set_in_exception_reporting(bool value) {
- thread_local_top_.in_exception_reporting_ = value;
- }
v8::TryCatch* catcher() {
return thread_local_top_.catcher_;
}
@@ -786,8 +819,8 @@
}
Zone* zone() { return &zone_; }
- ScannerConstants* scanner_constants() {
- return scanner_constants_;
+ UnicodeCache* unicode_cache() {
+ return unicode_cache_;
}
PcToCodeCache* pc_to_code_cache() { return pc_to_code_cache_; }
@@ -1005,7 +1038,6 @@
static Thread::LocalStorageKey thread_id_key_;
static Isolate* default_isolate_;
static ThreadDataTable* thread_data_table_;
- static ThreadId highest_thread_id_;
bool PreInit();
@@ -1090,7 +1122,7 @@
DescriptorLookupCache* descriptor_lookup_cache_;
v8::ImplementationUtilities::HandleScopeData handle_scope_data_;
HandleScopeImplementer* handle_scope_implementer_;
- ScannerConstants* scanner_constants_;
+ UnicodeCache* unicode_cache_;
Zone zone_;
PreallocatedStorage in_use_list_;
PreallocatedStorage free_list_;
@@ -1165,6 +1197,7 @@
friend class ExecutionAccess;
friend class IsolateInitializer;
+ friend class ThreadId;
friend class v8::Isolate;
friend class v8::Locker;
diff --git a/src/messages.cc b/src/messages.cc
index 0cc8251..abc2537 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -104,15 +104,6 @@
void MessageHandler::ReportMessage(Isolate* isolate,
MessageLocation* loc,
Handle<Object> message) {
- // If we are in process of message reporting, just ignore all other requests
- // to report a message as they are due to unhandled exceptions thrown in
- // message callbacks.
- if (isolate->in_exception_reporting()) {
- PrintF("uncaught exception thrown while reporting\n");
- return;
- }
- isolate->set_in_exception_reporting(true);
-
// We are calling into embedder's code which can throw exceptions.
// Thus we need to save current exception state, reset it to the clean one
// and ignore scheduled exceptions callbacks can throw.
@@ -138,14 +129,16 @@
v8::MessageCallback callback =
FUNCTION_CAST<v8::MessageCallback>(callback_obj->proxy());
Handle<Object> callback_data(listener.get(1));
- callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+ {
+ // Do not allow exceptions to propagate.
+ v8::TryCatch tryCatch;
+ callback(api_message_obj, v8::Utils::ToLocal(callback_data));
+ }
if (isolate->has_scheduled_exception()) {
isolate->clear_scheduled_exception();
}
}
}
-
- isolate->set_in_exception_reporting(false);
}
diff --git a/src/natives.h b/src/natives.h
index 639a2d3..1df94b0 100644
--- a/src/natives.h
+++ b/src/natives.h
@@ -36,7 +36,7 @@
int index);
enum NativeType {
- CORE, D8
+ CORE, D8, I18N
};
template <NativeType type>
diff --git a/src/objects-inl.h b/src/objects-inl.h
index ebdf0a0..823b2da 100644
--- a/src/objects-inl.h
+++ b/src/objects-inl.h
@@ -3309,6 +3309,11 @@
}
+bool JSFunction::IsOptimizable() {
+ return code()->kind() == Code::FUNCTION && code()->optimizable();
+}
+
+
bool JSFunction::IsMarkedForLazyRecompilation() {
return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
}
diff --git a/src/objects.cc b/src/objects.cc
index d211d62..6ce4c44 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -1279,6 +1279,22 @@
}
+static bool IsIdentifier(UnicodeCache* cache,
+ unibrow::CharacterStream* buffer) {
+ // Checks whether the buffer contains an identifier (no escape).
+ if (!buffer->has_more()) return false;
+ if (!cache->IsIdentifierStart(buffer->GetNext())) {
+ return false;
+ }
+ while (buffer->has_more()) {
+ if (!cache->IsIdentifierPart(buffer->GetNext())) {
+ return false;
+ }
+ }
+ return true;
+}
+
+
MaybeObject* JSObject::AddFastProperty(String* name,
Object* value,
PropertyAttributes attributes) {
@@ -1288,7 +1304,7 @@
// hidden symbols) and is not a real identifier.
Isolate* isolate = GetHeap()->isolate();
StringInputBuffer buffer(name);
- if (!isolate->scanner_constants()->IsIdentifier(&buffer)
+ if (!IsIdentifier(isolate->unicode_cache(), &buffer)
&& name != isolate->heap()->hidden_symbol()) {
Object* obj;
{ MaybeObject* maybe_obj =
@@ -5423,8 +5439,8 @@
bool String::IsEqualTo(Vector<const char> str) {
Isolate* isolate = GetIsolate();
int slen = length();
- Access<ScannerConstants::Utf8Decoder>
- decoder(isolate->scanner_constants()->utf8_decoder());
+ Access<UnicodeCache::Utf8Decoder>
+ decoder(isolate->unicode_cache()->utf8_decoder());
decoder->Reset(str.start(), str.length());
int i;
for (i = 0; i < slen && decoder->has_more(); i++) {
@@ -7635,7 +7651,6 @@
Handle<InterceptorInfo> interceptor(GetIndexedInterceptor(), isolate);
Handle<Object> this_handle(receiver, isolate);
Handle<JSObject> holder_handle(this, isolate);
-
if (!interceptor->getter()->IsUndefined()) {
v8::IndexedPropertyGetter getter =
v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter());
diff --git a/src/objects.h b/src/objects.h
index 449a210..03445e8 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4526,6 +4526,9 @@
// Tells whether or not this function has been optimized.
inline bool IsOptimized();
+ // Tells whether or not this function can be optimized.
+ inline bool IsOptimizable();
+
// Mark this function for lazy recompilation. The function will be
// recompiled the next time it is executed.
void MarkForLazyRecompilation();
diff --git a/src/parser.cc b/src/parser.cc
index 4fad6e4..cf84bfa 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -576,7 +576,7 @@
: isolate_(script->GetIsolate()),
symbol_cache_(pre_data ? pre_data->symbol_count() : 0),
script_(script),
- scanner_(isolate_->scanner_constants()),
+ scanner_(isolate_->unicode_cache()),
top_scope_(NULL),
with_nesting_level_(0),
lexical_scope_(NULL),
@@ -2894,7 +2894,8 @@
case Token::NUMBER: {
Consume(Token::NUMBER);
ASSERT(scanner().is_literal_ascii());
- double value = StringToDouble(scanner().literal_ascii_string(),
+ double value = StringToDouble(isolate()->unicode_cache(),
+ scanner().literal_ascii_string(),
ALLOW_HEX | ALLOW_OCTALS);
result = NewNumberLiteral(value);
break;
@@ -3392,7 +3393,8 @@
case Token::NUMBER: {
Consume(Token::NUMBER);
ASSERT(scanner().is_literal_ascii());
- double value = StringToDouble(scanner().literal_ascii_string(),
+ double value = StringToDouble(isolate()->unicode_cache(),
+ scanner().literal_ascii_string(),
ALLOW_HEX | ALLOW_OCTALS);
key = NewNumberLiteral(value);
break;
@@ -5056,7 +5058,7 @@
bool allow_lazy,
ParserRecorder* recorder) {
Isolate* isolate = Isolate::Current();
- V8JavaScriptScanner scanner(isolate->scanner_constants());
+ V8JavaScriptScanner scanner(isolate->unicode_cache());
scanner.Initialize(source);
intptr_t stack_limit = isolate->stack_guard()->real_climit();
if (!preparser::PreParser::PreParseProgram(&scanner,
diff --git a/src/parser.h b/src/parser.h
index e8cd102..a63651a 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -783,7 +783,7 @@
private:
JsonParser()
: isolate_(Isolate::Current()),
- scanner_(isolate_->scanner_constants()) { }
+ scanner_(isolate_->unicode_cache()) { }
~JsonParser() { }
Isolate* isolate() { return isolate_; }
diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc
index d591b9d..6511328 100644
--- a/src/platform-cygwin.cc
+++ b/src/platform-cygwin.cc
@@ -362,50 +362,17 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
-
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: thread_ = pthread_self(); break;
- case ThreadHandle::INVALID: thread_ = kNoThread; break;
- }
- }
-
+ PlatformData() : thread_(kNoThread) {}
pthread_t thread_; // Thread handle for pthread.
};
-ThreadHandle::ThreadHandle(Kind kind) {
- data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
- delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
- return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
- return data_->thread_ != kNoThread;
-}
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -413,7 +380,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -421,6 +388,7 @@
Thread::~Thread() {
+ delete data_;
}
@@ -429,8 +397,8 @@
// This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new
// one) so we initialize it here too.
- thread->thread_handle_data()->thread_ = pthread_self();
- ASSERT(thread->IsValid());
+ thread->data()->thread_ = pthread_self();
+ ASSERT(thread->data()->thread_ != kNoThread);
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return NULL;
@@ -451,13 +419,13 @@
pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
attr_ptr = &attr;
}
- pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
- ASSERT(IsValid());
+ pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+ ASSERT(data_->thread_ != kNoThread);
}
void Thread::Join() {
- pthread_join(thread_handle_data()->thread_, NULL);
+ pthread_join(data_->thread_, NULL);
}
diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc
index 2a73b6e..ca4e54f 100644
--- a/src/platform-freebsd.cc
+++ b/src/platform-freebsd.cc
@@ -391,18 +391,8 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
-
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: thread_ = pthread_self(); break;
- case ThreadHandle::INVALID: thread_ = kNoThread; break;
- }
- }
pthread_t thread_; // Thread handle for pthread.
};
@@ -433,7 +423,7 @@
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -441,7 +431,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -449,6 +439,7 @@
Thread::~Thread() {
+ delete data_;
}
@@ -457,7 +448,7 @@
// This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new
// one) so we initialize it here too.
- thread->thread_handle_data()->thread_ = pthread_self();
+ thread_->data_->thread_ = pthread_self();
ASSERT(thread->IsValid());
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
diff --git a/src/platform-linux.cc b/src/platform-linux.cc
index 73a6ccb..e2ab9d8 100644
--- a/src/platform-linux.cc
+++ b/src/platform-linux.cc
@@ -92,9 +92,10 @@
uint64_t OS::CpuFeaturesImpliedByPlatform() {
#if (defined(__VFP_FP__) && !defined(__SOFTFP__))
- // Here gcc is telling us that we are on an ARM and gcc is assuming that we
- // have VFP3 instructions. If gcc can assume it then so can we.
- return 1u << VFP3;
+ // Here gcc is telling us that we are on an ARM and gcc is assuming
+ // that we have VFP3 instructions. If gcc can assume it then so can
+ // we. VFPv3 implies ARMv7, see ARM DDI 0406B, page A1-6.
+ return 1u << VFP3 | 1u << ARMv7;
#elif CAN_USE_ARMV7_INSTRUCTIONS
return 1u << ARMv7;
#elif(defined(__mips_hard_float) && __mips_hard_float != 0)
@@ -588,50 +589,15 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
-
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: thread_ = pthread_self(); break;
- case ThreadHandle::INVALID: thread_ = kNoThread; break;
- }
- }
+ PlatformData() : thread_(kNoThread) {}
pthread_t thread_; // Thread handle for pthread.
};
-
-ThreadHandle::ThreadHandle(Kind kind) {
- data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
- delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
- return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
- return data_->thread_ != kNoThread;
-}
-
-
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -639,7 +605,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -647,6 +613,7 @@
Thread::~Thread() {
+ delete data_;
}
@@ -658,8 +625,8 @@
prctl(PR_SET_NAME,
reinterpret_cast<unsigned long>(thread->name()), // NOLINT
0, 0, 0);
- thread->thread_handle_data()->thread_ = pthread_self();
- ASSERT(thread->IsValid());
+ thread->data()->thread_ = pthread_self();
+ ASSERT(thread->data()->thread_ != kNoThread);
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return NULL;
@@ -680,13 +647,13 @@
pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
attr_ptr = &attr;
}
- pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
- ASSERT(IsValid());
+ pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+ ASSERT(data_->thread_ != kNoThread);
}
void Thread::Join() {
- pthread_join(thread_handle_data()->thread_, NULL);
+ pthread_join(data_->thread_, NULL);
}
diff --git a/src/platform-macos.cc b/src/platform-macos.cc
index bfdf3b2..3e10b6a 100644
--- a/src/platform-macos.cc
+++ b/src/platform-macos.cc
@@ -392,50 +392,14 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
-
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: thread_ = pthread_self(); break;
- case ThreadHandle::INVALID: thread_ = kNoThread; break;
- }
- }
+ PlatformData() : thread_(kNoThread) {}
pthread_t thread_; // Thread handle for pthread.
};
-
-
-ThreadHandle::ThreadHandle(Kind kind) {
- data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
- delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
- return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
- return data_->thread_ != kNoThread;
-}
-
-
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -443,7 +407,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -451,6 +415,7 @@
Thread::~Thread() {
+ delete data_;
}
@@ -476,9 +441,9 @@
// This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new
// one) so we initialize it here too.
- thread->thread_handle_data()->thread_ = pthread_self();
+ thread->data()->thread_ = pthread_self();
SetThreadName(thread->name());
- ASSERT(thread->IsValid());
+ ASSERT(thread->data()->thread_ != kNoThread);
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return NULL;
@@ -499,13 +464,13 @@
pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
attr_ptr = &attr;
}
- pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
- ASSERT(IsValid());
+ pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
+ ASSERT(data_->thread_ != kNoThread);
}
void Thread::Join() {
- pthread_join(thread_handle_data()->thread_, NULL);
+ pthread_join(data_->thread_, NULL);
}
diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc
index 5409936..aacad14 100644
--- a/src/platform-nullos.cc
+++ b/src/platform-nullos.cc
@@ -299,9 +299,9 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
+ PlatformData() {
UNIMPLEMENTED();
}
@@ -309,39 +309,8 @@
};
-ThreadHandle::ThreadHandle(Kind kind) {
- UNIMPLEMENTED();
- // Shared setup follows.
- data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- UNIMPLEMENTED();
-}
-
-
-ThreadHandle::~ThreadHandle() {
- UNIMPLEMENTED();
- // Shared tear down follows.
- delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
- UNIMPLEMENTED();
- return false;
-}
-
-
-bool ThreadHandle::IsValid() const {
- UNIMPLEMENTED();
- return false;
-}
-
-
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -350,7 +319,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -359,6 +328,7 @@
Thread::~Thread() {
+ delete data_;
UNIMPLEMENTED();
}
diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc
index fe1a62a..e90b3e8 100644
--- a/src/platform-openbsd.cc
+++ b/src/platform-openbsd.cc
@@ -359,49 +359,16 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
+ PlatformData() : thread_(kNoThread) {}
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: thread_ = pthread_self(); break;
- case ThreadHandle::INVALID: thread_ = kNoThread; break;
- }
- }
pthread_t thread_; // Thread handle for pthread.
};
-ThreadHandle::ThreadHandle(Kind kind) {
- data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
- delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
- return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
- return data_->thread_ != kNoThread;
-}
-
-
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -409,7 +376,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatfromData()),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -417,6 +384,7 @@
Thread::~Thread() {
+ delete data_;
}
@@ -425,8 +393,8 @@
// This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new
// one) so we initialize it here too.
- thread->thread_handle_data()->thread_ = pthread_self();
- ASSERT(thread->IsValid());
+ thread->data()->thread_ = pthread_self();
+ ASSERT(thread->data()->thread_ != kNoThread);
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return NULL;
@@ -447,13 +415,13 @@
pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
attr_ptr = &attr;
}
- pthread_create(&thread_handle_data()->thread_, attr_ptr, ThreadEntry, this);
+ pthread_create(&data_->thread_, attr_ptr, ThreadEntry, this);
ASSERT(IsValid());
}
void Thread::Join() {
- pthread_join(thread_handle_data()->thread_, NULL);
+ pthread_join(data_->thread_, NULL);
}
diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc
index da278f3..1a19bac 100644
--- a/src/platform-solaris.cc
+++ b/src/platform-solaris.cc
@@ -373,50 +373,15 @@
}
-class ThreadHandle::PlatformData : public Malloced {
+class Thread::PlatformData : public Malloced {
public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
-
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: thread_ = pthread_self(); break;
- case ThreadHandle::INVALID: thread_ = kNoThread; break;
- }
- }
+ PlatformData() : thread_(kNoThread) { }
pthread_t thread_; // Thread handle for pthread.
};
-
-ThreadHandle::ThreadHandle(Kind kind) {
- data_ = new PlatformData(kind);
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- data_->Initialize(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
- delete data_;
-}
-
-
-bool ThreadHandle::IsSelf() const {
- return pthread_equal(data_->thread_, pthread_self());
-}
-
-
-bool ThreadHandle::IsValid() const {
- return data_->thread_ != kNoThread;
-}
-
-
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(options.stack_size) {
set_name(options.name);
@@ -424,7 +389,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
+ : data_(new PlatformData()),
isolate_(isolate),
stack_size_(0) {
set_name(name);
@@ -432,6 +397,7 @@
Thread::~Thread() {
+ delete data_;
}
@@ -440,8 +406,8 @@
// This is also initialized by the first argument to pthread_create() but we
// don't know which thread will run first (the original thread or the new
// one) so we initialize it here too.
- thread->thread_handle_data()->thread_ = pthread_self();
- ASSERT(thread->IsValid());
+ thread->data()->thread_ = pthread_self();
+ ASSERT(thread->data()->thread_ != kNoThread);
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return NULL;
@@ -462,13 +428,13 @@
pthread_attr_setstacksize(&attr, static_cast<size_t>(stack_size_));
attr_ptr = &attr;
}
- pthread_create(&thread_handle_data()->thread_, NULL, ThreadEntry, this);
- ASSERT(IsValid());
+ pthread_create(&data_->thread_, NULL, ThreadEntry, this);
+ ASSERT(data_->thread_ != kNoThread);
}
void Thread::Join() {
- pthread_join(thread_handle_data()->thread_, NULL);
+ pthread_join(data_->thread_, NULL);
}
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index ab03e3d..8673f04 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -1468,24 +1468,6 @@
// Definition of invalid thread handle and id.
static const HANDLE kNoThread = INVALID_HANDLE_VALUE;
-static const DWORD kNoThreadId = 0;
-
-
-class ThreadHandle::PlatformData : public Malloced {
- public:
- explicit PlatformData(ThreadHandle::Kind kind) {
- Initialize(kind);
- }
-
- void Initialize(ThreadHandle::Kind kind) {
- switch (kind) {
- case ThreadHandle::SELF: tid_ = GetCurrentThreadId(); break;
- case ThreadHandle::INVALID: tid_ = kNoThreadId; break;
- }
- }
- DWORD tid_; // Win32 thread identifier.
-};
-
// Entry point for threads. The supplied argument is a pointer to the thread
// object. The entry function dispatches to the run method in the thread
@@ -1496,41 +1478,12 @@
// This is also initialized by the last parameter to _beginthreadex() but we
// don't know which thread will run first (the original thread or the new
// one) so we initialize it here too.
- thread->thread_handle_data()->tid_ = GetCurrentThreadId();
Thread::SetThreadLocal(Isolate::isolate_key(), thread->isolate());
thread->Run();
return 0;
}
-// Initialize thread handle to invalid handle.
-ThreadHandle::ThreadHandle(ThreadHandle::Kind kind) {
- data_ = new PlatformData(kind);
-}
-
-
-ThreadHandle::~ThreadHandle() {
- delete data_;
-}
-
-
-// The thread is running if it has the same id as the current thread.
-bool ThreadHandle::IsSelf() const {
- return GetCurrentThreadId() == data_->tid_;
-}
-
-
-// Test for invalid thread handle.
-bool ThreadHandle::IsValid() const {
- return data_->tid_ != kNoThreadId;
-}
-
-
-void ThreadHandle::Initialize(ThreadHandle::Kind kind) {
- data_->Initialize(kind);
-}
-
-
class Thread::PlatformData : public Malloced {
public:
explicit PlatformData(HANDLE thread) : thread_(thread) {}
@@ -1542,8 +1495,7 @@
// handle until it is started.
Thread::Thread(Isolate* isolate, const Options& options)
- : ThreadHandle(ThreadHandle::INVALID),
- isolate_(isolate),
+ : isolate_(isolate),
stack_size_(options.stack_size) {
data_ = new PlatformData(kNoThread);
set_name(options.name);
@@ -1551,8 +1503,7 @@
Thread::Thread(Isolate* isolate, const char* name)
- : ThreadHandle(ThreadHandle::INVALID),
- isolate_(isolate),
+ : isolate_(isolate),
stack_size_(0) {
data_ = new PlatformData(kNoThread);
set_name(name);
@@ -1582,9 +1533,7 @@
ThreadEntry,
this,
0,
- reinterpret_cast<unsigned int*>(
- &thread_handle_data()->tid_)));
- ASSERT(IsValid());
+ NULL));
}
diff --git a/src/platform.h b/src/platform.h
index fea16c8..fc417ef 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -354,40 +354,6 @@
size_t size_; // Size of the virtual memory.
};
-
-// ----------------------------------------------------------------------------
-// ThreadHandle
-//
-// A ThreadHandle represents a thread identifier for a thread. The ThreadHandle
-// does not own the underlying os handle. Thread handles can be used for
-// refering to threads and testing equality.
-
-class ThreadHandle {
- public:
- enum Kind { SELF, INVALID };
- explicit ThreadHandle(Kind kind);
-
- // Destructor.
- ~ThreadHandle();
-
- // Test for thread running.
- bool IsSelf() const;
-
- // Test for valid thread handle.
- bool IsValid() const;
-
- // Get platform-specific data.
- class PlatformData;
- PlatformData* thread_handle_data() { return data_; }
-
- // Initialize the handle to kind
- void Initialize(Kind kind);
-
- private:
- PlatformData* data_; // Captures platform dependent data.
-};
-
-
// ----------------------------------------------------------------------------
// Thread
//
@@ -396,7 +362,7 @@
// thread. The Thread object should not be deallocated before the thread has
// terminated.
-class Thread: public ThreadHandle {
+class Thread {
public:
// Opaque data type for thread-local storage keys.
// LOCAL_STORAGE_KEY_MIN_VALUE and LOCAL_STORAGE_KEY_MAX_VALUE are specified
@@ -468,11 +434,15 @@
// The thread name length is limited to 16 based on Linux's implementation of
// prctl().
static const int kMaxThreadNameLength = 16;
+
+ class PlatformData;
+ PlatformData* data() { return data_; }
+
private:
void set_name(const char *name);
- class PlatformData;
PlatformData* data_;
+
Isolate* isolate_;
char name_[kMaxThreadNameLength];
int stack_size_;
diff --git a/src/preparser-api.cc b/src/preparser-api.cc
index 61e9e7e..9646eb6 100644
--- a/src/preparser-api.cc
+++ b/src/preparser-api.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -159,8 +159,8 @@
class StandAloneJavaScriptScanner : public JavaScriptScanner {
public:
- explicit StandAloneJavaScriptScanner(ScannerConstants* scanner_constants)
- : JavaScriptScanner(scanner_constants) { }
+ explicit StandAloneJavaScriptScanner(UnicodeCache* unicode_cache)
+ : JavaScriptScanner(unicode_cache) { }
void Initialize(UC16CharacterStream* source) {
source_ = source;
@@ -192,8 +192,8 @@
PreParserData Preparse(UnicodeInputStream* input, size_t max_stack) {
internal::InputStreamUTF16Buffer buffer(input);
uintptr_t stack_limit = reinterpret_cast<uintptr_t>(&buffer) - max_stack;
- internal::ScannerConstants scanner_constants;
- internal::StandAloneJavaScriptScanner scanner(&scanner_constants);
+ internal::UnicodeCache unicode_cache;
+ internal::StandAloneJavaScriptScanner scanner(&unicode_cache);
scanner.Initialize(&buffer);
internal::CompleteParserRecorder recorder;
preparser::PreParser::PreParseResult result =
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 6e25169..97f0341 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -107,12 +107,6 @@
}
-static bool IsOptimizable(JSFunction* function) {
- Code* code = function->code();
- return code->kind() == Code::FUNCTION && code->optimizable();
-}
-
-
Atomic32 RuntimeProfiler::state_ = 0;
// TODO(isolates): Create the semaphore lazily and clean it up when no
// longer required.
@@ -120,6 +114,11 @@
Semaphore* RuntimeProfiler::semaphore_ = OS::CreateSemaphore(0);
#endif
+#ifdef DEBUG
+bool RuntimeProfiler::has_been_globally_setup_ = false;
+#endif
+bool RuntimeProfiler::enabled_ = false;
+
RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
: isolate_(isolate),
@@ -140,13 +139,17 @@
}
-bool RuntimeProfiler::IsEnabled() {
- return V8::UseCrankshaft() && FLAG_opt;
+void RuntimeProfiler::GlobalSetup() {
+ ASSERT(!has_been_globally_setup_);
+ enabled_ = V8::UseCrankshaft() && FLAG_opt;
+#ifdef DEBUG
+ has_been_globally_setup_ = true;
+#endif
}
void RuntimeProfiler::Optimize(JSFunction* function, bool eager, int delay) {
- ASSERT(IsOptimizable(function));
+ ASSERT(function->IsOptimizable());
if (FLAG_trace_opt) {
PrintF("[marking (%s) ", eager ? "eagerly" : "lazily");
function->PrintName();
@@ -245,7 +248,7 @@
if (current->IsValid()) {
Handle<JSFunction> function = current->function();
int delay = current->Delay();
- if (IsOptimizable(*function)) {
+ if (function->IsOptimizable()) {
Optimize(*function, true, delay);
}
}
@@ -290,7 +293,7 @@
}
// Do not record non-optimizable functions.
- if (!IsOptimizable(function)) continue;
+ if (!function->IsOptimizable()) continue;
samples[sample_count++] = function;
int function_size = function->shared()->SourceSize();
@@ -330,7 +333,7 @@
void RuntimeProfiler::OptimizeSoon(JSFunction* function) {
- if (!IsOptimizable(function)) return;
+ if (!function->IsOptimizable()) return;
PendingListNode* node = new PendingListNode(function);
node->set_next(optimize_soon_list_);
optimize_soon_list_ = node;
@@ -369,6 +372,7 @@
void RuntimeProfiler::Setup() {
+ ASSERT(has_been_globally_setup_);
ClearSampleBuffer();
// If the ticker hasn't already started, make sure to do so to get
// the ticks for the runtime profiler.
diff --git a/src/runtime-profiler.h b/src/runtime-profiler.h
index 3656893..692b4ff 100644
--- a/src/runtime-profiler.h
+++ b/src/runtime-profiler.h
@@ -44,7 +44,12 @@
public:
explicit RuntimeProfiler(Isolate* isolate);
- static bool IsEnabled();
+ static void GlobalSetup();
+
+ static inline bool IsEnabled() {
+ ASSERT(has_been_globally_setup_);
+ return enabled_;
+ }
void OptimizeNow();
void OptimizeSoon(JSFunction* function);
@@ -143,6 +148,11 @@
// 0 or positive => the number of isolates running JavaScript code.
static Atomic32 state_;
static Semaphore* semaphore_;
+
+#ifdef DEBUG
+ static bool has_been_globally_setup_;
+#endif
+ static bool enabled_;
};
diff --git a/src/runtime.cc b/src/runtime.cc
index c7ff3a3..ceb6c10 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -4680,7 +4680,8 @@
}
// Slower case.
- return isolate->heap()->NumberFromDouble(StringToDouble(subject, ALLOW_HEX));
+ return isolate->heap()->NumberFromDouble(
+ StringToDouble(isolate->unicode_cache(), subject, ALLOW_HEX));
}
@@ -5179,7 +5180,7 @@
s->TryFlatten();
RUNTIME_ASSERT(radix == 0 || (2 <= radix && radix <= 36));
- double value = StringToInt(s, radix);
+ double value = StringToInt(isolate->unicode_cache(), s, radix);
return isolate->heap()->NumberFromDouble(value);
}
@@ -5189,7 +5190,8 @@
CONVERT_CHECKED(String, str, args[0]);
// ECMA-262 section 15.1.2.3, empty string is NaN
- double value = StringToDouble(str, ALLOW_TRAILING_JUNK, OS::nan_value());
+ double value = StringToDouble(isolate->unicode_cache(),
+ str, ALLOW_TRAILING_JUNK, OS::nan_value());
// Create a number object from the value.
return isolate->heap()->NumberFromDouble(value);
@@ -7405,6 +7407,16 @@
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_OptimizeFunctionOnNextCall) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSFunction, function, 0);
+ if (!function->IsOptimizable()) return isolate->heap()->undefined_value();
+ function->MarkForLazyRecompilation();
+ return isolate->heap()->undefined_value();
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
HandleScope scope(isolate);
ASSERT(args.length() == 1);
@@ -8069,10 +8081,14 @@
RUNTIME_ASSERT(output_array->length() >= DateParser::OUTPUT_SIZE);
bool result;
if (str->IsAsciiRepresentation()) {
- result = DateParser::Parse(str->ToAsciiVector(), output_array);
+ result = DateParser::Parse(str->ToAsciiVector(),
+ output_array,
+ isolate->unicode_cache());
} else {
ASSERT(str->IsTwoByteRepresentation());
- result = DateParser::Parse(str->ToUC16Vector(), output_array);
+ result = DateParser::Parse(str->ToUC16Vector(),
+ output_array,
+ isolate->unicode_cache());
}
if (result) {
@@ -10161,8 +10177,7 @@
details->set(kThreadDetailsCurrentThreadIndex,
isolate->heap()->true_value());
details->set(kThreadDetailsThreadIdIndex,
- Smi::FromInt(
- isolate->thread_manager()->CurrentId()));
+ Smi::FromInt(ThreadId::Current().ToInteger()));
} else {
// Find the thread with the requested index.
int n = 1;
@@ -10179,7 +10194,8 @@
// Fill the details.
details->set(kThreadDetailsCurrentThreadIndex,
isolate->heap()->false_value());
- details->set(kThreadDetailsThreadIdIndex, Smi::FromInt(thread->id()));
+ details->set(kThreadDetailsThreadIdIndex,
+ Smi::FromInt(thread->id().ToInteger()));
}
// Convert to JS array and return.
diff --git a/src/runtime.h b/src/runtime.h
index 58062ca..bf1ba68 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -84,7 +84,8 @@
F(LazyRecompile, 1, 1) \
F(NotifyDeoptimized, 1, 1) \
F(NotifyOSR, 0, 1) \
- F(DeoptimizeFunction, 1, 1) \
+ F(DeoptimizeFunction, 1, 1) \
+ F(OptimizeFunctionOnNextCall, 1, 1) \
F(CompileForOnStackReplacement, 1, 1) \
F(SetNewFunctionAttributes, 1, 1) \
F(AllocateInNewSpace, 1, 1) \
diff --git a/src/scanner-base.cc b/src/scanner-base.cc
index 2066b5a..9715ca9 100644
--- a/src/scanner-base.cc
+++ b/src/scanner-base.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -35,29 +35,11 @@
namespace internal {
// ----------------------------------------------------------------------------
-// Compound predicates.
-
-bool ScannerConstants::IsIdentifier(unibrow::CharacterStream* buffer) {
- // Checks whether the buffer contains an identifier (no escape).
- if (!buffer->has_more()) return false;
- if (!kIsIdentifierStart.get(buffer->GetNext())) {
- return false;
- }
- while (buffer->has_more()) {
- if (!kIsIdentifierPart.get(buffer->GetNext())) {
- return false;
- }
- }
- return true;
-}
-
-// ----------------------------------------------------------------------------
// Scanner
-Scanner::Scanner(ScannerConstants* scanner_constants)
- : scanner_constants_(scanner_constants),
- octal_pos_(kNoOctalLocation) {
-}
+Scanner::Scanner(UnicodeCache* unicode_cache)
+ : unicode_cache_(unicode_cache),
+ octal_pos_(kNoOctalLocation) { }
uc32 Scanner::ScanHexEscape(uc32 c, int length) {
@@ -114,7 +96,7 @@
// ----------------------------------------------------------------------------
// JavaScriptScanner
-JavaScriptScanner::JavaScriptScanner(ScannerConstants* scanner_contants)
+JavaScriptScanner::JavaScriptScanner(UnicodeCache* scanner_contants)
: Scanner(scanner_contants) { }
@@ -144,9 +126,9 @@
while (true) {
// We treat byte-order marks (BOMs) as whitespace for better
// compatibility with Spidermonkey and other JavaScript engines.
- while (scanner_constants_->IsWhiteSpace(c0_) || IsByteOrderMark(c0_)) {
+ while (unicode_cache_->IsWhiteSpace(c0_) || IsByteOrderMark(c0_)) {
// IsWhiteSpace() includes line terminators!
- if (scanner_constants_->IsLineTerminator(c0_)) {
+ if (unicode_cache_->IsLineTerminator(c0_)) {
// Ignore line terminators, but remember them. This is necessary
// for automatic semicolon insertion.
has_line_terminator_before_next_ = true;
@@ -186,7 +168,7 @@
// separately by the lexical grammar and becomes part of the
// stream of input elements for the syntactic grammar (see
// ECMA-262, section 7.4, page 12).
- while (c0_ >= 0 && !scanner_constants_->IsLineTerminator(c0_)) {
+ while (c0_ >= 0 && !unicode_cache_->IsLineTerminator(c0_)) {
Advance();
}
@@ -451,7 +433,7 @@
break;
default:
- if (scanner_constants_->IsIdentifierStart(c0_)) {
+ if (unicode_cache_->IsIdentifierStart(c0_)) {
token = ScanIdentifierOrKeyword();
} else if (IsDecimalDigit(c0_)) {
token = ScanNumber(false);
@@ -499,7 +481,7 @@
Advance();
// Skip escaped newlines.
- if (scanner_constants_->IsLineTerminator(c)) {
+ if (unicode_cache_->IsLineTerminator(c)) {
// Allow CR+LF newlines in multiline string literals.
if (IsCarriageReturn(c) && IsLineFeed(c0_)) Advance();
// Allow LF+CR newlines in multiline string literals.
@@ -542,7 +524,7 @@
LiteralScope literal(this);
while (c0_ != quote && c0_ >= 0
- && !scanner_constants_->IsLineTerminator(c0_)) {
+ && !unicode_cache_->IsLineTerminator(c0_)) {
uc32 c = c0_;
Advance();
if (c == '\\') {
@@ -641,7 +623,7 @@
// not be an identifier start or a decimal digit; see ECMA-262
// section 7.8.3, page 17 (note that we read only one decimal digit
// if the value is 0).
- if (IsDecimalDigit(c0_) || scanner_constants_->IsIdentifierStart(c0_))
+ if (IsDecimalDigit(c0_) || unicode_cache_->IsIdentifierStart(c0_))
return Token::ILLEGAL;
literal.Complete();
@@ -663,14 +645,14 @@
Token::Value JavaScriptScanner::ScanIdentifierOrKeyword() {
- ASSERT(scanner_constants_->IsIdentifierStart(c0_));
+ ASSERT(unicode_cache_->IsIdentifierStart(c0_));
LiteralScope literal(this);
KeywordMatcher keyword_match;
// Scan identifier start character.
if (c0_ == '\\') {
uc32 c = ScanIdentifierUnicodeEscape();
// Only allow legal identifier start characters.
- if (!scanner_constants_->IsIdentifierStart(c)) return Token::ILLEGAL;
+ if (!unicode_cache_->IsIdentifierStart(c)) return Token::ILLEGAL;
AddLiteralChar(c);
return ScanIdentifierSuffix(&literal);
}
@@ -683,7 +665,7 @@
}
// Scan the rest of the identifier characters.
- while (scanner_constants_->IsIdentifierPart(c0_)) {
+ while (unicode_cache_->IsIdentifierPart(c0_)) {
if (c0_ != '\\') {
uc32 next_char = c0_;
Advance();
@@ -701,11 +683,11 @@
Token::Value JavaScriptScanner::ScanIdentifierSuffix(LiteralScope* literal) {
// Scan the rest of the identifier characters.
- while (scanner_constants_->IsIdentifierPart(c0_)) {
+ while (unicode_cache_->IsIdentifierPart(c0_)) {
if (c0_ == '\\') {
uc32 c = ScanIdentifierUnicodeEscape();
// Only allow legal identifier part characters.
- if (!scanner_constants_->IsIdentifierPart(c)) return Token::ILLEGAL;
+ if (!unicode_cache_->IsIdentifierPart(c)) return Token::ILLEGAL;
AddLiteralChar(c);
} else {
AddLiteralChar(c0_);
@@ -735,10 +717,10 @@
AddLiteralChar('=');
while (c0_ != '/' || in_character_class) {
- if (scanner_constants_->IsLineTerminator(c0_) || c0_ < 0) return false;
+ if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
if (c0_ == '\\') { // Escape sequence.
AddLiteralCharAdvance();
- if (scanner_constants_->IsLineTerminator(c0_) || c0_ < 0) return false;
+ if (unicode_cache_->IsLineTerminator(c0_) || c0_ < 0) return false;
AddLiteralCharAdvance();
// If the escape allows more characters, i.e., \x??, \u????, or \c?,
// only "safe" characters are allowed (letters, digits, underscore),
@@ -764,7 +746,7 @@
bool JavaScriptScanner::ScanRegExpFlags() {
// Scan regular expression flags.
LiteralScope literal(this);
- while (scanner_constants_->IsIdentifierPart(c0_)) {
+ while (unicode_cache_->IsIdentifierPart(c0_)) {
if (c0_ == '\\') {
uc32 c = ScanIdentifierUnicodeEscape();
if (c != static_cast<uc32>(unibrow::Utf8::kBadChar)) {
diff --git a/src/scanner-base.h b/src/scanner-base.h
index 552f387..60b97d2 100644
--- a/src/scanner-base.h
+++ b/src/scanner-base.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -119,11 +119,11 @@
};
-class ScannerConstants {
+class UnicodeCache {
// ---------------------------------------------------------------------
-// Constants used by scanners.
+// Caching predicates used by scanners.
public:
- ScannerConstants() {}
+ UnicodeCache() {}
typedef unibrow::Utf8InputBuffer<1024> Utf8Decoder;
StaticResource<Utf8Decoder>* utf8_decoder() {
@@ -135,8 +135,6 @@
bool IsLineTerminator(unibrow::uchar c) { return kIsLineTerminator.get(c); }
bool IsWhiteSpace(unibrow::uchar c) { return kIsWhiteSpace.get(c); }
- bool IsIdentifier(unibrow::CharacterStream* buffer);
-
private:
unibrow::Predicate<IdentifierStart, 128> kIsIdentifierStart;
@@ -145,9 +143,10 @@
unibrow::Predicate<unibrow::WhiteSpace, 128> kIsWhiteSpace;
StaticResource<Utf8Decoder> utf8_decoder_;
- DISALLOW_COPY_AND_ASSIGN(ScannerConstants);
+ DISALLOW_COPY_AND_ASSIGN(UnicodeCache);
};
+
// ----------------------------------------------------------------------------
// LiteralBuffer - Collector of chars of literals.
@@ -272,7 +271,7 @@
bool complete_;
};
- explicit Scanner(ScannerConstants* scanner_contants);
+ explicit Scanner(UnicodeCache* scanner_contants);
// Returns the current token again.
Token::Value current_token() { return current_.token; }
@@ -427,7 +426,7 @@
return source_->pos() - kCharacterLookaheadBufferSize;
}
- ScannerConstants* scanner_constants_;
+ UnicodeCache* unicode_cache_;
// Buffers collecting literal strings, numbers, etc.
LiteralBuffer literal_buffer1_;
@@ -473,7 +472,7 @@
bool complete_;
};
- explicit JavaScriptScanner(ScannerConstants* scanner_contants);
+ explicit JavaScriptScanner(UnicodeCache* scanner_contants);
// Returns the next token.
Token::Value Next();
diff --git a/src/scanner.cc b/src/scanner.cc
index d9c2188..666818e 100755
--- a/src/scanner.cc
+++ b/src/scanner.cc
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -345,8 +345,8 @@
// ----------------------------------------------------------------------------
// JsonScanner
-JsonScanner::JsonScanner(ScannerConstants* scanner_constants)
- : Scanner(scanner_constants) { }
+JsonScanner::JsonScanner(UnicodeCache* unicode_cache)
+ : Scanner(unicode_cache) { }
void JsonScanner::Initialize(UC16CharacterStream* source) {
@@ -560,7 +560,8 @@
}
literal.Complete();
ASSERT_NOT_NULL(next_.literal_chars);
- number_ = StringToDouble(next_.literal_chars->ascii_literal(),
+ number_ = StringToDouble(unicode_cache_,
+ next_.literal_chars->ascii_literal(),
NO_FLAGS, // Hex, octal or trailing junk.
OS::nan_value());
return Token::NUMBER;
@@ -575,7 +576,7 @@
Advance();
text++;
}
- if (scanner_constants_->IsIdentifierPart(c0_)) return Token::ILLEGAL;
+ if (unicode_cache_->IsIdentifierPart(c0_)) return Token::ILLEGAL;
literal.Complete();
return token;
}
diff --git a/src/scanner.h b/src/scanner.h
index 776ba53..871c69b 100644
--- a/src/scanner.h
+++ b/src/scanner.h
@@ -1,4 +1,4 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
+// Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -134,8 +134,8 @@
class V8JavaScriptScanner : public JavaScriptScanner {
public:
- explicit V8JavaScriptScanner(ScannerConstants* scanner_constants)
- : JavaScriptScanner(scanner_constants) {}
+ explicit V8JavaScriptScanner(UnicodeCache* unicode_cache)
+ : JavaScriptScanner(unicode_cache) {}
void Initialize(UC16CharacterStream* source);
};
@@ -143,7 +143,7 @@
class JsonScanner : public Scanner {
public:
- explicit JsonScanner(ScannerConstants* scanner_constants);
+ explicit JsonScanner(UnicodeCache* unicode_cache);
void Initialize(UC16CharacterStream* source);
diff --git a/src/top.cc b/src/top.cc
index 8611a31..899dfbe 100644
--- a/src/top.cc
+++ b/src/top.cc
@@ -69,10 +69,8 @@
#endif
try_catch_handler_address_ = NULL;
context_ = NULL;
- int id = Isolate::Current()->thread_manager()->CurrentId();
- thread_id_ = (id == 0) ? ThreadManager::kInvalidId : id;
+ thread_id_ = ThreadId::Current();
external_caught_exception_ = false;
- in_exception_reporting_ = false;
failed_access_check_callback_ = NULL;
save_context_ = NULL;
catcher_ = NULL;
diff --git a/src/v8.cc b/src/v8.cc
index 19ed184..0b562fc 100644
--- a/src/v8.cc
+++ b/src/v8.cc
@@ -63,8 +63,8 @@
}
ASSERT(i::Isolate::CurrentPerIsolateThreadData() != NULL);
- ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id() ==
- i::Thread::GetThreadLocalInt(i::Isolate::thread_id_key()));
+ ASSERT(i::Isolate::CurrentPerIsolateThreadData()->thread_id().Equals(
+ i::ThreadId::Current()));
ASSERT(i::Isolate::CurrentPerIsolateThreadData()->isolate() ==
i::Isolate::Current());
@@ -204,6 +204,8 @@
use_crankshaft_ = false;
}
+ RuntimeProfiler::GlobalSetup();
+
// Peephole optimization might interfere with deoptimization.
FLAG_peephole_optimization = !use_crankshaft_;
}
diff --git a/src/v8threads.cc b/src/v8threads.cc
index cecafaa..4b033fc 100644
--- a/src/v8threads.cc
+++ b/src/v8threads.cc
@@ -147,11 +147,11 @@
// First check whether the current thread has been 'lazily archived', ie
// not archived at all. If that is the case we put the state storage we
// had prepared back in the free list, since we didn't need it after all.
- if (lazily_archived_thread_.IsSelf()) {
- lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
+ if (lazily_archived_thread_.Equals(ThreadId::Current())) {
+ lazily_archived_thread_ = ThreadId::Invalid();
ASSERT(Isolate::CurrentPerIsolateThreadData()->thread_state() ==
lazily_archived_thread_state_);
- lazily_archived_thread_state_->set_id(kInvalidId);
+ lazily_archived_thread_state_->set_id(ThreadId::Invalid());
lazily_archived_thread_state_->LinkInto(ThreadState::FREE_LIST);
lazily_archived_thread_state_ = NULL;
Isolate::CurrentPerIsolateThreadData()->set_thread_state(NULL);
@@ -190,7 +190,7 @@
isolate_->stack_guard()->TerminateExecution();
state->set_terminate_on_restore(false);
}
- state->set_id(kInvalidId);
+ state->set_id(ThreadId::Invalid());
state->Unlink();
state->LinkInto(ThreadState::FREE_LIST);
return true;
@@ -199,13 +199,13 @@
void ThreadManager::Lock() {
mutex_->Lock();
- mutex_owner_.Initialize(ThreadHandle::SELF);
+ mutex_owner_ = ThreadId::Current();
ASSERT(IsLockedByCurrentThread());
}
void ThreadManager::Unlock() {
- mutex_owner_.Initialize(ThreadHandle::INVALID);
+ mutex_owner_ = ThreadId::Invalid();
mutex_->Unlock();
}
@@ -224,7 +224,7 @@
ThreadState::ThreadState(ThreadManager* thread_manager)
- : id_(ThreadManager::kInvalidId),
+ : id_(ThreadId::Invalid()),
terminate_on_restore_(false),
next_(this),
previous_(this),
@@ -282,8 +282,8 @@
// defined as 0.)
ThreadManager::ThreadManager()
: mutex_(OS::CreateMutex()),
- mutex_owner_(ThreadHandle::INVALID),
- lazily_archived_thread_(ThreadHandle::INVALID),
+ mutex_owner_(ThreadId::Invalid()),
+ lazily_archived_thread_(ThreadId::Invalid()),
lazily_archived_thread_state_(NULL),
free_anchor_(NULL),
in_use_anchor_(NULL) {
@@ -298,16 +298,16 @@
void ThreadManager::ArchiveThread() {
- ASSERT(!lazily_archived_thread_.IsValid());
+ ASSERT(lazily_archived_thread_.Equals(ThreadId::Invalid()));
ASSERT(!IsArchived());
ThreadState* state = GetFreeThreadState();
state->Unlink();
Isolate::CurrentPerIsolateThreadData()->set_thread_state(state);
- lazily_archived_thread_.Initialize(ThreadHandle::SELF);
+ lazily_archived_thread_ = ThreadId::Current();
lazily_archived_thread_state_ = state;
- ASSERT(state->id() == kInvalidId);
+ ASSERT(state->id().Equals(ThreadId::Invalid()));
state->set_id(CurrentId());
- ASSERT(state->id() != kInvalidId);
+ ASSERT(!state->id().Equals(ThreadId::Invalid()));
}
@@ -326,7 +326,7 @@
to = isolate_->stack_guard()->ArchiveStackGuard(to);
to = isolate_->regexp_stack()->ArchiveStack(to);
to = isolate_->bootstrapper()->ArchiveState(to);
- lazily_archived_thread_.Initialize(ThreadHandle::INVALID);
+ lazily_archived_thread_ = ThreadId::Invalid();
lazily_archived_thread_state_ = NULL;
}
@@ -373,16 +373,16 @@
}
-int ThreadManager::CurrentId() {
- return Thread::GetThreadLocalInt(Isolate::thread_id_key());
+ThreadId ThreadManager::CurrentId() {
+ return ThreadId::Current();
}
-void ThreadManager::TerminateExecution(int thread_id) {
+void ThreadManager::TerminateExecution(ThreadId thread_id) {
for (ThreadState* state = FirstThreadStateInUse();
state != NULL;
state = state->Next()) {
- if (thread_id == state->id()) {
+ if (thread_id.Equals(state->id())) {
state->set_terminate_on_restore(true);
}
}
diff --git a/src/v8threads.h b/src/v8threads.h
index 1266af7..d8a923e 100644
--- a/src/v8threads.h
+++ b/src/v8threads.h
@@ -43,8 +43,8 @@
void Unlink();
// Id of thread.
- void set_id(int id) { id_ = id; }
- int id() { return id_; }
+ void set_id(ThreadId id) { id_ = id; }
+ ThreadId id() { return id_; }
// Should the thread be terminated when it is restored?
bool terminate_on_restore() { return terminate_on_restore_; }
@@ -59,7 +59,7 @@
void AllocateSpace();
- int id_;
+ ThreadId id_;
bool terminate_on_restore_;
char* data_;
ThreadState* next_;
@@ -97,17 +97,18 @@
void Iterate(ObjectVisitor* v);
void IterateArchivedThreads(ThreadVisitor* v);
- bool IsLockedByCurrentThread() { return mutex_owner_.IsSelf(); }
+ bool IsLockedByCurrentThread() {
+ return mutex_owner_.Equals(ThreadId::Current());
+ }
- int CurrentId();
+ ThreadId CurrentId();
- void TerminateExecution(int thread_id);
+ void TerminateExecution(ThreadId thread_id);
// Iterate over in-use states.
ThreadState* FirstThreadStateInUse();
ThreadState* GetFreeThreadState();
- static const int kInvalidId = -1;
private:
ThreadManager();
~ThreadManager();
@@ -115,8 +116,8 @@
void EagerlyArchiveThread();
Mutex* mutex_;
- ThreadHandle mutex_owner_;
- ThreadHandle lazily_archived_thread_;
+ ThreadId mutex_owner_;
+ ThreadId lazily_archived_thread_;
ThreadState* lazily_archived_thread_state_;
// In the following two lists there is always at least one object on the list.
diff --git a/src/version.cc b/src/version.cc
index 120e564..c5ded6d 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -34,8 +34,8 @@
// cannot be changed without changing the SCons build script.
#define MAJOR_VERSION 3
#define MINOR_VERSION 2
-#define BUILD_NUMBER 9
-#define PATCH_LEVEL 1
+#define BUILD_NUMBER 10
+#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
diff --git a/src/x64/assembler-x64.cc b/src/x64/assembler-x64.cc
index 0ab676f..9fe212e 100644
--- a/src/x64/assembler-x64.cc
+++ b/src/x64/assembler-x64.cc
@@ -99,7 +99,7 @@
// ecx:edx. Temporarily enable CPUID support because we know it's
// safe here.
__ bind(&cpuid);
- __ movq(rax, Immediate(1));
+ __ movl(rax, Immediate(1));
supported_ = kDefaultCpuFeatures | (1 << CPUID);
{ Scope fscope(CPUID);
__ cpuid();
@@ -1398,7 +1398,12 @@
void Assembler::movb(Register dst, const Operand& src) {
EnsureSpace ensure_space(this);
- emit_rex_32(dst, src);
+ if (dst.code() > 3) {
+ // Register is not one of al, bl, cl, dl. Its encoding needs REX.
+ emit_rex_32(dst, src);
+ } else {
+ emit_optional_rex_32(dst, src);
+ }
emit(0x8A);
emit_operand(dst, src);
}
@@ -1406,16 +1411,21 @@
void Assembler::movb(Register dst, Immediate imm) {
EnsureSpace ensure_space(this);
- emit_rex_32(dst);
- emit(0xC6);
- emit_modrm(0x0, dst);
+ if (dst.code() > 3) {
+ emit_rex_32(dst);
+ }
+ emit(0xB0 + dst.low_bits());
emit(imm.value_);
}
void Assembler::movb(const Operand& dst, Register src) {
EnsureSpace ensure_space(this);
- emit_rex_32(src, dst);
+ if (src.code() > 3) {
+ emit_rex_32(src, dst);
+ } else {
+ emit_optional_rex_32(src, dst);
+ }
emit(0x88);
emit_operand(src, dst);
}
@@ -1465,16 +1475,15 @@
emit_optional_rex_32(dst);
emit(0xC7);
emit_operand(0x0, dst);
- emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
+ emit(value);
}
void Assembler::movl(Register dst, Immediate value) {
EnsureSpace ensure_space(this);
emit_optional_rex_32(dst);
- emit(0xC7);
- emit_modrm(0x0, dst);
- emit(value); // Only 32-bit immediates are possible, not 8-bit immediates.
+ emit(0xB8 + dst.low_bits());
+ emit(value);
}
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index fc3257d..a549633 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -96,7 +96,7 @@
// rax: number of arguments
__ bind(&non_function_call);
// Set expected number of arguments to zero (not changing rax).
- __ movq(rbx, Immediate(0));
+ __ Set(rbx, 0);
__ GetBuiltinEntry(rdx, Builtins::CALL_NON_FUNCTION_AS_CONSTRUCTOR);
__ Jump(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
RelocInfo::CODE_TARGET);
@@ -1372,7 +1372,7 @@
// Copy receiver and all expected arguments.
const int offset = StandardFrameConstants::kCallerSPOffset;
__ lea(rax, Operand(rbp, rax, times_pointer_size, offset));
- __ movq(rcx, Immediate(-1)); // account for receiver
+ __ Set(rcx, -1); // account for receiver
Label copy;
__ bind(©);
@@ -1391,7 +1391,7 @@
// Copy receiver and all actual arguments.
const int offset = StandardFrameConstants::kCallerSPOffset;
__ lea(rdi, Operand(rbp, rax, times_pointer_size, offset));
- __ movq(rcx, Immediate(-1)); // account for receiver
+ __ Set(rcx, -1); // account for receiver
Label copy;
__ bind(©);
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index f2f0fc6..11727a0 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -273,7 +273,7 @@
// Return 1/0 for true/false in rax.
__ bind(&true_result);
- __ movq(rax, Immediate(1));
+ __ Set(rax, 1);
__ ret(1 * kPointerSize);
__ bind(&false_result);
__ Set(rax, 0);
@@ -1281,7 +1281,7 @@
__ bind(&check_undefined_arg1);
__ CompareRoot(rdx, Heap::kUndefinedValueRootIndex);
__ j(not_equal, conversion_failure);
- __ movl(r8, Immediate(0));
+ __ Set(r8, 0);
__ jmp(&load_arg2);
__ bind(&arg1_is_object);
@@ -1301,7 +1301,7 @@
__ bind(&check_undefined_arg2);
__ CompareRoot(rax, Heap::kUndefinedValueRootIndex);
__ j(not_equal, conversion_failure);
- __ movl(rcx, Immediate(0));
+ __ Set(rcx, 0);
__ jmp(&done);
__ bind(&arg2_is_object);
@@ -1458,7 +1458,7 @@
__ j(not_equal, &slow);
// Operand is a float, negate its value by flipping sign bit.
__ movq(rdx, FieldOperand(rax, HeapNumber::kValueOffset));
- __ movq(kScratchRegister, Immediate(0x01));
+ __ Set(kScratchRegister, 0x01);
__ shl(kScratchRegister, Immediate(63));
__ xor_(rdx, kScratchRegister); // Flip sign.
// rdx is value to store.
@@ -1530,7 +1530,7 @@
__ movq(rax, Operand(rsp, 1 * kPointerSize));
// Save 1 in xmm3 - we need this several times later on.
- __ movl(rcx, Immediate(1));
+ __ Set(rcx, 1);
__ cvtlsi2sd(xmm3, rcx);
Label exponent_nonsmi;
@@ -3253,7 +3253,7 @@
__ cmpl(Operand(kScratchRegister, kOffsetToResultValue - 4), rax);
__ Assert(equal, "InstanceofStub unexpected call site cache (mov).");
}
- __ xorl(rax, rax);
+ __ Set(rax, 0);
}
__ ret(2 * kPointerSize + extra_stack_space);
@@ -4112,7 +4112,7 @@
// if (hash == 0) hash = 27;
Label hash_not_zero;
__ j(not_zero, &hash_not_zero);
- __ movl(hash, Immediate(27));
+ __ Set(hash, 27);
__ bind(&hash_not_zero);
}
@@ -4308,7 +4308,7 @@
// Use scratch3 as loop index, min_length as limit and scratch2
// for computation.
const Register index = scratch3;
- __ movl(index, Immediate(0)); // Index into strings.
+ __ Set(index, 0); // Index into strings.
__ bind(&loop);
// Compare characters.
// TODO(lrn): Could we load more than one character at a time?
diff --git a/src/x64/deoptimizer-x64.cc b/src/x64/deoptimizer-x64.cc
index ffd84ef..abac2b6 100644
--- a/src/x64/deoptimizer-x64.cc
+++ b/src/x64/deoptimizer-x64.cc
@@ -665,7 +665,7 @@
__ PrepareCallCFunction(6);
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
__ movq(arg1, rax);
- __ movq(arg2, Immediate(type()));
+ __ Set(arg2, type());
// Args 3 and 4 are already in the right registers.
// On windows put the arguments on the stack (PrepareCallCFunction
diff --git a/src/x64/disasm-x64.cc b/src/x64/disasm-x64.cc
index 189ee42..2b7b7b7 100644
--- a/src/x64/disasm-x64.cc
+++ b/src/x64/disasm-x64.cc
@@ -652,6 +652,9 @@
case 2:
mnem = "adc";
break;
+ case 3:
+ mnem = "sbb";
+ break;
case 4:
mnem = "and";
break;
@@ -1502,7 +1505,39 @@
data++;
}
break;
-
+ case 0xB0:
+ case 0xB1:
+ case 0xB2:
+ case 0xB3:
+ case 0xB4:
+ case 0xB5:
+ case 0xB6:
+ case 0xB7:
+ case 0xB8:
+ case 0xB9:
+ case 0xBA:
+ case 0xBB:
+ case 0xBC:
+ case 0xBD:
+ case 0xBE:
+ case 0xBF: {
+ // mov reg8,imm8 or mov reg32,imm32
+ byte opcode = *data;
+ data++;
+ bool is_32bit = (opcode >= 0xB8);
+ int reg = (opcode & 0x7) | (rex_b() ? 8 : 0);
+ if (is_32bit) {
+ AppendToBuffer("mov%c %s, ",
+ operand_size_code(),
+ NameOfCPURegister(reg));
+ data += PrintImmediate(data, DOUBLEWORD_SIZE);
+ } else {
+ AppendToBuffer("movb %s, ",
+ NameOfByteCPURegister(reg));
+ data += PrintImmediate(data, BYTE_SIZE);
+ }
+ break;
+ }
case 0xFE: {
data++;
int mod, regop, rm;
@@ -1513,9 +1548,8 @@
} else {
UnimplementedInstruction();
}
- }
break;
-
+ }
case 0x68:
AppendToBuffer("push 0x%x", *reinterpret_cast<int32_t*>(data + 1));
data += 5;
diff --git a/src/x64/ic-x64.cc b/src/x64/ic-x64.cc
index 38c85f0..5ca56ac 100644
--- a/src/x64/ic-x64.cc
+++ b/src/x64/ic-x64.cc
@@ -1010,7 +1010,7 @@
// Call the entry.
CEntryStub stub(1);
- __ movq(rax, Immediate(2));
+ __ Set(rax, 2);
__ LoadAddress(rbx, ExternalReference(IC_Utility(id), masm->isolate()));
__ CallStub(&stub);
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 56e6cc2..202e7a2 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -149,7 +149,7 @@
int slots = StackSlotCount();
if (slots > 0) {
if (FLAG_debug_code) {
- __ movl(rax, Immediate(slots));
+ __ Set(rax, slots);
__ movq(kScratchRegister, kSlotsZapValue, RelocInfo::NONE);
Label loop;
__ bind(&loop);
@@ -1099,7 +1099,7 @@
void LCodeGen::DoConstantI(LConstantI* instr) {
ASSERT(instr->result()->IsRegister());
- __ movl(ToRegister(instr->result()), Immediate(instr->value()));
+ __ Set(ToRegister(instr->result()), instr->value());
}
@@ -1514,10 +1514,11 @@
__ CompareRoot(reg, Heap::kNullValueRootIndex);
if (instr->is_strict()) {
+ ASSERT(Heap::kTrueValueRootIndex >= 0);
__ movl(result, Immediate(Heap::kTrueValueRootIndex));
NearLabel load;
__ j(equal, &load);
- __ movl(result, Immediate(Heap::kFalseValueRootIndex));
+ __ Set(result, Heap::kFalseValueRootIndex);
__ bind(&load);
__ LoadRootIndexed(result, result, 0);
} else {
@@ -1976,11 +1977,11 @@
__ Push(instr->function());
Register temp = ToRegister(instr->TempAt(0));
- static const int kAdditionalDelta = 13;
+ static const int kAdditionalDelta = 10;
int delta =
masm_->SizeOfCodeGeneratedSince(map_check) + kAdditionalDelta;
- __ movq(temp, Immediate(delta));
- __ push(temp);
+ ASSERT(delta >= 0);
+ __ push_imm32(delta);
// We are pushing three values on the stack but recording a
// safepoint with two arguments because stub is going to
@@ -1992,6 +1993,8 @@
RECORD_SAFEPOINT_WITH_REGISTERS,
2);
ASSERT(delta == masm_->SizeOfCodeGeneratedSince(map_check));
+ // Move result to a register that survives the end of the
+ // PushSafepointRegisterScope.
__ movq(kScratchRegister, rax);
}
__ testq(kScratchRegister, kScratchRegister);
@@ -2426,14 +2429,14 @@
} else {
__ cmpq(rbp, ToOperand(instr->InputAt(0)));
}
- __ movq(result, Immediate(scope()->num_parameters()));
+ __ movl(result, Immediate(scope()->num_parameters()));
__ j(equal, &done);
// Arguments adaptor frame present. Get argument length from there.
__ movq(result, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
- __ movq(result, Operand(result,
- ArgumentsAdaptorFrameConstants::kLengthOffset));
- __ SmiToInteger32(result, result);
+ __ SmiToInteger32(result,
+ Operand(result,
+ ArgumentsAdaptorFrameConstants::kLengthOffset));
// Argument length is in result register.
__ bind(&done);
@@ -3415,7 +3418,7 @@
// conversions.
__ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
DeoptimizeIf(not_equal, instr->environment());
- __ movl(input_reg, Immediate(0));
+ __ Set(input_reg, 0);
__ jmp(&done);
__ bind(&heap_number);
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index b097166..7f027f7 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -788,10 +788,10 @@
void MacroAssembler::Set(Register dst, int64_t x) {
if (x == 0) {
xorl(dst, dst);
- } else if (is_int32(x)) {
- movq(dst, Immediate(static_cast<int32_t>(x)));
} else if (is_uint32(x)) {
movl(dst, Immediate(static_cast<uint32_t>(x)));
+ } else if (is_int32(x)) {
+ movq(dst, Immediate(static_cast<int32_t>(x)));
} else {
movq(dst, x, RelocInfo::NONE);
}
@@ -801,7 +801,7 @@
if (is_int32(x)) {
movq(dst, Immediate(static_cast<int32_t>(x)));
} else {
- movq(kScratchRegister, x, RelocInfo::NONE);
+ Set(kScratchRegister, x);
movq(dst, kScratchRegister);
}
}
@@ -1814,7 +1814,7 @@
// Set external caught exception to false.
ExternalReference external_caught(
Isolate::k_external_caught_exception_address, isolate());
- movq(rax, Immediate(false));
+ Set(rax, static_cast<int64_t>(false));
Store(external_caught, rax);
// Set pending exception and rax to out of memory exception.
@@ -2002,7 +2002,7 @@
void MacroAssembler::SetCounter(StatsCounter* counter, int value) {
if (FLAG_native_code_counters && counter->Enabled()) {
Operand counter_operand = ExternalOperand(ExternalReference(counter));
- movq(counter_operand, Immediate(value));
+ movl(counter_operand, Immediate(value));
}
}
@@ -2220,8 +2220,8 @@
const int kFrameAlignment = OS::ActivationFrameAlignment();
if (kFrameAlignment > 0) {
ASSERT(IsPowerOf2(kFrameAlignment));
- movq(kScratchRegister, Immediate(-kFrameAlignment));
- and_(rsp, kScratchRegister);
+ ASSERT(is_int8(kFrameAlignment));
+ and_(rsp, Immediate(-kFrameAlignment));
}
// Patch the saved entry sp.
diff --git a/src/x64/regexp-macro-assembler-x64.cc b/src/x64/regexp-macro-assembler-x64.cc
index 03f91fa..d4ccb0e 100644
--- a/src/x64/regexp-macro-assembler-x64.cc
+++ b/src/x64/regexp-macro-assembler-x64.cc
@@ -762,7 +762,7 @@
__ j(above_equal, &stack_ok);
// Exit with OutOfMemory exception. There is not enough space on the stack
// for our working registers.
- __ movq(rax, Immediate(EXCEPTION));
+ __ Set(rax, EXCEPTION);
__ jmp(&exit_label_);
__ bind(&stack_limit_hit);
@@ -799,7 +799,7 @@
// Fill saved registers with initial value = start offset - 1
// Fill in stack push order, to avoid accessing across an unwritten
// page (a problem on Windows).
- __ movq(rcx, Immediate(kRegisterZero));
+ __ Set(rcx, kRegisterZero);
Label init_loop;
__ bind(&init_loop);
__ movq(Operand(rbp, rcx, times_1, 0), rax);
@@ -829,7 +829,7 @@
LoadCurrentCharacterUnchecked(-1, 1); // Load previous char.
__ jmp(&start_label_);
__ bind(&at_start);
- __ movq(current_character(), Immediate('\n'));
+ __ Set(current_character(), '\n');
__ jmp(&start_label_);
@@ -857,7 +857,7 @@
__ movl(Operand(rbx, i * kIntSize), rax);
}
}
- __ movq(rax, Immediate(SUCCESS));
+ __ Set(rax, SUCCESS);
}
// Exit and return rax
@@ -959,7 +959,7 @@
// If any of the code above needed to exit with an exception.
__ bind(&exit_with_exception);
// Exit with Result EXCEPTION(-1) to signal thrown exception.
- __ movq(rax, Immediate(EXCEPTION));
+ __ Set(rax, EXCEPTION);
__ jmp(&exit_label_);
}
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 26b20f4..c19d29d 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -399,7 +399,7 @@
ExternalReference ref =
ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorOnly),
masm->isolate());
- __ movq(rax, Immediate(5));
+ __ Set(rax, 5);
__ LoadAddress(rbx, ref);
CEntryStub stub(1);