commit b324d0bb99045fcfe80397a978eb2ce29af4990f Author: igorklopov Date: Mon Aug 17 11:31:50 2015 +0400 some older revisions mixed together diff --git a/src/code-stubs.cc b/src/code-stubs.cc index 0e68ab8..92aca16 100644 --- node/deps/v8/src/code-stubs.cc +++ node/deps/v8/src/code-stubs.cc @@ -252,6 +252,172 @@ void CodeStub::PrintName(OStream& os) const { // NOLINT } +void CheckCodeStub(CodeStub* pstub, CodeStub::Major MajorKey, int MinorKey) { + if (pstub->MajorKey() != MajorKey) fprintf(stderr, "MajorKey %d != %d in %s\n", pstub->MajorKey(), MajorKey, pstub->MajorName(MajorKey, false)); + if (pstub->MinorKey() != MinorKey) fprintf(stderr, "MinorKey %d != %d in %s\n", pstub->MinorKey(), MinorKey, pstub->MajorName(MajorKey, false)); + // if (pstub->MajorKey() == MajorKey) fprintf(stderr, "correct MajorKey in %s\n", pstub->MajorName(MajorKey, false)); + // if (pstub->MinorKey() == MinorKey) fprintf(stderr, "correct MinorKey in %s\n", pstub->MajorName(MajorKey, false)); +} + + +void CodeStub::Dispatch(Isolate* isolate, uint32_t key, void** value_out, + DispatchedCall call) { + CodeStub::Major MajorKey = MajorKeyFromKey(key); + int MinorKey = MinorKeyFromKey(key); + switch (MajorKey) { + case CEntry: { + // int result = (save_doubles_ == kSaveFPRegs) ? 1 : 0; + int result_size = (MinorKey & 0x02) ? 2 : 1; + // return result | ((result_size_ == 1) ? 0 : 2); + SaveFPRegsMode save_doubles = (MinorKey & 0x01) ? kSaveFPRegs : kDontSaveFPRegs; + CEntryStub stub(isolate, result_size, save_doubles); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case CallConstruct: { + // int MinorKey() const { return flags_; } + CallConstructorFlags flags = (CallConstructorFlags) MinorKey; + CallConstructStub stub(isolate, flags); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case FastNewContext: { + // int NotMissMinorKey() const V8_OVERRIDE { return slots_; } + int slots = MinorKey; + FastNewContextStub stub(isolate, slots); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case FastNewClosure: { + // class StrictModeBits: public BitField {}; + StrictMode strict_mode = (StrictMode) (MinorKey & 0x01); + // class IsGeneratorBits: public BitField {}; + bool is_generator = MinorKey & 0x02; + FastNewClosureStub stub(isolate, strict_mode, is_generator); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case RecordWrite: { + #if V8_TARGET_ARCH_IA32 + // class ObjectBits: public BitField {}; + Register object = Register::from_code(MinorKey & 0x07); + // class ValueBits: public BitField {}; + Register value = Register::from_code((MinorKey >> 3) & 0x07); + // class AddressBits: public BitField {}; + Register address = Register::from_code((MinorKey >> 6) & 0x07); + // class RememberedSetActionBits: public BitField {}; + RememberedSetAction remembered_set_action = (RememberedSetAction) ((MinorKey >> 9) & 0x01); + // class SaveFPRegsModeBits: public BitField {}; + SaveFPRegsMode fp_mode = (SaveFPRegsMode) ((MinorKey >> 10) & 0x01); + RecordWriteStub stub(isolate, object, value, address, remembered_set_action, fp_mode); + #endif + #if V8_TARGET_ARCH_X64 + // class ObjectBits: public BitField {}; + Register object = Register::from_code(MinorKey & 0x0F); + // class ValueBits: public BitField {}; + Register value = Register::from_code((MinorKey >> 4) & 0x0F); + // class AddressBits: public BitField {}; + Register address = Register::from_code((MinorKey >> 8) & 0x0F); + // class RememberedSetActionBits: public BitField {}; + RememberedSetAction remembered_set_action = (RememberedSetAction) ((MinorKey >> 12) & 0x01); + // class SaveFPRegsModeBits: public BitField {}; + SaveFPRegsMode fp_mode = (SaveFPRegsMode) ((MinorKey >> 13) & 0x01); + RecordWriteStub stub(isolate, object, value, address, remembered_set_action, fp_mode); + #endif + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case ToNumber: { + ToNumberStub stub(isolate); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case ArgumentsAccess: { + // int MinorKey() const { return type_; } + ArgumentsAccessStub::Type type = (ArgumentsAccessStub::Type) MinorKey; + ArgumentsAccessStub stub(isolate, type); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case FastCloneShallowArray: { + // class AllocationSiteModeBits: public BitField {}; + AllocationSiteMode allocation_site_mode = (AllocationSiteMode) (MinorKey & 0x01); + FastCloneShallowArrayStub stub(isolate, allocation_site_mode); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case StoreArrayLiteralElement: { + StoreArrayLiteralElementStub stub(isolate); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case CallFunction: { + // class FlagBits: public BitField {}; + CallFunctionFlags flags = (CallFunctionFlags) (MinorKey & 0x03); + // class ArgcBits : public BitField {}; + unsigned argc = MinorKey >> 2; + CallFunctionStub stub(isolate, argc, flags); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case Instanceof: { + // int MinorKey() const { return static_cast(flags_); } + InstanceofStub::Flags flags = (InstanceofStub::Flags) MinorKey; + InstanceofStub stub(isolate, flags); + CodeStub* pstub = &stub; + CheckCodeStub(pstub, MajorKey, MinorKey); + call(pstub, value_out); + break; + } + case NUMBER_OF_IDS: + UNREACHABLE(); + case NoCache: + *value_out = NULL; + break; + default: { + fprintf(stderr, "unhandled MajorKey: %s (%d)\n", MajorName(MajorKey, false), MajorKey); + UNREACHABLE(); + } + } +} + + +void CodeStub::GetCodeDispatchCall(CodeStub* stub, void** value_out) { + Handle* code_out = reinterpret_cast*>(value_out); + // Code stubs with special cache cannot be recreated from stub key. + *code_out = stub->UseSpecialCache() ? Handle() : stub->GetCode(); +} + + +MaybeHandle CodeStub::GetCode(Isolate* isolate, uint32_t key) { + HandleScope scope(isolate); + Handle code; + void** value_out = reinterpret_cast(&code); + Dispatch(isolate, key, value_out, &GetCodeDispatchCall); + return scope.CloseAndEscape(code); +} + + // static void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) { // Generate the uninitialized versions of the stub. diff --git a/src/code-stubs.h b/src/code-stubs.h index c1d051b..9cc12df 100644 --- node/deps/v8/src/code-stubs.h +++ node/deps/v8/src/code-stubs.h @@ -179,6 +179,8 @@ class CodeStub BASE_EMBEDDED { // Lookup the code in the (possibly custom) cache. bool FindCodeInCache(Code** code_out); + static MaybeHandle GetCode(Isolate* isolate, uint32_t key); + // Returns information for computing the number key. virtual Major MajorKey() const = 0; virtual int MinorKey() const = 0; @@ -242,6 +244,14 @@ class CodeStub BASE_EMBEDDED { // If a stub uses a special cache override this. virtual bool UseSpecialCache() { return false; } + // We use this dispatch to statically instantiate the correct code stub for + // the given stub key and call the passed function with that code stub. + typedef void (*DispatchedCall)(CodeStub* stub, void** value_out); + static void Dispatch(Isolate* isolate, uint32_t key, void** value_out, + DispatchedCall call); + + static void GetCodeDispatchCall(CodeStub* stub, void** value_out); + STATIC_ASSERT(NUMBER_OF_IDS < (1 << kStubMajorKeyBits)); class MajorKeyBits: public BitField {}; class MinorKeyBits: public BitField