Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(950)

Unified Diff: src/ic.cc

Issue 844006: Merge changes up to V8 version 2.1.3 into the partial snapshots (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/partial_snapshots/
Patch Set: Created 10 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/ic.h ('k') | src/jsregexp.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ic.cc
===================================================================
--- src/ic.cc (revision 3964)
+++ src/ic.cc (working copy)
@@ -63,7 +63,9 @@
Code* new_target,
const char* extra_info) {
if (FLAG_trace_ic) {
- State new_state = StateFrom(new_target, Heap::undefined_value());
+ State new_state = StateFrom(new_target,
+ Heap::undefined_value(),
+ Heap::undefined_value());
PrintF("[%s (%c->%c)%s", type,
TransitionMarkFromState(old_state),
TransitionMarkFromState(new_state),
@@ -132,7 +134,7 @@
}
#endif
-IC::State IC::StateFrom(Code* target, Object* receiver) {
+IC::State IC::StateFrom(Code* target, Object* receiver, Object* name) {
IC::State state = target->ic_state();
if (state != MONOMORPHIC) return state;
@@ -148,7 +150,7 @@
// the receiver map's code cache. Therefore, if the current target
// is in the receiver map's code cache, the inline cache failed due
// to prototype check failure.
- int index = map->IndexInCodeCache(target);
+ int index = map->IndexInCodeCache(String::cast(name), target);
if (index >= 0) {
// For keyed load/store, the most likely cause of cache failure is
// that the key has changed. We do not distinguish between
@@ -160,7 +162,7 @@
// Remove the target from the code cache to avoid hitting the same
// invalid stub again.
- map->RemoveFromCodeCache(index);
+ map->RemoveFromCodeCache(String::cast(name), target, index);
return MONOMORPHIC_PROTOTYPE_FAILURE;
}
@@ -222,6 +224,7 @@
case Code::STORE_IC: return StoreIC::Clear(address, target);
case Code::KEYED_STORE_IC: return KeyedStoreIC::Clear(address, target);
case Code::CALL_IC: return CallIC::Clear(address, target);
+ case Code::BINARY_OP_IC: return BinaryOpIC::Clear(address, target);
default: UNREACHABLE();
}
}
@@ -1290,7 +1293,7 @@
NoHandleAllocation na;
ASSERT(args.length() == 2);
CallIC ic;
- IC::State state = IC::StateFrom(ic.target(), args[0]);
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
Object* result =
ic.LoadFunction(state, args.at<Object>(0), args.at<String>(1));
@@ -1323,7 +1326,7 @@
NoHandleAllocation na;
ASSERT(args.length() == 2);
LoadIC ic;
- IC::State state = IC::StateFrom(ic.target(), args[0]);
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
return ic.Load(state, args.at<Object>(0), args.at<String>(1));
}
@@ -1333,7 +1336,7 @@
NoHandleAllocation na;
ASSERT(args.length() == 2);
KeyedLoadIC ic;
- IC::State state = IC::StateFrom(ic.target(), args[0]);
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
return ic.Load(state, args.at<Object>(0), args.at<Object>(1));
}
@@ -1343,7 +1346,7 @@
NoHandleAllocation na;
ASSERT(args.length() == 3);
StoreIC ic;
- IC::State state = IC::StateFrom(ic.target(), args[0]);
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
return ic.Store(state, args.at<Object>(0), args.at<String>(1),
args.at<Object>(2));
}
@@ -1356,7 +1359,9 @@
JSObject* receiver = JSObject::cast(args[0]);
Object* len = args[1];
- return receiver->SetElementsLength(len);
+ Object* result = receiver->SetElementsLength(len);
+ if (result->IsFailure()) return result;
+ return len;
}
@@ -1399,12 +1404,118 @@
NoHandleAllocation na;
ASSERT(args.length() == 3);
KeyedStoreIC ic;
- IC::State state = IC::StateFrom(ic.target(), args[0]);
+ IC::State state = IC::StateFrom(ic.target(), args[0], args[1]);
return ic.Store(state, args.at<Object>(0), args.at<Object>(1),
args.at<Object>(2));
}
+void BinaryOpIC::patch(Code* code) {
+ set_target(code);
+}
+
+
+void BinaryOpIC::Clear(Address address, Code* target) {
+ if (target->ic_state() == UNINITIALIZED) return;
+
+ // At the end of a fast case stub there should be a reference to
+ // a corresponding UNINITIALIZED stub, so look for the last reloc info item.
+ RelocInfo* rinfo = NULL;
+ for (RelocIterator it(target, RelocInfo::kCodeTargetMask);
+ !it.done(); it.next()) {
+ rinfo = it.rinfo();
+ }
+
+ ASSERT(rinfo != NULL);
+ Code* uninit_stub = Code::GetCodeFromTargetAddress(rinfo->target_address());
+ ASSERT(uninit_stub->ic_state() == UNINITIALIZED &&
+ uninit_stub->kind() == Code::BINARY_OP_IC);
+ SetTargetAtAddress(address, uninit_stub);
+}
+
+
+const char* BinaryOpIC::GetName(TypeInfo type_info) {
+ switch (type_info) {
+ case DEFAULT: return "Default";
+ case GENERIC: return "Generic";
+ case HEAP_NUMBERS: return "HeapNumbers";
+ case STRINGS: return "Strings";
+ default: return "Invalid";
+ }
+}
+
+
+BinaryOpIC::State BinaryOpIC::ToState(TypeInfo type_info) {
+ switch (type_info) {
+ // DEFAULT is mapped to UNINITIALIZED so that calls to DEFAULT stubs
+ // are not cleared at GC.
+ case DEFAULT: return UNINITIALIZED;
+
+ // Could have mapped GENERIC to MONOMORPHIC just as well but MEGAMORPHIC is
+ // conceptually closer.
+ case GENERIC: return MEGAMORPHIC;
+
+ default: return MONOMORPHIC;
+ }
+}
+
+
+BinaryOpIC::TypeInfo BinaryOpIC::GetTypeInfo(Object* left,
+ Object* right) {
+ // Patching is never requested for the two smis.
+ ASSERT(!left->IsSmi() || !right->IsSmi());
+
+ if (left->IsNumber() && right->IsNumber()) {
+ return HEAP_NUMBERS;
+ }
+
+ if (left->IsString() || right->IsString()) {
+ // Patching for fast string ADD makes sense even if only one of the
+ // arguments is a string.
+ return STRINGS;
+ }
+
+ return GENERIC;
+}
+
+
+// defined in codegen-<arch>.cc
+Handle<Code> GetBinaryOpStub(int key, BinaryOpIC::TypeInfo type_info);
+
+
+Object* BinaryOp_Patch(Arguments args) {
+ ASSERT(args.length() == 6);
+
+ Handle<Object> left = args.at<Object>(0);
+ Handle<Object> right = args.at<Object>(1);
+ Handle<Object> result = args.at<Object>(2);
+ int key = Smi::cast(args[3])->value();
+#ifdef DEBUG
+ Token::Value op = static_cast<Token::Value>(Smi::cast(args[4])->value());
+ BinaryOpIC::TypeInfo prev_type_info =
+ static_cast<BinaryOpIC::TypeInfo>(Smi::cast(args[5])->value());
+#endif // DEBUG
+ { HandleScope scope;
+ BinaryOpIC::TypeInfo type_info = BinaryOpIC::GetTypeInfo(*left, *right);
+ Handle<Code> code = GetBinaryOpStub(key, type_info);
+ if (!code.is_null()) {
+ BinaryOpIC ic;
+ ic.patch(*code);
+#ifdef DEBUG
+ if (FLAG_trace_ic) {
+ PrintF("[BinaryOpIC (%s->%s)#%s]\n",
+ BinaryOpIC::GetName(prev_type_info),
+ BinaryOpIC::GetName(type_info),
+ Token::Name(op));
+ }
+#endif // DEBUG
+ }
+ }
+
+ return *result;
+}
+
+
static Address IC_utilities[] = {
#define ADDR(name) FUNCTION_ADDR(name),
IC_UTIL_LIST(ADDR)
« no previous file with comments | « src/ic.h ('k') | src/jsregexp.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698