Version 3.24.0
Performance and stability improvements on all platforms.
git-svn-id: http://v8.googlecode.com/svn/trunk@18280 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
diff --git a/src/api.cc b/src/api.cc
index aee9e3a..943dbba 100644
--- a/src/api.cc
+++ b/src/api.cc
@@ -5318,7 +5318,6 @@
global_constructor->set_needs_access_check(
proxy_constructor->needs_access_check());
}
- isolate->runtime_profiler()->Reset();
}
// Leave V8.
diff --git a/src/arm/builtins-arm.cc b/src/arm/builtins-arm.cc
index bef4bc3..4b65845 100644
--- a/src/arm/builtins-arm.cc
+++ b/src/arm/builtins-arm.cc
@@ -938,18 +938,9 @@
__ ldr(r0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
{
FrameScope scope(masm, StackFrame::INTERNAL);
- // Lookup and calculate pc offset.
- __ ldr(r1, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
- __ ldr(r2, FieldMemOperand(r0, JSFunction::kSharedFunctionInfoOffset));
- __ ldr(r2, FieldMemOperand(r2, SharedFunctionInfo::kCodeOffset));
- __ sub(r1, r1, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ sub(r1, r1, r2);
- __ SmiTag(r1);
-
- // Pass both function and pc offset as arguments.
+ // Pass function as argument.
__ push(r0);
- __ push(r1);
- __ CallRuntime(Runtime::kCompileForOnStackReplacement, 2);
+ __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
}
// If the code object is null, just return to the unoptimized code.
diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc
index cc2dbdc..4eb08a1 100644
--- a/src/arm/code-stubs-arm.cc
+++ b/src/arm/code-stubs-arm.cc
@@ -1418,18 +1418,6 @@
}
AllowExternalCallThatCantCauseGC scope(masm);
switch (type_) {
- case TranscendentalCache::SIN:
- __ CallCFunction(ExternalReference::math_sin_double_function(isolate),
- 0, 1);
- break;
- case TranscendentalCache::COS:
- __ CallCFunction(ExternalReference::math_cos_double_function(isolate),
- 0, 1);
- break;
- case TranscendentalCache::TAN:
- __ CallCFunction(ExternalReference::math_tan_double_function(isolate),
- 0, 1);
- break;
case TranscendentalCache::LOG:
__ CallCFunction(ExternalReference::math_log_double_function(isolate),
0, 1);
@@ -1445,9 +1433,6 @@
Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
switch (type_) {
// Add more cases when necessary.
- case TranscendentalCache::SIN: return Runtime::kMath_sin;
- case TranscendentalCache::COS: return Runtime::kMath_cos;
- case TranscendentalCache::TAN: return Runtime::kMath_tan;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
diff --git a/src/arm/codegen-arm.cc b/src/arm/codegen-arm.cc
index 238d34e..255e1f3 100644
--- a/src/arm/codegen-arm.cc
+++ b/src/arm/codegen-arm.cc
@@ -39,9 +39,6 @@
UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
switch (type) {
- case TranscendentalCache::SIN: return &sin;
- case TranscendentalCache::COS: return &cos;
- case TranscendentalCache::TAN: return &tan;
case TranscendentalCache::LOG: return &log;
default: UNIMPLEMENTED();
}
@@ -836,8 +833,10 @@
#undef __
+#ifdef DEBUG
// add(r0, pc, Operand(-8))
static const uint32_t kCodeAgePatchFirstInstruction = 0xe24f0008;
+#endif
static byte* GetNoCodeAgeSequence(uint32_t* length) {
// The sequence of instructions that is patched out for aging code is the
diff --git a/src/arm/full-codegen-arm.cc b/src/arm/full-codegen-arm.cc
index 5508803..f6d3ea3 100644
--- a/src/arm/full-codegen-arm.cc
+++ b/src/arm/full-codegen-arm.cc
@@ -334,10 +334,6 @@
void FullCodeGenerator::EmitProfilingCounterReset() {
int reset_value = FLAG_interrupt_budget;
- if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
- // Self-optimization is a one-off thing: if it fails, don't try again.
- reset_value = Smi::kMaxValue;
- }
if (isolate()->IsDebuggerActive()) {
// Detect debug break requests as soon as possible.
reset_value = FLAG_interrupt_budget >> 4;
@@ -355,13 +351,10 @@
Assembler::BlockConstPoolScope block_const_pool(masm_);
Label ok;
- int weight = 1;
- if (FLAG_weighted_back_edges) {
- ASSERT(back_edge_target->is_bound());
- int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
+ ASSERT(back_edge_target->is_bound());
+ int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
+ int weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
EmitProfilingCounterDecrement(weight);
__ b(pl, &ok);
__ Call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
@@ -394,32 +387,24 @@
__ push(r0);
__ CallRuntime(Runtime::kTraceExit, 1);
}
- if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
- // Pretend that the exit is a backwards jump to the entry.
- int weight = 1;
- if (info_->ShouldSelfOptimize()) {
- weight = FLAG_interrupt_budget / FLAG_self_opt_count;
- } else if (FLAG_weighted_back_edges) {
- int distance = masm_->pc_offset();
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
- EmitProfilingCounterDecrement(weight);
- Label ok;
- __ b(pl, &ok);
- __ push(r0);
- if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
- __ ldr(r2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ push(r2);
- __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
- } else {
- __ Call(isolate()->builtins()->InterruptCheck(),
- RelocInfo::CODE_TARGET);
- }
- __ pop(r0);
- EmitProfilingCounterReset();
- __ bind(&ok);
+ // Pretend that the exit is a backwards jump to the entry.
+ int weight = 1;
+ if (info_->ShouldSelfOptimize()) {
+ weight = FLAG_interrupt_budget / FLAG_self_opt_count;
+ } else {
+ int distance = masm_->pc_offset();
+ weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
}
+ EmitProfilingCounterDecrement(weight);
+ Label ok;
+ __ b(pl, &ok);
+ __ push(r0);
+ __ Call(isolate()->builtins()->InterruptCheck(),
+ RelocInfo::CODE_TARGET);
+ __ pop(r0);
+ EmitProfilingCounterReset();
+ __ bind(&ok);
#ifdef DEBUG
// Add a label for checking the size of the code used for returning.
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 6119b24..5a1d55e 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -256,7 +256,7 @@
stream->Add("if typeof ");
value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
- *hydrogen()->type_literal()->ToCString(),
+ hydrogen()->type_literal()->ToCString().get(),
true_block_id(), false_block_id());
}
@@ -309,13 +309,13 @@
void LCallNamed::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
void LCallGlobal::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
@@ -360,7 +360,7 @@
void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add(".");
- stream->Add(*String::cast(*name())->ToCString());
+ stream->Add(String::cast(*name())->ToCString().get());
stream->Add(" <- ");
value()->PrintTo(stream);
}
@@ -1187,9 +1187,6 @@
case kMathRound: return DoMathRound(instr);
case kMathAbs: return DoMathAbs(instr);
case kMathLog: return DoMathLog(instr);
- case kMathSin: return DoMathSin(instr);
- case kMathCos: return DoMathCos(instr);
- case kMathTan: return DoMathTan(instr);
case kMathExp: return DoMathExp(instr);
case kMathSqrt: return DoMathSqrt(instr);
case kMathPowHalf: return DoMathPowHalf(instr);
@@ -1233,27 +1230,6 @@
}
-LInstruction* LChunkBuilder::DoMathSin(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), d2);
- LMathSin* result = new(zone()) LMathSin(input);
- return MarkAsCall(DefineFixedDouble(result, d2), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathCos(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), d2);
- LMathCos* result = new(zone()) LMathCos(input);
- return MarkAsCall(DefineFixedDouble(result, d2), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), d2);
- LMathTan* result = new(zone()) LMathTan(input);
- return MarkAsCall(DefineFixedDouble(result, d2), instr);
-}
-
-
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble());
@@ -2677,5 +2653,4 @@
return DefineAsRegister(new(zone()) LLoadFieldByIndex(object, index));
}
-
} } // namespace v8::internal
diff --git a/src/arm/lithium-arm.h b/src/arm/lithium-arm.h
index cfafc06..4bac4b1 100644
--- a/src/arm/lithium-arm.h
+++ b/src/arm/lithium-arm.h
@@ -131,7 +131,6 @@
V(LoadNamedGeneric) \
V(MapEnumLength) \
V(MathAbs) \
- V(MathCos) \
V(MathExp) \
V(MathFloor) \
V(MathFloorOfDiv) \
@@ -139,9 +138,7 @@
V(MathMinMax) \
V(MathPowHalf) \
V(MathRound) \
- V(MathSin) \
V(MathSqrt) \
- V(MathTan) \
V(ModI) \
V(MulI) \
V(MultiplyAddD) \
@@ -816,42 +813,6 @@
};
-class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathSin(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
-};
-
-
-class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathCos(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
-};
-
-
-class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathTan(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
-};
-
-
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 3> {
public:
LMathExp(LOperand* value,
@@ -2778,9 +2739,6 @@
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
- LInstruction* DoMathSin(HUnaryMathOperation* instr);
- LInstruction* DoMathCos(HUnaryMathOperation* instr);
- LInstruction* DoMathTan(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index b9f1a5f..8f1c9c0 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -3951,39 +3951,6 @@
}
-void LCodeGen::DoMathTan(LMathTan* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(d2));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ mov(cp, Operand::Zero());
- TranscendentalCacheStub stub(TranscendentalCache::TAN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathCos(LMathCos* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(d2));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ mov(cp, Operand::Zero());
- TranscendentalCacheStub stub(TranscendentalCache::COS,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathSin(LMathSin* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(d2));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ mov(cp, Operand::Zero());
- TranscendentalCacheStub stub(TranscendentalCache::SIN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->function()).is(r1));
diff --git a/src/arm/stub-cache-arm.cc b/src/arm/stub-cache-arm.cc
index 265265d..9d1418b 100644
--- a/src/arm/stub-cache-arm.cc
+++ b/src/arm/stub-cache-arm.cc
@@ -911,12 +911,12 @@
__ str(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
// Write receiver to stack frame.
int index = stack_space - 1;
- __ str(receiver, MemOperand(sp, index * kPointerSize));
+ __ str(receiver, MemOperand(sp, index-- * kPointerSize));
// Write the arguments to stack frame.
for (int i = 0; i < argc; i++) {
ASSERT(!receiver.is(values[i]));
ASSERT(!scratch.is(values[i]));
- __ str(receiver, MemOperand(sp, index-- * kPointerSize));
+ __ str(values[i], MemOperand(sp, index-- * kPointerSize));
}
GenerateFastApiDirectCall(masm, optimization, argc, true);
@@ -927,12 +927,10 @@
public:
CallInterceptorCompiler(CallStubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name,
- ExtraICState extra_ic_state)
+ Register name)
: stub_compiler_(stub_compiler),
arguments_(arguments),
- name_(name),
- extra_ic_state_(extra_ic_state) {}
+ name_(name) {}
void Compile(MacroAssembler* masm,
Handle<JSObject> object,
@@ -1107,7 +1105,6 @@
CallStubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
- ExtraICState extra_ic_state_;
};
@@ -2466,7 +2463,7 @@
// Get the receiver from the stack.
__ ldr(r1, MemOperand(sp, argc * kPointerSize));
- CallInterceptorCompiler compiler(this, arguments(), r2, extra_state());
+ CallInterceptorCompiler compiler(this, arguments(), r2);
compiler.Compile(masm(), object, holder, name, &lookup, r1, r3, r4, r0,
&miss);
diff --git a/src/assembler.cc b/src/assembler.cc
index febae63..b77e92d 100644
--- a/src/assembler.cc
+++ b/src/assembler.cc
@@ -306,7 +306,9 @@
// dropped, and last non-zero chunk tagged with 1.)
+#ifdef DEBUG
const int kMaxStandardNonCompactModes = 14;
+#endif
const int kTagBits = 2;
const int kTagMask = (1 << kTagBits) - 1;
@@ -1418,50 +1420,11 @@
}
-static double math_sin_double(double x) {
- return sin(x);
-}
-
-
-static double math_cos_double(double x) {
- return cos(x);
-}
-
-
-static double math_tan_double(double x) {
- return tan(x);
-}
-
-
static double math_log_double(double x) {
return log(x);
}
-ExternalReference ExternalReference::math_sin_double_function(
- Isolate* isolate) {
- return ExternalReference(Redirect(isolate,
- FUNCTION_ADDR(math_sin_double),
- BUILTIN_FP_CALL));
-}
-
-
-ExternalReference ExternalReference::math_cos_double_function(
- Isolate* isolate) {
- return ExternalReference(Redirect(isolate,
- FUNCTION_ADDR(math_cos_double),
- BUILTIN_FP_CALL));
-}
-
-
-ExternalReference ExternalReference::math_tan_double_function(
- Isolate* isolate) {
- return ExternalReference(Redirect(isolate,
- FUNCTION_ADDR(math_tan_double),
- BUILTIN_FP_CALL));
-}
-
-
ExternalReference ExternalReference::math_log_double_function(
Isolate* isolate) {
return ExternalReference(Redirect(isolate,
diff --git a/src/assembler.h b/src/assembler.h
index 0c706c4..6c06262 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -811,9 +811,6 @@
static ExternalReference address_of_the_hole_nan();
static ExternalReference address_of_uint32_bias();
- static ExternalReference math_sin_double_function(Isolate* isolate);
- static ExternalReference math_cos_double_function(Isolate* isolate);
- static ExternalReference math_tan_double_function(Isolate* isolate);
static ExternalReference math_log_double_function(Isolate* isolate);
static ExternalReference math_exp_constants(int constant_index);
diff --git a/src/bootstrapper.cc b/src/bootstrapper.cc
index 4d69f84..1d2fb86 100644
--- a/src/bootstrapper.cc
+++ b/src/bootstrapper.cc
@@ -41,10 +41,11 @@
#include "platform.h"
#include "snapshot.h"
#include "trig-table.h"
-#include "extensions/free-buffer-extension.h"
#include "extensions/externalize-string-extension.h"
+#include "extensions/free-buffer-extension.h"
#include "extensions/gc-extension.h"
#include "extensions/statistics-extension.h"
+#include "extensions/trigger-failure-extension.h"
#include "code-stubs.h"
namespace v8 {
@@ -107,6 +108,7 @@
GCExtension::Register();
ExternalizeStringExtension::Register();
StatisticsExtension::Register();
+ TriggerFailureExtension::Register();
}
@@ -2266,6 +2268,9 @@
if (FLAG_track_gc_object_stats) {
InstallExtension(isolate, "v8/statistics", &extension_states);
}
+ if (FLAG_expose_trigger_failure) {
+ InstallExtension(isolate, "v8/trigger-failure", &extension_states);
+ }
if (extensions == NULL) return true;
// Install required extensions
diff --git a/src/builtins.cc b/src/builtins.cc
index f9c2708..b27f29a 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -153,8 +153,8 @@
#endif
-static inline bool CalledAsConstructor(Isolate* isolate) {
#ifdef DEBUG
+static inline bool CalledAsConstructor(Isolate* isolate) {
// Calculate the result using a full stack frame iterator and check
// that the state of the stack is as we assume it to be in the
// code below.
@@ -163,7 +163,6 @@
it.Advance();
StackFrame* frame = it.frame();
bool reference_result = frame->is_construct();
-#endif
Address fp = Isolate::c_entry_fp(isolate->thread_local_top());
// Because we know fp points to an exit frame we can use the relevant
// part of ExitFrame::ComputeCallerState directly.
@@ -180,6 +179,7 @@
ASSERT_EQ(result, reference_result);
return result;
}
+#endif
// ----------------------------------------------------------------------------
diff --git a/src/cached-powers.cc b/src/cached-powers.cc
index fbfaf26..9e2919b 100644
--- a/src/cached-powers.cc
+++ b/src/cached-powers.cc
@@ -133,7 +133,10 @@
{V8_2PART_UINT64_C(0xaf87023b, 9bf0ee6b), 1066, 340},
};
+#ifdef DEBUG
static const int kCachedPowersLength = ARRAY_SIZE(kCachedPowers);
+#endif
+
static const int kCachedPowersOffset = 348; // -1 * the first decimal_exponent.
static const double kD_1_LOG2_10 = 0.30102999566398114; // 1 / lg(10)
// Difference between the decimal exponents in the table above.
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index 96cfc37..7922d6c 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -300,7 +300,8 @@
Handle<Code> code = chunk->Codegen();
if (FLAG_profile_hydrogen_code_stub_compilation) {
double ms = timer.Elapsed().InMillisecondsF();
- PrintF("[Lazy compilation of %s took %0.3f ms]\n", *stub->GetName(), ms);
+ PrintF("[Lazy compilation of %s took %0.3f ms]\n",
+ stub->GetName().get(), ms);
}
return code;
}
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 3fb6153..c66001a 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -80,8 +80,8 @@
void CodeStub::RecordCodeGeneration(Code* code, Isolate* isolate) {
SmartArrayPointer<const char> name = GetName();
- PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, *name));
- GDBJIT(AddCode(GDBJITInterface::STUB, *name, code));
+ PROFILE(isolate, CodeCreateEvent(Logger::STUB_TAG, code, name.get()));
+ GDBJIT(AddCode(GDBJITInterface::STUB, name.get(), code));
Counters* counters = isolate->counters();
counters->total_stubs_code_size()->Increment(code->instruction_size());
}
@@ -164,7 +164,7 @@
#ifdef ENABLE_DISASSEMBLER
if (FLAG_print_code_stubs) {
CodeTracer::Scope trace_scope(isolate->GetCodeTracer());
- new_object->Disassemble(*GetName(), trace_scope.file());
+ new_object->Disassemble(GetName().get(), trace_scope.file());
PrintF(trace_scope.file(), "\n");
}
#endif
diff --git a/src/codegen.cc b/src/codegen.cc
index 28f7d6c..adb47b8 100644
--- a/src/codegen.cc
+++ b/src/codegen.cc
@@ -81,7 +81,7 @@
CodeStub::MajorName(info->code_stub()->MajorKey(), true);
PrintF("%s", name == NULL ? "<unknown>" : name);
} else {
- PrintF("%s", *info->function()->debug_name()->ToCString());
+ PrintF("%s", info->function()->debug_name()->ToCString().get());
}
PrintF("]\n");
}
@@ -162,7 +162,7 @@
if (FLAG_print_unopt_code) {
PrintF(tracing_scope.file(), "--- Unoptimized code ---\n");
info->closure()->shared()->code()->Disassemble(
- *function->debug_name()->ToCString(), tracing_scope.file());
+ function->debug_name()->ToCString().get(), tracing_scope.file());
}
PrintF(tracing_scope.file(), "--- Optimized code ---\n");
} else {
@@ -177,7 +177,7 @@
code->Disassemble(CodeStub::MajorName(major_key, false),
tracing_scope.file());
} else {
- code->Disassemble(*function->debug_name()->ToCString(),
+ code->Disassemble(function->debug_name()->ToCString().get(),
tracing_scope.file());
}
PrintF(tracing_scope.file(), "--- End code ---\n");
diff --git a/src/compiler.cc b/src/compiler.cc
index 83f9ab2..c6dfa04 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -235,8 +235,7 @@
// profiler, so they trigger their own optimization when they're called
// for the SharedFunctionInfo::kCallsUntilPrimitiveOptimization-th time.
bool CompilationInfo::ShouldSelfOptimize() {
- return FLAG_self_optimization &&
- FLAG_crankshaft &&
+ return FLAG_crankshaft &&
!function()->flags()->Contains(kDontSelfOptimize) &&
!function()->dont_optimize() &&
function()->scope()->AllowsLazyCompilation() &&
@@ -460,7 +459,7 @@
if (FLAG_trace_hydrogen) {
Handle<String> name = info()->function()->debug_name();
PrintF("-----------------------------------------------------------\n");
- PrintF("Compiling method %s using hydrogen\n", *name->ToCString());
+ PrintF("Compiling method %s using hydrogen\n", name->ToCString().get());
isolate()->GetHTracer()->TraceCompilation(info());
}
@@ -1056,6 +1055,7 @@
bool Compiler::RecompileConcurrent(Handle<JSFunction> closure,
+ Handle<Code> unoptimized,
uint32_t osr_pc_offset) {
bool compiling_for_osr = (osr_pc_offset != 0);
@@ -1078,11 +1078,10 @@
Handle<SharedFunctionInfo> shared = info->shared_info();
if (compiling_for_osr) {
- BailoutId osr_ast_id =
- shared->code()->TranslatePcOffsetToAstId(osr_pc_offset);
+ BailoutId osr_ast_id = unoptimized->TranslatePcOffsetToAstId(osr_pc_offset);
ASSERT(!osr_ast_id.IsNone());
info->SetOptimizing(osr_ast_id);
- info->set_osr_pc_offset(osr_pc_offset);
+ info->SetOsrInfo(unoptimized, osr_pc_offset);
if (FLAG_trace_osr) {
PrintF("[COSR - attempt to queue ");
@@ -1100,30 +1099,30 @@
isolate->counters()->total_compile_size()->Increment(compiled_size);
{
- CompilationHandleScope handle_scope(*info);
+ CompilationHandleScope handle_scope(info.get());
- if (!compiling_for_osr && InstallCodeFromOptimizedCodeMap(*info)) {
+ if (!compiling_for_osr && InstallCodeFromOptimizedCodeMap(info.get())) {
return true;
}
- if (Parser::Parse(*info)) {
+ if (Parser::Parse(info.get())) {
LanguageMode language_mode = info->function()->language_mode();
info->SetLanguageMode(language_mode);
shared->set_language_mode(language_mode);
info->SaveHandles();
- if (Rewriter::Rewrite(*info) && Scope::Analyze(*info)) {
- RecompileJob* job = new(info->zone()) RecompileJob(*info);
+ if (Rewriter::Rewrite(info.get()) && Scope::Analyze(info.get())) {
+ RecompileJob* job = new(info->zone()) RecompileJob(info.get());
RecompileJob::Status status = job->CreateGraph();
if (status == RecompileJob::SUCCEEDED) {
info.Detach();
- shared->code()->set_profiler_ticks(0);
+ unoptimized->set_profiler_ticks(0);
isolate->optimizing_compiler_thread()->QueueForOptimization(job);
ASSERT(!isolate->has_pending_exception());
return true;
} else if (status == RecompileJob::BAILED_OUT) {
isolate->clear_pending_exception();
- InstallFullCode(*info);
+ InstallFullCode(info.get());
}
}
}
@@ -1140,7 +1139,7 @@
// Except when OSR already disabled optimization for some reason.
if (info->shared_info()->optimization_disabled()) {
info->AbortOptimization();
- InstallFullCode(*info);
+ InstallFullCode(info.get());
if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** aborting optimization for ");
info->closure()->PrintName();
@@ -1172,14 +1171,14 @@
status == RecompileJob::BAILED_OUT);
}
- InstallCodeCommon(*info);
+ InstallCodeCommon(info.get());
if (status == RecompileJob::SUCCEEDED) {
Handle<Code> code = info->code();
ASSERT(info->shared_info()->scope_info() != ScopeInfo::Empty(isolate));
info->closure()->ReplaceCode(*code);
if (info->shared_info()->SearchOptimizedCodeMap(
info->closure()->context()->native_context()) == -1) {
- InsertCodeIntoOptimizedCodeMap(*info);
+ InsertCodeIntoOptimizedCodeMap(info.get());
}
if (FLAG_trace_concurrent_recompilation) {
PrintF(" ** Optimized code for ");
@@ -1188,7 +1187,7 @@
}
} else {
info->AbortOptimization();
- InstallFullCode(*info);
+ InstallFullCode(info.get());
}
// Optimized code is finally replacing unoptimized code. Reset the latter's
// profiler ticks to prevent too soon re-opt after a deopt.
diff --git a/src/compiler.h b/src/compiler.h
index 080907e..7599c13 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -85,6 +85,7 @@
Handle<Context> context() const { return context_; }
BailoutId osr_ast_id() const { return osr_ast_id_; }
uint32_t osr_pc_offset() const { return osr_pc_offset_; }
+ Handle<Code> osr_patched_code() const { return osr_patched_code_; }
int opt_count() const { return opt_count_; }
int num_parameters() const;
int num_heap_slots() const;
@@ -265,6 +266,7 @@
SaveHandle(&shared_info_);
SaveHandle(&context_);
SaveHandle(&script_);
+ SaveHandle(&osr_patched_code_);
}
BailoutReason bailout_reason() const { return bailout_reason_; }
@@ -311,7 +313,8 @@
return abort_due_to_dependency_;
}
- void set_osr_pc_offset(uint32_t pc_offset) {
+ void SetOsrInfo(Handle<Code> code, uint32_t pc_offset) {
+ osr_patched_code_ = code;
osr_pc_offset_ = pc_offset;
}
@@ -416,6 +419,10 @@
// The pc_offset corresponding to osr_ast_id_ in unoptimized code.
// We can look this up in the back edge table, but cache it for quick access.
uint32_t osr_pc_offset_;
+ // The unoptimized code we patched for OSR may not be the shared code
+ // afterwards, since we may need to compile it again to include deoptimization
+ // data. Keep track which code we patched.
+ Handle<Code> osr_patched_code_;
// Flag whether compilation needs to be aborted due to dependency change.
bool abort_due_to_dependency_;
@@ -626,6 +633,7 @@
static bool CompileLazy(CompilationInfo* info);
static bool RecompileConcurrent(Handle<JSFunction> function,
+ Handle<Code> unoptimized,
uint32_t osr_pc_offset = 0);
// Compile a shared function info object (the function is possibly lazily
diff --git a/src/d8-debug.cc b/src/d8-debug.cc
index 6c297d7..0cd1cc2 100644
--- a/src/d8-debug.cc
+++ b/src/d8-debug.cc
@@ -332,13 +332,13 @@
// Receive the connect message (with empty body).
i::SmartArrayPointer<char> message =
i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
- ASSERT(*message == NULL);
+ ASSERT(message.get() == NULL);
while (true) {
// Receive a message.
i::SmartArrayPointer<char> message =
i::DebuggerAgentUtil::ReceiveMessage(remote_debugger_->conn());
- if (*message == NULL) {
+ if (message.get() == NULL) {
remote_debugger_->ConnectionClosed();
return;
}
diff --git a/src/d8-debug.h b/src/d8-debug.h
index 5587622..f753177 100644
--- a/src/d8-debug.h
+++ b/src/d8-debug.h
@@ -135,7 +135,7 @@
static const int kDisconnect = 3;
int type() { return type_; }
- char* data() { return *data_; }
+ char* data() { return data_.get(); }
private:
void set_next(RemoteDebuggerEvent* event) { next_ = event; }
diff --git a/src/d8.cc b/src/d8.cc
index 2fdbe0c..eb70f3e 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -168,10 +168,9 @@
const char* Shell::kPrompt = "d8> ";
+#ifndef V8_SHARED
const int MB = 1024 * 1024;
-
-#ifndef V8_SHARED
bool CounterMap::Match(void* key1, void* key2) {
const char* name1 = reinterpret_cast<const char*>(key1);
const char* name2 = reinterpret_cast<const char*>(key2);
@@ -610,19 +609,19 @@
Handle<Array> Shell::GetCompletions(Isolate* isolate,
Handle<String> text,
Handle<String> full) {
- HandleScope handle_scope(isolate);
+ EscapableHandleScope handle_scope(isolate);
v8::Local<v8::Context> utility_context =
v8::Local<v8::Context>::New(isolate, utility_context_);
v8::Context::Scope context_scope(utility_context);
Handle<Object> global = utility_context->Global();
- Handle<Value> fun =
+ Local<Value> fun =
global->Get(String::NewFromUtf8(isolate, "GetCompletions"));
static const int kArgc = 3;
v8::Local<v8::Context> evaluation_context =
v8::Local<v8::Context>::New(isolate, evaluation_context_);
Handle<Value> argv[kArgc] = { evaluation_context->Global(), text, full };
- Handle<Value> val = Handle<Function>::Cast(fun)->Call(global, kArgc, argv);
- return handle_scope.Close(Handle<Array>::Cast(val));
+ Local<Value> val = Local<Function>::Cast(fun)->Call(global, kArgc, argv);
+ return handle_scope.Escape(Local<Array>::Cast(val));
}
@@ -966,7 +965,7 @@
#endif // V8_SHARED
// Initialize the global objects
Handle<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
- HandleScope handle_scope(isolate);
+ EscapableHandleScope handle_scope(isolate);
Local<Context> context = Context::New(isolate, NULL, global_template);
ASSERT(!context.IsEmpty());
Context::Scope scope(context);
@@ -986,7 +985,7 @@
context->Global()->Set(String::NewFromUtf8(isolate, "arguments"),
Utils::ToLocal(arguments_jsarray));
#endif // V8_SHARED
- return handle_scope.Close(context);
+ return handle_scope.Escape(context);
}
diff --git a/src/date.cc b/src/date.cc
index a377451..4afd8dc 100644
--- a/src/date.cc
+++ b/src/date.cc
@@ -36,7 +36,6 @@
namespace internal {
-static const int kDays4Years[] = {0, 365, 2 * 365, 3 * 365 + 1};
static const int kDaysIn4Years = 4 * 365 + 1;
static const int kDaysIn100Years = 25 * kDaysIn4Years - 1;
static const int kDaysIn400Years = 4 * kDaysIn100Years + 1;
diff --git a/src/debug-agent.cc b/src/debug-agent.cc
index 51823aa..d3d22c9 100644
--- a/src/debug-agent.cc
+++ b/src/debug-agent.cc
@@ -192,7 +192,7 @@
void DebuggerAgentSession::Run() {
// Send the hello message.
- bool ok = DebuggerAgentUtil::SendConnectMessage(client_, *agent_->name_);
+ bool ok = DebuggerAgentUtil::SendConnectMessage(client_, agent_->name_.get());
if (!ok) return;
while (true) {
@@ -200,7 +200,7 @@
SmartArrayPointer<char> message =
DebuggerAgentUtil::ReceiveMessage(client_);
- const char* msg = *message;
+ const char* msg = message.get();
bool is_closing_session = (msg == NULL);
if (msg == NULL) {
diff --git a/src/deoptimizer.cc b/src/deoptimizer.cc
index 76f2fa9..fc0df65 100644
--- a/src/deoptimizer.cc
+++ b/src/deoptimizer.cc
@@ -691,12 +691,12 @@
}
}
PrintF(stderr, "[couldn't find pc offset for node=%d]\n", id.ToInt());
- PrintF(stderr, "[method: %s]\n", *shared->DebugName()->ToCString());
+ PrintF(stderr, "[method: %s]\n", shared->DebugName()->ToCString().get());
// Print the source code if available.
HeapStringAllocator string_allocator;
StringStream stream(&string_allocator);
shared->SourceCodePrint(&stream, -1);
- PrintF(stderr, "[source:\n%s\n]", *stream.ToCString());
+ PrintF(stderr, "[source:\n%s\n]", stream.ToCString().get());
FATAL("unable to find pc offset during deoptimization");
return -1;
diff --git a/src/disassembler.cc b/src/disassembler.cc
index 69737ed..8bec2ce 100644
--- a/src/disassembler.cc
+++ b/src/disassembler.cc
@@ -224,7 +224,7 @@
StringStream accumulator(&allocator);
relocinfo.target_object()->ShortPrint(&accumulator);
SmartArrayPointer<const char> obj_name = accumulator.ToCString();
- out.AddFormatted(" ;; object: %s", *obj_name);
+ out.AddFormatted(" ;; object: %s", obj_name.get());
} else if (rmode == RelocInfo::EXTERNAL_REFERENCE) {
const char* reference_name =
ref_encoder.NameOfAddress(relocinfo.target_reference());
diff --git a/src/extensions/trigger-failure-extension.cc b/src/extensions/trigger-failure-extension.cc
new file mode 100644
index 0000000..5fe6bbb
--- /dev/null
+++ b/src/extensions/trigger-failure-extension.cc
@@ -0,0 +1,82 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#include "trigger-failure-extension.h"
+#include "v8.h"
+
+namespace v8 {
+namespace internal {
+
+
+const char* const TriggerFailureExtension::kSource =
+ "native function triggerCheckFalse();"
+ "native function triggerAssertFalse();"
+ "native function triggerSlowAssertFalse();";
+
+
+v8::Handle<v8::FunctionTemplate>
+TriggerFailureExtension::GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
+ v8::Handle<v8::String> str) {
+ if (strcmp(*v8::String::Utf8Value(str), "triggerCheckFalse") == 0) {
+ return v8::FunctionTemplate::New(
+ TriggerFailureExtension::TriggerCheckFalse);
+ } else if (strcmp(*v8::String::Utf8Value(str), "triggerAssertFalse") == 0) {
+ return v8::FunctionTemplate::New(
+ TriggerFailureExtension::TriggerAssertFalse);
+ } else {
+ CHECK_EQ(0, strcmp(*v8::String::Utf8Value(str), "triggerSlowAssertFalse"));
+ return v8::FunctionTemplate::New(
+ TriggerFailureExtension::TriggerSlowAssertFalse);
+ }
+}
+
+
+void TriggerFailureExtension::TriggerCheckFalse(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ CHECK(false);
+}
+
+
+void TriggerFailureExtension::TriggerAssertFalse(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ ASSERT(false);
+}
+
+
+void TriggerFailureExtension::TriggerSlowAssertFalse(
+ const v8::FunctionCallbackInfo<v8::Value>& args) {
+ SLOW_ASSERT(false);
+}
+
+
+void TriggerFailureExtension::Register() {
+ static TriggerFailureExtension trigger_failure_extension;
+ static v8::DeclareExtension declaration(&trigger_failure_extension);
+}
+
+} } // namespace v8::internal
diff --git a/src/extensions/trigger-failure-extension.h b/src/extensions/trigger-failure-extension.h
new file mode 100644
index 0000000..5a4223f
--- /dev/null
+++ b/src/extensions/trigger-failure-extension.h
@@ -0,0 +1,56 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef V8_EXTENSIONS_TRIGGER_FAILURE_EXTENSION_H_
+#define V8_EXTENSIONS_TRIGGER_FAILURE_EXTENSION_H_
+
+#include "v8.h"
+
+namespace v8 {
+namespace internal {
+
+class TriggerFailureExtension : public v8::Extension {
+ public:
+ TriggerFailureExtension() : v8::Extension("v8/trigger-failure", kSource) {}
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate(
+ v8::Isolate* isolate,
+ v8::Handle<v8::String> name);
+ static void TriggerCheckFalse(
+ const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void TriggerAssertFalse(
+ const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void TriggerSlowAssertFalse(
+ const v8::FunctionCallbackInfo<v8::Value>& args);
+ static void Register();
+
+ private:
+ static const char* const kSource;
+};
+
+} } // namespace v8::internal
+
+#endif // V8_EXTENSIONS_TRIGGER_FAILURE_EXTENSION_H_
diff --git a/src/factory.cc b/src/factory.cc
index 483e6a6..c10111a 100644
--- a/src/factory.cc
+++ b/src/factory.cc
@@ -896,10 +896,10 @@
if (space > 0) {
MaybeObject* maybe_arg = args->GetElement(isolate(), i);
Handle<String> arg_str(reinterpret_cast<String*>(maybe_arg));
- const char* arg = *arg_str->ToCString();
+ SmartArrayPointer<char> arg = arg_str->ToCString();
Vector<char> v2(p, static_cast<int>(space));
- OS::StrNCpy(v2, arg, space);
- space -= Min(space, strlen(arg));
+ OS::StrNCpy(v2, arg.get(), space);
+ space -= Min(space, strlen(arg.get()));
p = &buffer[kBufferSize] - space;
}
}
diff --git a/src/flag-definitions.h b/src/flag-definitions.h
index b304ce5..658991f 100644
--- a/src/flag-definitions.h
+++ b/src/flag-definitions.h
@@ -347,19 +347,8 @@
DEFINE_bool(new_string_add, true, "enable new string addition")
-// Experimental profiler changes.
-DEFINE_bool(experimental_profiler, true, "enable all profiler experiments")
-DEFINE_bool(watch_ic_patching, false, "profiler considers IC stability")
+// Profiler flags.
DEFINE_int(frame_count, 1, "number of stack frames inspected by the profiler")
-DEFINE_bool(self_optimization, false,
- "primitive functions trigger their own optimization")
-DEFINE_bool(direct_self_opt, false,
- "call recompile stub directly when self-optimizing")
-DEFINE_bool(retry_self_opt, false, "re-try self-optimization if it failed")
-DEFINE_bool(interrupt_at_exit, false,
- "insert an interrupt check at function exit")
-DEFINE_bool(weighted_back_edges, false,
- "weight back edges by jump distance for interrupt triggering")
// 0x1700 fits in the immediate field of an ARM instruction.
DEFINE_int(interrupt_budget, 0x1700,
"execution budget before interrupt is triggered")
@@ -367,13 +356,6 @@
"percentage of ICs that must have type info to allow optimization")
DEFINE_int(self_opt_count, 130, "call count before self-optimization")
-DEFINE_implication(experimental_profiler, watch_ic_patching)
-DEFINE_implication(experimental_profiler, self_optimization)
-// Not implying direct_self_opt here because it seems to be a bad idea.
-DEFINE_implication(experimental_profiler, retry_self_opt)
-DEFINE_implication(experimental_profiler, interrupt_at_exit)
-DEFINE_implication(experimental_profiler, weighted_back_edges)
-
DEFINE_bool(trace_opt_verbose, false, "extra verbose compilation tracing")
DEFINE_implication(trace_opt_verbose, trace_opt)
@@ -421,6 +403,7 @@
DEFINE_implication(expose_gc_as, expose_gc)
DEFINE_bool(expose_externalize_string, false,
"expose externalize string extension")
+DEFINE_bool(expose_trigger_failure, false, "expose trigger-failure extension")
DEFINE_int(stack_trace_limit, 10, "number of stack frames to capture")
DEFINE_bool(builtins_in_stack_traces, false,
"show built-in functions in stack traces")
diff --git a/src/flags.cc b/src/flags.cc
index 0c36aed..8e42206 100644
--- a/src/flags.cc
+++ b/src/flags.cc
@@ -566,7 +566,7 @@
Flag* f = &flags[i];
SmartArrayPointer<const char> value = ToString(f);
printf(" --%s (%s)\n type: %s default: %s\n",
- f->name(), f->comment(), Type2String(f->type()), *value);
+ f->name(), f->comment(), Type2String(f->type()), value.get());
}
}
diff --git a/src/frames.cc b/src/frames.cc
index 9549c2d..bcf675b 100644
--- a/src/frames.cc
+++ b/src/frames.cc
@@ -824,7 +824,7 @@
SmartArrayPointer<char> c_script_name =
script_name->ToCString(DISALLOW_NULLS,
ROBUST_STRING_TRAVERSAL);
- PrintF(file, " at %s:%d", *c_script_name, line);
+ PrintF(file, " at %s:%d", c_script_name.get(), line);
} else {
PrintF(file, " at <unknown>:%d", line);
}
diff --git a/src/full-codegen.cc b/src/full-codegen.cc
index 483d1e3..a40b61e 100644
--- a/src/full-codegen.cc
+++ b/src/full-codegen.cc
@@ -1697,9 +1697,11 @@
void BackEdgeTable::AddStackCheck(CompilationInfo* info) {
DisallowHeapAllocation no_gc;
Isolate* isolate = info->isolate();
- Code* code = info->shared_info()->code();
+ Code* code = *info->osr_patched_code();
Address pc = code->instruction_start() + info->osr_pc_offset();
- ASSERT_EQ(ON_STACK_REPLACEMENT, GetBackEdgeState(isolate, code, pc));
+ ASSERT_EQ(info->osr_ast_id().ToInt(),
+ code->TranslatePcOffsetToAstId(info->osr_pc_offset()).ToInt());
+ ASSERT_NE(INTERRUPT, GetBackEdgeState(isolate, code, pc));
Code* patch = isolate->builtins()->builtin(Builtins::kOsrAfterStackCheck);
PatchAt(code, pc, OSR_AFTER_STACK_CHECK, patch);
}
@@ -1708,8 +1710,10 @@
void BackEdgeTable::RemoveStackCheck(CompilationInfo* info) {
DisallowHeapAllocation no_gc;
Isolate* isolate = info->isolate();
- Code* code = info->shared_info()->code();
+ Code* code = *info->osr_patched_code();
Address pc = code->instruction_start() + info->osr_pc_offset();
+ ASSERT_EQ(info->osr_ast_id().ToInt(),
+ code->TranslatePcOffsetToAstId(info->osr_pc_offset()).ToInt());
if (GetBackEdgeState(isolate, code, pc) == OSR_AFTER_STACK_CHECK) {
Code* patch = isolate->builtins()->builtin(Builtins::kOnStackReplacement);
PatchAt(code, pc, ON_STACK_REPLACEMENT, patch);
diff --git a/src/gdb-jit.cc b/src/gdb-jit.cc
index 21cfd22..afe5b71 100644
--- a/src/gdb-jit.cc
+++ b/src/gdb-jit.cc
@@ -1089,7 +1089,7 @@
w->Write<uint8_t>(sizeof(intptr_t));
w->WriteULEB128(1); // Abbreviation code.
- w->WriteString(*desc_->GetFilename());
+ w->WriteString(desc_->GetFilename().get());
w->Write<intptr_t>(desc_->CodeStart());
w->Write<intptr_t>(desc_->CodeStart() + desc_->CodeSize());
w->Write<uint32_t>(0);
@@ -1131,7 +1131,7 @@
for (int param = 0; param < params; ++param) {
w->WriteULEB128(current_abbreviation++);
w->WriteString(
- *scope->parameter(param)->name()->ToCString(DISALLOW_NULLS));
+ scope->parameter(param)->name()->ToCString(DISALLOW_NULLS).get());
w->Write<uint32_t>(ty_offset);
Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
uintptr_t block_start = w->position();
@@ -1182,7 +1182,7 @@
for (int local = 0; local < locals; ++local) {
w->WriteULEB128(current_abbreviation++);
w->WriteString(
- *stack_locals[local]->name()->ToCString(DISALLOW_NULLS));
+ stack_locals[local]->name()->ToCString(DISALLOW_NULLS).get());
w->Write<uint32_t>(ty_offset);
Writer::Slot<uint32_t> block_size = w->CreateSlotHere<uint32_t>();
uintptr_t block_start = w->position();
@@ -1455,7 +1455,7 @@
w->Write<uint8_t>(1); // DW_LNS_SET_COLUMN operands count.
w->Write<uint8_t>(0); // DW_LNS_NEGATE_STMT operands count.
w->Write<uint8_t>(0); // Empty include_directories sequence.
- w->WriteString(*desc_->GetFilename()); // File name.
+ w->WriteString(desc_->GetFilename().get()); // File name.
w->WriteULEB128(0); // Current directory.
w->WriteULEB128(0); // Unknown modification time.
w->WriteULEB128(0); // Unknown file size.
@@ -2009,7 +2009,8 @@
if (!name.is_null() && name->IsString()) {
SmartArrayPointer<char> name_cstring =
Handle<String>::cast(name)->ToCString(DISALLOW_NULLS);
- AddCode(*name_cstring, *code, GDBJITInterface::FUNCTION, *script, info);
+ AddCode(name_cstring.get(), *code, GDBJITInterface::FUNCTION, *script,
+ info);
} else {
AddCode("", *code, GDBJITInterface::FUNCTION, *script, info);
}
@@ -2132,7 +2133,7 @@
Code* code) {
if (!FLAG_gdbjit) return;
if (name != NULL && name->IsString()) {
- AddCode(tag, *String::cast(name)->ToCString(DISALLOW_NULLS), code);
+ AddCode(tag, String::cast(name)->ToCString(DISALLOW_NULLS).get(), code);
} else {
AddCode(tag, "", code);
}
diff --git a/src/harmony-math.js b/src/harmony-math.js
index a4d3f2e..2bf33d6 100644
--- a/src/harmony-math.js
+++ b/src/harmony-math.js
@@ -47,13 +47,82 @@
}
+// ES6 draft 09-27-13, section 20.2.2.30.
+function MathSinh(x) {
+ if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+ // Idempotent for NaN, +/-0 and +/-Infinity.
+ if (x === 0 || !NUMBER_IS_FINITE(x)) return x;
+ return (MathExp(x) - MathExp(-x)) / 2;
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.12.
+function MathCosh(x) {
+ if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+ // Idempotent for NaN and +/-Infinity.
+ if (!NUMBER_IS_FINITE(x)) return x;
+ return (MathExp(x) + MathExp(-x)) / 2;
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.33.
+function MathTanh(x) {
+ if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+ // Idempotent for +/-0.
+ if (x === 0) return x;
+ // Returns +/-1 for +/-Infinity.
+ if (!NUMBER_IS_FINITE(x)) return MathSign(x);
+ var exp1 = MathExp(x);
+ var exp2 = MathExp(-x);
+ return (exp1 - exp2) / (exp1 + exp2);
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.5.
+function MathAsinh(x) {
+ if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+ // Idempotent for NaN, +/-0 and +/-Infinity.
+ if (x === 0 || !NUMBER_IS_FINITE(x)) return x;
+ if (x > 0) return MathLog(x + MathSqrt(x * x + 1));
+ // This is to prevent numerical errors caused by large negative x.
+ return -MathLog(-x + MathSqrt(x * x + 1));
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.3.
+function MathAcosh(x) {
+ if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+ if (x < 1) return NAN;
+ // Idempotent for NaN and +Infinity.
+ if (!NUMBER_IS_FINITE(x)) return x;
+ return MathLog(x + MathSqrt(x + 1) * MathSqrt(x - 1));
+}
+
+
+// ES6 draft 09-27-13, section 20.2.2.7.
+function MathAtanh(x) {
+ if (!IS_NUMBER(x)) x = NonNumberToNumber(x);
+ // Idempotent for +/-0.
+ if (x === 0) return x;
+ // Returns NaN for NaN and +/- Infinity.
+ if (!NUMBER_IS_FINITE(x)) return NAN;
+ return 0.5 * MathLog((1 + x) / (1 - x));
+}
+
+
function ExtendMath() {
%CheckIsBootstrapping();
// Set up the non-enumerable functions on the Math object.
InstallFunctions($Math, DONT_ENUM, $Array(
"sign", MathSign,
- "trunc", MathTrunc
+ "trunc", MathTrunc,
+ "sinh", MathSinh,
+ "cosh", MathCosh,
+ "tanh", MathTanh,
+ "asinh", MathAsinh,
+ "acosh", MathAcosh,
+ "atanh", MathAtanh
));
}
diff --git a/src/heap-inl.h b/src/heap-inl.h
index 525c634..3229aee 100644
--- a/src/heap-inl.h
+++ b/src/heap-inl.h
@@ -763,23 +763,10 @@
double TranscendentalCache::SubCache::Calculate(double input) {
switch (type_) {
- case ACOS:
- return acos(input);
- case ASIN:
- return asin(input);
- case ATAN:
- return atan(input);
- case COS:
- return fast_cos(input);
- case EXP:
- return exp(input);
case LOG:
return fast_log(input);
- case SIN:
- return fast_sin(input);
- case TAN:
- return fast_tan(input);
default:
+ UNREACHABLE();
return 0.0; // Never happens.
}
}
diff --git a/src/heap-profiler.cc b/src/heap-profiler.cc
index 6ae6272..1e40950 100644
--- a/src/heap-profiler.cc
+++ b/src/heap-profiler.cc
@@ -118,7 +118,7 @@
is_tracking_object_moves_ = true;
ASSERT(!is_tracking_allocations());
if (track_allocations) {
- allocation_tracker_.Reset(new AllocationTracker(*ids_, *names_));
+ allocation_tracker_.Reset(new AllocationTracker(ids_.get(), names_.get()));
heap()->DisableInlineAllocation();
}
}
diff --git a/src/heap-profiler.h b/src/heap-profiler.h
index 3dd5b4d..6d15868 100644
--- a/src/heap-profiler.h
+++ b/src/heap-profiler.h
@@ -55,9 +55,11 @@
void StartHeapObjectsTracking(bool track_allocations);
void StopHeapObjectsTracking();
- AllocationTracker* allocation_tracker() { return *allocation_tracker_; }
- HeapObjectsMap* heap_object_map() { return *ids_; }
- StringsStorage* names() { return *names_; }
+ AllocationTracker* allocation_tracker() const {
+ return allocation_tracker_.get();
+ }
+ HeapObjectsMap* heap_object_map() const { return ids_.get(); }
+ StringsStorage* names() const { return names_.get(); }
SnapshotObjectId PushHeapObjectsStats(OutputStream* stream);
int GetSnapshotsCount();
@@ -80,7 +82,9 @@
void SetRetainedObjectInfo(UniqueId id, RetainedObjectInfo* info);
bool is_tracking_object_moves() const { return is_tracking_object_moves_; }
- bool is_tracking_allocations() { return !allocation_tracker_.is_empty(); }
+ bool is_tracking_allocations() const {
+ return !allocation_tracker_.is_empty();
+ }
Handle<HeapObject> FindHeapObjectById(SnapshotObjectId id);
diff --git a/src/heap-snapshot-generator.cc b/src/heap-snapshot-generator.cc
index 84e819d..b9bea75 100644
--- a/src/heap-snapshot-generator.cc
+++ b/src/heap-snapshot-generator.cc
@@ -202,6 +202,7 @@
} // namespace
+
HeapSnapshot::HeapSnapshot(HeapProfiler* profiler,
const char* title,
unsigned uid)
@@ -218,6 +219,10 @@
STATIC_CHECK(
sizeof(HeapEntry) ==
SnapshotSizeConstants<kPointerSize>::kExpectedHeapEntrySize);
+ USE(SnapshotSizeConstants<4>::kExpectedHeapGraphEdgeSize);
+ USE(SnapshotSizeConstants<4>::kExpectedHeapEntrySize);
+ USE(SnapshotSizeConstants<8>::kExpectedHeapGraphEdgeSize);
+ USE(SnapshotSizeConstants<8>::kExpectedHeapEntrySize);
for (int i = 0; i < VisitorSynchronization::kNumberOfSyncTags; ++i) {
gc_subroot_indexes_[i] = HeapEntry::kNoEntry;
}
@@ -1854,8 +1859,8 @@
const char* name = name_format_string != NULL && reference_name->IsString()
? names_->GetFormatted(
name_format_string,
- *String::cast(reference_name)->ToCString(
- DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL)) :
+ String::cast(reference_name)->ToCString(
+ DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL).get()) :
names_->GetName(reference_name);
filler_->SetNamedReference(type,
diff --git a/src/heap.cc b/src/heap.cc
index d5c40ad..13c874a 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -1548,9 +1548,6 @@
promotion_queue_.Destroy();
- if (!FLAG_watch_ic_patching) {
- isolate()->runtime_profiler()->UpdateSamplesAfterScavenge();
- }
incremental_marking()->UpdateMarkingDequeAfterScavenge();
ScavengeWeakObjectRetainer weak_object_retainer(this);
diff --git a/src/heap.h b/src/heap.h
index 1c8e0e1..c8ccb7f 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -2904,7 +2904,7 @@
class TranscendentalCache {
public:
- enum Type {ACOS, ASIN, ATAN, COS, EXP, LOG, SIN, TAN, kNumberOfCaches};
+ enum Type { LOG, kNumberOfCaches};
static const int kTranscendentalTypeBits = 3;
STATIC_ASSERT((1 << kTranscendentalTypeBits) >= kNumberOfCaches);
diff --git a/src/hydrogen-dce.cc b/src/hydrogen-dce.cc
index e101ee5..3a2eac4 100644
--- a/src/hydrogen-dce.cc
+++ b/src/hydrogen-dce.cc
@@ -64,7 +64,7 @@
}
stream.Add(" -> ");
instr->PrintTo(&stream);
- PrintF("[MarkLive %s]\n", *stream.ToCString());
+ PrintF("[MarkLive %s]\n", stream.ToCString().get());
}
diff --git a/src/hydrogen-gvn.cc b/src/hydrogen-gvn.cc
index 02b3a0a..3ad9312 100644
--- a/src/hydrogen-gvn.cc
+++ b/src/hydrogen-gvn.cc
@@ -412,10 +412,13 @@
// Propagate loop side effects upwards.
if (block->HasParentLoopHeader()) {
- int header_id = block->parent_loop_header()->block_id();
- loop_side_effects_[header_id].Add(block->IsLoopHeader()
- ? loop_side_effects_[id]
- : side_effects);
+ HBasicBlock* with_parent = block;
+ if (block->IsLoopHeader()) side_effects = loop_side_effects_[id];
+ do {
+ HBasicBlock* parent_block = with_parent->parent_loop_header();
+ loop_side_effects_[parent_block->block_id()].Add(side_effects);
+ with_parent = parent_block;
+ } while (with_parent->HasParentLoopHeader());
}
}
}
@@ -517,7 +520,7 @@
GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
TRACE_GVN_2("Try loop invariant motion for block B%d %s\n",
block->block_id(),
- *GetGVNFlagsString(side_effects));
+ GetGVNFlagsString(side_effects).get());
GVNFlagSet accumulated_first_time_depends;
GVNFlagSet accumulated_first_time_changes;
@@ -542,7 +545,7 @@
GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
TRACE_GVN_2("Loop invariant motion for B%d %s\n",
block->block_id(),
- *GetGVNFlagsString(depends_flags));
+ GetGVNFlagsString(depends_flags).get());
HInstruction* instr = block->first();
while (instr != NULL) {
HInstruction* next = instr->next();
@@ -551,8 +554,8 @@
TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n",
instr->id(),
instr->Mnemonic(),
- *GetGVNFlagsString(instr->gvn_flags()),
- *GetGVNFlagsString(loop_kills));
+ GetGVNFlagsString(instr->gvn_flags()).get(),
+ GetGVNFlagsString(loop_kills).get());
bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
if (can_hoist && !graph()->use_optimistic_licm()) {
can_hoist = block->IsLoopSuccessorDominator();
@@ -567,7 +570,8 @@
}
if (inputs_loop_invariant && ShouldMove(instr, loop_header)) {
- TRACE_GVN_1("Hoisting loop invariant instruction %d\n", instr->id());
+ TRACE_GVN_2("Hoisting loop invariant instruction i%d to block B%d\n",
+ instr->id(), pre_header->block_id());
// Move the instruction out of the loop.
instr->Unlink();
instr->InsertBefore(pre_header->end());
@@ -585,11 +589,11 @@
first_time_changes->Add(instr->ChangesFlags());
if (!(previous_depends == *first_time_depends)) {
TRACE_GVN_1("Updated first-time accumulated %s\n",
- *GetGVNFlagsString(*first_time_depends));
+ GetGVNFlagsString(*first_time_depends).get());
}
if (!(previous_changes == *first_time_changes)) {
TRACE_GVN_1("Updated first-time accumulated %s\n",
- *GetGVNFlagsString(*first_time_changes));
+ GetGVNFlagsString(*first_time_changes).get());
}
}
instr = next;
@@ -801,7 +805,7 @@
map->Kill(flags);
dominators->Store(flags, instr);
TRACE_GVN_2("Instruction %d %s\n", instr->id(),
- *GetGVNFlagsString(flags));
+ GetGVNFlagsString(flags).get());
}
if (instr->CheckFlag(HValue::kUseGVN)) {
ASSERT(!instr->HasObservableSideEffects());
diff --git a/src/hydrogen-instructions.cc b/src/hydrogen-instructions.cc
index 9f96202..e7ad219 100644
--- a/src/hydrogen-instructions.cc
+++ b/src/hydrogen-instructions.cc
@@ -1119,9 +1119,6 @@
case kMathRound: return "round";
case kMathAbs: return "abs";
case kMathLog: return "log";
- case kMathSin: return "sin";
- case kMathCos: return "cos";
- case kMathTan: return "tan";
case kMathExp: return "exp";
case kMathSqrt: return "sqrt";
case kMathPowHalf: return "pow-half";
@@ -1536,7 +1533,7 @@
*tag = kStringTag;
return;
case IS_INTERNALIZED_STRING:
- *mask = kIsNotInternalizedMask;
+ *mask = kIsNotStringMask | kIsNotInternalizedMask;
*tag = kInternalizedTag;
return;
default:
@@ -1779,10 +1776,7 @@
result->set_can_be_minus_zero(!CheckFlag(kAllUsesTruncatingToInt32) &&
(a->CanBeMinusZero() ||
(a->CanBeZero() && b->CanBeNegative())));
- if (!a->Includes(kMinInt) ||
- !b->Includes(-1) ||
- CheckFlag(kAllUsesTruncatingToInt32)) {
- // It is safe to clear kCanOverflow when kAllUsesTruncatingToInt32.
+ if (!a->Includes(kMinInt) || !b->Includes(-1)) {
ClearFlag(HValue::kCanOverflow);
}
@@ -2501,7 +2495,7 @@
void HEnterInlined::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name = function()->debug_name()->ToCString();
- stream->Add("%s, id=%d", *name, function()->id().ToInt());
+ stream->Add("%s, id=%d", name.get(), function()->id().ToInt());
}
@@ -3112,7 +3106,7 @@
void HLoadNamedGeneric::PrintDataTo(StringStream* stream) {
object()->PrintNameTo(stream);
stream->Add(".");
- stream->Add(*String::cast(*name())->ToCString());
+ stream->Add(String::cast(*name())->ToCString().get());
}
@@ -3250,7 +3244,7 @@
object()->PrintNameTo(stream);
stream->Add(".");
ASSERT(name()->IsString());
- stream->Add(*String::cast(*name())->ToCString());
+ stream->Add(String::cast(*name())->ToCString().get());
stream->Add(" = ");
value()->PrintNameTo(stream);
}
@@ -3859,10 +3853,6 @@
}
if (std::isinf(d)) { // +Infinity and -Infinity.
switch (op) {
- case kMathSin:
- case kMathCos:
- case kMathTan:
- return H_CONSTANT_DOUBLE(OS::nan_value());
case kMathExp:
return H_CONSTANT_DOUBLE((d > 0.0) ? d : 0.0);
case kMathLog:
@@ -3880,12 +3870,6 @@
}
}
switch (op) {
- case kMathSin:
- return H_CONSTANT_DOUBLE(fast_sin(d));
- case kMathCos:
- return H_CONSTANT_DOUBLE(fast_cos(d));
- case kMathTan:
- return H_CONSTANT_DOUBLE(fast_tan(d));
case kMathExp:
return H_CONSTANT_DOUBLE(fast_exp(d));
case kMathLog:
@@ -4269,6 +4253,29 @@
}
+HObjectAccess HObjectAccess::ForAllocationSiteOffset(int offset) {
+ switch (offset) {
+ case AllocationSite::kTransitionInfoOffset:
+ return HObjectAccess(kInobject, offset, Representation::Tagged());
+ case AllocationSite::kNestedSiteOffset:
+ return HObjectAccess(kInobject, offset, Representation::Tagged());
+ case AllocationSite::kMementoFoundCountOffset:
+ return HObjectAccess(kInobject, offset, Representation::Smi());
+ case AllocationSite::kMementoCreateCountOffset:
+ return HObjectAccess(kInobject, offset, Representation::Smi());
+ case AllocationSite::kPretenureDecisionOffset:
+ return HObjectAccess(kInobject, offset, Representation::Smi());
+ case AllocationSite::kDependentCodeOffset:
+ return HObjectAccess(kInobject, offset, Representation::Tagged());
+ case AllocationSite::kWeakNextOffset:
+ return HObjectAccess(kInobject, offset, Representation::Tagged());
+ default:
+ UNREACHABLE();
+ }
+ return HObjectAccess(kInobject, offset);
+}
+
+
HObjectAccess HObjectAccess::ForContextSlot(int index) {
ASSERT(index >= 0);
Portion portion = kInobject;
@@ -4402,11 +4409,15 @@
break;
case kDouble: // fall through
case kInobject:
- if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
+ if (!name_.is_null()) {
+ stream->Add(String::cast(*name_)->ToCString().get());
+ }
stream->Add("[in-object]");
break;
case kBackingStore:
- if (!name_.is_null()) stream->Add(*String::cast(*name_)->ToCString());
+ if (!name_.is_null()) {
+ stream->Add(String::cast(*name_)->ToCString().get());
+ }
stream->Add("[backing-store]");
break;
case kExternalMemory:
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index 9f7605f..23dbbd2 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2638,9 +2638,6 @@
case kMathPowHalf:
case kMathLog:
case kMathExp:
- case kMathSin:
- case kMathCos:
- case kMathTan:
return Representation::Double();
case kMathAbs:
return representation();
@@ -2685,9 +2682,6 @@
SetGVNFlag(kChangesNewSpacePromotion);
break;
case kMathLog:
- case kMathSin:
- case kMathCos:
- case kMathTan:
set_representation(Representation::Double());
// These operations use the TranscendentalCache, so they may allocate.
SetGVNFlag(kChangesNewSpacePromotion);
@@ -5961,10 +5955,7 @@
? Representation::Smi() : Representation::Tagged());
}
- static HObjectAccess ForAllocationSiteOffset(int offset) {
- ASSERT(offset >= HeapObject::kHeaderSize && offset < AllocationSite::kSize);
- return HObjectAccess(kInobject, offset);
- }
+ static HObjectAccess ForAllocationSiteOffset(int offset);
static HObjectAccess ForAllocationSiteList() {
return HObjectAccess(kExternalMemory, 0, Representation::Tagged());
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 900e07e..176dd9f 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -2592,6 +2592,9 @@
AllocationSite::kMementoCreateCountOffset));
memento_create_count = AddUncasted<HAdd>(
memento_create_count, graph()->GetConstant1());
+ // This smi value is reset to zero after every gc, overflow isn't a problem
+ // since the counter is bounded by the new space size.
+ memento_create_count->ClearFlag(HValue::kCanOverflow);
HStoreNamedField* store = Add<HStoreNamedField>(
allocation_site, HObjectAccess::ForAllocationSiteOffset(
AllocationSite::kMementoCreateCountOffset), memento_create_count);
@@ -6779,7 +6782,7 @@
SmartArrayPointer<char> caller_name =
caller->shared()->DebugName()->ToCString();
PrintF("Trying to inline the polymorphic call to %s from %s\n",
- *name->ToCString(), *caller_name);
+ name->ToCString().get(), caller_name.get());
}
if (!TryInlineCall(expr)) {
@@ -6892,8 +6895,8 @@
SmartArrayPointer<char> caller_name =
caller->shared()->DebugName()->ToCString();
PrintF("Trying to inline the polymorphic call to %s from %s\n",
- *name->ToCString(),
- *caller_name);
+ name->ToCString().get(),
+ caller_name.get());
}
if (FLAG_polymorphic_inlining && TryInlineCall(expr)) {
// Trying to inline will signal that we should bailout from the
@@ -6957,10 +6960,11 @@
SmartArrayPointer<char> caller_name =
caller->shared()->DebugName()->ToCString();
if (reason == NULL) {
- PrintF("Inlined %s called from %s.\n", *target_name, *caller_name);
+ PrintF("Inlined %s called from %s.\n", target_name.get(),
+ caller_name.get());
} else {
PrintF("Did not inline %s called from %s (%s).\n",
- *target_name, *caller_name, reason);
+ target_name.get(), caller_name.get(), reason);
}
}
}
@@ -10496,7 +10500,7 @@
HeapStringAllocator string_allocator;
StringStream trace(&string_allocator);
PrintTo(&trace);
- PrintF("%s", *trace.ToCString());
+ PrintF("%s", trace.ToCString().get());
}
@@ -10504,8 +10508,8 @@
Tag tag(this, "compilation");
if (info->IsOptimizing()) {
Handle<String> name = info->function()->debug_name();
- PrintStringProperty("name", *name->ToCString());
- PrintStringProperty("method", *name->ToCString());
+ PrintStringProperty("name", name->ToCString().get());
+ PrintStringProperty("method", name->ToCString().get());
} else {
CodeStub::Major major_key = info->code_stub()->MajorKey();
PrintStringProperty("name", CodeStub::MajorName(major_key, false));
@@ -10725,7 +10729,8 @@
void HTracer::FlushToFile() {
- AppendChars(filename_.start(), *trace_.ToCString(), trace_.length(), false);
+ AppendChars(filename_.start(), trace_.ToCString().get(), trace_.length(),
+ false);
trace_.Reset();
}
diff --git a/src/ia32/builtins-ia32.cc b/src/ia32/builtins-ia32.cc
index 32c3397..7b44bc0 100644
--- a/src/ia32/builtins-ia32.cc
+++ b/src/ia32/builtins-ia32.cc
@@ -1316,17 +1316,9 @@
__ mov(eax, Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
{
FrameScope scope(masm, StackFrame::INTERNAL);
- // Lookup and calculate pc offset.
- __ mov(edx, Operand(ebp, StandardFrameConstants::kCallerPCOffset));
- __ mov(ebx, FieldOperand(eax, JSFunction::kSharedFunctionInfoOffset));
- __ sub(edx, Immediate(Code::kHeaderSize - kHeapObjectTag));
- __ sub(edx, FieldOperand(ebx, SharedFunctionInfo::kCodeOffset));
- __ SmiTag(edx);
-
- // Pass both function and pc offset as arguments.
+ // Pass function as argument.
__ push(eax);
- __ push(edx);
- __ CallRuntime(Runtime::kCompileForOnStackReplacement, 2);
+ __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
}
Label skip;
diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc
index 0481814..4633400 100644
--- a/src/ia32/code-stubs-ia32.cc
+++ b/src/ia32/code-stubs-ia32.cc
@@ -896,9 +896,6 @@
Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
switch (type_) {
- case TranscendentalCache::SIN: return Runtime::kMath_sin;
- case TranscendentalCache::COS: return Runtime::kMath_cos;
- case TranscendentalCache::TAN: return Runtime::kMath_tan;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
@@ -913,95 +910,10 @@
// Input value is on FP stack, and also in ebx/edx.
// Input value is possibly in xmm1.
// Address of result (a newly allocated HeapNumber) may be in eax.
- if (type == TranscendentalCache::SIN ||
- type == TranscendentalCache::COS ||
- type == TranscendentalCache::TAN) {
- // Both fsin and fcos require arguments in the range +/-2^63 and
- // return NaN for infinities and NaN. They can share all code except
- // the actual fsin/fcos operation.
- Label in_range, done;
- // If argument is outside the range -2^63..2^63, fsin/cos doesn't
- // work. We must reduce it to the appropriate range.
- __ mov(edi, edx);
- __ and_(edi, Immediate(0x7ff00000)); // Exponent only.
- int supported_exponent_limit =
- (63 + HeapNumber::kExponentBias) << HeapNumber::kExponentShift;
- __ cmp(edi, Immediate(supported_exponent_limit));
- __ j(below, &in_range, Label::kNear);
- // Check for infinity and NaN. Both return NaN for sin.
- __ cmp(edi, Immediate(0x7ff00000));
- Label non_nan_result;
- __ j(not_equal, &non_nan_result, Label::kNear);
- // Input is +/-Infinity or NaN. Result is NaN.
- __ fstp(0);
- // NaN is represented by 0x7ff8000000000000.
- __ push(Immediate(0x7ff80000));
- __ push(Immediate(0));
- __ fld_d(Operand(esp, 0));
- __ add(esp, Immediate(2 * kPointerSize));
- __ jmp(&done, Label::kNear);
-
- __ bind(&non_nan_result);
-
- // Use fpmod to restrict argument to the range +/-2*PI.
- __ mov(edi, eax); // Save eax before using fnstsw_ax.
- __ fldpi();
- __ fadd(0);
- __ fld(1);
- // FPU Stack: input, 2*pi, input.
- {
- Label no_exceptions;
- __ fwait();
- __ fnstsw_ax();
- // Clear if Illegal Operand or Zero Division exceptions are set.
- __ test(eax, Immediate(5));
- __ j(zero, &no_exceptions, Label::kNear);
- __ fnclex();
- __ bind(&no_exceptions);
- }
-
- // Compute st(0) % st(1)
- {
- Label partial_remainder_loop;
- __ bind(&partial_remainder_loop);
- __ fprem1();
- __ fwait();
- __ fnstsw_ax();
- __ test(eax, Immediate(0x400 /* C2 */));
- // If C2 is set, computation only has partial result. Loop to
- // continue computation.
- __ j(not_zero, &partial_remainder_loop);
- }
- // FPU Stack: input, 2*pi, input % 2*pi
- __ fstp(2);
- __ fstp(0);
- __ mov(eax, edi); // Restore eax (allocated HeapNumber pointer).
-
- // FPU Stack: input % 2*pi
- __ bind(&in_range);
- switch (type) {
- case TranscendentalCache::SIN:
- __ fsin();
- break;
- case TranscendentalCache::COS:
- __ fcos();
- break;
- case TranscendentalCache::TAN:
- // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the
- // FP register stack.
- __ fptan();
- __ fstp(0); // Pop FP register stack.
- break;
- default:
- UNREACHABLE();
- }
- __ bind(&done);
- } else {
- ASSERT(type == TranscendentalCache::LOG);
- __ fldln2();
- __ fxch();
- __ fyl2x();
- }
+ ASSERT(type == TranscendentalCache::LOG);
+ __ fldln2();
+ __ fxch();
+ __ fyl2x();
}
diff --git a/src/ia32/codegen-ia32.cc b/src/ia32/codegen-ia32.cc
index ab4029d..84187b0 100644
--- a/src/ia32/codegen-ia32.cc
+++ b/src/ia32/codegen-ia32.cc
@@ -66,9 +66,6 @@
if (buffer == NULL) {
// Fallback to library function if function cannot be created.
switch (type) {
- case TranscendentalCache::SIN: return &sin;
- case TranscendentalCache::COS: return &cos;
- case TranscendentalCache::TAN: return &tan;
case TranscendentalCache::LOG: return &log;
default: UNIMPLEMENTED();
}
diff --git a/src/ia32/full-codegen-ia32.cc b/src/ia32/full-codegen-ia32.cc
index 3c5d4aa..3c92afa 100644
--- a/src/ia32/full-codegen-ia32.cc
+++ b/src/ia32/full-codegen-ia32.cc
@@ -319,10 +319,6 @@
void FullCodeGenerator::EmitProfilingCounterReset() {
int reset_value = FLAG_interrupt_budget;
- if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
- // Self-optimization is a one-off thing: if it fails, don't try again.
- reset_value = Smi::kMaxValue;
- }
__ mov(ebx, Immediate(profiling_counter_));
__ mov(FieldOperand(ebx, Cell::kValueOffset),
Immediate(Smi::FromInt(reset_value)));
@@ -334,13 +330,10 @@
Comment cmnt(masm_, "[ Back edge bookkeeping");
Label ok;
- int weight = 1;
- if (FLAG_weighted_back_edges) {
- ASSERT(back_edge_target->is_bound());
- int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
+ ASSERT(back_edge_target->is_bound());
+ int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
+ int weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
__ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
@@ -372,31 +365,24 @@
__ push(eax);
__ CallRuntime(Runtime::kTraceExit, 1);
}
- if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
- // Pretend that the exit is a backwards jump to the entry.
- int weight = 1;
- if (info_->ShouldSelfOptimize()) {
- weight = FLAG_interrupt_budget / FLAG_self_opt_count;
- } else if (FLAG_weighted_back_edges) {
- int distance = masm_->pc_offset();
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
- EmitProfilingCounterDecrement(weight);
- Label ok;
- __ j(positive, &ok, Label::kNear);
- __ push(eax);
- if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
- __ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
- __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
- } else {
- __ call(isolate()->builtins()->InterruptCheck(),
- RelocInfo::CODE_TARGET);
- }
- __ pop(eax);
- EmitProfilingCounterReset();
- __ bind(&ok);
+ // Pretend that the exit is a backwards jump to the entry.
+ int weight = 1;
+ if (info_->ShouldSelfOptimize()) {
+ weight = FLAG_interrupt_budget / FLAG_self_opt_count;
+ } else {
+ int distance = masm_->pc_offset();
+ weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
}
+ EmitProfilingCounterDecrement(weight);
+ Label ok;
+ __ j(positive, &ok, Label::kNear);
+ __ push(eax);
+ __ call(isolate()->builtins()->InterruptCheck(),
+ RelocInfo::CODE_TARGET);
+ __ pop(eax);
+ EmitProfilingCounterReset();
+ __ bind(&ok);
#ifdef DEBUG
// Add a label for checking the size of the code used for returning.
Label check_exit_codesize;
@@ -4847,9 +4833,11 @@
static const byte kJnsInstruction = 0x79;
static const byte kJnsOffset = 0x11;
-static const byte kCallInstruction = 0xe8;
static const byte kNopByteOne = 0x66;
static const byte kNopByteTwo = 0x90;
+#ifdef DEBUG
+static const byte kCallInstruction = 0xe8;
+#endif
void BackEdgeTable::PatchAt(Code* unoptimized_code,
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc
index 28ae469..bba3aca 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -4197,39 +4197,6 @@
}
-void LCodeGen::DoMathTan(LMathTan* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ Set(esi, Immediate(0));
- TranscendentalCacheStub stub(TranscendentalCache::TAN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathCos(LMathCos* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ Set(esi, Immediate(0));
- TranscendentalCacheStub stub(TranscendentalCache::COS,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathSin(LMathSin* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ Set(esi, Immediate(0));
- TranscendentalCacheStub stub(TranscendentalCache::SIN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
ASSERT(ToRegister(instr->context()).is(esi));
ASSERT(ToRegister(instr->function()).is(edi));
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index aa35e9d..aca9bdf 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -286,7 +286,7 @@
stream->Add("if typeof ");
value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
- *hydrogen()->type_literal()->ToCString(),
+ hydrogen()->type_literal()->ToCString().get(),
true_block_id(), false_block_id());
}
@@ -341,13 +341,13 @@
void LCallNamed::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
void LCallGlobal::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
@@ -420,7 +420,7 @@
void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add(".");
- stream->Add(*String::cast(*name())->ToCString());
+ stream->Add(String::cast(*name())->ToCString().get());
stream->Add(" <- ");
value()->PrintTo(stream);
}
@@ -1272,9 +1272,6 @@
case kMathRound: return DoMathRound(instr);
case kMathAbs: return DoMathAbs(instr);
case kMathLog: return DoMathLog(instr);
- case kMathSin: return DoMathSin(instr);
- case kMathCos: return DoMathCos(instr);
- case kMathTan: return DoMathTan(instr);
case kMathExp: return DoMathExp(instr);
case kMathSqrt: return DoMathSqrt(instr);
case kMathPowHalf: return DoMathPowHalf(instr);
@@ -1317,27 +1314,6 @@
}
-LInstruction* LChunkBuilder::DoMathSin(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), xmm1);
- LMathSin* result = new(zone()) LMathSin(input);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathCos(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), xmm1);
- LMathCos* result = new(zone()) LMathCos(input);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), xmm1);
- LMathTan* result = new(zone()) LMathTan(input);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
-}
-
-
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble());
diff --git a/src/ia32/lithium-ia32.h b/src/ia32/lithium-ia32.h
index ea4fef8..912ec1e 100644
--- a/src/ia32/lithium-ia32.h
+++ b/src/ia32/lithium-ia32.h
@@ -133,7 +133,6 @@
V(LoadRoot) \
V(MapEnumLength) \
V(MathAbs) \
- V(MathCos) \
V(MathExp) \
V(MathFloor) \
V(MathFloorOfDiv) \
@@ -141,9 +140,7 @@
V(MathMinMax) \
V(MathPowHalf) \
V(MathRound) \
- V(MathSin) \
V(MathSqrt) \
- V(MathTan) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -792,42 +789,6 @@
};
-class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathSin(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
-};
-
-
-class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathCos(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
-};
-
-
-class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathTan(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
-};
-
-
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 2> {
public:
LMathExp(LOperand* value,
@@ -2787,9 +2748,6 @@
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
- LInstruction* DoMathSin(HUnaryMathOperation* instr);
- LInstruction* DoMathCos(HUnaryMathOperation* instr);
- LInstruction* DoMathTan(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc
index f4f3b2b..88923c3 100644
--- a/src/ia32/stub-cache-ia32.cc
+++ b/src/ia32/stub-cache-ia32.cc
@@ -647,8 +647,7 @@
public:
CallInterceptorCompiler(CallStubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name,
- ExtraICState extra_state)
+ Register name)
: stub_compiler_(stub_compiler),
arguments_(arguments),
name_(name) {}
@@ -2589,7 +2588,7 @@
// Get the receiver from the stack.
__ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
- CallInterceptorCompiler compiler(this, arguments(), ecx, extra_state());
+ CallInterceptorCompiler compiler(this, arguments(), ecx);
compiler.Compile(masm(), object, holder, name, &lookup, edx, ebx, edi, eax,
&miss);
diff --git a/src/ic.cc b/src/ic.cc
index 8a25504..25f875a 100644
--- a/src/ic.cc
+++ b/src/ic.cc
@@ -440,9 +440,6 @@
void IC::PostPatching(Address address, Code* target, Code* old_target) {
- if (FLAG_type_info_threshold == 0 && !FLAG_watch_ic_patching) {
- return;
- }
Isolate* isolate = target->GetHeap()->isolate();
Code* host = isolate->
inner_pointer_to_code_cache()->GetCacheEntry(address)->code;
@@ -465,10 +462,8 @@
TypeFeedbackInfo::cast(host->type_feedback_info());
info->change_own_type_change_checksum();
}
- if (FLAG_watch_ic_patching) {
- host->set_profiler_ticks(0);
- isolate->runtime_profiler()->NotifyICChanged();
- }
+ host->set_profiler_ticks(0);
+ isolate->runtime_profiler()->NotifyICChanged();
// TODO(2029): When an optimized function is patched, it would
// be nice to propagate the corresponding type information to its
// unoptimized version for the benefit of later inlining.
diff --git a/src/isolate.cc b/src/isolate.cc
index 25bc546..a0dd958 100644
--- a/src/isolate.cc
+++ b/src/isolate.cc
@@ -1182,7 +1182,7 @@
fatal_exception_depth++;
PrintF(stderr,
"%s\n\nFROM\n",
- *MessageHandler::GetLocalizedMessage(this, message_obj));
+ MessageHandler::GetLocalizedMessage(this, message_obj).get());
PrintCurrentStackTrace(stderr);
OS::Abort();
}
@@ -1197,13 +1197,13 @@
if (exception->IsString() && location->script()->name()->IsString()) {
OS::PrintError(
"Extension or internal compilation error: %s in %s at line %d.\n",
- *String::cast(exception)->ToCString(),
- *String::cast(location->script()->name())->ToCString(),
+ String::cast(exception)->ToCString().get(),
+ String::cast(location->script()->name())->ToCString().get(),
line_number + 1);
} else if (location->script()->name()->IsString()) {
OS::PrintError(
"Extension or internal compilation error in %s at line %d.\n",
- *String::cast(location->script()->name())->ToCString(),
+ String::cast(location->script()->name())->ToCString().get(),
line_number + 1);
} else {
OS::PrintError("Extension or internal compilation error.\n");
@@ -1688,7 +1688,6 @@
bootstrapper_->TearDown();
if (runtime_profiler_ != NULL) {
- runtime_profiler_->TearDown();
delete runtime_profiler_;
runtime_profiler_ = NULL;
}
@@ -2049,7 +2048,6 @@
if (!create_heap_objects) Assembler::QuietNaN(heap_.nan_value());
runtime_profiler_ = new RuntimeProfiler(this);
- runtime_profiler_->SetUp();
// If we are deserializing, log non-function code objects and compiled
// functions found in the snapshot.
diff --git a/src/jsregexp.cc b/src/jsregexp.cc
index 1f3f2a1..edd2eac 100644
--- a/src/jsregexp.cc
+++ b/src/jsregexp.cc
@@ -645,8 +645,8 @@
#if defined(V8_INTERPRETED_REGEXP) && defined(DEBUG)
if (FLAG_trace_regexp_bytecodes) {
String* pattern = regexp->Pattern();
- PrintF("\n\nRegexp match: /%s/\n\n", *(pattern->ToCString()));
- PrintF("\n\nSubject string: '%s'\n\n", *(subject->ToCString()));
+ PrintF("\n\nRegexp match: /%s/\n\n", pattern->ToCString().get());
+ PrintF("\n\nSubject string: '%s'\n\n", subject->ToCString().get());
}
#endif
int required_registers = RegExpImpl::IrregexpPrepare(regexp, subject);
@@ -1151,7 +1151,7 @@
#ifdef DEBUG
if (FLAG_print_code) {
CodeTracer::Scope trace_scope(heap->isolate()->GetCodeTracer());
- Handle<Code>::cast(code)->Disassemble(*pattern->ToCString(),
+ Handle<Code>::cast(code)->Disassemble(pattern->ToCString().get(),
trace_scope.file());
}
if (FLAG_trace_regexp_assembler) {
@@ -4374,7 +4374,7 @@
stream()->Add("\"];\n");
Visit(node);
stream()->Add("}\n");
- printf("%s", *(stream()->ToCString()));
+ printf("%s", stream()->ToCString().get());
}
@@ -4669,7 +4669,7 @@
StringStream stream(&alloc);
DispatchTableDumper dumper(&stream);
tree()->ForEach(&dumper);
- OS::PrintError("%s", *stream.ToCString());
+ OS::PrintError("%s", stream.ToCString().get());
}
diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
index 29c3194..48fa862 100644
--- a/src/lithium-allocator.cc
+++ b/src/lithium-allocator.cc
@@ -1369,7 +1369,7 @@
ASSERT(chunk_->info()->IsOptimizing());
AllowHandleDereference allow_deref;
PrintF("Function: %s\n",
- *chunk_->info()->function()->debug_name()->ToCString());
+ chunk_->info()->function()->debug_name()->ToCString().get());
}
PrintF("Value %d used before first definition!\n", operand_index);
LiveRange* range = LiveRangeFor(operand_index);
diff --git a/src/log.cc b/src/log.cc
index a508e87..95362c0 100644
--- a/src/log.cc
+++ b/src/log.cc
@@ -1041,7 +1041,7 @@
if (key->IsString()) {
SmartArrayPointer<char> str =
String::cast(key)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- ApiEvent("api,check-security,\"%s\"\n", *str);
+ ApiEvent("api,check-security,\"%s\"\n", str.get());
} else if (key->IsSymbol()) {
Symbol* symbol = Symbol::cast(key);
if (symbol->name()->IsUndefined()) {
@@ -1051,7 +1051,7 @@
SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,check-security,symbol(\"%s\" hash %x)\n",
- *str,
+ str.get(),
Symbol::cast(key)->Hash());
}
} else if (key->IsUndefined()) {
@@ -1253,17 +1253,18 @@
if (name->IsString()) {
SmartArrayPointer<char> property_name =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, *class_name, *property_name);
+ ApiEvent("api,%s,\"%s\",\"%s\"\n", tag, class_name.get(),
+ property_name.get());
} else {
Symbol* symbol = Symbol::cast(name);
uint32_t hash = symbol->Hash();
if (symbol->name()->IsUndefined()) {
- ApiEvent("api,%s,\"%s\",symbol(hash %x)\n", tag, *class_name, hash);
+ ApiEvent("api,%s,\"%s\",symbol(hash %x)\n", tag, class_name.get(), hash);
} else {
SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
ApiEvent("api,%s,\"%s\",symbol(\"%s\" hash %x)\n",
- tag, *class_name, *str, hash);
+ tag, class_name.get(), str.get(), hash);
}
}
}
@@ -1275,7 +1276,7 @@
String* class_name_obj = holder->class_name();
SmartArrayPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- ApiEvent("api,%s,\"%s\",%u\n", tag, *class_name, index);
+ ApiEvent("api,%s,\"%s\",%u\n", tag, class_name.get(), index);
}
@@ -1284,7 +1285,7 @@
String* class_name_obj = object->class_name();
SmartArrayPointer<char> class_name =
class_name_obj->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- ApiEvent("api,%s,\"%s\"\n", tag, *class_name);
+ ApiEvent("api,%s,\"%s\"\n", tag, class_name.get());
}
@@ -1332,7 +1333,7 @@
if (name->IsString()) {
SmartArrayPointer<char> str =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append(",1,\"%s%s\"", prefix, *str);
+ msg.Append(",1,\"%s%s\"", prefix, str.get());
} else {
Symbol* symbol = Symbol::cast(name);
if (symbol->name()->IsUndefined()) {
@@ -1340,7 +1341,8 @@
} else {
SmartArrayPointer<char> str = String::cast(symbol->name())->ToCString(
DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append(",1,symbol(\"%s\" hash %x)", prefix, *str, symbol->Hash());
+ msg.Append(",1,symbol(\"%s\" hash %x)", prefix, str.get(),
+ symbol->Hash());
}
}
msg.Append('\n');
@@ -1439,7 +1441,7 @@
if (name->IsString()) {
SmartArrayPointer<char> str =
String::cast(name)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append("\"%s\"", *str);
+ msg.Append("\"%s\"", str.get());
} else {
msg.AppendSymbolName(Symbol::cast(name));
}
@@ -1470,11 +1472,11 @@
AppendCodeCreateHeader(&msg, tag, code);
SmartArrayPointer<char> name =
shared->DebugName()->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append("\"%s ", *name);
+ msg.Append("\"%s ", name.get());
if (source->IsString()) {
SmartArrayPointer<char> sourcestr =
String::cast(source)->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- msg.Append("%s", *sourcestr);
+ msg.Append("%s", sourcestr.get());
} else {
msg.AppendSymbolName(Symbol::cast(source));
}
@@ -2064,7 +2066,7 @@
SmartArrayPointer<const char> log_file_name =
PrepareLogFileName(isolate, FLAG_logfile);
- log_->Initialize(*log_file_name);
+ log_->Initialize(log_file_name.get());
if (FLAG_perf_basic_prof) {
@@ -2078,7 +2080,7 @@
}
if (FLAG_ll_prof) {
- ll_logger_ = new LowLevelLogger(*log_file_name);
+ ll_logger_ = new LowLevelLogger(log_file_name.get());
addCodeEventListener(ll_logger_);
}
diff --git a/src/mark-compact.cc b/src/mark-compact.cc
index 0e6b980..7da765d 100644
--- a/src/mark-compact.cc
+++ b/src/mark-compact.cc
@@ -2422,11 +2422,6 @@
}
}
- if (!FLAG_watch_ic_patching) {
- // Clean up dead objects from the runtime profiler.
- heap()->isolate()->runtime_profiler()->RemoveDeadSamples();
- }
-
if (FLAG_track_gc_object_stats) {
heap()->CheckpointObjectStats();
}
@@ -3514,12 +3509,6 @@
heap_->UpdateReferencesInExternalStringTable(
&UpdateReferenceInExternalStringTableEntry);
- if (!FLAG_watch_ic_patching) {
- // Update JSFunction pointers from the runtime profiler.
- heap()->isolate()->runtime_profiler()->UpdateSamplesAfterCompact(
- &updating_visitor);
- }
-
EvacuationWeakObjectRetainer evacuation_object_retainer;
heap()->ProcessWeakReferences(&evacuation_object_retainer);
diff --git a/src/messages.cc b/src/messages.cc
index 9eae67a..3f4484a 100644
--- a/src/messages.cc
+++ b/src/messages.cc
@@ -43,15 +43,15 @@
Handle<Object> message_obj) {
SmartArrayPointer<char> str = GetLocalizedMessage(isolate, message_obj);
if (loc == NULL) {
- PrintF("%s\n", *str);
+ PrintF("%s\n", str.get());
} else {
HandleScope scope(isolate);
Handle<Object> data(loc->script()->name(), isolate);
SmartArrayPointer<char> data_str;
if (data->IsString())
data_str = Handle<String>::cast(data)->ToCString(DISALLOW_NULLS);
- PrintF("%s:%i: %s\n", *data_str ? *data_str : "<unknown>",
- loc->start_pos(), *str);
+ PrintF("%s:%i: %s\n", data_str.get() ? data_str.get() : "<unknown>",
+ loc->start_pos(), str.get());
}
}
diff --git a/src/mips/assembler-mips.cc b/src/mips/assembler-mips.cc
index 9aed3bd..f551dd5 100644
--- a/src/mips/assembler-mips.cc
+++ b/src/mips/assembler-mips.cc
@@ -260,6 +260,12 @@
}
+MemOperand::MemOperand(Register rm, int32_t unit, int32_t multiplier,
+ OffsetAddend offset_addend) : Operand(rm) {
+ offset_ = unit * multiplier + offset_addend;
+}
+
+
// -----------------------------------------------------------------------------
// Specific instructions, constants, and masks.
@@ -1623,6 +1629,15 @@
}
+void Assembler::pref(int32_t hint, const MemOperand& rs) {
+ ASSERT(kArchVariant != kLoongson);
+ ASSERT(is_uint5(hint) && is_uint16(rs.offset_));
+ Instr instr = PREF | (rs.rm().code() << kRsShift) | (hint << kRtShift)
+ | (rs.offset_);
+ emit(instr);
+}
+
+
//--------Coprocessor-instructions----------------
// Load, store, move.
diff --git a/src/mips/assembler-mips.h b/src/mips/assembler-mips.h
index d9ef46c..70f77ea 100644
--- a/src/mips/assembler-mips.h
+++ b/src/mips/assembler-mips.h
@@ -386,7 +386,15 @@
// Class MemOperand represents a memory operand in load and store instructions.
class MemOperand : public Operand {
public:
+ // Immediate value attached to offset.
+ enum OffsetAddend {
+ offset_minus_one = -1,
+ offset_zero = 0
+ };
+
explicit MemOperand(Register rn, int32_t offset = 0);
+ explicit MemOperand(Register rn, int32_t unit, int32_t multiplier,
+ OffsetAddend offset_addend = offset_zero);
int32_t offset() const { return offset_; }
bool OffsetIsInt16Encodable() const {
@@ -711,6 +719,11 @@
void swr(Register rd, const MemOperand& rs);
+ //----------------Prefetch--------------------
+
+ void pref(int32_t hint, const MemOperand& rs);
+
+
//-------------Misc-instructions--------------
// Break / Trap instructions.
diff --git a/src/mips/builtins-mips.cc b/src/mips/builtins-mips.cc
index 19f3cdf..40cc99f 100644
--- a/src/mips/builtins-mips.cc
+++ b/src/mips/builtins-mips.cc
@@ -969,18 +969,9 @@
__ lw(a0, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
{
FrameScope scope(masm, StackFrame::INTERNAL);
- // Lookup and calculate pc offset.
- __ lw(a1, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
- __ lw(a2, FieldMemOperand(a0, JSFunction::kSharedFunctionInfoOffset));
- __ lw(a2, FieldMemOperand(a2, SharedFunctionInfo::kCodeOffset));
- __ Subu(a1, a1, Operand(Code::kHeaderSize - kHeapObjectTag));
- __ Subu(a1, a1, a2);
- __ SmiTag(a1);
-
- // Pass both function and pc offset as arguments.
+ // Pass function as argument.
__ push(a0);
- __ push(a1);
- __ CallRuntime(Runtime::kCompileForOnStackReplacement, 2);
+ __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
}
// If the code object is null, just return to the unoptimized code.
diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc
index 4c3708c..cd1af91 100644
--- a/src/mips/code-stubs-mips.cc
+++ b/src/mips/code-stubs-mips.cc
@@ -1467,20 +1467,6 @@
AllowExternalCallThatCantCauseGC scope(masm);
Isolate* isolate = masm->isolate();
switch (type_) {
- case TranscendentalCache::SIN:
- __ CallCFunction(
- ExternalReference::math_sin_double_function(isolate),
- 0, 1);
- break;
- case TranscendentalCache::COS:
- __ CallCFunction(
- ExternalReference::math_cos_double_function(isolate),
- 0, 1);
- break;
- case TranscendentalCache::TAN:
- __ CallCFunction(ExternalReference::math_tan_double_function(isolate),
- 0, 1);
- break;
case TranscendentalCache::LOG:
__ CallCFunction(
ExternalReference::math_log_double_function(isolate),
@@ -1497,9 +1483,6 @@
Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
switch (type_) {
// Add more cases when necessary.
- case TranscendentalCache::SIN: return Runtime::kMath_sin;
- case TranscendentalCache::COS: return Runtime::kMath_cos;
- case TranscendentalCache::TAN: return Runtime::kMath_tan;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
diff --git a/src/mips/codegen-mips.cc b/src/mips/codegen-mips.cc
index 3a87c5a..cd3a24f 100644
--- a/src/mips/codegen-mips.cc
+++ b/src/mips/codegen-mips.cc
@@ -39,9 +39,6 @@
UnaryMathFunction CreateTranscendentalFunction(TranscendentalCache::Type type) {
switch (type) {
- case TranscendentalCache::SIN: return &sin;
- case TranscendentalCache::COS: return &cos;
- case TranscendentalCache::TAN: return &tan;
case TranscendentalCache::LOG: return &log;
default: UNIMPLEMENTED();
}
@@ -113,6 +110,430 @@
}
+#if defined(V8_HOST_ARCH_MIPS)
+OS::MemCopyUint8Function CreateMemCopyUint8Function(
+ OS::MemCopyUint8Function stub) {
+#if defined(USE_SIMULATOR)
+ return stub;
+#else
+ if (Serializer::enabled()) {
+ return stub;
+ }
+
+ size_t actual_size;
+ byte* buffer = static_cast<byte*>(OS::Allocate(3 * KB, &actual_size, true));
+ if (buffer == NULL) return stub;
+
+ // This code assumes that cache lines are 32 bytes and if the cache line is
+ // larger it will not work correctly.
+ MacroAssembler masm(NULL, buffer, static_cast<int>(actual_size));
+
+ {
+ Label lastb, unaligned, aligned, chkw,
+ loop16w, chk1w, wordCopy_loop, skip_pref, lastbloop,
+ leave, ua_chk16w, ua_loop16w, ua_skip_pref, ua_chkw,
+ ua_chk1w, ua_wordCopy_loop, ua_smallCopy, ua_smallCopy_loop;
+
+ // The size of each prefetch.
+ uint32_t pref_chunk = 32;
+ // The maximum size of a prefetch, it must not be less then pref_chunk.
+ // If the real size of a prefetch is greater then max_pref_size and
+ // the kPrefHintPrepareForStore hint is used, the code will not work
+ // correctly.
+ uint32_t max_pref_size = 128;
+ ASSERT(pref_chunk < max_pref_size);
+
+ // pref_limit is set based on the fact that we never use an offset
+ // greater then 5 on a store pref and that a single pref can
+ // never be larger then max_pref_size.
+ uint32_t pref_limit = (5 * pref_chunk) + max_pref_size;
+ int32_t pref_hint_load = kPrefHintLoadStreamed;
+ int32_t pref_hint_store = kPrefHintPrepareForStore;
+ uint32_t loadstore_chunk = 4;
+
+ // The initial prefetches may fetch bytes that are before the buffer being
+ // copied. Start copies with an offset of 4 so avoid this situation when
+ // using kPrefHintPrepareForStore.
+ ASSERT(pref_hint_store != kPrefHintPrepareForStore ||
+ pref_chunk * 4 >= max_pref_size);
+
+ // If the size is less than 8, go to lastb. Regardless of size,
+ // copy dst pointer to v0 for the retuen value.
+ __ slti(t2, a2, 2 * loadstore_chunk);
+ __ bne(t2, zero_reg, &lastb);
+ __ mov(v0, a0); // In delay slot.
+
+ // If src and dst have different alignments, go to unaligned, if they
+ // have the same alignment (but are not actually aligned) do a partial
+ // load/store to make them aligned. If they are both already aligned
+ // we can start copying at aligned.
+ __ xor_(t8, a1, a0);
+ __ andi(t8, t8, loadstore_chunk - 1); // t8 is a0/a1 word-displacement.
+ __ bne(t8, zero_reg, &unaligned);
+ __ subu(a3, zero_reg, a0); // In delay slot.
+
+ __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1.
+ __ beq(a3, zero_reg, &aligned); // Already aligned.
+ __ subu(a2, a2, a3); // In delay slot. a2 is the remining bytes count.
+
+ __ lwr(t8, MemOperand(a1));
+ __ addu(a1, a1, a3);
+ __ swr(t8, MemOperand(a0));
+ __ addu(a0, a0, a3);
+
+ // Now dst/src are both aligned to (word) aligned addresses. Set a2 to
+ // count how many bytes we have to copy after all the 64 byte chunks are
+ // copied and a3 to the dst pointer after all the 64 byte chunks have been
+ // copied. We will loop, incrementing a0 and a1 until a0 equals a3.
+ __ bind(&aligned);
+ __ andi(t8, a2, 0x3f);
+ __ beq(a2, t8, &chkw); // Less than 64?
+ __ subu(a3, a2, t8); // In delay slot.
+ __ addu(a3, a0, a3); // Now a3 is the final dst after loop.
+
+ // When in the loop we prefetch with kPrefHintPrepareForStore hint,
+ // in this case the a0+x should be past the "t0-32" address. This means:
+ // for x=128 the last "safe" a0 address is "t0-160". Alternatively, for
+ // x=64 the last "safe" a0 address is "t0-96". In the current version we
+ // will use "pref hint, 128(a0)", so "t0-160" is the limit.
+ if (pref_hint_store == kPrefHintPrepareForStore) {
+ __ addu(t0, a0, a2); // t0 is the "past the end" address.
+ __ Subu(t9, t0, pref_limit); // t9 is the "last safe pref" address.
+ }
+
+ __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
+
+ if (pref_hint_store != kPrefHintPrepareForStore) {
+ __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
+ }
+ __ bind(&loop16w);
+ __ lw(t0, MemOperand(a1));
+
+ if (pref_hint_store == kPrefHintPrepareForStore) {
+ __ sltu(v1, t9, a0); // If a0 > t9, don't use next prefetch.
+ __ Branch(USE_DELAY_SLOT, &skip_pref, gt, v1, Operand(zero_reg));
+ }
+ __ lw(t1, MemOperand(a1, 1, loadstore_chunk)); // Maybe in delay slot.
+
+ __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
+
+ __ bind(&skip_pref);
+ __ lw(t2, MemOperand(a1, 2, loadstore_chunk));
+ __ lw(t3, MemOperand(a1, 3, loadstore_chunk));
+ __ lw(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lw(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lw(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lw(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
+
+ __ sw(t0, MemOperand(a0));
+ __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
+ __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
+ __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
+ __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
+ __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
+ __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
+ __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
+
+ __ lw(t0, MemOperand(a1, 8, loadstore_chunk));
+ __ lw(t1, MemOperand(a1, 9, loadstore_chunk));
+ __ lw(t2, MemOperand(a1, 10, loadstore_chunk));
+ __ lw(t3, MemOperand(a1, 11, loadstore_chunk));
+ __ lw(t4, MemOperand(a1, 12, loadstore_chunk));
+ __ lw(t5, MemOperand(a1, 13, loadstore_chunk));
+ __ lw(t6, MemOperand(a1, 14, loadstore_chunk));
+ __ lw(t7, MemOperand(a1, 15, loadstore_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
+
+ __ sw(t0, MemOperand(a0, 8, loadstore_chunk));
+ __ sw(t1, MemOperand(a0, 9, loadstore_chunk));
+ __ sw(t2, MemOperand(a0, 10, loadstore_chunk));
+ __ sw(t3, MemOperand(a0, 11, loadstore_chunk));
+ __ sw(t4, MemOperand(a0, 12, loadstore_chunk));
+ __ sw(t5, MemOperand(a0, 13, loadstore_chunk));
+ __ sw(t6, MemOperand(a0, 14, loadstore_chunk));
+ __ sw(t7, MemOperand(a0, 15, loadstore_chunk));
+ __ addiu(a0, a0, 16 * loadstore_chunk);
+ __ bne(a0, a3, &loop16w);
+ __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot.
+ __ mov(a2, t8);
+
+ // Here we have src and dest word-aligned but less than 64-bytes to go.
+ // Check for a 32 bytes chunk and copy if there is one. Otherwise jump
+ // down to chk1w to handle the tail end of the copy.
+ __ bind(&chkw);
+ __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
+ __ andi(t8, a2, 0x1f);
+ __ beq(a2, t8, &chk1w); // Less than 32?
+ __ nop(); // In delay slot.
+ __ lw(t0, MemOperand(a1));
+ __ lw(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lw(t2, MemOperand(a1, 2, loadstore_chunk));
+ __ lw(t3, MemOperand(a1, 3, loadstore_chunk));
+ __ lw(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lw(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lw(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lw(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ addiu(a1, a1, 8 * loadstore_chunk);
+ __ sw(t0, MemOperand(a0));
+ __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
+ __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
+ __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
+ __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
+ __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
+ __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
+ __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
+ __ addiu(a0, a0, 8 * loadstore_chunk);
+
+ // Here we have less than 32 bytes to copy. Set up for a loop to copy
+ // one word at a time. Set a2 to count how many bytes we have to copy
+ // after all the word chunks are copied and a3 to the dst pointer after
+ // all the word chunks have been copied. We will loop, incrementing a0
+ // and a1 untill a0 equals a3.
+ __ bind(&chk1w);
+ __ andi(a2, t8, loadstore_chunk - 1);
+ __ beq(a2, t8, &lastb);
+ __ subu(a3, t8, a2); // In delay slot.
+ __ addu(a3, a0, a3);
+
+ __ bind(&wordCopy_loop);
+ __ lw(t3, MemOperand(a1));
+ __ addiu(a0, a0, loadstore_chunk);
+ __ addiu(a1, a1, loadstore_chunk);
+ __ bne(a0, a3, &wordCopy_loop);
+ __ sw(t3, MemOperand(a0, -1, loadstore_chunk)); // In delay slot.
+
+ __ bind(&lastb);
+ __ Branch(&leave, le, a2, Operand(zero_reg));
+ __ addu(a3, a0, a2);
+
+ __ bind(&lastbloop);
+ __ lb(v1, MemOperand(a1));
+ __ addiu(a0, a0, 1);
+ __ addiu(a1, a1, 1);
+ __ bne(a0, a3, &lastbloop);
+ __ sb(v1, MemOperand(a0, -1)); // In delay slot.
+
+ __ bind(&leave);
+ __ jr(ra);
+ __ nop();
+
+ // Unaligned case. Only the dst gets aligned so we need to do partial
+ // loads of the source followed by normal stores to the dst (once we
+ // have aligned the destination).
+ __ bind(&unaligned);
+ __ andi(a3, a3, loadstore_chunk - 1); // Copy a3 bytes to align a0/a1.
+ __ beq(a3, zero_reg, &ua_chk16w);
+ __ subu(a2, a2, a3); // In delay slot.
+
+ __ lwr(v1, MemOperand(a1));
+ __ lwl(v1,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ addu(a1, a1, a3);
+ __ swr(v1, MemOperand(a0));
+ __ addu(a0, a0, a3);
+
+ // Now the dst (but not the source) is aligned. Set a2 to count how many
+ // bytes we have to copy after all the 64 byte chunks are copied and a3 to
+ // the dst pointer after all the 64 byte chunks have been copied. We will
+ // loop, incrementing a0 and a1 until a0 equals a3.
+ __ bind(&ua_chk16w);
+ __ andi(t8, a2, 0x3f);
+ __ beq(a2, t8, &ua_chkw);
+ __ subu(a3, a2, t8); // In delay slot.
+ __ addu(a3, a0, a3);
+
+ if (pref_hint_store == kPrefHintPrepareForStore) {
+ __ addu(t0, a0, a2);
+ __ Subu(t9, t0, pref_limit);
+ }
+
+ __ Pref(pref_hint_load, MemOperand(a1, 0 * pref_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 1 * pref_chunk));
+ __ Pref(pref_hint_load, MemOperand(a1, 2 * pref_chunk));
+
+ if (pref_hint_store != kPrefHintPrepareForStore) {
+ __ Pref(pref_hint_store, MemOperand(a0, 1 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 2 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 3 * pref_chunk));
+ }
+
+ __ bind(&ua_loop16w);
+ __ Pref(pref_hint_load, MemOperand(a1, 3 * pref_chunk));
+ __ lwr(t0, MemOperand(a1));
+ __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
+
+ if (pref_hint_store == kPrefHintPrepareForStore) {
+ __ sltu(v1, t9, a0);
+ __ Branch(USE_DELAY_SLOT, &ua_skip_pref, gt, v1, Operand(zero_reg));
+ }
+ __ lwr(t3, MemOperand(a1, 3, loadstore_chunk)); // Maybe in delay slot.
+
+ __ Pref(pref_hint_store, MemOperand(a0, 4 * pref_chunk));
+ __ Pref(pref_hint_store, MemOperand(a0, 5 * pref_chunk));
+
+ __ bind(&ua_skip_pref);
+ __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ lwl(t0,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t1,
+ MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t2,
+ MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t3,
+ MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t4,
+ MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t5,
+ MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t6,
+ MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t7,
+ MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
+ __ Pref(pref_hint_load, MemOperand(a1, 4 * pref_chunk));
+ __ sw(t0, MemOperand(a0));
+ __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
+ __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
+ __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
+ __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
+ __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
+ __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
+ __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
+ __ lwr(t0, MemOperand(a1, 8, loadstore_chunk));
+ __ lwr(t1, MemOperand(a1, 9, loadstore_chunk));
+ __ lwr(t2, MemOperand(a1, 10, loadstore_chunk));
+ __ lwr(t3, MemOperand(a1, 11, loadstore_chunk));
+ __ lwr(t4, MemOperand(a1, 12, loadstore_chunk));
+ __ lwr(t5, MemOperand(a1, 13, loadstore_chunk));
+ __ lwr(t6, MemOperand(a1, 14, loadstore_chunk));
+ __ lwr(t7, MemOperand(a1, 15, loadstore_chunk));
+ __ lwl(t0,
+ MemOperand(a1, 9, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t1,
+ MemOperand(a1, 10, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t2,
+ MemOperand(a1, 11, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t3,
+ MemOperand(a1, 12, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t4,
+ MemOperand(a1, 13, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t5,
+ MemOperand(a1, 14, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t6,
+ MemOperand(a1, 15, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t7,
+ MemOperand(a1, 16, loadstore_chunk, MemOperand::offset_minus_one));
+ __ Pref(pref_hint_load, MemOperand(a1, 5 * pref_chunk));
+ __ sw(t0, MemOperand(a0, 8, loadstore_chunk));
+ __ sw(t1, MemOperand(a0, 9, loadstore_chunk));
+ __ sw(t2, MemOperand(a0, 10, loadstore_chunk));
+ __ sw(t3, MemOperand(a0, 11, loadstore_chunk));
+ __ sw(t4, MemOperand(a0, 12, loadstore_chunk));
+ __ sw(t5, MemOperand(a0, 13, loadstore_chunk));
+ __ sw(t6, MemOperand(a0, 14, loadstore_chunk));
+ __ sw(t7, MemOperand(a0, 15, loadstore_chunk));
+ __ addiu(a0, a0, 16 * loadstore_chunk);
+ __ bne(a0, a3, &ua_loop16w);
+ __ addiu(a1, a1, 16 * loadstore_chunk); // In delay slot.
+ __ mov(a2, t8);
+
+ // Here less than 64-bytes. Check for
+ // a 32 byte chunk and copy if there is one. Otherwise jump down to
+ // ua_chk1w to handle the tail end of the copy.
+ __ bind(&ua_chkw);
+ __ Pref(pref_hint_load, MemOperand(a1));
+ __ andi(t8, a2, 0x1f);
+
+ __ beq(a2, t8, &ua_chk1w);
+ __ nop(); // In delay slot.
+ __ lwr(t0, MemOperand(a1));
+ __ lwr(t1, MemOperand(a1, 1, loadstore_chunk));
+ __ lwr(t2, MemOperand(a1, 2, loadstore_chunk));
+ __ lwr(t3, MemOperand(a1, 3, loadstore_chunk));
+ __ lwr(t4, MemOperand(a1, 4, loadstore_chunk));
+ __ lwr(t5, MemOperand(a1, 5, loadstore_chunk));
+ __ lwr(t6, MemOperand(a1, 6, loadstore_chunk));
+ __ lwr(t7, MemOperand(a1, 7, loadstore_chunk));
+ __ lwl(t0,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t1,
+ MemOperand(a1, 2, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t2,
+ MemOperand(a1, 3, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t3,
+ MemOperand(a1, 4, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t4,
+ MemOperand(a1, 5, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t5,
+ MemOperand(a1, 6, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t6,
+ MemOperand(a1, 7, loadstore_chunk, MemOperand::offset_minus_one));
+ __ lwl(t7,
+ MemOperand(a1, 8, loadstore_chunk, MemOperand::offset_minus_one));
+ __ addiu(a1, a1, 8 * loadstore_chunk);
+ __ sw(t0, MemOperand(a0));
+ __ sw(t1, MemOperand(a0, 1, loadstore_chunk));
+ __ sw(t2, MemOperand(a0, 2, loadstore_chunk));
+ __ sw(t3, MemOperand(a0, 3, loadstore_chunk));
+ __ sw(t4, MemOperand(a0, 4, loadstore_chunk));
+ __ sw(t5, MemOperand(a0, 5, loadstore_chunk));
+ __ sw(t6, MemOperand(a0, 6, loadstore_chunk));
+ __ sw(t7, MemOperand(a0, 7, loadstore_chunk));
+ __ addiu(a0, a0, 8 * loadstore_chunk);
+
+ // Less than 32 bytes to copy. Set up for a loop to
+ // copy one word at a time.
+ __ bind(&ua_chk1w);
+ __ andi(a2, t8, loadstore_chunk - 1);
+ __ beq(a2, t8, &ua_smallCopy);
+ __ subu(a3, t8, a2); // In delay slot.
+ __ addu(a3, a0, a3);
+
+ __ bind(&ua_wordCopy_loop);
+ __ lwr(v1, MemOperand(a1));
+ __ lwl(v1,
+ MemOperand(a1, 1, loadstore_chunk, MemOperand::offset_minus_one));
+ __ addiu(a0, a0, loadstore_chunk);
+ __ addiu(a1, a1, loadstore_chunk);
+ __ bne(a0, a3, &ua_wordCopy_loop);
+ __ sw(v1, MemOperand(a0, -1, loadstore_chunk)); // In delay slot.
+
+ // Copy the last 8 bytes.
+ __ bind(&ua_smallCopy);
+ __ beq(a2, zero_reg, &leave);
+ __ addu(a3, a0, a2); // In delay slot.
+
+ __ bind(&ua_smallCopy_loop);
+ __ lb(v1, MemOperand(a1));
+ __ addiu(a0, a0, 1);
+ __ addiu(a1, a1, 1);
+ __ bne(a0, a3, &ua_smallCopy_loop);
+ __ sb(v1, MemOperand(a0, -1)); // In delay slot.
+
+ __ jr(ra);
+ __ nop();
+ }
+ CodeDesc desc;
+ masm.GetCode(&desc);
+ ASSERT(!RelocInfo::RequiresRelocation(desc));
+
+ CPU::FlushICache(buffer, actual_size);
+ OS::ProtectCode(buffer, actual_size);
+ return FUNCTION_CAST<OS::MemCopyUint8Function>(buffer);
+#endif
+}
+#endif
+
#undef __
@@ -603,9 +1024,10 @@
__ bind(&done);
}
-
+#ifdef DEBUG
// nop(CODE_AGE_MARKER_NOP)
static const uint32_t kCodeAgePatchFirstInstruction = 0x00010180;
+#endif
static byte* GetNoCodeAgeSequence(uint32_t* length) {
// The sequence of instructions that is patched out for aging code is the
diff --git a/src/mips/constants-mips.h b/src/mips/constants-mips.h
index 5a0870f..dcf8b82 100644
--- a/src/mips/constants-mips.h
+++ b/src/mips/constants-mips.h
@@ -124,6 +124,16 @@
const uint32_t kFCSRExceptionFlagMask = kFCSRFlagMask ^ kFCSRInexactFlagMask;
+// 'pref' instruction hints
+const int32_t kPrefHintLoad = 0;
+const int32_t kPrefHintStore = 1;
+const int32_t kPrefHintLoadStreamed = 4;
+const int32_t kPrefHintStoreStreamed = 5;
+const int32_t kPrefHintLoadRetained = 6;
+const int32_t kPrefHintStoreRetained = 7;
+const int32_t kPrefHintWritebackInvalidate = 25;
+const int32_t kPrefHintPrepareForStore = 30;
+
// Helper functions for converting between register numbers and names.
class Registers {
public:
@@ -297,6 +307,8 @@
LWC1 = ((6 << 3) + 1) << kOpcodeShift,
LDC1 = ((6 << 3) + 5) << kOpcodeShift,
+ PREF = ((6 << 3) + 3) << kOpcodeShift,
+
SWC1 = ((7 << 3) + 1) << kOpcodeShift,
SDC1 = ((7 << 3) + 5) << kOpcodeShift,
diff --git a/src/mips/disasm-mips.cc b/src/mips/disasm-mips.cc
index 691df94..1ae0340 100644
--- a/src/mips/disasm-mips.cc
+++ b/src/mips/disasm-mips.cc
@@ -899,6 +899,9 @@
case LWR:
Format(instr, "lwr 'rt, 'imm16s('rs)");
break;
+ case PREF:
+ Format(instr, "pref 'rt, 'imm16s('rs)");
+ break;
case SB:
Format(instr, "sb 'rt, 'imm16s('rs)");
break;
diff --git a/src/mips/full-codegen-mips.cc b/src/mips/full-codegen-mips.cc
index 3ce2ab5..74b3807 100644
--- a/src/mips/full-codegen-mips.cc
+++ b/src/mips/full-codegen-mips.cc
@@ -341,10 +341,6 @@
void FullCodeGenerator::EmitProfilingCounterReset() {
int reset_value = FLAG_interrupt_budget;
- if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
- // Self-optimization is a one-off thing: if it fails, don't try again.
- reset_value = Smi::kMaxValue;
- }
if (isolate()->IsDebuggerActive()) {
// Detect debug break requests as soon as possible.
reset_value = FLAG_interrupt_budget >> 4;
@@ -365,13 +361,10 @@
Assembler::BlockTrampolinePoolScope block_trampoline_pool(masm_);
Comment cmnt(masm_, "[ Back edge bookkeeping");
Label ok;
- int weight = 1;
- if (FLAG_weighted_back_edges) {
- ASSERT(back_edge_target->is_bound());
- int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
+ ASSERT(back_edge_target->is_bound());
+ int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
+ int weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
EmitProfilingCounterDecrement(weight);
__ slt(at, a3, zero_reg);
__ beq(at, zero_reg, &ok);
@@ -404,32 +397,24 @@
__ push(v0);
__ CallRuntime(Runtime::kTraceExit, 1);
}
- if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
- // Pretend that the exit is a backwards jump to the entry.
- int weight = 1;
- if (info_->ShouldSelfOptimize()) {
- weight = FLAG_interrupt_budget / FLAG_self_opt_count;
- } else if (FLAG_weighted_back_edges) {
- int distance = masm_->pc_offset();
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
- EmitProfilingCounterDecrement(weight);
- Label ok;
- __ Branch(&ok, ge, a3, Operand(zero_reg));
- __ push(v0);
- if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
- __ lw(a2, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
- __ push(a2);
- __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
- } else {
- __ Call(isolate()->builtins()->InterruptCheck(),
- RelocInfo::CODE_TARGET);
- }
- __ pop(v0);
- EmitProfilingCounterReset();
- __ bind(&ok);
+ // Pretend that the exit is a backwards jump to the entry.
+ int weight = 1;
+ if (info_->ShouldSelfOptimize()) {
+ weight = FLAG_interrupt_budget / FLAG_self_opt_count;
+ } else {
+ int distance = masm_->pc_offset();
+ weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
}
+ EmitProfilingCounterDecrement(weight);
+ Label ok;
+ __ Branch(&ok, ge, a3, Operand(zero_reg));
+ __ push(v0);
+ __ Call(isolate()->builtins()->InterruptCheck(),
+ RelocInfo::CODE_TARGET);
+ __ pop(v0);
+ EmitProfilingCounterReset();
+ __ bind(&ok);
#ifdef DEBUG
// Add a label for checking the size of the code used for returning.
diff --git a/src/mips/lithium-codegen-mips.cc b/src/mips/lithium-codegen-mips.cc
index 26f446c..b4d9441 100644
--- a/src/mips/lithium-codegen-mips.cc
+++ b/src/mips/lithium-codegen-mips.cc
@@ -3874,39 +3874,6 @@
}
-void LCodeGen::DoMathTan(LMathTan* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(f4));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ mov(cp, zero_reg);
- TranscendentalCacheStub stub(TranscendentalCache::TAN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathCos(LMathCos* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(f4));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ mov(cp, zero_reg);
- TranscendentalCacheStub stub(TranscendentalCache::COS,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathSin(LMathSin* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(f4));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ mov(cp, zero_reg);
- TranscendentalCacheStub stub(TranscendentalCache::SIN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
ASSERT(ToRegister(instr->context()).is(cp));
ASSERT(ToRegister(instr->function()).is(a1));
diff --git a/src/mips/lithium-mips.cc b/src/mips/lithium-mips.cc
index a441ba5..1ca008c 100644
--- a/src/mips/lithium-mips.cc
+++ b/src/mips/lithium-mips.cc
@@ -261,7 +261,7 @@
stream->Add("if typeof ");
value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
- *hydrogen()->type_literal()->ToCString(),
+ hydrogen()->type_literal()->ToCString().get(),
true_block_id(), false_block_id());
}
@@ -314,13 +314,13 @@
void LCallNamed::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
void LCallGlobal::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
@@ -365,7 +365,7 @@
void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add(".");
- stream->Add(*String::cast(*name())->ToCString());
+ stream->Add(String::cast(*name())->ToCString().get());
stream->Add(" <- ");
value()->PrintTo(stream);
}
@@ -1190,9 +1190,6 @@
case kMathRound: return DoMathRound(instr);
case kMathAbs: return DoMathAbs(instr);
case kMathLog: return DoMathLog(instr);
- case kMathSin: return DoMathSin(instr);
- case kMathCos: return DoMathCos(instr);
- case kMathTan: return DoMathTan(instr);
case kMathExp: return DoMathExp(instr);
case kMathSqrt: return DoMathSqrt(instr);
case kMathPowHalf: return DoMathPowHalf(instr);
@@ -1210,27 +1207,6 @@
}
-LInstruction* LChunkBuilder::DoMathSin(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), f4);
- LMathSin* result = new(zone()) LMathSin(input);
- return MarkAsCall(DefineFixedDouble(result, f4), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathCos(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), f4);
- LMathCos* result = new(zone()) LMathCos(input);
- return MarkAsCall(DefineFixedDouble(result, f4), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), f4);
- LMathTan* result = new(zone()) LMathTan(input);
- return MarkAsCall(DefineFixedDouble(result, f4), instr);
-}
-
-
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble());
diff --git a/src/mips/lithium-mips.h b/src/mips/lithium-mips.h
index dbb78ea..99885dc 100644
--- a/src/mips/lithium-mips.h
+++ b/src/mips/lithium-mips.h
@@ -131,7 +131,6 @@
V(LoadNamedGeneric) \
V(MapEnumLength) \
V(MathAbs) \
- V(MathCos) \
V(MathExp) \
V(MathFloor) \
V(MathFloorOfDiv) \
@@ -139,9 +138,7 @@
V(MathMinMax) \
V(MathPowHalf) \
V(MathRound) \
- V(MathSin) \
V(MathSqrt) \
- V(MathTan) \
V(ModI) \
V(MulI) \
V(MultiplyAddD) \
@@ -811,42 +808,6 @@
};
-class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathSin(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
-};
-
-
-class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathCos(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
-};
-
-
-class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathTan(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
-};
-
-
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 3> {
public:
LMathExp(LOperand* value,
@@ -2752,9 +2713,6 @@
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
- LInstruction* DoMathSin(HUnaryMathOperation* instr);
- LInstruction* DoMathCos(HUnaryMathOperation* instr);
- LInstruction* DoMathTan(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc
index f33e6fa..bc981cb 100644
--- a/src/mips/macro-assembler-mips.cc
+++ b/src/mips/macro-assembler-mips.cc
@@ -789,8 +789,29 @@
}
+void MacroAssembler::Pref(int32_t hint, const MemOperand& rs) {
+ if (kArchVariant == kLoongson) {
+ lw(zero_reg, rs);
+ } else {
+ pref(hint, rs);
+ }
+}
+
+
//------------Pseudo-instructions-------------
+void MacroAssembler::Ulw(Register rd, const MemOperand& rs) {
+ lwr(rd, rs);
+ lwl(rd, MemOperand(rs.rm(), rs.offset() + 3));
+}
+
+
+void MacroAssembler::Usw(Register rd, const MemOperand& rs) {
+ swr(rd, rs);
+ swl(rd, MemOperand(rs.rm(), rs.offset() + 3));
+}
+
+
void MacroAssembler::li(Register dst, Handle<Object> value, LiFlags mode) {
AllowDeferredHandleDereference smi_check;
if (value->IsSmi()) {
diff --git a/src/mips/macro-assembler-mips.h b/src/mips/macro-assembler-mips.h
index 4e30c35..f1b82ed 100644
--- a/src/mips/macro-assembler-mips.h
+++ b/src/mips/macro-assembler-mips.h
@@ -601,12 +601,17 @@
#undef DEFINE_INSTRUCTION
#undef DEFINE_INSTRUCTION2
+ void Pref(int32_t hint, const MemOperand& rs);
+
// ---------------------------------------------------------------------------
// Pseudo-instructions.
void mov(Register rd, Register rt) { or_(rd, rt, zero_reg); }
+ void Ulw(Register rd, const MemOperand& rs);
+ void Usw(Register rd, const MemOperand& rs);
+
// Load int32 in the rd register.
void li(Register rd, Operand j, LiFlags mode = OPTIMIZE_SIZE);
inline void li(Register rd, int32_t j, LiFlags mode = OPTIMIZE_SIZE) {
diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc
index 3d4617a..0db010e 100644
--- a/src/mips/stub-cache-mips.cc
+++ b/src/mips/stub-cache-mips.cc
@@ -899,12 +899,12 @@
__ sw(receiver, MemOperand(sp, FCA::kHolderIndex * kPointerSize));
// Write receiver to stack frame.
int index = stack_space - 1;
- __ sw(receiver, MemOperand(sp, index * kPointerSize));
+ __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
// Write the arguments to stack frame.
for (int i = 0; i < argc; i++) {
ASSERT(!receiver.is(values[i]));
ASSERT(!scratch.is(values[i]));
- __ sw(receiver, MemOperand(sp, index-- * kPointerSize));
+ __ sw(values[i], MemOperand(sp, index-- * kPointerSize));
}
GenerateFastApiDirectCall(masm, optimization, argc, true);
@@ -915,12 +915,10 @@
public:
CallInterceptorCompiler(CallStubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name,
- ExtraICState extra_ic_state)
+ Register name)
: stub_compiler_(stub_compiler),
arguments_(arguments),
- name_(name),
- extra_ic_state_(extra_ic_state) {}
+ name_(name) {}
void Compile(MacroAssembler* masm,
Handle<JSObject> object,
@@ -1095,7 +1093,6 @@
CallStubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
- ExtraICState extra_ic_state_;
};
@@ -2463,7 +2460,7 @@
// Get the receiver from the stack.
__ lw(a1, MemOperand(sp, argc * kPointerSize));
- CallInterceptorCompiler compiler(this, arguments(), a2, extra_state());
+ CallInterceptorCompiler compiler(this, arguments(), a2);
compiler.Compile(masm(), object, holder, name, &lookup, a1, a3, t0, a0,
&miss);
diff --git a/src/objects-printer.cc b/src/objects-printer.cc
index 381c9aa..1da9852 100644
--- a/src/objects-printer.cc
+++ b/src/objects-printer.cc
@@ -903,7 +903,7 @@
source->ToCString(DISALLOW_NULLS,
FAST_STRING_TRAVERSAL,
start, length, NULL);
- PrintF(out, "%s", *source_string);
+ PrintF(out, "%s", source_string.get());
}
// Script files are often large, hard to read.
// PrintF(out, "\n - script =");
diff --git a/src/objects.cc b/src/objects.cc
index f96fd83..43a047e 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -1683,7 +1683,7 @@
SmartArrayPointer<char> debug_name =
shared->DebugName()->ToCString();
if (debug_name[0] != 0) {
- accumulator->Add("<SharedFunctionInfo %s>", *debug_name);
+ accumulator->Add("<SharedFunctionInfo %s>", debug_name.get());
} else {
accumulator->Add("<SharedFunctionInfo>");
}
@@ -9913,7 +9913,7 @@
void JSFunction::PrintName(FILE* out) {
SmartArrayPointer<char> name = shared()->DebugName()->ToCString();
- PrintF(out, "%s", *name);
+ PrintF(out, "%s", name.get());
}
diff --git a/src/objects.h b/src/objects.h
index bbdefc1..f09d58f 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -6494,12 +6494,6 @@
V(Math, ceil, MathCeil) \
V(Math, abs, MathAbs) \
V(Math, log, MathLog) \
- V(Math, sin, MathSin) \
- V(Math, cos, MathCos) \
- V(Math, tan, MathTan) \
- V(Math, asin, MathASin) \
- V(Math, acos, MathACos) \
- V(Math, atan, MathATan) \
V(Math, exp, MathExp) \
V(Math, sqrt, MathSqrt) \
V(Math, pow, MathPow) \
diff --git a/src/parser.cc b/src/parser.cc
index b168919..bfb5bd1 100644
--- a/src/parser.cc
+++ b/src/parser.cc
@@ -600,7 +600,7 @@
} else if (info()->script()->name()->IsString()) {
String* name = String::cast(info()->script()->name());
SmartArrayPointer<char> name_chars = name->ToCString();
- PrintF("[parsing script: %s", *name_chars);
+ PrintF("[parsing script: %s", name_chars.get());
} else {
PrintF("[parsing script");
}
@@ -729,7 +729,7 @@
if (FLAG_trace_parse && result != NULL) {
double ms = timer.Elapsed().InMillisecondsF();
SmartArrayPointer<char> name_chars = result->debug_name()->ToCString();
- PrintF("[parsing function: %s - took %0.3f ms]\n", *name_chars, ms);
+ PrintF("[parsing function: %s - took %0.3f ms]\n", name_chars.get(), ms);
}
return result;
}
@@ -1521,7 +1521,7 @@
// In harmony mode we treat re-declarations as early errors. See
// ES5 16 for a definition of early errors.
SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Variable", *c_string };
+ const char* elms[2] = { "Variable", c_string.get() };
Vector<const char*> args(elms, 2);
ReportMessage("redeclaration", args);
*ok = false;
@@ -2145,7 +2145,7 @@
// make later anyway so we should go back and fix this then.
if (ContainsLabel(labels, label) || TargetStackContainsLabel(label)) {
SmartArrayPointer<char> c_string = label->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Label", *c_string };
+ const char* elms[2] = { "Label", c_string.get() };
Vector<const char*> args(elms, 2);
ReportMessage("redeclaration", args);
*ok = false;
@@ -3512,7 +3512,7 @@
void Parser::ReportInvalidPreparseData(Handle<String> name, bool* ok) {
SmartArrayPointer<char> name_string = name->ToCString(DISALLOW_NULLS);
- const char* element[1] = { *name_string };
+ const char* element[1] = { name_string.get() };
ReportMessage("invalid_preparser_data",
Vector<const char*>(element, 1));
*ok = false;
@@ -4601,7 +4601,7 @@
// errors. See ES5 16 for a definition of early errors.
Handle<String> name = decl->proxy()->name();
SmartArrayPointer<char> c_string = name->ToCString(DISALLOW_NULLS);
- const char* elms[2] = { "Variable", *c_string };
+ const char* elms[2] = { "Variable", c_string.get() };
Vector<const char*> args(elms, 2);
int position = decl->proxy()->position();
Scanner::Location location = position == RelocInfo::kNoPosition
diff --git a/src/platform-posix.cc b/src/platform-posix.cc
index 879dcc8..0070bdf 100644
--- a/src/platform-posix.cc
+++ b/src/platform-posix.cc
@@ -302,9 +302,6 @@
return (*fast_##name##_function)(x); \
}
-UNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN))
-UNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS))
-UNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN))
UNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG))
UNARY_MATH_FUNCTION(exp, CreateExpFunction())
UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
@@ -506,6 +503,12 @@
OS::MemCopyUint8Function stub);
OS::MemCopyUint16Uint8Function CreateMemCopyUint16Uint8Function(
OS::MemCopyUint16Uint8Function stub);
+
+#elif defined(V8_HOST_ARCH_MIPS)
+OS::MemCopyUint8Function OS::memcopy_uint8_function = &OS::MemCopyUint8Wrapper;
+// Defined in codegen-mips.cc.
+OS::MemCopyUint8Function CreateMemCopyUint8Function(
+ OS::MemCopyUint8Function stub);
#endif
@@ -520,10 +523,10 @@
CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
OS::memcopy_uint16_uint8_function =
CreateMemCopyUint16Uint8Function(&OS::MemCopyUint16Uint8Wrapper);
+#elif defined(V8_HOST_ARCH_MIPS)
+ OS::memcopy_uint8_function =
+ CreateMemCopyUint8Function(&OS::MemCopyUint8Wrapper);
#endif
- init_fast_sin_function();
- init_fast_cos_function();
- init_fast_tan_function();
init_fast_log_function();
// fast_exp is initialized lazily.
init_fast_sqrt_function();
diff --git a/src/platform-win32.cc b/src/platform-win32.cc
index ea11806..7ca5e55 100644
--- a/src/platform-win32.cc
+++ b/src/platform-win32.cc
@@ -196,9 +196,6 @@
return (*fast_##name##_function)(x); \
}
-UNARY_MATH_FUNCTION(sin, CreateTranscendentalFunction(TranscendentalCache::SIN))
-UNARY_MATH_FUNCTION(cos, CreateTranscendentalFunction(TranscendentalCache::COS))
-UNARY_MATH_FUNCTION(tan, CreateTranscendentalFunction(TranscendentalCache::TAN))
UNARY_MATH_FUNCTION(log, CreateTranscendentalFunction(TranscendentalCache::LOG))
UNARY_MATH_FUNCTION(exp, CreateExpFunction())
UNARY_MATH_FUNCTION(sqrt, CreateSqrtFunction())
@@ -217,9 +214,6 @@
#ifdef _WIN64
init_modulo_function();
#endif
- init_fast_sin_function();
- init_fast_cos_function();
- init_fast_tan_function();
init_fast_log_function();
// fast_exp is initialized lazily.
init_fast_sqrt_function();
diff --git a/src/platform.h b/src/platform.h
index 3bd87a9..f94a526 100644
--- a/src/platform.h
+++ b/src/platform.h
@@ -96,9 +96,6 @@
double modulo(double x, double y);
// Custom implementation of math functions.
-double fast_sin(double input);
-double fast_cos(double input);
-double fast_tan(double input);
double fast_log(double input);
double fast_exp(double input);
double fast_sqrt(double input);
@@ -368,6 +365,26 @@
size_t size) {
(*memcopy_uint16_uint8_function)(dest, src, size);
}
+#elif defined(V8_HOST_ARCH_MIPS)
+ typedef void (*MemCopyUint8Function)(uint8_t* dest,
+ const uint8_t* src,
+ size_t size);
+ static MemCopyUint8Function memcopy_uint8_function;
+ static void MemCopyUint8Wrapper(uint8_t* dest,
+ const uint8_t* src,
+ size_t chars) {
+ memcpy(dest, src, chars);
+ }
+ // For values < 16, the assembler function is slower than the inlined C code.
+ static const int kMinComplexMemCopy = 16;
+ static void MemCopy(void* dest, const void* src, size_t size) {
+ (*memcopy_uint8_function)(reinterpret_cast<uint8_t*>(dest),
+ reinterpret_cast<const uint8_t*>(src),
+ size);
+ }
+ static void MemMove(void* dest, const void* src, size_t size) {
+ memmove(dest, src, size);
+ }
#else
// Copy memory area to disjoint memory area.
static void MemCopy(void* dest, const void* src, size_t size) {
diff --git a/src/regexp-macro-assembler-tracer.cc b/src/regexp-macro-assembler-tracer.cc
index 1ce1fa4..c446b4b 100644
--- a/src/regexp-macro-assembler-tracer.cc
+++ b/src/regexp-macro-assembler-tracer.cc
@@ -427,7 +427,7 @@
Handle<HeapObject> RegExpMacroAssemblerTracer::GetCode(Handle<String> source) {
- PrintF(" GetCode(%s);\n", *(source->ToCString()));
+ PrintF(" GetCode(%s);\n", source->ToCString().get());
return assembler_->GetCode(source);
}
diff --git a/src/runtime-profiler.cc b/src/runtime-profiler.cc
index 691fc66..8c4b11f 100644
--- a/src/runtime-profiler.cc
+++ b/src/runtime-profiler.cc
@@ -45,24 +45,6 @@
namespace internal {
-// Optimization sampler constants.
-static const int kSamplerFrameCount = 2;
-
-// Constants for statistical profiler.
-static const int kSamplerFrameWeight[kSamplerFrameCount] = { 2, 1 };
-
-static const int kSamplerTicksBetweenThresholdAdjustment = 32;
-
-static const int kSamplerThresholdInit = 3;
-static const int kSamplerThresholdMin = 1;
-static const int kSamplerThresholdDelta = 1;
-
-static const int kSamplerThresholdSizeFactorInit = 3;
-
-static const int kSizeLimit = 1500;
-
-// Constants for counter based profiler.
-
// Number of times a function has to be seen on the stack before it is
// optimized.
static const int kProfilerTicksBeforeOptimization = 2;
@@ -94,14 +76,7 @@
RuntimeProfiler::RuntimeProfiler(Isolate* isolate)
: isolate_(isolate),
- sampler_threshold_(kSamplerThresholdInit),
- sampler_threshold_size_factor_(kSamplerThresholdSizeFactorInit),
- sampler_ticks_until_threshold_adjustment_(
- kSamplerTicksBetweenThresholdAdjustment),
- sampler_window_position_(0),
- any_ic_changed_(false),
- code_generated_(false) {
- ClearSampleBuffer();
+ any_ic_changed_(false) {
}
@@ -189,38 +164,6 @@
}
-void RuntimeProfiler::ClearSampleBuffer() {
- memset(sampler_window_, 0, sizeof(sampler_window_));
- memset(sampler_window_weight_, 0, sizeof(sampler_window_weight_));
-}
-
-
-int RuntimeProfiler::LookupSample(JSFunction* function) {
- int weight = 0;
- for (int i = 0; i < kSamplerWindowSize; i++) {
- Object* sample = sampler_window_[i];
- if (sample != NULL) {
- bool fits = FLAG_lookup_sample_by_shared
- ? (function->shared() == JSFunction::cast(sample)->shared())
- : (function == JSFunction::cast(sample));
- if (fits) {
- weight += sampler_window_weight_[i];
- }
- }
- }
- return weight;
-}
-
-
-void RuntimeProfiler::AddSample(JSFunction* function, int weight) {
- ASSERT(IsPowerOf2(kSamplerWindowSize));
- sampler_window_[sampler_window_position_] = function;
- sampler_window_weight_[sampler_window_position_] = weight;
- sampler_window_position_ = (sampler_window_position_ + 1) &
- (kSamplerWindowSize - 1);
-}
-
-
void RuntimeProfiler::OptimizeNow() {
HandleScope scope(isolate_);
@@ -231,34 +174,14 @@
// Run through the JavaScript frames and collect them. If we already
// have a sample of the function, we mark it for optimizations
// (eagerly or lazily).
- JSFunction* samples[kSamplerFrameCount];
- int sample_count = 0;
int frame_count = 0;
- int frame_count_limit = FLAG_watch_ic_patching ? FLAG_frame_count
- : kSamplerFrameCount;
+ int frame_count_limit = FLAG_frame_count;
for (JavaScriptFrameIterator it(isolate_);
frame_count++ < frame_count_limit && !it.done();
it.Advance()) {
JavaScriptFrame* frame = it.frame();
JSFunction* function = frame->function();
- if (!FLAG_watch_ic_patching) {
- // Adjust threshold each time we have processed
- // a certain number of ticks.
- if (sampler_ticks_until_threshold_adjustment_ > 0) {
- sampler_ticks_until_threshold_adjustment_--;
- if (sampler_ticks_until_threshold_adjustment_ <= 0) {
- // If the threshold is not already at the minimum
- // modify and reset the ticks until next adjustment.
- if (sampler_threshold_ > kSamplerThresholdMin) {
- sampler_threshold_ -= kSamplerThresholdDelta;
- sampler_ticks_until_threshold_adjustment_ =
- kSamplerTicksBetweenThresholdAdjustment;
- }
- }
- }
- }
-
SharedFunctionInfo* shared = function->shared();
Code* shared_code = shared->code();
@@ -322,116 +245,36 @@
}
if (!function->IsOptimizable()) continue;
- if (FLAG_watch_ic_patching) {
- int ticks = shared_code->profiler_ticks();
+ int ticks = shared_code->profiler_ticks();
- if (ticks >= kProfilerTicksBeforeOptimization) {
- int typeinfo, total, percentage;
- GetICCounts(shared_code, &typeinfo, &total, &percentage);
- if (percentage >= FLAG_type_info_threshold) {
- // If this particular function hasn't had any ICs patched for enough
- // ticks, optimize it now.
- Optimize(function, "hot and stable");
- } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
- Optimize(function, "not much type info but very hot");
- } else {
- shared_code->set_profiler_ticks(ticks + 1);
- if (FLAG_trace_opt_verbose) {
- PrintF("[not yet optimizing ");
- function->PrintName();
- PrintF(", not enough type info: %d/%d (%d%%)]\n",
- typeinfo, total, percentage);
- }
- }
- } else if (!any_ic_changed_ &&
- shared_code->instruction_size() < kMaxSizeEarlyOpt) {
- // If no IC was patched since the last tick and this function is very
- // small, optimistically optimize it now.
- Optimize(function, "small function");
+ if (ticks >= kProfilerTicksBeforeOptimization) {
+ int typeinfo, total, percentage;
+ GetICCounts(shared_code, &typeinfo, &total, &percentage);
+ if (percentage >= FLAG_type_info_threshold) {
+ // If this particular function hasn't had any ICs patched for enough
+ // ticks, optimize it now.
+ Optimize(function, "hot and stable");
+ } else if (ticks >= kTicksWhenNotEnoughTypeInfo) {
+ Optimize(function, "not much type info but very hot");
} else {
shared_code->set_profiler_ticks(ticks + 1);
+ if (FLAG_trace_opt_verbose) {
+ PrintF("[not yet optimizing ");
+ function->PrintName();
+ PrintF(", not enough type info: %d/%d (%d%%)]\n",
+ typeinfo, total, percentage);
+ }
}
- } else { // !FLAG_watch_ic_patching
- samples[sample_count++] = function;
-
- int function_size = function->shared()->SourceSize();
- int threshold_size_factor = (function_size > kSizeLimit)
- ? sampler_threshold_size_factor_
- : 1;
-
- int threshold = sampler_threshold_ * threshold_size_factor;
-
- if (LookupSample(function) >= threshold) {
- Optimize(function, "sampler window lookup");
- }
+ } else if (!any_ic_changed_ &&
+ shared_code->instruction_size() < kMaxSizeEarlyOpt) {
+ // If no IC was patched since the last tick and this function is very
+ // small, optimistically optimize it now.
+ Optimize(function, "small function");
+ } else {
+ shared_code->set_profiler_ticks(ticks + 1);
}
}
- if (FLAG_watch_ic_patching) {
- any_ic_changed_ = false;
- } else { // !FLAG_watch_ic_patching
- // Add the collected functions as samples. It's important not to do
- // this as part of collecting them because this will interfere with
- // the sample lookup in case of recursive functions.
- for (int i = 0; i < sample_count; i++) {
- AddSample(samples[i], kSamplerFrameWeight[i]);
- }
- }
-}
-
-
-void RuntimeProfiler::SetUp() {
- if (!FLAG_watch_ic_patching) {
- ClearSampleBuffer();
- }
-}
-
-
-void RuntimeProfiler::Reset() {
- if (!FLAG_watch_ic_patching) {
- sampler_threshold_ = kSamplerThresholdInit;
- sampler_threshold_size_factor_ = kSamplerThresholdSizeFactorInit;
- sampler_ticks_until_threshold_adjustment_ =
- kSamplerTicksBetweenThresholdAdjustment;
- }
-}
-
-
-void RuntimeProfiler::TearDown() {
- // Nothing to do.
-}
-
-
-// Update the pointers in the sampler window after a GC.
-void RuntimeProfiler::UpdateSamplesAfterScavenge() {
- for (int i = 0; i < kSamplerWindowSize; i++) {
- Object* function = sampler_window_[i];
- if (function != NULL && isolate_->heap()->InNewSpace(function)) {
- MapWord map_word = HeapObject::cast(function)->map_word();
- if (map_word.IsForwardingAddress()) {
- sampler_window_[i] = map_word.ToForwardingAddress();
- } else {
- sampler_window_[i] = NULL;
- }
- }
- }
-}
-
-
-void RuntimeProfiler::RemoveDeadSamples() {
- for (int i = 0; i < kSamplerWindowSize; i++) {
- Object* function = sampler_window_[i];
- if (function != NULL &&
- !Marking::MarkBitFrom(HeapObject::cast(function)).Get()) {
- sampler_window_[i] = NULL;
- }
- }
-}
-
-
-void RuntimeProfiler::UpdateSamplesAfterCompact(ObjectVisitor* visitor) {
- for (int i = 0; i < kSamplerWindowSize; i++) {
- visitor->VisitPointer(&sampler_window_[i]);
- }
+ any_ic_changed_ = false;
}
diff --git a/src/runtime-profiler.h b/src/runtime-profiler.h
index 28d6d32..efd9b50 100644
--- a/src/runtime-profiler.h
+++ b/src/runtime-profiler.h
@@ -45,47 +45,18 @@
void OptimizeNow();
- void SetUp();
- void Reset();
- void TearDown();
-
void NotifyICChanged() { any_ic_changed_ = true; }
- // Rate limiting support.
-
- void UpdateSamplesAfterScavenge();
- void RemoveDeadSamples();
- void UpdateSamplesAfterCompact(ObjectVisitor* visitor);
-
void AttemptOnStackReplacement(JSFunction* function);
private:
- static const int kSamplerWindowSize = 16;
-
void Optimize(JSFunction* function, const char* reason);
- void ClearSampleBuffer();
-
- void ClearSampleBufferNewSpaceEntries();
-
- int LookupSample(JSFunction* function);
-
- void AddSample(JSFunction* function, int weight);
-
bool CodeSizeOKForOSR(Code* shared_code);
Isolate* isolate_;
- int sampler_threshold_;
- int sampler_threshold_size_factor_;
- int sampler_ticks_until_threshold_adjustment_;
-
- Object* sampler_window_[kSamplerWindowSize];
- int sampler_window_position_;
- int sampler_window_weight_[kSamplerWindowSize];
-
bool any_ic_changed_;
- bool code_generated_;
};
} } // namespace v8::internal
diff --git a/src/runtime.cc b/src/runtime.cc
index 7dc96f2..e763d43 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -7655,7 +7655,7 @@
isolate->counters()->math_acos()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::ACOS, x);
+ return isolate->heap()->AllocateHeapNumber(acos(x));
}
@@ -7665,7 +7665,7 @@
isolate->counters()->math_asin()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::ASIN, x);
+ return isolate->heap()->AllocateHeapNumber(asin(x));
}
@@ -7675,7 +7675,7 @@
isolate->counters()->math_atan()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::ATAN, x);
+ return isolate->heap()->AllocateHeapNumber(atan(x));
}
@@ -7705,16 +7705,6 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_cos) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- isolate->counters()->math_cos()->Increment();
-
- CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::COS, x);
-}
-
-
RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_exp) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -7742,7 +7732,7 @@
isolate->counters()->math_log()->Increment();
CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::LOG, x);
+ return isolate->heap()->AllocateHeapNumber(fast_log(x));
}
@@ -7831,16 +7821,6 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sin) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- isolate->counters()->math_sin()->Increment();
-
- CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::SIN, x);
-}
-
-
RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_sqrt) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 1);
@@ -7851,16 +7831,6 @@
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_Math_tan) {
- SealHandleScope shs(isolate);
- ASSERT(args.length() == 1);
- isolate->counters()->math_tan()->Increment();
-
- CONVERT_DOUBLE_ARG_CHECKED(x, 0);
- return isolate->transcendental_cache()->Get(TranscendentalCache::TAN, x);
-}
-
-
RUNTIME_FUNCTION(MaybeObject*, Runtime_DateMakeDay) {
SealHandleScope shs(isolate);
ASSERT(args.length() == 2);
@@ -8234,7 +8204,7 @@
bool exception = false;
Handle<Object> result =
Execution::New(Handle<JSFunction>::cast(bound_function),
- total_argc, *param_data, &exception);
+ total_argc, param_data.get(), &exception);
if (exception) {
return Failure::Exception();
}
@@ -8407,10 +8377,11 @@
function->ReplaceCode(function->shared()->code());
return isolate->heap()->undefined_value();
}
- function->shared()->code()->set_profiler_ticks(0);
+ Handle<Code> shared_code(function->shared()->code());
+ shared_code->set_profiler_ticks(0);
ASSERT(isolate->concurrent_recompilation_enabled());
- if (!Compiler::RecompileConcurrent(function)) {
- function->ReplaceCode(function->shared()->code());
+ if (!Compiler::RecompileConcurrent(function, shared_code)) {
+ function->ReplaceCode(*shared_code);
}
return isolate->heap()->undefined_value();
}
@@ -8660,20 +8631,27 @@
RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileForOnStackReplacement) {
HandleScope scope(isolate);
- ASSERT(args.length() == 2);
+ ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
- CONVERT_NUMBER_CHECKED(uint32_t, pc_offset, Uint32, args[1]);
Handle<Code> unoptimized(function->shared()->code(), isolate);
-#ifdef DEBUG
+ // Passing the PC in the javascript frame from the caller directly is
+ // not GC safe, so we walk the stack to get it.
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
+ if (!unoptimized->contains(frame->pc())) {
+ // Code on the stack may not be the code object referenced by the shared
+ // function info. It may have been replaced to include deoptimization data.
+ unoptimized = Handle<Code>(frame->LookupCode());
+ }
+
+ uint32_t pc_offset = static_cast<uint32_t>(frame->pc() -
+ unoptimized->instruction_start());
+
+#ifdef DEBUG
ASSERT_EQ(frame->function(), *function);
ASSERT_EQ(frame->LookupCode(), *unoptimized);
ASSERT(unoptimized->contains(frame->pc()));
-
- ASSERT(pc_offset ==
- static_cast<uint32_t>(frame->pc() - unoptimized->instruction_start()));
#endif // DEBUG
// We're not prepared to handle a function with arguments object.
@@ -8699,12 +8677,12 @@
if (job == NULL) {
if (IsSuitableForOnStackReplacement(isolate, function, unoptimized) &&
- Compiler::RecompileConcurrent(function, pc_offset)) {
+ Compiler::RecompileConcurrent(function, unoptimized, pc_offset)) {
if (function->IsMarkedForLazyRecompilation() ||
function->IsMarkedForConcurrentRecompilation()) {
// Prevent regular recompilation if we queue this for OSR.
// TODO(yangguo): remove this as soon as OSR becomes one-shot.
- function->ReplaceCode(*unoptimized);
+ function->ReplaceCode(function->shared()->code());
}
return NULL;
}
@@ -13560,7 +13538,7 @@
CONVERT_ARG_CHECKED(String, arg, 0);
SmartArrayPointer<char> flags =
arg->ToCString(DISALLOW_NULLS, ROBUST_STRING_TRAVERSAL);
- FlagList::SetFlagsFromString(*flags, StrLength(*flags));
+ FlagList::SetFlagsFromString(flags.get(), StrLength(flags.get()));
return isolate->heap()->undefined_value();
}
@@ -14335,7 +14313,7 @@
HandleScope scope(isolate);
ASSERT(args.length() == 1);
CONVERT_ARG_HANDLE_CHECKED(String, message, 0);
- OS::PrintError("abort: %s\n", *message->ToCString());
+ OS::PrintError("abort: %s\n", message->ToCString().get());
isolate->PrintStack(stderr);
OS::Abort();
UNREACHABLE();
diff --git a/src/runtime.h b/src/runtime.h
index 0f920c7..95fb419 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -101,7 +101,7 @@
F(GetOptimizationStatus, -1, 1) \
F(GetOptimizationCount, 1, 1) \
F(UnblockConcurrentRecompilation, 0, 1) \
- F(CompileForOnStackReplacement, 2, 1) \
+ F(CompileForOnStackReplacement, 1, 1) \
F(SetAllocationTimeout, 2, 1) \
F(AllocateInNewSpace, 1, 1) \
F(AllocateInTargetSpace, 2, 1) \
@@ -180,16 +180,13 @@
F(Math_asin, 1, 1) \
F(Math_atan, 1, 1) \
F(Math_atan2, 2, 1) \
- F(Math_cos, 1, 1) \
F(Math_exp, 1, 1) \
F(Math_floor, 1, 1) \
F(Math_log, 1, 1) \
F(Math_pow, 2, 1) \
F(Math_pow_cfunction, 2, 1) \
F(RoundNumber, 1, 1) \
- F(Math_sin, 1, 1) \
F(Math_sqrt, 1, 1) \
- F(Math_tan, 1, 1) \
\
/* Regular expressions */ \
F(RegExpCompile, 3, 1) \
diff --git a/src/scanner-character-streams.cc b/src/scanner-character-streams.cc
index fb50345..cbef3f9 100644
--- a/src/scanner-character-streams.cc
+++ b/src/scanner-character-streams.cc
@@ -213,11 +213,11 @@
static const byte kUtf8MultiByteMask = 0xC0;
-static const byte kUtf8MultiByteCharStart = 0xC0;
static const byte kUtf8MultiByteCharFollower = 0x80;
#ifdef DEBUG
+static const byte kUtf8MultiByteCharStart = 0xC0;
static bool IsUtf8MultiCharacterStart(byte first_byte) {
return (first_byte & kUtf8MultiByteMask) == kUtf8MultiByteCharStart;
}
diff --git a/src/scopes.cc b/src/scopes.cc
index fefc696..a84d4e7 100644
--- a/src/scopes.cc
+++ b/src/scopes.cc
@@ -800,7 +800,7 @@
static void PrintName(Handle<String> name) {
SmartArrayPointer<char> s = name->ToCString(DISALLOW_NULLS);
- PrintF("%s", *s);
+ PrintF("%s", s.get());
}
diff --git a/src/smart-pointers.h b/src/smart-pointers.h
index 7c35b2a..7203c16 100644
--- a/src/smart-pointers.h
+++ b/src/smart-pointers.h
@@ -36,35 +36,31 @@
class SmartPointerBase {
public:
// Default constructor. Constructs an empty scoped pointer.
- inline SmartPointerBase() : p_(NULL) {}
+ SmartPointerBase() : p_(NULL) {}
// Constructs a scoped pointer from a plain one.
- explicit inline SmartPointerBase(T* ptr) : p_(ptr) {}
+ explicit SmartPointerBase(T* ptr) : p_(ptr) {}
// Copy constructor removes the pointer from the original to avoid double
// freeing.
- inline SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs)
+ SmartPointerBase(const SmartPointerBase<Deallocator, T>& rhs)
: p_(rhs.p_) {
const_cast<SmartPointerBase<Deallocator, T>&>(rhs).p_ = NULL;
}
- // When the destructor of the scoped pointer is executed the plain pointer
- // is deleted using DeleteArray. This implies that you must allocate with
- // NewArray.
- inline ~SmartPointerBase() { if (p_) Deallocator::Delete(p_); }
+ T* operator->() const { return p_; }
- inline T* operator->() const { return p_; }
+ T& operator*() const { return *p_; }
- // You can get the underlying pointer out with the * operator.
- inline T* operator*() { return p_; }
+ T* get() const { return p_; }
// You can use [n] to index as if it was a plain pointer.
- inline T& operator[](size_t i) {
+ T& operator[](size_t i) {
return p_[i];
}
// You can use [n] to index as if it was a plain pointer.
- const inline T& operator[](size_t i) const {
+ const T& operator[](size_t i) const {
return p_[i];
}
@@ -76,13 +72,14 @@
// If you want to take out the plain pointer and don't want it automatically
// deleted then call Detach(). Afterwards, the smart pointer is empty
// (NULL).
- inline T* Detach() {
+ T* Detach() {
T* temp = p_;
p_ = NULL;
return temp;
}
- inline void Reset(T* new_value) {
+ void Reset(T* new_value) {
+ ASSERT(p_ == NULL || p_ != new_value);
if (p_) Deallocator::Delete(p_);
p_ = new_value;
}
@@ -90,7 +87,7 @@
// Assignment requires an empty (NULL) SmartArrayPointer as the receiver. Like
// the copy constructor it removes the pointer in the original to avoid
// double freeing.
- inline SmartPointerBase<Deallocator, T>& operator=(
+ SmartPointerBase<Deallocator, T>& operator=(
const SmartPointerBase<Deallocator, T>& rhs) {
ASSERT(is_empty());
T* tmp = rhs.p_; // swap to handle self-assignment
@@ -99,7 +96,13 @@
return *this;
}
- inline bool is_empty() { return p_ == NULL; }
+ bool is_empty() const { return p_ == NULL; }
+
+ protected:
+ // When the destructor of the scoped pointer is executed the plain pointer
+ // is deleted using DeleteArray. This implies that you must allocate with
+ // NewArray.
+ ~SmartPointerBase() { if (p_) Deallocator::Delete(p_); }
private:
T* p_;
@@ -119,10 +122,10 @@
template<typename T>
class SmartArrayPointer: public SmartPointerBase<ArrayDeallocator<T>, T> {
public:
- inline SmartArrayPointer() { }
- explicit inline SmartArrayPointer(T* ptr)
+ SmartArrayPointer() { }
+ explicit SmartArrayPointer(T* ptr)
: SmartPointerBase<ArrayDeallocator<T>, T>(ptr) { }
- inline SmartArrayPointer(const SmartArrayPointer<T>& rhs)
+ SmartArrayPointer(const SmartArrayPointer<T>& rhs)
: SmartPointerBase<ArrayDeallocator<T>, T>(rhs) { }
};
@@ -138,10 +141,10 @@
template<typename T>
class SmartPointer: public SmartPointerBase<ObjectDeallocator<T>, T> {
public:
- inline SmartPointer() { }
- explicit inline SmartPointer(T* ptr)
+ SmartPointer() { }
+ explicit SmartPointer(T* ptr)
: SmartPointerBase<ObjectDeallocator<T>, T>(ptr) { }
- inline SmartPointer(const SmartPointer<T>& rhs)
+ SmartPointer(const SmartPointer<T>& rhs)
: SmartPointerBase<ObjectDeallocator<T>, T>(rhs) { }
};
diff --git a/src/stub-cache.cc b/src/stub-cache.cc
index eec5baf..a562ace 100644
--- a/src/stub-cache.cc
+++ b/src/stub-cache.cc
@@ -1110,7 +1110,7 @@
Handle<Code> StubCompiler::GetCodeWithFlags(Code::Flags flags,
Handle<Name> name) {
return (FLAG_print_code_stubs && !name.is_null() && name->IsString())
- ? GetCodeWithFlags(flags, *Handle<String>::cast(name)->ToCString())
+ ? GetCodeWithFlags(flags, Handle<String>::cast(name)->ToCString().get())
: GetCodeWithFlags(flags, NULL);
}
diff --git a/src/v8-counters.h b/src/v8-counters.h
index 9178046..72f5650 100644
--- a/src/v8-counters.h
+++ b/src/v8-counters.h
@@ -242,15 +242,12 @@
SC(math_asin, V8.MathAsin) \
SC(math_atan, V8.MathAtan) \
SC(math_atan2, V8.MathAtan2) \
- SC(math_cos, V8.MathCos) \
SC(math_exp, V8.MathExp) \
SC(math_floor, V8.MathFloor) \
SC(math_log, V8.MathLog) \
SC(math_pow, V8.MathPow) \
SC(math_round, V8.MathRound) \
- SC(math_sin, V8.MathSin) \
SC(math_sqrt, V8.MathSqrt) \
- SC(math_tan, V8.MathTan) \
SC(transcendental_cache_hit, V8.TranscendentalCacheHit) \
SC(transcendental_cache_miss, V8.TranscendentalCacheMiss) \
SC(stack_interrupts, V8.StackInterrupts) \
diff --git a/src/v8utils.h b/src/v8utils.h
index 02e57eb..058b153 100644
--- a/src/v8utils.h
+++ b/src/v8utils.h
@@ -266,6 +266,9 @@
INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint8_t* src, int chars));
INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
+#elif defined(V8_HOST_ARCH_MIPS)
+INLINE(void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars));
+INLINE(void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars));
#endif
// Copy from ASCII/16bit chars to ASCII/16bit chars.
@@ -421,6 +424,24 @@
break;
}
}
+
+
+#elif defined(V8_HOST_ARCH_MIPS)
+void CopyCharsUnsigned(uint8_t* dest, const uint8_t* src, int chars) {
+ if (chars < OS::kMinComplexMemCopy) {
+ memcpy(dest, src, chars);
+ } else {
+ OS::MemCopy(dest, src, chars);
+ }
+}
+
+void CopyCharsUnsigned(uint16_t* dest, const uint16_t* src, int chars) {
+ if (chars < OS::kMinComplexMemCopy) {
+ memcpy(dest, src, chars * sizeof(*dest));
+ } else {
+ OS::MemCopy(dest, src, chars * sizeof(*dest));
+ }
+}
#endif
diff --git a/src/version.cc b/src/version.cc
index ef9c078..1dca166 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -33,8 +33,8 @@
// NOTE these macros are used by some of the tool scripts and the build
// system so their names cannot be changed without changing the scripts.
#define MAJOR_VERSION 3
-#define MINOR_VERSION 23
-#define BUILD_NUMBER 18
+#define MINOR_VERSION 24
+#define BUILD_NUMBER 0
#define PATCH_LEVEL 0
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
diff --git a/src/x64/builtins-x64.cc b/src/x64/builtins-x64.cc
index f4864f8..aef9164 100644
--- a/src/x64/builtins-x64.cc
+++ b/src/x64/builtins-x64.cc
@@ -1393,17 +1393,9 @@
__ movq(rax, Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
{
FrameScope scope(masm, StackFrame::INTERNAL);
- // Lookup and calculate pc offset.
- __ movq(rdx, Operand(rbp, StandardFrameConstants::kCallerPCOffset));
- __ movq(rbx, FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset));
- __ subq(rdx, Immediate(Code::kHeaderSize - kHeapObjectTag));
- __ subq(rdx, FieldOperand(rbx, SharedFunctionInfo::kCodeOffset));
- __ Integer32ToSmi(rdx, rdx);
-
- // Pass both function and pc offset as arguments.
+ // Pass function as argument.
__ push(rax);
- __ push(rdx);
- __ CallRuntime(Runtime::kCompileForOnStackReplacement, 2);
+ __ CallRuntime(Runtime::kCompileForOnStackReplacement, 1);
}
Label skip;
diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
index 0c9a0f2..2f65856 100644
--- a/src/x64/code-stubs-x64.cc
+++ b/src/x64/code-stubs-x64.cc
@@ -789,9 +789,6 @@
Runtime::FunctionId TranscendentalCacheStub::RuntimeFunction() {
switch (type_) {
// Add more cases when necessary.
- case TranscendentalCache::SIN: return Runtime::kMath_sin;
- case TranscendentalCache::COS: return Runtime::kMath_cos;
- case TranscendentalCache::TAN: return Runtime::kMath_tan;
case TranscendentalCache::LOG: return Runtime::kMath_log;
default:
UNIMPLEMENTED();
@@ -807,99 +804,10 @@
// rbx: Bits of input double. Must be preserved.
// rcx: Pointer to cache entry. Must be preserved.
// st(0): Input double
- Label done;
- if (type == TranscendentalCache::SIN ||
- type == TranscendentalCache::COS ||
- type == TranscendentalCache::TAN) {
- // Both fsin and fcos require arguments in the range +/-2^63 and
- // return NaN for infinities and NaN. They can share all code except
- // the actual fsin/fcos operation.
- Label in_range;
- // If argument is outside the range -2^63..2^63, fsin/cos doesn't
- // work. We must reduce it to the appropriate range.
- __ movq(rdi, rbx);
- // Move exponent and sign bits to low bits.
- __ shr(rdi, Immediate(HeapNumber::kMantissaBits));
- // Remove sign bit.
- __ andl(rdi, Immediate((1 << HeapNumber::kExponentBits) - 1));
- int supported_exponent_limit = (63 + HeapNumber::kExponentBias);
- __ cmpl(rdi, Immediate(supported_exponent_limit));
- __ j(below, &in_range);
- // Check for infinity and NaN. Both return NaN for sin.
- __ cmpl(rdi, Immediate(0x7ff));
- Label non_nan_result;
- __ j(not_equal, &non_nan_result, Label::kNear);
- // Input is +/-Infinity or NaN. Result is NaN.
- __ fstp(0);
- // NaN is represented by 0x7ff8000000000000.
- __ subq(rsp, Immediate(kPointerSize));
- __ movl(Operand(rsp, 4), Immediate(0x7ff80000));
- __ movl(Operand(rsp, 0), Immediate(0x00000000));
- __ fld_d(Operand(rsp, 0));
- __ addq(rsp, Immediate(kPointerSize));
- __ jmp(&done);
-
- __ bind(&non_nan_result);
-
- // Use fpmod to restrict argument to the range +/-2*PI.
- __ movq(rdi, rax); // Save rax before using fnstsw_ax.
- __ fldpi();
- __ fadd(0);
- __ fld(1);
- // FPU Stack: input, 2*pi, input.
- {
- Label no_exceptions;
- __ fwait();
- __ fnstsw_ax();
- // Clear if Illegal Operand or Zero Division exceptions are set.
- __ testl(rax, Immediate(5)); // #IO and #ZD flags of FPU status word.
- __ j(zero, &no_exceptions);
- __ fnclex();
- __ bind(&no_exceptions);
- }
-
- // Compute st(0) % st(1)
- {
- Label partial_remainder_loop;
- __ bind(&partial_remainder_loop);
- __ fprem1();
- __ fwait();
- __ fnstsw_ax();
- __ testl(rax, Immediate(0x400)); // Check C2 bit of FPU status word.
- // If C2 is set, computation only has partial result. Loop to
- // continue computation.
- __ j(not_zero, &partial_remainder_loop);
- }
- // FPU Stack: input, 2*pi, input % 2*pi
- __ fstp(2);
- // FPU Stack: input % 2*pi, 2*pi,
- __ fstp(0);
- // FPU Stack: input % 2*pi
- __ movq(rax, rdi); // Restore rax, pointer to the new HeapNumber.
- __ bind(&in_range);
- switch (type) {
- case TranscendentalCache::SIN:
- __ fsin();
- break;
- case TranscendentalCache::COS:
- __ fcos();
- break;
- case TranscendentalCache::TAN:
- // FPTAN calculates tangent onto st(0) and pushes 1.0 onto the
- // FP register stack.
- __ fptan();
- __ fstp(0); // Pop FP register stack.
- break;
- default:
- UNREACHABLE();
- }
- __ bind(&done);
- } else {
- ASSERT(type == TranscendentalCache::LOG);
- __ fldln2();
- __ fxch();
- __ fyl2x();
- }
+ ASSERT(type == TranscendentalCache::LOG);
+ __ fldln2();
+ __ fxch();
+ __ fyl2x();
}
diff --git a/src/x64/codegen-x64.cc b/src/x64/codegen-x64.cc
index afe0e3b..96d930e 100644
--- a/src/x64/codegen-x64.cc
+++ b/src/x64/codegen-x64.cc
@@ -64,9 +64,6 @@
if (buffer == NULL) {
// Fallback to library function if function cannot be created.
switch (type) {
- case TranscendentalCache::SIN: return &sin;
- case TranscendentalCache::COS: return &cos;
- case TranscendentalCache::TAN: return &tan;
case TranscendentalCache::LOG: return &log;
default: UNIMPLEMENTED();
}
diff --git a/src/x64/full-codegen-x64.cc b/src/x64/full-codegen-x64.cc
index e479368..473f548 100644
--- a/src/x64/full-codegen-x64.cc
+++ b/src/x64/full-codegen-x64.cc
@@ -310,10 +310,6 @@
void FullCodeGenerator::EmitProfilingCounterReset() {
int reset_value = FLAG_interrupt_budget;
- if (info_->ShouldSelfOptimize() && !FLAG_retry_self_opt) {
- // Self-optimization is a one-off thing; if it fails, don't try again.
- reset_value = Smi::kMaxValue;
- }
__ movq(rbx, profiling_counter_, RelocInfo::EMBEDDED_OBJECT);
__ Move(kScratchRegister, Smi::FromInt(reset_value));
__ movq(FieldOperand(rbx, Cell::kValueOffset), kScratchRegister);
@@ -325,13 +321,10 @@
Comment cmnt(masm_, "[ Back edge bookkeeping");
Label ok;
- int weight = 1;
- if (FLAG_weighted_back_edges) {
- ASSERT(back_edge_target->is_bound());
- int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
+ ASSERT(back_edge_target->is_bound());
+ int distance = masm_->SizeOfCodeGeneratedSince(back_edge_target);
+ int weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
EmitProfilingCounterDecrement(weight);
__ j(positive, &ok, Label::kNear);
__ call(isolate()->builtins()->InterruptCheck(), RelocInfo::CODE_TARGET);
@@ -362,31 +355,24 @@
__ push(rax);
__ CallRuntime(Runtime::kTraceExit, 1);
}
- if (FLAG_interrupt_at_exit || FLAG_self_optimization) {
- // Pretend that the exit is a backwards jump to the entry.
- int weight = 1;
- if (info_->ShouldSelfOptimize()) {
- weight = FLAG_interrupt_budget / FLAG_self_opt_count;
- } else if (FLAG_weighted_back_edges) {
- int distance = masm_->pc_offset();
- weight = Min(kMaxBackEdgeWeight,
- Max(1, distance / kCodeSizeMultiplier));
- }
- EmitProfilingCounterDecrement(weight);
- Label ok;
- __ j(positive, &ok, Label::kNear);
- __ push(rax);
- if (info_->ShouldSelfOptimize() && FLAG_direct_self_opt) {
- __ push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
- __ CallRuntime(Runtime::kOptimizeFunctionOnNextCall, 1);
- } else {
- __ call(isolate()->builtins()->InterruptCheck(),
- RelocInfo::CODE_TARGET);
- }
- __ pop(rax);
- EmitProfilingCounterReset();
- __ bind(&ok);
+ // Pretend that the exit is a backwards jump to the entry.
+ int weight = 1;
+ if (info_->ShouldSelfOptimize()) {
+ weight = FLAG_interrupt_budget / FLAG_self_opt_count;
+ } else {
+ int distance = masm_->pc_offset();
+ weight = Min(kMaxBackEdgeWeight,
+ Max(1, distance / kCodeSizeMultiplier));
}
+ EmitProfilingCounterDecrement(weight);
+ Label ok;
+ __ j(positive, &ok, Label::kNear);
+ __ push(rax);
+ __ call(isolate()->builtins()->InterruptCheck(),
+ RelocInfo::CODE_TARGET);
+ __ pop(rax);
+ EmitProfilingCounterReset();
+ __ bind(&ok);
#ifdef DEBUG
// Add a label for checking the size of the code used for returning.
Label check_exit_codesize;
@@ -4840,9 +4826,11 @@
static const byte kJnsInstruction = 0x79;
static const byte kJnsOffset = 0x1d;
-static const byte kCallInstruction = 0xe8;
static const byte kNopByteOne = 0x66;
static const byte kNopByteTwo = 0x90;
+#ifdef DEBUG
+static const byte kCallInstruction = 0xe8;
+#endif
void BackEdgeTable::PatchAt(Code* unoptimized_code,
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index 3ab5236..7c9949a 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -3747,39 +3747,6 @@
}
-void LCodeGen::DoMathTan(LMathTan* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ Set(rsi, 0);
- TranscendentalCacheStub stub(TranscendentalCache::TAN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathCos(LMathCos* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ Set(rsi, 0);
- TranscendentalCacheStub stub(TranscendentalCache::COS,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
-void LCodeGen::DoMathSin(LMathSin* instr) {
- ASSERT(ToDoubleRegister(instr->result()).is(xmm1));
- // Set the context register to a GC-safe fake value. Clobbering it is
- // OK because this instruction is marked as a call.
- __ Set(rsi, 0);
- TranscendentalCacheStub stub(TranscendentalCache::SIN,
- TranscendentalCacheStub::UNTAGGED);
- CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
-}
-
-
void LCodeGen::DoInvokeFunction(LInvokeFunction* instr) {
ASSERT(ToRegister(instr->context()).is(rsi));
ASSERT(ToRegister(instr->function()).is(rdi));
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index 0f7ebc4..974a970 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -259,7 +259,7 @@
stream->Add("if typeof ");
value()->PrintTo(stream);
stream->Add(" == \"%s\" then B%d else B%d",
- *hydrogen()->type_literal()->ToCString(),
+ hydrogen()->type_literal()->ToCString().get(),
true_block_id(), false_block_id());
}
@@ -312,13 +312,13 @@
void LCallNamed::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
void LCallGlobal::PrintDataTo(StringStream* stream) {
SmartArrayPointer<char> name_string = name()->ToCString();
- stream->Add("%s #%d / ", *name_string, arity());
+ stream->Add("%s #%d / ", name_string.get(), arity());
}
@@ -384,7 +384,7 @@
void LStoreNamedGeneric::PrintDataTo(StringStream* stream) {
object()->PrintTo(stream);
stream->Add(".");
- stream->Add(*String::cast(*name())->ToCString());
+ stream->Add(String::cast(*name())->ToCString().get());
stream->Add(" <- ");
value()->PrintTo(stream);
}
@@ -1187,9 +1187,6 @@
case kMathRound: return DoMathRound(instr);
case kMathAbs: return DoMathAbs(instr);
case kMathLog: return DoMathLog(instr);
- case kMathSin: return DoMathSin(instr);
- case kMathCos: return DoMathCos(instr);
- case kMathTan: return DoMathTan(instr);
case kMathExp: return DoMathExp(instr);
case kMathSqrt: return DoMathSqrt(instr);
case kMathPowHalf: return DoMathPowHalf(instr);
@@ -1231,27 +1228,6 @@
}
-LInstruction* LChunkBuilder::DoMathSin(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), xmm1);
- LMathSin* result = new(zone()) LMathSin(input);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathCos(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), xmm1);
- LMathCos* result = new(zone()) LMathCos(input);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
-}
-
-
-LInstruction* LChunkBuilder::DoMathTan(HUnaryMathOperation* instr) {
- LOperand* input = UseFixedDouble(instr->value(), xmm1);
- LMathTan* result = new(zone()) LMathTan(input);
- return MarkAsCall(DefineFixedDouble(result, xmm1), instr);
-}
-
-
LInstruction* LChunkBuilder::DoMathExp(HUnaryMathOperation* instr) {
ASSERT(instr->representation().IsDouble());
ASSERT(instr->value()->representation().IsDouble());
diff --git a/src/x64/lithium-x64.h b/src/x64/lithium-x64.h
index 44bd992..e644c2d 100644
--- a/src/x64/lithium-x64.h
+++ b/src/x64/lithium-x64.h
@@ -131,7 +131,6 @@
V(LoadNamedGeneric) \
V(MapEnumLength) \
V(MathAbs) \
- V(MathCos) \
V(MathExp) \
V(MathFloor) \
V(MathFloorOfDiv) \
@@ -139,9 +138,7 @@
V(MathMinMax) \
V(MathPowHalf) \
V(MathRound) \
- V(MathSin) \
V(MathSqrt) \
- V(MathTan) \
V(ModI) \
V(MulI) \
V(NumberTagD) \
@@ -770,42 +767,6 @@
};
-class LMathSin V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathSin(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
-};
-
-
-class LMathCos V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathCos(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
-};
-
-
-class LMathTan V8_FINAL : public LTemplateInstruction<1, 1, 0> {
- public:
- explicit LMathTan(LOperand* value) {
- inputs_[0] = value;
- }
-
- LOperand* value() { return inputs_[0]; }
-
- DECLARE_CONCRETE_INSTRUCTION(MathTan, "math-tan")
-};
-
-
class LMathExp V8_FINAL : public LTemplateInstruction<1, 1, 2> {
public:
LMathExp(LOperand* value, LOperand* temp1, LOperand* temp2) {
@@ -2705,9 +2666,6 @@
LInstruction* DoMathRound(HUnaryMathOperation* instr);
LInstruction* DoMathAbs(HUnaryMathOperation* instr);
LInstruction* DoMathLog(HUnaryMathOperation* instr);
- LInstruction* DoMathSin(HUnaryMathOperation* instr);
- LInstruction* DoMathCos(HUnaryMathOperation* instr);
- LInstruction* DoMathTan(HUnaryMathOperation* instr);
LInstruction* DoMathExp(HUnaryMathOperation* instr);
LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc
index 9bf6e9f..9cfcf46 100644
--- a/src/x64/stub-cache-x64.cc
+++ b/src/x64/stub-cache-x64.cc
@@ -639,12 +639,10 @@
public:
CallInterceptorCompiler(CallStubCompiler* stub_compiler,
const ParameterCount& arguments,
- Register name,
- ExtraICState extra_ic_state)
+ Register name)
: stub_compiler_(stub_compiler),
arguments_(arguments),
- name_(name),
- extra_ic_state_(extra_ic_state) {}
+ name_(name) {}
void Compile(MacroAssembler* masm,
Handle<JSObject> object,
@@ -820,7 +818,6 @@
CallStubCompiler* stub_compiler_;
const ParameterCount& arguments_;
Register name_;
- ExtraICState extra_ic_state_;
};
@@ -2497,7 +2494,7 @@
StackArgumentsAccessor args(rsp, arguments());
__ movq(rdx, args.GetReceiverOperand());
- CallInterceptorCompiler compiler(this, arguments(), rcx, extra_state());
+ CallInterceptorCompiler compiler(this, arguments(), rcx);
compiler.Compile(masm(), object, holder, name, &lookup, rdx, rbx, rdi, rax,
&miss);