Index: src/code-stubs.cc |
diff --git a/src/code-stubs.cc b/src/code-stubs.cc |
index 5bec7e05f913be19ef8526f76e86580b99041115..bfc71fcb92ad99155c0eb0d651d438269e582952 100644 |
--- a/src/code-stubs.cc |
+++ b/src/code-stubs.cc |
@@ -29,6 +29,7 @@ |
#include "bootstrapper.h" |
#include "code-stubs.h" |
+#include "cpu-profiler.h" |
#include "stub-cache.h" |
#include "factory.h" |
#include "gdb-jit.h" |
@@ -84,6 +85,14 @@ Code::Kind CodeStub::GetCodeKind() const { |
} |
+Handle<Code> CodeStub::GetCodeCopyFromTemplate(Isolate* isolate) { |
+ Handle<Code> ic = GetCode(isolate); |
+ ic = isolate->factory()->CopyCode(ic); |
+ RecordCodeGeneration(*ic, isolate); |
+ return ic; |
+} |
+ |
+ |
Handle<Code> PlatformCodeStub::GenerateCode() { |
Isolate* isolate = Isolate::Current(); |
Factory* factory = isolate->factory(); |
@@ -184,11 +193,82 @@ const char* CodeStub::MajorName(CodeStub::Major major_key, |
} |
-void CodeStub::PrintName(StringStream* stream) { |
+void CodeStub::PrintBaseName(StringStream* stream) { |
stream->Add("%s", MajorName(MajorKey(), false)); |
} |
+void CodeStub::PrintName(StringStream* stream) { |
+ PrintBaseName(stream); |
+ PrintState(stream); |
+} |
+ |
+ |
+Builtins::JavaScript UnaryOpStub::ToJSBuiltin() { |
+ switch (operation_) { |
+ default: |
+ UNREACHABLE(); |
+ case Token::SUB: |
+ return Builtins::UNARY_MINUS; |
+ case Token::BIT_NOT: |
+ return Builtins::BIT_NOT; |
+ } |
+} |
+ |
+ |
+Handle<JSFunction> UnaryOpStub::ToJSFunction(Isolate* isolate) { |
+ Handle<JSBuiltinsObject> builtins(isolate->js_builtins_object()); |
+ Object* builtin = builtins->javascript_builtin(ToJSBuiltin()); |
+ return Handle<JSFunction>(JSFunction::cast(builtin), isolate); |
+} |
+ |
+ |
+MaybeObject* UnaryOpStub::Result(Handle<Object> object, Isolate* isolate) { |
+ Handle<JSFunction> builtin_function = ToJSFunction(isolate); |
+ bool caught_exception; |
+ Handle<Object> result = Execution::Call(builtin_function, object, |
+ 0, NULL, &caught_exception); |
+ if (caught_exception) { |
+ return Failure::Exception(); |
+ } |
+ return *result; |
+} |
+ |
+ |
+void UnaryOpStub::UpdateStatus(Handle<Object> object) { |
+ State old_state(state_); |
+ if (object->IsSmi()) { |
+ state_.Add(SMI); |
+ if (operation_ == Token::SUB && *object == 0) { |
+ // The result (-0) has to be represented as double. |
+ state_.Add(HEAP_NUMBER); |
+ } |
+ } else if (object->IsHeapNumber()) { |
+ state_.Add(HEAP_NUMBER); |
+ } else { |
+ state_.Add(GENERIC); |
+ } |
+ TraceTransition(old_state, state_); |
+} |
+ |
+ |
+Handle<Type> UnaryOpStub::GetType(Isolate* isolate) { |
+ if (state_.Contains(GENERIC)) { |
+ return handle(Type::Any(), isolate); |
+ } |
+ Handle<Type> type = handle(Type::None(), isolate); |
+ if (state_.Contains(SMI)) { |
+ type = handle( |
+ Type::Union(type, handle(Type::Smi(), isolate)), isolate); |
+ } |
+ if (state_.Contains(HEAP_NUMBER)) { |
+ type = handle( |
+ Type::Union(type, handle(Type::Double(), isolate)), isolate); |
+ } |
+ return type; |
+} |
+ |
+ |
void BinaryOpStub::Generate(MacroAssembler* masm) { |
// Explicitly allow generation of nested stubs. It is safe here because |
// generation code does not use any raw pointers. |
@@ -274,6 +354,29 @@ void BinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { |
#undef __ |
+void UnaryOpStub::PrintBaseName(StringStream* stream) { |
+ CodeStub::PrintBaseName(stream); |
+ if (operation_ == Token::SUB) stream->Add("Minus"); |
+ if (operation_ == Token::BIT_NOT) stream->Add("Not"); |
+} |
+ |
+ |
+void UnaryOpStub::PrintState(StringStream* stream) { |
+ state_.Print(stream); |
+} |
+ |
+ |
+void UnaryOpStub::State::Print(StringStream* stream) const { |
+ stream->Add("("); |
+ SimpleListPrinter printer(stream); |
+ if (IsEmpty()) printer.Add("None"); |
+ if (Contains(GENERIC)) printer.Add("Generic"); |
+ if (Contains(HEAP_NUMBER)) printer.Add("HeapNumber"); |
+ if (Contains(SMI)) printer.Add("Smi"); |
+ stream->Add(")"); |
+} |
+ |
+ |
void BinaryOpStub::PrintName(StringStream* stream) { |
const char* op_name = Token::Name(op_); |
const char* overwrite_name; |
@@ -430,8 +533,9 @@ void ICCompareStub::Generate(MacroAssembler* masm) { |
} |
-void CompareNilICStub::Record(Handle<Object> object) { |
+void CompareNilICStub::UpdateStatus(Handle<Object> object) { |
ASSERT(state_ != State::Generic()); |
+ State old_state(state_); |
if (object->IsNull()) { |
state_.Add(NULL_TYPE); |
} else if (object->IsUndefined()) { |
@@ -445,18 +549,22 @@ void CompareNilICStub::Record(Handle<Object> object) { |
} else { |
state_.Add(MONOMORPHIC_MAP); |
} |
+ TraceTransition(old_state, state_); |
} |
-void CompareNilICStub::State::TraceTransition(State to) const { |
+template<class StateType> |
+void HydrogenCodeStub::TraceTransition(StateType from, StateType to) { |
#ifdef DEBUG |
if (!FLAG_trace_ic) return; |
char buffer[100]; |
NoAllocationStringAllocator allocator(buffer, |
static_cast<unsigned>(sizeof(buffer))); |
StringStream stream(&allocator); |
- stream.Add("[CompareNilIC : "); |
- Print(&stream); |
+ stream.Add("["); |
+ PrintBaseName(&stream); |
+ stream.Add(": "); |
+ from.Print(&stream); |
stream.Add("=>"); |
to.Print(&stream); |
stream.Add("]\n"); |
@@ -465,11 +573,15 @@ void CompareNilICStub::State::TraceTransition(State to) const { |
} |
-void CompareNilICStub::PrintName(StringStream* stream) { |
- stream->Add("CompareNilICStub_"); |
+void CompareNilICStub::PrintBaseName(StringStream* stream) { |
+ CodeStub::PrintBaseName(stream); |
+ stream->Add((nil_value_ == kNullValue) ? "(NullValue)": |
+ "(UndefinedValue)"); |
+} |
+ |
+ |
+void CompareNilICStub::PrintState(StringStream* stream) { |
state_.Print(stream); |
- stream->Add((nil_value_ == kNullValue) ? "(NullValue|": |
- "(UndefinedValue|"); |
} |
@@ -551,6 +663,12 @@ void KeyedLoadDictionaryElementStub::Generate(MacroAssembler* masm) { |
} |
+void CreateAllocationSiteStub::GenerateAheadOfTime(Isolate* isolate) { |
+ CreateAllocationSiteStub stub; |
+ stub.GetCode(isolate)->set_is_pregenerated(true); |
+} |
+ |
+ |
void KeyedStoreElementStub::Generate(MacroAssembler* masm) { |
switch (elements_kind_) { |
case FAST_ELEMENTS: |
@@ -614,16 +732,15 @@ void CallConstructStub::PrintName(StringStream* stream) { |
} |
-bool ToBooleanStub::Record(Handle<Object> object) { |
+bool ToBooleanStub::UpdateStatus(Handle<Object> object) { |
Types old_types(types_); |
- bool to_boolean_value = types_.Record(object); |
- old_types.TraceTransition(types_); |
+ bool to_boolean_value = types_.UpdateStatus(object); |
+ TraceTransition(old_types, types_); |
return to_boolean_value; |
} |
-void ToBooleanStub::PrintName(StringStream* stream) { |
- stream->Add("ToBooleanStub_"); |
+void ToBooleanStub::PrintState(StringStream* stream) { |
types_.Print(stream); |
} |
@@ -644,24 +761,7 @@ void ToBooleanStub::Types::Print(StringStream* stream) const { |
} |
-void ToBooleanStub::Types::TraceTransition(Types to) const { |
- #ifdef DEBUG |
- if (!FLAG_trace_ic) return; |
- char buffer[100]; |
- NoAllocationStringAllocator allocator(buffer, |
- static_cast<unsigned>(sizeof(buffer))); |
- StringStream stream(&allocator); |
- stream.Add("[ToBooleanIC : "); |
- Print(&stream); |
- stream.Add("=>"); |
- to.Print(&stream); |
- stream.Add("]\n"); |
- stream.OutputToStdOut(); |
- #endif |
-} |
- |
- |
-bool ToBooleanStub::Types::Record(Handle<Object> object) { |
+bool ToBooleanStub::Types::UpdateStatus(Handle<Object> object) { |
if (object->IsUndefined()) { |
Add(UNDEFINED); |
return false; |
@@ -713,7 +813,7 @@ bool ToBooleanStub::Types::CanBeUndetectable() const { |
void ElementsTransitionAndStoreStub::Generate(MacroAssembler* masm) { |
Label fail; |
- AllocationSiteMode mode = AllocationSiteInfo::GetMode(from_, to_); |
+ AllocationSiteMode mode = AllocationSite::GetMode(from_, to_); |
ASSERT(!IsFastHoleyElementsKind(from_) || IsFastHoleyElementsKind(to_)); |
if (!FLAG_trace_elements_transitions) { |
if (IsFastSmiOrObjectElementsKind(to_)) { |
@@ -757,24 +857,11 @@ void StubFailureTrampolineStub::GenerateAheadOfTime(Isolate* isolate) { |
} |
-FunctionEntryHook ProfileEntryHookStub::entry_hook_ = NULL; |
- |
- |
void ProfileEntryHookStub::EntryHookTrampoline(intptr_t function, |
intptr_t stack_pointer) { |
- if (entry_hook_ != NULL) |
- entry_hook_(function, stack_pointer); |
-} |
- |
- |
-bool ProfileEntryHookStub::SetFunctionEntryHook(FunctionEntryHook entry_hook) { |
- // We don't allow setting a new entry hook over one that's |
- // already active, as the hooks won't stack. |
- if (entry_hook != 0 && entry_hook_ != 0) |
- return false; |
- |
- entry_hook_ = entry_hook; |
- return true; |
+ FunctionEntryHook entry_hook = Isolate::Current()->function_entry_hook(); |
+ ASSERT(entry_hook != NULL); |
+ entry_hook(function, stack_pointer); |
} |