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

Side by Side Diff: src/asmjs/asm-wasm-builder.cc

Issue 2384623003: [wasm] [asm.js] Track direct function indices and fixup. (Closed)
Patch Set: fix Created 4 years, 2 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 unified diff | Download patch
« no previous file with comments | « no previous file | src/wasm/wasm-module-builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 // Required to get M_E etc. in MSVC. 7 // Required to get M_E etc. in MSVC.
8 #if defined(_WIN32) 8 #if defined(_WIN32)
9 #define _USE_MATH_DEFINES 9 #define _USE_MATH_DEFINES
10 #endif 10 #endif
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 i::Handle<i::FixedArray> GetForeignArgs() { 101 i::Handle<i::FixedArray> GetForeignArgs() {
102 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray( 102 i::Handle<FixedArray> ret = isolate_->factory()->NewFixedArray(
103 static_cast<int>(foreign_variables_.size())); 103 static_cast<int>(foreign_variables_.size()));
104 for (size_t i = 0; i < foreign_variables_.size(); ++i) { 104 for (size_t i = 0; i < foreign_variables_.size(); ++i) {
105 ForeignVariable* fv = &foreign_variables_[i]; 105 ForeignVariable* fv = &foreign_variables_[i];
106 ret->set(static_cast<int>(i), *fv->name); 106 ret->set(static_cast<int>(i), *fv->name);
107 } 107 }
108 return ret; 108 return ret;
109 } 109 }
110 110
111 void BuildImports() {
112 for (const AsmTyper::FFIUseSignature& ffi : typer_->FFIUseSignatures()) {
113 size_t ret_count = ffi.return_type_ == AsmType::Void() ? 0 : 1;
114 FunctionSig::Builder b(zone_, ret_count, ffi.arg_types_.size());
115 for (AsmType* arg : ffi.arg_types_) b.AddParam(TypeFrom(arg));
116 if (ffi.return_type_ != AsmType::Void()) {
117 b.AddReturn(TypeFrom(ffi.return_type_));
118 }
119 imported_function_table_.AddFunction(ffi.var, b.Build());
120 }
121 }
122
123 void Build() { 111 void Build() {
124 BuildImports();
125 InitializeInitFunction(); 112 InitializeInitFunction();
126 RECURSE(VisitFunctionLiteral(literal_)); 113 RECURSE(VisitFunctionLiteral(literal_));
127 BuildForeignInitFunction(); 114 BuildForeignInitFunction();
128 } 115 }
129 116
130 void VisitVariableDeclaration(VariableDeclaration* decl) {} 117 void VisitVariableDeclaration(VariableDeclaration* decl) {}
131 118
132 void VisitFunctionDeclaration(FunctionDeclaration* decl) { 119 void VisitFunctionDeclaration(FunctionDeclaration* decl) {
133 DCHECK_EQ(kModuleScope, scope_); 120 DCHECK_EQ(kModuleScope, scope_);
134 DCHECK_NULL(current_function_builder_); 121 DCHECK_NULL(current_function_builder_);
(...skipping 591 matching lines...) Expand 10 before | Expand all | Expand 10 after
726 ZoneHashMap::Entry* entry = 713 ZoneHashMap::Entry* entry =
727 function_tables_.Lookup(v, ComputePointerHash(v)); 714 function_tables_.Lookup(v, ComputePointerHash(v));
728 DCHECK_NOT_NULL(entry); 715 DCHECK_NOT_NULL(entry);
729 return reinterpret_cast<FunctionTableIndices*>(entry->value); 716 return reinterpret_cast<FunctionTableIndices*>(entry->value);
730 } 717 }
731 718
732 class ImportedFunctionTable { 719 class ImportedFunctionTable {
733 private: 720 private:
734 class ImportedFunctionIndices : public ZoneObject { 721 class ImportedFunctionIndices : public ZoneObject {
735 public: 722 public:
736 bool has_name_; 723 const char* name_;
724 int name_length_;
737 WasmModuleBuilder::SignatureMap signature_to_index_; 725 WasmModuleBuilder::SignatureMap signature_to_index_;
738 726
739 explicit ImportedFunctionIndices(Zone* zone) 727 ImportedFunctionIndices(const char* name, int name_length, Zone* zone)
740 : has_name_(false), signature_to_index_(zone) {} 728 : name_(name), name_length_(name_length), signature_to_index_(zone) {}
741 }; 729 };
742 ZoneHashMap table_; 730 ZoneHashMap table_;
743 AsmWasmBuilderImpl* builder_; 731 AsmWasmBuilderImpl* builder_;
744 732
745 public: 733 public:
746 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder) 734 explicit ImportedFunctionTable(AsmWasmBuilderImpl* builder)
747 : table_(ZoneHashMap::kDefaultHashMapCapacity, 735 : table_(ZoneHashMap::kDefaultHashMapCapacity,
748 ZoneAllocationPolicy(builder->zone())), 736 ZoneAllocationPolicy(builder->zone())),
749 builder_(builder) {} 737 builder_(builder) {}
750 738
751 // Set the imported name of a variable. Must happen after all signatures 739 void AddImport(Variable* v, const char* name, int name_length) {
752 // (and thus import indices) are added for a given variable. 740 ImportedFunctionIndices* indices = new (builder_->zone())
753 void SetImportName(Variable* v, const char* name, int name_length) { 741 ImportedFunctionIndices(name, name_length, builder_->zone());
754 auto indices = GetEntry(v); 742 auto* entry = table_.LookupOrInsert(
755 if (indices) { 743 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone()));
756 for (auto entry : indices->signature_to_index_) { 744 entry->value = indices;
757 uint32_t index = entry.second;
758 builder_->builder_->SetImportName(index, name, name_length);
759 }
760 indices->has_name_ = true;
761 }
762 } 745 }
763 746
764 // Get a function's index. Does not insert new entries. 747 // Get a function's index (or allocate if new).
765 uint32_t GetFunctionIndex(Variable* v, FunctionSig* sig) { 748 uint32_t LookupOrInsertImport(Variable* v, FunctionSig* sig) {
766 auto indices = GetEntry(v); 749 ZoneHashMap::Entry* entry = table_.Lookup(v, ComputePointerHash(v));
767 DCHECK_NOT_NULL(indices); 750 DCHECK_NOT_NULL(entry);
768 auto pos = indices->signature_to_index_.find(sig); 751 ImportedFunctionIndices* indices =
769 DCHECK(pos != indices->signature_to_index_.end()); 752 reinterpret_cast<ImportedFunctionIndices*>(entry->value);
770 return pos->second; 753 WasmModuleBuilder::SignatureMap::iterator pos =
771 } 754 indices->signature_to_index_.find(sig);
772 755 if (pos != indices->signature_to_index_.end()) {
773 // Add a function and register it as an import with the builder. 756 return pos->second;
774 void AddFunction(Variable* v, FunctionSig* sig) { 757 } else {
775 auto entry = table_.LookupOrInsert( 758 uint32_t index = builder_->builder_->AddImport(
776 v, ComputePointerHash(v), ZoneAllocationPolicy(builder_->zone())); 759 indices->name_, indices->name_length_, sig);
777 if (entry->value == nullptr) { 760 indices->signature_to_index_[sig] = index;
778 entry->value = 761 return index;
779 new (builder_->zone()) ImportedFunctionIndices(builder_->zone());
780 } 762 }
781 auto indices = reinterpret_cast<ImportedFunctionIndices*>(entry->value);
782 DCHECK(!indices->has_name_);
783 auto pos = indices->signature_to_index_.find(sig);
784 if (pos == indices->signature_to_index_.end()) {
785 // A new import. Name is not known up front.
786 uint32_t index = builder_->builder_->AddImport(nullptr, 0, sig);
787 indices->signature_to_index_[sig] = index;
788 }
789 }
790
791 ImportedFunctionIndices* GetEntry(Variable* v) {
792 auto entry = table_.Lookup(v, ComputePointerHash(v));
793 if (entry == nullptr) return nullptr;
794 return reinterpret_cast<ImportedFunctionIndices*>(entry->value);
795 } 763 }
796 }; 764 };
797 765
798 void EmitAssignmentLhs(Expression* target, MachineType* mtype) { 766 void EmitAssignmentLhs(Expression* target, MachineType* mtype) {
799 // Match the left hand side of the assignment. 767 // Match the left hand side of the assignment.
800 VariableProxy* target_var = target->AsVariableProxy(); 768 VariableProxy* target_var = target->AsVariableProxy();
801 if (target_var != nullptr) { 769 if (target_var != nullptr) {
802 // Left hand side is a local or a global variable, no code on LHS. 770 // Left hand side is a local or a global variable, no code on LHS.
803 return; 771 return;
804 } 772 }
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 } 903 }
936 Property* prop = expr->value()->AsProperty(); 904 Property* prop = expr->value()->AsProperty();
937 if (prop != nullptr) { 905 if (prop != nullptr) {
938 VariableProxy* vp = prop->obj()->AsVariableProxy(); 906 VariableProxy* vp = prop->obj()->AsVariableProxy();
939 if (vp != nullptr && vp->var()->IsParameter() && 907 if (vp != nullptr && vp->var()->IsParameter() &&
940 vp->var()->index() == 1) { 908 vp->var()->index() == 1) {
941 VariableProxy* target = expr->target()->AsVariableProxy(); 909 VariableProxy* target = expr->target()->AsVariableProxy();
942 if (typer_->TypeOf(target)->AsFFIType() != nullptr) { 910 if (typer_->TypeOf(target)->AsFFIType() != nullptr) {
943 const AstRawString* name = 911 const AstRawString* name =
944 prop->key()->AsLiteral()->AsRawPropertyName(); 912 prop->key()->AsLiteral()->AsRawPropertyName();
945 imported_function_table_.SetImportName( 913 imported_function_table_.AddImport(
946 target->var(), reinterpret_cast<const char*>(name->raw_data()), 914 target->var(), reinterpret_cast<const char*>(name->raw_data()),
947 name->length()); 915 name->length());
948 } 916 }
949 } 917 }
950 // Property values in module scope don't emit code, so return. 918 // Property values in module scope don't emit code, so return.
951 return; 919 return;
952 } 920 }
953 ArrayLiteral* funcs = expr->value()->AsArrayLiteral(); 921 ArrayLiteral* funcs = expr->value()->AsArrayLiteral();
954 if (funcs != nullptr && 922 if (funcs != nullptr &&
955 typer_->TypeOf(funcs) 923 typer_->TypeOf(funcs)
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after
1386 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1, 1354 FunctionSig::Builder sig(zone(), return_type == kAstStmt ? 0 : 1,
1387 args->length()); 1355 args->length());
1388 if (return_type != kAstStmt) { 1356 if (return_type != kAstStmt) {
1389 sig.AddReturn(return_type); 1357 sig.AddReturn(return_type);
1390 } else { 1358 } else {
1391 returns_value = false; 1359 returns_value = false;
1392 } 1360 }
1393 for (int i = 0; i < args->length(); ++i) { 1361 for (int i = 0; i < args->length(); ++i) {
1394 sig.AddParam(TypeOf(args->at(i))); 1362 sig.AddParam(TypeOf(args->at(i)));
1395 } 1363 }
1396 uint32_t index = 1364 uint32_t index = imported_function_table_.LookupOrInsertImport(
1397 imported_function_table_.GetFunctionIndex(vp->var(), sig.Build()); 1365 vp->var(), sig.Build());
1398 VisitCallArgs(expr); 1366 VisitCallArgs(expr);
1399 current_function_builder_->Emit(kExprCallFunction); 1367 current_function_builder_->Emit(kExprCallFunction);
1400 current_function_builder_->EmitVarInt(index); 1368 current_function_builder_->EmitVarInt(index);
1401 } else { 1369 } else {
1402 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var()); 1370 WasmFunctionBuilder* function = LookupOrInsertFunction(vp->var());
1403 VisitCallArgs(expr); 1371 VisitCallArgs(expr);
1404 current_function_builder_->Emit(kExprCallFunction); 1372 current_function_builder_->Emit(kExprCallFunction);
1405 current_function_builder_->EmitVarInt(function->func_index()); 1373 current_function_builder_->EmitDirectCallIndex(
1374 function->func_index());
1406 returns_value = function->signature()->return_count() > 0; 1375 returns_value = function->signature()->return_count() > 0;
1407 } 1376 }
1408 break; 1377 break;
1409 } 1378 }
1410 case Call::KEYED_PROPERTY_CALL: { 1379 case Call::KEYED_PROPERTY_CALL: {
1411 DCHECK_EQ(kFuncScope, scope_); 1380 DCHECK_EQ(kFuncScope, scope_);
1412 Property* p = expr->expression()->AsProperty(); 1381 Property* p = expr->expression()->AsProperty();
1413 DCHECK_NOT_NULL(p); 1382 DCHECK_NOT_NULL(p);
1414 VariableProxy* var = p->obj()->AsVariableProxy(); 1383 VariableProxy* var = p->obj()->AsVariableProxy();
1415 DCHECK_NOT_NULL(var); 1384 DCHECK_NOT_NULL(var);
(...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 impl.builder_->WriteTo(*buffer); 1883 impl.builder_->WriteTo(*buffer);
1915 return buffer; 1884 return buffer;
1916 } 1885 }
1917 1886
1918 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__"; 1887 const char* AsmWasmBuilder::foreign_init_name = "__foreign_init__";
1919 const char* AsmWasmBuilder::single_function_name = "__single_function__"; 1888 const char* AsmWasmBuilder::single_function_name = "__single_function__";
1920 1889
1921 } // namespace wasm 1890 } // namespace wasm
1922 } // namespace internal 1891 } // namespace internal
1923 } // namespace v8 1892 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/wasm/wasm-module-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698