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

Unified Diff: src/ia32/codegen-ia32.cc

Issue 99120: Inline the inobject property case for named property loads. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 8 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/debug.cc ('k') | src/ia32/ic-ia32.cc » ('j') | src/ia32/ic-ia32.cc » ('J')
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/ia32/codegen-ia32.cc
===================================================================
--- src/ia32/codegen-ia32.cc (revision 1804)
+++ src/ia32/codegen-ia32.cc (working copy)
@@ -30,6 +30,7 @@
#include "bootstrapper.h"
#include "codegen-inl.h"
#include "debug.h"
+#include "ic-inl.h"
#include "parser.h"
#include "register-allocator-inl.h"
#include "runtime.h"
@@ -3410,7 +3411,10 @@
? RelocInfo::CODE_TARGET
: RelocInfo::CODE_TARGET_CONTEXT;
Result answer = frame_->CallLoadIC(mode);
-
+ // A test eax instruction following the call signals that the inobject
+ // property case was inlined. Ensure that there is not a test eax
+ // instruction here.
+ __ nop();
// Discard the global object. The result is in answer.
frame_->Drop();
return answer;
@@ -5233,6 +5237,47 @@
#endif
+class DeferredReferenceGetNamedValue: public DeferredCode {
+ public:
+ DeferredReferenceGetNamedValue(CodeGenerator* cgen, Handle<String> name)
+ : DeferredCode(cgen), name_(name) {
+ set_comment("[ DeferredReferenceGetNamedValue");
+ }
+
+ virtual void Generate();
+
+ Label* patch_site() { return &patch_site_; }
+
+ private:
+ Label patch_site_;
+ Handle<String> name_;
+};
+
+
+void DeferredReferenceGetNamedValue::Generate() {
+ CodeGenerator* cgen = generator();
+ Result receiver(cgen);
+ enter()->Bind(&receiver);
+
+ cgen->frame()->Push(&receiver);
+ cgen->frame()->Push(name_);
+ Result answer = cgen->frame()->CallLoadIC(RelocInfo::CODE_TARGET);
+ // The call must be followed by a test eax instruction to indicate
+ // that the inobject property case was inlined.
+ ASSERT(answer.is_register() && answer.reg().is(eax));
+ // Store the delta to the map check instruction here in the test
+ // instruction.
+ int delta_to_patch_site = __ SizeOfCodeGeneratedSince(patch_site());
+ // Here we use masm_-> instead of the double underscore macro because
+ // this is the instruction that gets patched and coverage code gets in
+ // the way.
+ masm_->test(answer.reg(), Immediate(-delta_to_patch_site));
+ __ IncrementCounter(&Counters::named_load_inline_miss, 1);
+ receiver = cgen->frame()->Pop();
+ exit_.Jump(&receiver, &answer);
+}
+
+
class DeferredReferenceGetKeyedValue: public DeferredCode {
public:
DeferredReferenceGetKeyedValue(CodeGenerator* generator, bool is_global)
@@ -5334,16 +5379,63 @@
// thrown below, we must distinguish between the two kinds of
// loads (typeof expression loads must not throw a reference
// error).
- Comment cmnt(masm, "[ Load from named Property");
- cgen_->frame()->Push(GetName());
+ Variable* var = expression_->AsVariableProxy()->AsVariable();
+ bool is_global = var != NULL;
+ ASSERT(!is_global || var->is_global());
- Variable* var = expression_->AsVariableProxy()->AsVariable();
- ASSERT(var == NULL || var->is_global());
- RelocInfo::Mode mode = (var == NULL)
- ? RelocInfo::CODE_TARGET
- : RelocInfo::CODE_TARGET_CONTEXT;
- Result answer = cgen_->frame()->CallLoadIC(mode);
- cgen_->frame()->Push(&answer);
+ if (is_global || cgen_->scope()->is_global_scope()) {
+ // Do not inline the inobject property case for loads from the
+ // global object or loads in toplevel code.
+ Comment cmnt(masm, "[ Load from named Property");
+ cgen_->frame()->Push(GetName());
+
+ RelocInfo::Mode mode = is_global
+ ? RelocInfo::CODE_TARGET_CONTEXT
+ : RelocInfo::CODE_TARGET;
+ Result answer = cgen_->frame()->CallLoadIC(mode);
+ // A test eax instruction following the call signals that the
+ // inobject property case was inlined. Ensure that there is not
+ // a test eax instruction here.
+ __ nop();
+ cgen_->frame()->Push(&answer);
+ } else {
+ // Inline the inobject property case.
+ Comment cmnt(masm, "[ Inlined named property load");
+ DeferredReferenceGetNamedValue* deferred =
+ new DeferredReferenceGetNamedValue(cgen_, GetName());
+ Result receiver = cgen_->frame()->Pop();
+ receiver.ToRegister();
+ // Check that the receiver is a heap object.
+ __ test(receiver.reg(), Immediate(kSmiTagMask));
+ deferred->enter()->Branch(zero, &receiver, not_taken);
+
+ // Preallocate the value register to ensure that there is no
+ // spill emitted between the patch site label and the offset in
+ // the load instruction.
+ Result value = cgen_->allocator()->Allocate();
+ ASSERT(value.is_valid());
+ __ bind(deferred->patch_site());
+ // This is the map chack instruction that will be patched.
+ // Initially use an invalid map to force a failure.
+ __ cmp(FieldOperand(receiver.reg(), HeapObject::kMapOffset),
+ Immediate(Factory::null_value()));
+ deferred->enter()->Branch(not_equal, &receiver, not_taken);
+
+ // The delta from the patch label to the load offset must be
+ // statically known.
+ ASSERT(masm->SizeOfCodeGeneratedSince(deferred->patch_site()) ==
+ LoadIC::kOffsetToLoadInstruction);
+ // The initial (invalid) offset has to be large enough to force
+ // a 32-bit instruction encoding to allow patching with an
+ // arbitrary offset. Use kMaxInt (minus kHeapObjectTag).
+ int offset = kMaxInt;
+ __ mov(value.reg(), FieldOperand(receiver.reg(), offset));
+
+ __ IncrementCounter(&Counters::named_load_inline, 1);
+ deferred->BindExit(&receiver, &value);
+ cgen_->frame()->Push(&receiver);
+ cgen_->frame()->Push(&value);
+ }
break;
}
« no previous file with comments | « src/debug.cc ('k') | src/ia32/ic-ia32.cc » ('j') | src/ia32/ic-ia32.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698